aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CREDITS2
-rw-r--r--Documentation/Changes31
-rw-r--r--Documentation/CodingStyle41
-rw-r--r--Documentation/RCU/rcuref.txt87
-rw-r--r--Documentation/SubmittingDrivers24
-rw-r--r--Documentation/SubmittingPatches63
-rw-r--r--Documentation/applying-patches.txt29
-rw-r--r--Documentation/block/stat.txt82
-rw-r--r--Documentation/cpu-hotplug.txt357
-rw-r--r--Documentation/cpusets.txt161
-rw-r--r--Documentation/dvb/avermedia.txt3
-rw-r--r--Documentation/dvb/get_dvb_firmware23
-rw-r--r--Documentation/dvb/ttusb-dec.txt3
-rw-r--r--Documentation/fb/cyblafb/bugs1
-rw-r--r--Documentation/fb/cyblafb/fb.modes57
-rw-r--r--Documentation/fb/cyblafb/performance1
-rw-r--r--Documentation/fb/cyblafb/todo5
-rw-r--r--Documentation/fb/cyblafb/usage33
-rw-r--r--Documentation/fb/cyblafb/whatsnew29
-rw-r--r--Documentation/filesystems/ext3.txt5
-rw-r--r--Documentation/filesystems/proc.txt17
-rw-r--r--Documentation/filesystems/ramfs-rootfs-initramfs.txt72
-rw-r--r--Documentation/filesystems/relayfs.txt126
-rw-r--r--Documentation/filesystems/spufs.txt521
-rw-r--r--Documentation/keys-request-key.txt22
-rw-r--r--Documentation/keys.txt43
-rw-r--r--Documentation/kprobes.txt3
-rw-r--r--Documentation/networking/bonding.txt2
-rw-r--r--Documentation/powerpc/00-INDEX10
-rw-r--r--Documentation/sysctl/vm.txt20
-rw-r--r--Documentation/video4linux/CARDLIST.bttv1
-rw-r--r--Documentation/video4linux/CARDLIST.cx8810
-rw-r--r--Documentation/video4linux/CARDLIST.saa71345
-rw-r--r--Documentation/video4linux/CARDLIST.tuner6
-rw-r--r--MAINTAINERS2
-rw-r--r--README7
-rw-r--r--arch/alpha/Kconfig3
-rw-r--r--arch/alpha/kernel/process.c5
-rw-r--r--arch/alpha/kernel/ptrace.c24
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/common/scoop.c1
-rw-r--r--arch/arm/kernel/asm-offsets.c9
-rw-r--r--arch/arm/kernel/irq.c14
-rw-r--r--arch/arm/mach-footbridge/netwinder-hw.c1
-rw-r--r--arch/arm/mach-integrator/time.c5
-rw-r--r--arch/arm/mach-omap1/serial.c3
-rw-r--r--arch/arm/mach-pxa/corgi.c7
-rw-r--r--arch/arm/mach-pxa/poodle.c7
-rw-r--r--arch/arm/mach-pxa/spitz.c7
-rw-r--r--arch/arm/mach-realview/localtimer.c1
-rw-r--r--arch/arm/mach-s3c2410/usb-simtec.c6
-rw-r--r--arch/arm26/Kconfig4
-rw-r--r--arch/arm26/kernel/asm-offsets.c7
-rw-r--r--arch/cris/Kconfig4
-rw-r--r--arch/frv/Kconfig23
-rw-r--r--arch/frv/Kconfig.debug22
-rw-r--r--arch/frv/Makefile6
-rw-r--r--arch/frv/kernel/Makefile1
-rw-r--r--arch/frv/kernel/frv_ksyms.c25
-rw-r--r--arch/frv/kernel/irq.c17
-rw-r--r--arch/frv/kernel/module.c80
-rw-r--r--arch/frv/kernel/pm.c2
-rw-r--r--arch/frv/kernel/setup.c2
-rw-r--r--arch/frv/kernel/time.c3
-rw-r--r--arch/frv/kernel/traps.c3
-rw-r--r--arch/frv/kernel/uaccess.c7
-rw-r--r--arch/frv/kernel/vmlinux.lds.S1
-rw-r--r--arch/frv/lib/Makefile2
-rw-r--r--arch/frv/lib/__ucmpdi2.S45
-rw-r--r--arch/frv/lib/atomic-ops.S92
-rw-r--r--arch/frv/lib/checksum.c31
-rw-r--r--arch/frv/mb93090-mb00/Makefile2
-rw-r--r--arch/frv/mb93090-mb00/pci-dma-nommu.c8
-rw-r--r--arch/frv/mb93090-mb00/pci-dma.c10
-rw-r--r--arch/frv/mb93090-mb00/pci-iomap.c29
-rw-r--r--arch/frv/mm/cache-page.c5
-rw-r--r--arch/frv/mm/extable.c34
-rw-r--r--arch/frv/mm/highmem.c8
-rw-r--r--arch/h8300/Kconfig4
-rw-r--r--arch/i386/Kconfig10
-rw-r--r--arch/i386/Makefile5
-rw-r--r--arch/i386/Makefile.cpu10
-rw-r--r--arch/i386/boot/compressed/misc.c2
-rw-r--r--arch/i386/kernel/Makefile6
-rw-r--r--arch/i386/kernel/apm.c4
-rw-r--r--arch/i386/kernel/cpu/common.c2
-rw-r--r--arch/i386/kernel/entry.S2
-rw-r--r--arch/i386/kernel/init_task.c2
-rw-r--r--arch/i386/kernel/irq.c2
-rw-r--r--arch/i386/kernel/process.c1
-rw-r--r--arch/i386/kernel/syscall_table.S1
-rw-r--r--arch/i386/kernel/time_hpet.c2
-rw-r--r--arch/ia64/Makefile4
-rw-r--r--arch/ia64/ia32/sys_ia32.c16
-rw-r--r--arch/ia64/kernel/efi.c160
-rw-r--r--arch/ia64/kernel/entry.S1
-rw-r--r--arch/ia64/kernel/head.S2
-rw-r--r--arch/ia64/kernel/ia64_ksyms.c2
-rw-r--r--arch/ia64/kernel/ptrace.c9
-rw-r--r--arch/ia64/oprofile/backtrace.c2
-rw-r--r--arch/m32r/kernel/process.c4
-rw-r--r--arch/m32r/kernel/ptrace.c22
-rw-r--r--arch/m68k/Kconfig4
-rw-r--r--arch/m68knommu/Kconfig4
-rw-r--r--arch/mips/kernel/ptrace32.c26
-rw-r--r--arch/mips/kernel/vpe.c3
-rw-r--r--arch/mips/sgi-ip27/ip27-berr.c1
-rw-r--r--arch/parisc/Kconfig3
-rw-r--r--arch/powerpc/Kconfig33
-rw-r--r--arch/powerpc/Makefile2
-rw-r--r--arch/powerpc/boot/Makefile30
-rw-r--r--arch/powerpc/configs/pmac32_defconfig1729
-rw-r--r--arch/powerpc/kernel/Makefile22
-rw-r--r--arch/powerpc/kernel/asm-offsets.c6
-rw-r--r--arch/powerpc/kernel/btext.c136
-rw-r--r--arch/powerpc/kernel/cputable.c106
-rw-r--r--arch/powerpc/kernel/crash.c264
-rw-r--r--arch/powerpc/kernel/crash_dump.c109
-rw-r--r--arch/powerpc/kernel/dma_64.c9
-rw-r--r--arch/powerpc/kernel/entry_32.S167
-rw-r--r--arch/powerpc/kernel/entry_64.S218
-rw-r--r--arch/powerpc/kernel/head_32.S56
-rw-r--r--arch/powerpc/kernel/head_64.S41
-rw-r--r--arch/powerpc/kernel/ibmebus.c396
-rw-r--r--arch/powerpc/kernel/irq.c81
-rw-r--r--arch/powerpc/kernel/legacy_serial.c557
-rw-r--r--arch/powerpc/kernel/lparmap.c12
-rw-r--r--arch/powerpc/kernel/machine_kexec.c67
-rw-r--r--arch/powerpc/kernel/machine_kexec_32.c65
-rw-r--r--arch/powerpc/kernel/machine_kexec_64.c43
-rw-r--r--arch/powerpc/kernel/misc_32.S113
-rw-r--r--arch/powerpc/kernel/nvram_64.c106
-rw-r--r--arch/powerpc/kernel/paca.c11
-rw-r--r--arch/powerpc/kernel/pci_64.c87
-rw-r--r--arch/powerpc/kernel/pmc.c5
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c5
-rw-r--r--arch/powerpc/kernel/prom.c468
-rw-r--r--arch/powerpc/kernel/prom_init.c60
-rw-r--r--arch/powerpc/kernel/prom_parse.c547
-rw-r--r--arch/powerpc/kernel/ptrace32.c28
-rw-r--r--arch/powerpc/kernel/rtas_pci.c49
-rw-r--r--arch/powerpc/kernel/setup-common.c129
-rw-r--r--arch/powerpc/kernel/setup_32.c34
-rw-r--r--arch/powerpc/kernel/setup_64.c207
-rw-r--r--arch/powerpc/kernel/signal_32.c68
-rw-r--r--arch/powerpc/kernel/signal_64.c23
-rw-r--r--arch/powerpc/kernel/smp.c29
-rw-r--r--arch/powerpc/kernel/syscalls.c28
-rw-r--r--arch/powerpc/kernel/systbl.S14
-rw-r--r--arch/powerpc/kernel/time.c4
-rw-r--r--arch/powerpc/kernel/traps.c25
-rw-r--r--arch/powerpc/kernel/udbg.c27
-rw-r--r--arch/powerpc/kernel/udbg_16550.c69
-rw-r--r--arch/powerpc/mm/fault.c7
-rw-r--r--arch/powerpc/mm/hash_utils_64.c7
-rw-r--r--arch/powerpc/mm/hugetlbpage.c42
-rw-r--r--arch/powerpc/mm/imalloc.c2
-rw-r--r--arch/powerpc/mm/init_32.c5
-rw-r--r--arch/powerpc/mm/mem.c13
-rw-r--r--arch/powerpc/mm/numa.c139
-rw-r--r--arch/powerpc/mm/slb.c16
-rw-r--r--arch/powerpc/mm/slb_low.S6
-rw-r--r--arch/powerpc/mm/stab.c16
-rw-r--r--arch/powerpc/mm/tlb_64.c2
-rw-r--r--arch/powerpc/oprofile/Makefile1
-rw-r--r--arch/powerpc/oprofile/common.c83
-rw-r--r--arch/powerpc/oprofile/op_model_7450.c206
-rw-r--r--arch/powerpc/oprofile/op_model_power4.c4
-rw-r--r--arch/powerpc/oprofile/op_model_rs64.c3
-rw-r--r--arch/powerpc/platforms/cell/Kconfig13
-rw-r--r--arch/powerpc/platforms/cell/Makefile8
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c42
-rw-r--r--arch/powerpc/platforms/cell/interrupt.h1
-rw-r--r--arch/powerpc/platforms/cell/iommu.c225
-rw-r--r--arch/powerpc/platforms/cell/pervasive.c229
-rw-r--r--arch/powerpc/platforms/cell/pervasive.h62
-rw-r--r--arch/powerpc/platforms/cell/setup.c93
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c711
-rw-r--r--arch/powerpc/platforms/cell/spu_priv1.c133
-rw-r--r--arch/powerpc/platforms/cell/spu_syscalls.c88
-rw-r--r--arch/powerpc/platforms/cell/spufs/Makefile54
-rw-r--r--arch/powerpc/platforms/cell/spufs/backing_ops.c308
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c167
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c794
-rw-r--r--arch/powerpc/platforms/cell/spufs/hw_ops.c255
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c486
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c131
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c461
-rw-r--r--arch/powerpc/platforms/cell/spufs/spu_restore.c336
-rw-r--r--arch/powerpc/platforms/cell/spufs/spu_restore_crt0.S116
-rw-r--r--arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped231
-rw-r--r--arch/powerpc/platforms/cell/spufs/spu_save.c195
-rw-r--r--arch/powerpc/platforms/cell/spufs/spu_save_crt0.S102
-rw-r--r--arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped191
-rw-r--r--arch/powerpc/platforms/cell/spufs/spu_utils.h160
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h163
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c2180
-rw-r--r--arch/powerpc/platforms/cell/spufs/syscalls.c101
-rw-r--r--arch/powerpc/platforms/chrp/setup.c16
-rw-r--r--arch/powerpc/platforms/iseries/irq.c337
-rw-r--r--arch/powerpc/platforms/iseries/irq.h1
-rw-r--r--arch/powerpc/platforms/iseries/lpardata.c7
-rw-r--r--arch/powerpc/platforms/iseries/setup.c10
-rw-r--r--arch/powerpc/platforms/maple/setup.c24
-rw-r--r--arch/powerpc/platforms/powermac/Makefile7
-rw-r--r--arch/powerpc/platforms/powermac/bootx_init.c547
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_64.c496
-rw-r--r--arch/powerpc/platforms/powermac/feature.c367
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c1414
-rw-r--r--arch/powerpc/platforms/powermac/nvram.c53
-rw-r--r--arch/powerpc/platforms/powermac/pci.c299
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_base.c405
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_core.c989
-rw-r--r--arch/powerpc/platforms/powermac/pic.c474
-rw-r--r--arch/powerpc/platforms/powermac/pmac.h6
-rw-r--r--arch/powerpc/platforms/powermac/setup.c107
-rw-r--r--arch/powerpc/platforms/powermac/smp.c382
-rw-r--r--arch/powerpc/platforms/powermac/time.c15
-rw-r--r--arch/powerpc/platforms/powermac/udbg_adb.c221
-rw-r--r--arch/powerpc/platforms/powermac/udbg_scc.c (renamed from arch/powerpc/kernel/udbg_scc.c)66
-rw-r--r--arch/powerpc/platforms/pseries/Makefile2
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c26
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c12
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c76
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c174
-rw-r--r--arch/powerpc/platforms/pseries/ras.c11
-rw-r--r--arch/powerpc/platforms/pseries/ras.h9
-rw-r--r--arch/powerpc/platforms/pseries/setup.c55
-rw-r--r--arch/powerpc/platforms/pseries/xics.c2
-rw-r--r--arch/powerpc/sysdev/Makefile3
-rw-r--r--arch/powerpc/sysdev/dart.h41
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c (renamed from arch/powerpc/sysdev/u3_iommu.c)173
-rw-r--r--arch/powerpc/sysdev/ipic.c (renamed from arch/ppc/syslib/ipic.c)0
-rw-r--r--arch/powerpc/sysdev/ipic.h (renamed from arch/ppc/syslib/ipic.h)0
-rw-r--r--arch/powerpc/sysdev/mpic.c247
-rw-r--r--arch/powerpc/xmon/Makefile8
-rw-r--r--arch/powerpc/xmon/start.c (renamed from arch/powerpc/xmon/start_64.c)0
-rw-r--r--arch/powerpc/xmon/start_32.c441
-rw-r--r--arch/powerpc/xmon/start_8xx.c44
-rw-r--r--arch/powerpc/xmon/xmon.c8
-rw-r--r--arch/ppc/Kconfig3
-rw-r--r--arch/ppc/boot/common/util.S6
-rw-r--r--arch/ppc/boot/images/Makefile2
-rw-r--r--arch/ppc/configs/TQM8540_defconfig973
-rw-r--r--arch/ppc/configs/TQM8541_defconfig986
-rw-r--r--arch/ppc/configs/TQM8555_defconfig983
-rw-r--r--arch/ppc/configs/TQM8560_defconfig992
-rw-r--r--arch/ppc/kernel/Makefile1
-rw-r--r--arch/ppc/kernel/asm-offsets.c2
-rw-r--r--arch/ppc/kernel/entry.S167
-rw-r--r--arch/ppc/kernel/misc.S6
-rw-r--r--arch/ppc/kernel/pci.c28
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c5
-rw-r--r--arch/ppc/kernel/setup.c3
-rw-r--r--arch/ppc/platforms/85xx/Kconfig28
-rw-r--r--arch/ppc/platforms/85xx/Makefile4
-rw-r--r--arch/ppc/platforms/85xx/tqm85xx.c419
-rw-r--r--arch/ppc/platforms/85xx/tqm85xx.h56
-rw-r--r--arch/ppc/platforms/chrp_setup.c1
-rw-r--r--arch/ppc/platforms/prep_setup.c2
-rw-r--r--arch/ppc/syslib/Makefile2
-rw-r--r--arch/ppc/syslib/m8xx_setup.c15
-rw-r--r--arch/ppc/syslib/m8xx_wdt.c92
-rw-r--r--arch/ppc/syslib/m8xx_wdt.h4
-rw-r--r--arch/s390/kernel/ptrace.c29
-rw-r--r--arch/sh/Kconfig4
-rw-r--r--arch/sh64/kernel/time.c7
-rw-r--r--arch/sparc/Kconfig4
-rw-r--r--arch/sparc/kernel/ptrace.c35
-rw-r--r--arch/sparc64/Kconfig5
-rw-r--r--arch/sparc64/kernel/ptrace.c34
-rw-r--r--arch/um/Kconfig6
-rw-r--r--arch/um/drivers/ubd_kern.c21
-rw-r--r--arch/um/include/kern_util.h19
-rw-r--r--arch/um/include/os.h16
-rw-r--r--arch/um/include/signal_user.h28
-rw-r--r--arch/um/include/user_util.h10
-rw-r--r--arch/um/kernel/Makefile4
-rw-r--r--arch/um/kernel/irq_user.c1
-rw-r--r--arch/um/kernel/process_kern.c1
-rw-r--r--arch/um/kernel/reboot.c2
-rw-r--r--arch/um/kernel/signal_kern.c1
-rw-r--r--arch/um/kernel/signal_user.c157
-rw-r--r--arch/um/kernel/skas/Makefile2
-rw-r--r--arch/um/kernel/skas/include/skas.h1
-rw-r--r--arch/um/kernel/skas/process.c11
-rw-r--r--arch/um/kernel/skas/process_kern.c1
-rw-r--r--arch/um/kernel/time.c2
-rw-r--r--arch/um/kernel/trap_kern.c25
-rw-r--r--arch/um/kernel/trap_user.c98
-rw-r--r--arch/um/kernel/tt/exec_kern.c1
-rw-r--r--arch/um/kernel/tt/process_kern.c1
-rw-r--r--arch/um/kernel/tt/tracer.c1
-rw-r--r--arch/um/kernel/tt/trap_user.c16
-rw-r--r--arch/um/kernel/um_arch.c7
-rw-r--r--arch/um/os-Linux/Makefile8
-rw-r--r--arch/um/os-Linux/main.c1
-rw-r--r--arch/um/os-Linux/process.c1
-rw-r--r--arch/um/os-Linux/signal.c158
-rw-r--r--arch/um/os-Linux/skas/Makefile10
-rw-r--r--arch/um/os-Linux/skas/trap.c (renamed from arch/um/kernel/skas/trap_user.c)49
-rw-r--r--arch/um/os-Linux/start_up.c1
-rw-r--r--arch/um/os-Linux/trap.c40
-rw-r--r--arch/um/os-Linux/tt.c15
-rw-r--r--arch/um/sys-i386/signal.c1
-rw-r--r--arch/v850/Kconfig3
-rw-r--r--arch/x86_64/Kconfig5
-rw-r--r--arch/x86_64/boot/compressed/misc.c2
-rw-r--r--arch/x86_64/boot/compressed/miscsetup.h39
-rw-r--r--arch/x86_64/ia32/ia32entry.S1
-rw-r--r--arch/x86_64/ia32/ptrace32.c44
-rw-r--r--arch/x86_64/kernel/init_task.c2
-rw-r--r--arch/x86_64/kernel/time.c2
-rw-r--r--block/elevator.c3
-rw-r--r--block/ioctl.c22
-rw-r--r--block/ll_rw_blk.c131
-rw-r--r--block/scsi_ioctl.c13
-rw-r--r--drivers/acorn/block/mfmhd.c36
-rw-r--r--drivers/acpi/osl.c2
-rw-r--r--drivers/atm/nicstar.c5
-rw-r--r--drivers/block/DAC960.c37
-rw-r--r--drivers/block/acsi.c26
-rw-r--r--drivers/block/amiflop.c25
-rw-r--r--drivers/block/aoe/aoeblk.c26
-rw-r--r--drivers/block/ataflop.c2
-rw-r--r--drivers/block/cciss.c196
-rw-r--r--drivers/block/cciss.h10
-rw-r--r--drivers/block/cciss_scsi.c2
-rw-r--r--drivers/block/cpqarray.c40
-rw-r--r--drivers/block/floppy.c44
-rw-r--r--drivers/block/nbd.c1
-rw-r--r--drivers/block/paride/pd.c34
-rw-r--r--drivers/block/paride/pf.c50
-rw-r--r--drivers/block/pktcdvd.c12
-rw-r--r--drivers/block/ps2esdi.c25
-rw-r--r--drivers/block/swim3.c38
-rw-r--r--drivers/block/sx8.c35
-rw-r--r--drivers/block/umem.c41
-rw-r--r--drivers/block/viodasd.c44
-rw-r--r--drivers/block/xd.c31
-rw-r--r--drivers/char/Kconfig12
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/agp/sworks-agp.c1
-rw-r--r--drivers/char/hw_random.c1
-rw-r--r--drivers/char/mem.c42
-rw-r--r--drivers/char/sonypi.c381
-rw-r--r--drivers/char/synclink_gt.c4501
-rw-r--r--drivers/char/tpm/Makefile3
-rw-r--r--drivers/char/tpm/tpm.c3
-rw-r--r--drivers/char/tpm/tpm.h15
-rw-r--r--drivers/char/tpm/tpm_bios.c540
-rw-r--r--drivers/char/vr41xx_giu.c4
-rw-r--r--drivers/char/watchdog/mpc8xx_wdt.c20
-rw-r--r--drivers/char/watchdog/wdt977.c216
-rw-r--r--drivers/connector/cn_proc.c4
-rw-r--r--drivers/i2c/busses/Kconfig24
-rw-r--r--drivers/i2c/busses/Makefile3
-rw-r--r--drivers/i2c/busses/i2c-keywest.c751
-rw-r--r--drivers/i2c/busses/i2c-keywest.h108
-rw-r--r--drivers/i2c/busses/i2c-pmac-smu.c315
-rw-r--r--drivers/i2c/busses/i2c-powermac.c290
-rw-r--r--drivers/i2c/chips/tps65010.c11
-rw-r--r--drivers/ide/ide-cd.c10
-rw-r--r--drivers/ide/ide-disk.c12
-rw-r--r--drivers/ide/ide-floppy.c12
-rw-r--r--drivers/ide/ide-io.c42
-rw-r--r--drivers/ide/ide-probe.c2
-rw-r--r--drivers/ide/ide.c13
-rw-r--r--drivers/ide/legacy/hd.c24
-rw-r--r--drivers/ide/pci/serverworks.c2
-rw-r--r--drivers/ide/ppc/pmac.c6
-rw-r--r--drivers/infiniband/core/cm.c16
-rw-r--r--drivers/infiniband/core/user_mad.c4
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c21
-rw-r--r--drivers/infiniband/core/verbs.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c12
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c23
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_eq.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mcg.c54
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c265
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c2
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c1
-rw-r--r--drivers/input/keyboard/corgikbd.c6
-rw-r--r--drivers/input/keyboard/spitzkbd.c27
-rw-r--r--drivers/input/misc/hp_sdc_rtc.c9
-rw-r--r--drivers/isdn/act2000/act2000.h6
-rw-r--r--drivers/isdn/act2000/capi.h90
-rw-r--r--drivers/isdn/capi/capifs.c2
-rw-r--r--drivers/isdn/hardware/eicon/os_4bri.c3
-rw-r--r--drivers/isdn/hardware/eicon/os_bri.c1
-rw-r--r--drivers/isdn/hardware/eicon/os_pri.c1
-rw-r--r--drivers/isdn/hisax/Kconfig10
-rw-r--r--drivers/isdn/hisax/hisax.h18
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.h18
-rw-r--r--drivers/isdn/sc/command.c1
-rw-r--r--drivers/macintosh/Kconfig10
-rw-r--r--drivers/macintosh/macio_asic.c254
-rw-r--r--drivers/macintosh/mediabay.c8
-rw-r--r--drivers/macintosh/smu.c50
-rw-r--r--drivers/macintosh/via-cuda.c52
-rw-r--r--drivers/macintosh/via-pmu.c364
-rw-r--r--drivers/macintosh/windfarm_lm75_sensor.c50
-rw-r--r--drivers/macintosh/windfarm_smu_controls.c1
-rw-r--r--drivers/macintosh/windfarm_smu_sensors.c1
-rw-r--r--drivers/md/md.c30
-rw-r--r--drivers/md/raid0.c6
-rw-r--r--drivers/media/common/saa7146_fops.c38
-rw-r--r--drivers/media/common/saa7146_hlp.c13
-rw-r--r--drivers/media/common/saa7146_vbi.c6
-rw-r--r--drivers/media/common/saa7146_video.c9
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c33
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h4
-rw-r--r--drivers/media/dvb/bt8xx/dst.c52
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c3
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c16
-rw-r--r--drivers/media/dvb/cinergyT2/Kconfig20
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c82
-rw-r--r--drivers/media/dvb/dvb-core/Kconfig2
-rw-r--r--drivers/media/dvb/dvb-core/Makefile2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c4
-rw-r--r--drivers/media/dvb/dvb-core/dvb_filter.c16
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c315
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h16
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c6
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.c32
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.h8
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c22
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h2
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig24
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c294
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.h2
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c46
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c6
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.h31
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-common.h2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-firmware.c154
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-i2c.c8
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h12
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-init.c59
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h29
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c7
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x-fe.c2
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x.h43
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c2
-rw-r--r--drivers/media/dvb/frontends/Kconfig46
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/bcm3510.c6
-rw-r--r--drivers/media/dvb/frontends/cx22702.c22
-rw-r--r--drivers/media/dvb/frontends/cx24110.c23
-rw-r--r--drivers/media/dvb/frontends/cx24123.c889
-rw-r--r--drivers/media/dvb/frontends/cx24123.h51
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c15
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h2
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c3
-rw-r--r--drivers/media/dvb/frontends/mt312.c3
-rw-r--r--drivers/media/dvb/frontends/nxt2002.c3
-rw-r--r--drivers/media/dvb/frontends/nxt6000.c10
-rw-r--r--drivers/media/dvb/frontends/or51211.c5
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c4
-rw-r--r--drivers/media/dvb/frontends/sp8870.c3
-rw-r--r--drivers/media/dvb/frontends/sp887x.c5
-rw-r--r--drivers/media/dvb/frontends/stv0299.c12
-rw-r--r--drivers/media/dvb/frontends/stv0299.h1
-rw-r--r--drivers/media/dvb/frontends/tda10021.c4
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c141
-rw-r--r--drivers/media/dvb/pluto2/Kconfig2
-rw-r--r--drivers/media/dvb/ttpci/Kconfig7
-rw-r--r--drivers/media/dvb/ttpci/Makefile2
-rw-r--r--drivers/media/dvb/ttpci/av7110.c133
-rw-r--r--drivers/media/dvb/ttpci/av7110.h17
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c12
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c7
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.h3
-rw-r--r--drivers/media/dvb/ttpci/av7110_ir.c14
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c118
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c184
-rw-r--r--drivers/media/dvb/ttpci/budget-core.c4
-rw-r--r--drivers/media/dvb/ttpci/budget.c13
-rw-r--r--drivers/media/dvb/ttpci/ttpci-eeprom.c2
-rw-r--r--drivers/media/dvb/ttusb-budget/Kconfig2
-rw-r--r--drivers/media/dvb/ttusb-dec/Kconfig13
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c20
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusbdecfe.c53
-rw-r--r--drivers/media/radio/miropcm20-radio.c1
-rw-r--r--drivers/media/radio/radio-aimslab.c1
-rw-r--r--drivers/media/radio/radio-aztech.c1
-rw-r--r--drivers/media/radio/radio-cadet.c1
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c1
-rw-r--r--drivers/media/radio/radio-gemtek.c1
-rw-r--r--drivers/media/radio/radio-maestro.c1
-rw-r--r--drivers/media/radio/radio-maxiradio.c1
-rw-r--r--drivers/media/radio/radio-rtrack2.c1
-rw-r--r--drivers/media/radio/radio-sf16fmi.c1
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c1
-rw-r--r--drivers/media/radio/radio-terratec.c1
-rw-r--r--drivers/media/radio/radio-trust.c1
-rw-r--r--drivers/media/radio/radio-typhoon.c1
-rw-r--r--drivers/media/radio/radio-zoltrix.c1
-rw-r--r--drivers/media/video/Kconfig11
-rw-r--r--drivers/media/video/Makefile10
-rw-r--r--drivers/media/video/arv.c1
-rw-r--r--drivers/media/video/bt832.c70
-rw-r--r--drivers/media/video/bttv-cards.c56
-rw-r--r--drivers/media/video/bttv-driver.c68
-rw-r--r--drivers/media/video/bttv-gpio.c18
-rw-r--r--drivers/media/video/bttv-i2c.c15
-rw-r--r--drivers/media/video/bttv-input.c (renamed from drivers/media/video/ir-kbd-gpio.c)256
-rw-r--r--drivers/media/video/bttv-vbi.c57
-rw-r--r--drivers/media/video/bttv.h37
-rw-r--r--drivers/media/video/bttvp.h13
-rw-r--r--drivers/media/video/bw-qcam.c1
-rw-r--r--drivers/media/video/c-qcam.c1
-rw-r--r--drivers/media/video/compat_ioctl32.c732
-rw-r--r--drivers/media/video/cpia.c1
-rw-r--r--drivers/media/video/cs53l32a.c92
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c91
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c388
-rw-r--r--drivers/media/video/cx25840/cx25840-firmware.c36
-rw-r--r--drivers/media/video/cx25840/cx25840-vbi.c4
-rw-r--r--drivers/media/video/cx25840/cx25840.h81
-rw-r--r--drivers/media/video/cx88/Kconfig25
-rw-r--r--drivers/media/video/cx88/Makefile4
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c848
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c18
-rw-r--r--drivers/media/video/cx88/cx88-cards.c227
-rw-r--r--drivers/media/video/cx88/cx88-core.c67
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c215
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c13
-rw-r--r--drivers/media/video/cx88/cx88-input.c142
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c5
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c10
-rw-r--r--drivers/media/video/cx88/cx88-video.c94
-rw-r--r--drivers/media/video/cx88/cx88-vp3054-i2c.c173
-rw-r--r--drivers/media/video/cx88/cx88-vp3054-i2c.h35
-rw-r--r--drivers/media/video/cx88/cx88.h17
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c8
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c61
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c3
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c167
-rw-r--r--drivers/media/video/em28xx/em28xx.h6
-rw-r--r--drivers/media/video/ir-kbd-i2c.c18
-rw-r--r--drivers/media/video/meye.c1
-rw-r--r--drivers/media/video/msp3400-driver.c1274
-rw-r--r--drivers/media/video/msp3400-kthreads.c1010
-rw-r--r--drivers/media/video/msp3400.c2229
-rw-r--r--drivers/media/video/msp3400.h102
-rw-r--r--drivers/media/video/mt20xx.c16
-rw-r--r--drivers/media/video/mxb.c1
-rw-r--r--drivers/media/video/pms.c1
-rw-r--r--drivers/media/video/saa5249.c1
-rw-r--r--drivers/media/video/saa6588.c12
-rw-r--r--drivers/media/video/saa7115.c319
-rw-r--r--drivers/media/video/saa711x.c2
-rw-r--r--drivers/media/video/saa7127.c82
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c8
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c83
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c138
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c3
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c3
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c39
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c40
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c7
-rw-r--r--drivers/media/video/saa7134/saa7134.h10
-rw-r--r--drivers/media/video/stradis.c1
-rw-r--r--drivers/media/video/tda7432.c43
-rw-r--r--drivers/media/video/tda8290.c6
-rw-r--r--drivers/media/video/tda9875.c7
-rw-r--r--drivers/media/video/tda9887.c228
-rw-r--r--drivers/media/video/tea5767.c7
-rw-r--r--drivers/media/video/tuner-core.c138
-rw-r--r--drivers/media/video/tuner-simple.c889
-rw-r--r--drivers/media/video/tvaudio.c177
-rw-r--r--drivers/media/video/tveeprom.c43
-rw-r--r--drivers/media/video/tvmixer.c20
-rw-r--r--drivers/media/video/tvp5150.c535
-rw-r--r--drivers/media/video/v4l1-compat.c11
-rw-r--r--drivers/media/video/v4l2-common.c219
-rw-r--r--drivers/media/video/videodev.c10
-rw-r--r--drivers/media/video/w9966.c1
-rw-r--r--drivers/media/video/wm8775.c88
-rw-r--r--drivers/media/video/zoran_driver.c1
-rw-r--r--drivers/media/video/zr36120.c1
-rw-r--r--drivers/message/i2o/i2o_block.c18
-rw-r--r--drivers/mfd/ucb1x00-core.c5
-rw-r--r--drivers/mfd/ucb1x00-ts.c1
-rw-r--r--drivers/mmc/mmc.c1
-rw-r--r--drivers/mmc/mmc_block.c33
-rw-r--r--drivers/mmc/wbsd.c533
-rw-r--r--drivers/mtd/mtd_blkdevs.c25
-rw-r--r--drivers/mtd/onenand/generic.c1
-rw-r--r--drivers/mtd/rfd_ftl.c1
-rw-r--r--drivers/net/3c503.c16
-rw-r--r--drivers/net/3c527.h50
-rw-r--r--drivers/net/Kconfig6
-rw-r--r--drivers/net/ac3200.c16
-rw-r--r--drivers/net/bonding/bonding.h8
-rw-r--r--drivers/net/cs89x0.c138
-rw-r--r--drivers/net/cs89x0.h19
-rw-r--r--drivers/net/e1000/e1000_param.c10
-rw-r--r--drivers/net/e2100.c14
-rw-r--r--drivers/net/es3210.c14
-rw-r--r--drivers/net/forcedeth.c164
-rw-r--r--drivers/net/gianfar.h4
-rw-r--r--drivers/net/hamradio/mkiss.c1
-rw-r--r--drivers/net/hp-plus.c12
-rw-r--r--drivers/net/hp.c12
-rw-r--r--drivers/net/ibm_emac/ibm_emac.h3
-rw-r--r--drivers/net/ibm_emac/ibm_emac_core.c2
-rw-r--r--drivers/net/irda/vlsi_ir.h4
-rw-r--r--drivers/net/lance.c22
-rw-r--r--drivers/net/lne390.c14
-rw-r--r--drivers/net/mv643xx_eth.c2
-rw-r--r--drivers/net/ne.c18
-rw-r--r--drivers/net/ne2.c16
-rw-r--r--drivers/net/sk98lin/skge.c129
-rw-r--r--drivers/net/smc-ultra.c24
-rw-r--r--drivers/net/smc91x.c5
-rw-r--r--drivers/net/smc91x.h18
-rw-r--r--drivers/net/tulip/tulip_core.c2
-rw-r--r--drivers/net/wan/sdla.c6
-rw-r--r--drivers/net/wd.c14
-rw-r--r--drivers/net/wireless/ipw2100.c5
-rw-r--r--drivers/oprofile/buffer_sync.c30
-rw-r--r--drivers/oprofile/cpu_buffer.c3
-rw-r--r--drivers/parport/Kconfig2
-rw-r--r--drivers/parport/parport_pc.c6
-rw-r--r--drivers/pci/hotplug/pciehp.h1
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c3
-rw-r--r--drivers/rapidio/rio-scan.c2
-rw-r--r--drivers/rapidio/rio-sysfs.c1
-rw-r--r--drivers/rapidio/rio.c1
-rw-r--r--drivers/s390/block/dasd.c23
-rw-r--r--drivers/s390/block/dasd_ioctl.c28
-rw-r--r--drivers/s390/block/xpram.c18
-rw-r--r--drivers/scsi/mac53c94.c22
-rw-r--r--drivers/scsi/mesh.c3
-rw-r--r--drivers/scsi/sata_nv.c30
-rw-r--r--drivers/scsi/scsi.c109
-rw-r--r--drivers/scsi/scsi_lib.c36
-rw-r--r--drivers/scsi/scsi_priv.h1
-rw-r--r--drivers/scsi/sd.c21
-rw-r--r--drivers/scsi/sg.c2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c2
-rw-r--r--drivers/serial/pmac_zilog.c15
-rw-r--r--drivers/usb/core/inode.c6
-rw-r--r--drivers/usb/host/ohci-au1xxx.c1
-rw-r--r--drivers/usb/host/ohci-lh7a404.c1
-rw-r--r--drivers/usb/host/ohci-ppc-soc.c1
-rw-r--r--drivers/usb/media/dsbr100.c1
-rw-r--r--drivers/usb/media/ov511.c1
-rw-r--r--drivers/usb/media/pwc/pwc-if.c1
-rw-r--r--drivers/usb/media/se401.c1
-rw-r--r--drivers/usb/media/stv680.c1
-rw-r--r--drivers/usb/media/usbvideo.c1
-rw-r--r--drivers/usb/media/vicam.c1
-rw-r--r--drivers/usb/media/w9968cf.c1
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/console/Kconfig2
-rw-r--r--drivers/video/console/vgacon.c36
-rw-r--r--drivers/video/controlfb.c114
-rw-r--r--drivers/video/cyblafb.c1523
-rw-r--r--drivers/video/offb.c122
-rw-r--r--drivers/video/platinumfb.c98
-rw-r--r--drivers/video/platinumfb.h4
-rw-r--r--drivers/video/valkyriefb.c12
-rw-r--r--fs/9p/9p.c314
-rw-r--r--fs/9p/9p.h77
-rw-r--r--fs/9p/Makefile10
-rw-r--r--fs/9p/conv.c884
-rw-r--r--fs/9p/conv.h35
-rw-r--r--fs/9p/debug.h23
-rw-r--r--fs/9p/error.c10
-rw-r--r--fs/9p/error.h2
-rw-r--r--fs/9p/fid.c5
-rw-r--r--fs/9p/mux.c1145
-rw-r--r--fs/9p/mux.h41
-rw-r--r--fs/9p/trans_fd.c53
-rw-r--r--fs/9p/trans_sock.c160
-rw-r--r--fs/9p/transport.h4
-rw-r--r--fs/9p/v9fs.c59
-rw-r--r--fs/9p/v9fs.h17
-rw-r--r--fs/9p/v9fs_vfs.h5
-rw-r--r--fs/9p/vfs_dentry.c15
-rw-r--r--fs/9p/vfs_dir.c47
-rw-r--r--fs/9p/vfs_file.c28
-rw-r--r--fs/9p/vfs_inode.c617
-rw-r--r--fs/9p/vfs_super.c12
-rw-r--r--fs/Kconfig.binfmt2
-rw-r--r--fs/Makefile2
-rw-r--r--fs/afs/dir.c2
-rw-r--r--fs/afs/volume.h4
-rw-r--r--fs/aio.c3
-rw-r--r--fs/attr.c24
-rw-r--r--fs/autofs4/autofs_i.h2
-rw-r--r--fs/autofs4/expire.c12
-rw-r--r--fs/autofs4/inode.c4
-rw-r--r--fs/autofs4/root.c3
-rw-r--r--fs/binfmt_elf.c16
-rw-r--r--fs/bio.c1
-rw-r--r--fs/buffer.c76
-rw-r--r--fs/cifs/file.c6
-rw-r--r--fs/cifs/inode.c3
-rw-r--r--fs/coda/cache.c2
-rw-r--r--fs/compat.c22
-rw-r--r--fs/compat_ioctl.c246
-rw-r--r--fs/dcache.c34
-rw-r--r--fs/drop_caches.c68
-rw-r--r--fs/exec.c8
-rw-r--r--fs/ext3/ialloc.c6
-rw-r--r--fs/ext3/namei.c2
-rw-r--r--fs/ext3/resize.c32
-rw-r--r--fs/ext3/super.c54
-rw-r--r--fs/fat/cache.c14
-rw-r--r--fs/fat/dir.c24
-rw-r--r--fs/fat/fatent.c10
-rw-r--r--fs/fat/file.c33
-rw-r--r--fs/fat/inode.c119
-rw-r--r--fs/fat/misc.c8
-rw-r--r--fs/fcntl.c6
-rw-r--r--fs/file_table.c8
-rw-r--r--fs/freevxfs/vxfs_immed.c4
-rw-r--r--fs/inode.c4
-rw-r--r--fs/jffs/inode-v23.c4
-rw-r--r--fs/jfs/jfs_dmap.c3
-rw-r--r--fs/jfs/jfs_imap.c6
-rw-r--r--fs/jfs/jfs_txnmgr.c6
-rw-r--r--fs/jfs/jfs_umount.c6
-rw-r--r--fs/jfs/resize.c3
-rw-r--r--fs/jfs/super.c3
-rw-r--r--fs/libfs.c12
-rw-r--r--fs/locks.c7
-rw-r--r--fs/mpage.c4
-rw-r--r--fs/namei.c2
-rw-r--r--fs/namespace.c6
-rw-r--r--fs/ncpfs/dir.c2
-rw-r--r--fs/ncpfs/ncplib_kernel.h4
-rw-r--r--fs/nfs/inode.c8
-rw-r--r--fs/nfs/nfsroot.c4
-rw-r--r--fs/ocfs2/cluster/masklog.h7
-rw-r--r--fs/open.c15
-rw-r--r--fs/pnode.c2
-rw-r--r--fs/proc/generic.c2
-rw-r--r--fs/proc/inode.c2
-rw-r--r--fs/proc/internal.h4
-rw-r--r--fs/proc/proc_misc.c4
-rw-r--r--fs/proc/root.c3
-rw-r--r--fs/proc/task_mmu.c127
-rw-r--r--fs/relayfs/buffers.c3
-rw-r--r--fs/relayfs/inode.c214
-rw-r--r--fs/relayfs/relay.c69
-rw-r--r--fs/relayfs/relay.h4
-rw-r--r--fs/romfs/inode.c6
-rw-r--r--fs/smbfs/cache.c4
-rw-r--r--fs/smbfs/file.c7
-rw-r--r--fs/smbfs/inode.c3
-rw-r--r--fs/smbfs/proc.c2
-rw-r--r--fs/super.c3
-rw-r--r--fs/sysv/dir.c4
-rw-r--r--fs/udf/balloc.c2
-rw-r--r--fs/udf/inode.c5
-rw-r--r--fs/ufs/super.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.c3
-rw-r--r--fs/xfs/xfs_log.h8
-rw-r--r--include/asm-alpha/cache.h1
-rw-r--r--include/asm-alpha/compiler.h2
-rw-r--r--include/asm-alpha/futex.h49
-rw-r--r--include/asm-alpha/processor.h21
-rw-r--r--include/asm-arm/cache.h5
-rw-r--r--include/asm-arm/futex.h49
-rw-r--r--include/asm-arm/irq.h12
-rw-r--r--include/asm-arm26/futex.h49
-rw-r--r--include/asm-cris/arch-v10/cache.h1
-rw-r--r--include/asm-cris/arch-v32/cache.h1
-rw-r--r--include/asm-cris/dma-mapping.h2
-rw-r--r--include/asm-cris/futex.h49
-rw-r--r--include/asm-frv/atomic.h96
-rw-r--r--include/asm-frv/bug.h1
-rw-r--r--include/asm-frv/dma-mapping.h2
-rw-r--r--include/asm-frv/io.h123
-rw-r--r--include/asm-frv/mb-regs.h4
-rw-r--r--include/asm-frv/mc146818rtc.h16
-rw-r--r--include/asm-frv/module.h16
-rw-r--r--include/asm-frv/pci.h8
-rw-r--r--include/asm-frv/pgtable.h5
-rw-r--r--include/asm-frv/types.h1
-rw-r--r--include/asm-frv/uaccess.h8
-rw-r--r--include/asm-frv/unistd.h2
-rw-r--r--include/asm-frv/vga.h17
-rw-r--r--include/asm-frv/xor.h1
-rw-r--r--include/asm-generic/atomic.h1
-rw-r--r--include/asm-generic/dma-mapping.h2
-rw-r--r--include/asm-generic/futex.h53
-rw-r--r--include/asm-h8300/futex.h49
-rw-r--r--include/asm-i386/cache.h2
-rw-r--r--include/asm-i386/dma-mapping.h2
-rw-r--r--include/asm-i386/irq.h2
-rw-r--r--include/asm-i386/ptrace.h3
-rw-r--r--include/asm-i386/unistd.h3
-rw-r--r--include/asm-i386/vm86.h20
-rw-r--r--include/asm-ia64/bug.h6
-rw-r--r--include/asm-ia64/cache.h2
-rw-r--r--include/asm-ia64/futex.h49
-rw-r--r--include/asm-ia64/io.h1
-rw-r--r--include/asm-ia64/spinlock.h2
-rw-r--r--include/asm-ia64/unistd.h3
-rw-r--r--include/asm-m32r/cache.h2
-rw-r--r--include/asm-m32r/futex.h49
-rw-r--r--include/asm-m68k/cache.h2
-rw-r--r--include/asm-m68k/futex.h49
-rw-r--r--include/asm-m68knommu/futex.h49
-rw-r--r--include/asm-mips/cache.h1
-rw-r--r--include/asm-parisc/cache.h1
-rw-r--r--include/asm-parisc/futex.h49
-rw-r--r--include/asm-powerpc/abs_addr.h2
-rw-r--r--include/asm-powerpc/agp.h2
-rw-r--r--include/asm-powerpc/asm-compat.h3
-rw-r--r--include/asm-powerpc/bootx.h171
-rw-r--r--include/asm-powerpc/btext.h19
-rw-r--r--include/asm-powerpc/bug.h2
-rw-r--r--include/asm-powerpc/cache.h1
-rw-r--r--include/asm-powerpc/checksum.h2
-rw-r--r--include/asm-powerpc/compat.h2
-rw-r--r--include/asm-powerpc/cputable.h36
-rw-r--r--include/asm-powerpc/current.h2
-rw-r--r--include/asm-powerpc/delay.h2
-rw-r--r--include/asm-powerpc/dma-mapping.h4
-rw-r--r--include/asm-powerpc/dma.h2
-rw-r--r--include/asm-powerpc/eeh.h15
-rw-r--r--include/asm-powerpc/eeh_event.h2
-rw-r--r--include/asm-powerpc/elf.h3
-rw-r--r--include/asm-powerpc/firmware.h6
-rw-r--r--include/asm-powerpc/floppy.h2
-rw-r--r--include/asm-powerpc/grackle.h5
-rw-r--r--include/asm-powerpc/hardirq.h2
-rw-r--r--include/asm-powerpc/heathrow.h5
-rw-r--r--include/asm-powerpc/hvcall.h2
-rw-r--r--include/asm-powerpc/hvconsole.h2
-rw-r--r--include/asm-powerpc/hvcserver.h2
-rw-r--r--include/asm-powerpc/i8259.h2
-rw-r--r--include/asm-powerpc/ibmebus.h85
-rw-r--r--include/asm-powerpc/io.h6
-rw-r--r--include/asm-powerpc/iommu.h8
-rw-r--r--include/asm-powerpc/ipic.h (renamed from include/asm-ppc/ipic.h)0
-rw-r--r--include/asm-powerpc/iseries/it_lp_reg_save.h2
-rw-r--r--include/asm-powerpc/kdebug.h2
-rw-r--r--include/asm-powerpc/kdump.h13
-rw-r--r--include/asm-powerpc/kexec.h19
-rw-r--r--include/asm-powerpc/keylargo.h15
-rw-r--r--include/asm-powerpc/kprobes.h2
-rw-r--r--include/asm-powerpc/lmb.h2
-rw-r--r--include/asm-powerpc/lppaca.h2
-rw-r--r--include/asm-powerpc/machdep.h12
-rw-r--r--include/asm-powerpc/macio.h2
-rw-r--r--include/asm-powerpc/mmu.h9
-rw-r--r--include/asm-powerpc/mmu_context.h2
-rw-r--r--include/asm-powerpc/mmzone.h2
-rw-r--r--include/asm-powerpc/module.h2
-rw-r--r--include/asm-powerpc/mpic.h6
-rw-r--r--include/asm-powerpc/numnodes.h2
-rw-r--r--include/asm-powerpc/nvram.h4
-rw-r--r--include/asm-powerpc/of_device.h2
-rw-r--r--include/asm-powerpc/ohare.h6
-rw-r--r--include/asm-powerpc/oprofile_impl.h33
-rw-r--r--include/asm-powerpc/pSeries_reconfig.h2
-rw-r--r--include/asm-powerpc/paca.h21
-rw-r--r--include/asm-powerpc/page.h32
-rw-r--r--include/asm-powerpc/page_32.h2
-rw-r--r--include/asm-powerpc/page_64.h12
-rw-r--r--include/asm-powerpc/param.h2
-rw-r--r--include/asm-powerpc/parport.h2
-rw-r--r--include/asm-powerpc/pci-bridge.h24
-rw-r--r--include/asm-powerpc/pci.h2
-rw-r--r--include/asm-powerpc/pgalloc.h2
-rw-r--r--include/asm-powerpc/pgtable-64k.h6
-rw-r--r--include/asm-powerpc/pgtable.h13
-rw-r--r--include/asm-powerpc/pmac_feature.h25
-rw-r--r--include/asm-powerpc/pmac_low_i2c.h92
-rw-r--r--include/asm-powerpc/pmac_pfunc.h253
-rw-r--r--include/asm-powerpc/pmc.h2
-rw-r--r--include/asm-powerpc/ppc-pci.h2
-rw-r--r--include/asm-powerpc/ppc_asm.h3
-rw-r--r--include/asm-powerpc/processor.h5
-rw-r--r--include/asm-powerpc/prom.h71
-rw-r--r--include/asm-powerpc/ptrace.h2
-rw-r--r--include/asm-powerpc/reg.h58
-rw-r--r--include/asm-powerpc/rtas.h2
-rw-r--r--include/asm-powerpc/seccomp.h4
-rw-r--r--include/asm-powerpc/sections.h2
-rw-r--r--include/asm-powerpc/serial.h2
-rw-r--r--include/asm-powerpc/signal.h7
-rw-r--r--include/asm-powerpc/smu.h34
-rw-r--r--include/asm-powerpc/sparsemem.h10
-rw-r--r--include/asm-powerpc/spinlock.h2
-rw-r--r--include/asm-powerpc/spu.h600
-rw-r--r--include/asm-powerpc/spu_csa.h255
-rw-r--r--include/asm-powerpc/synch.h4
-rw-r--r--include/asm-powerpc/system.h3
-rw-r--r--include/asm-powerpc/tce.h2
-rw-r--r--include/asm-powerpc/thread_info.h12
-rw-r--r--include/asm-powerpc/tlb.h2
-rw-r--r--include/asm-powerpc/topology.h6
-rw-r--r--include/asm-powerpc/udbg.h17
-rw-r--r--include/asm-powerpc/unistd.h4
-rw-r--r--include/asm-powerpc/vdso_datapage.h2
-rw-r--r--include/asm-powerpc/vio.h2
-rw-r--r--include/asm-ppc/bseip.h38
-rw-r--r--include/asm-ppc/btext.h2
-rw-r--r--include/asm-ppc/machdep.h4
-rw-r--r--include/asm-ppc/mpc85xx.h4
-rw-r--r--include/asm-ppc/pci-bridge.h9
-rw-r--r--include/asm-ppc/prom.h32
-rw-r--r--include/asm-s390/cache.h1
-rw-r--r--include/asm-s390/futex.h49
-rw-r--r--include/asm-sh/cache.h2
-rw-r--r--include/asm-sh/futex.h49
-rw-r--r--include/asm-sh64/cache.h2
-rw-r--r--include/asm-sh64/futex.h49
-rw-r--r--include/asm-sparc/cache.h1
-rw-r--r--include/asm-sparc/futex.h49
-rw-r--r--include/asm-sparc64/cache.h1
-rw-r--r--include/asm-sparc64/futex.h49
-rw-r--r--include/asm-sparc64/system.h4
-rw-r--r--include/asm-um/cache.h3
-rw-r--r--include/asm-um/futex.h12
-rw-r--r--include/asm-um/rwsem.h4
-rw-r--r--include/asm-v850/cache.h2
-rw-r--r--include/asm-v850/futex.h49
-rw-r--r--include/asm-v850/unistd.h18
-rw-r--r--include/asm-x86_64/cache.h1
-rw-r--r--include/asm-x86_64/ia32_unistd.h3
-rw-r--r--include/asm-x86_64/unistd.h4
-rw-r--r--include/linux/aio.h12
-rw-r--r--include/linux/atalk.h18
-rw-r--r--include/linux/blkdev.h22
-rw-r--r--include/linux/buffer_head.h3
-rw-r--r--include/linux/byteorder/generic.h2
-rw-r--r--include/linux/byteorder/swab.h2
-rw-r--r--include/linux/byteorder/swabb.h2
-rw-r--r--include/linux/cache.h17
-rw-r--r--include/linux/compat_ioctl.h26
-rw-r--r--include/linux/compiler-gcc.h9
-rw-r--r--include/linux/compiler-gcc2.h29
-rw-r--r--include/linux/compiler-gcc3.h17
-rw-r--r--include/linux/compiler-gcc4.h7
-rw-r--r--include/linux/compiler.h2
-rw-r--r--include/linux/cpuset.h40
-rw-r--r--include/linux/cycx_x25.h66
-rw-r--r--include/linux/dcache.h9
-rw-r--r--include/linux/dvb/frontend.h10
-rw-r--r--include/linux/elevator.h2
-rw-r--r--include/linux/elf.h2
-rw-r--r--include/linux/fs.h11
-rw-r--r--include/linux/i2c-id.h1
-rw-r--r--include/linux/ide.h3
-rw-r--r--include/linux/if_frad.h12
-rw-r--r--include/linux/interrupt.h4
-rw-r--r--include/linux/ipv6.h4
-rw-r--r--include/linux/isdnif.h70
-rw-r--r--include/linux/kernel.h2
-rw-r--r--include/linux/key.h12
-rw-r--r--include/linux/keyctl.h3
-rw-r--r--include/linux/memory.h8
-rw-r--r--include/linux/mempolicy.h46
-rw-r--r--include/linux/mm.h50
-rw-r--r--include/linux/mm_inline.h22
-rw-r--r--include/linux/mmc/mmc.h6
-rw-r--r--include/linux/mmzone.h6
-rw-r--r--include/linux/mount.h3
-rw-r--r--include/linux/msdos_fs.h3
-rw-r--r--include/linux/ncp.h126
-rw-r--r--include/linux/netfilter.h92
-rw-r--r--include/linux/netfilter_ipv4/ipt_policy.h52
-rw-r--r--include/linux/netfilter_ipv6/ip6t_policy.h52
-rw-r--r--include/linux/pagevec.h5
-rw-r--r--include/linux/parport.h4
-rw-r--r--include/linux/pci_regs.h1
-rw-r--r--include/linux/percpu.h8
-rw-r--r--include/linux/pmu.h8
-rw-r--r--include/linux/ptrace.h4
-rw-r--r--include/linux/radix-tree.h1
-rw-r--r--include/linux/rcupdate.h33
-rw-r--r--include/linux/rcuref.h220
-rw-r--r--include/linux/relayfs_fs.h65
-rw-r--r--include/linux/rio_drv.h1
-rw-r--r--include/linux/rtc.h3
-rw-r--r--include/linux/sched.h22
-rw-r--r--include/linux/screen_info.h77
-rw-r--r--include/linux/sdla.h64
-rw-r--r--include/linux/seccomp.h6
-rw-r--r--include/linux/signal.h30
-rw-r--r--include/linux/skbuff.h2
-rw-r--r--include/linux/slab.h35
-rw-r--r--include/linux/spinlock_types_up.h14
-rw-r--r--include/linux/swap.h9
-rw-r--r--include/linux/synclink.h9
-rw-r--r--include/linux/syscalls.h7
-rw-r--r--include/linux/sysctl.h2
-rw-r--r--include/linux/tty.h72
-rw-r--r--include/linux/video_decoder.h2
-rw-r--r--include/linux/videodev2.h16
-rw-r--r--include/linux/wavefront.h36
-rw-r--r--include/linux/workqueue.h1
-rw-r--r--include/linux/writeback.h4
-rw-r--r--include/media/audiochip.h16
-rw-r--r--include/media/saa7146_vv.h2
-rw-r--r--include/media/tuner.h98
-rw-r--r--include/media/v4l2-common.h85
-rw-r--r--include/net/dn_dev.h84
-rw-r--r--include/net/dn_nsp.h74
-rw-r--r--include/net/dst.h11
-rw-r--r--include/net/ip.h10
-rw-r--r--include/net/ipv6.h2
-rw-r--r--include/net/protocol.h2
-rw-r--r--include/net/xfrm.h9
-rw-r--r--include/sound/wavefront.h36
-rw-r--r--include/video/cyblafb.h4
-rw-r--r--init/Kconfig47
-rw-r--r--init/main.c8
-rw-r--r--ipc/shm.c22
-rw-r--r--kernel/audit.c2
-rw-r--r--kernel/cpuset.c537
-rw-r--r--kernel/crash_dump.c3
-rw-r--r--kernel/exit.c4
-rw-r--r--kernel/fork.c33
-rw-r--r--kernel/irq/proc.c2
-rw-r--r--kernel/module.c56
-rw-r--r--kernel/pid.c22
-rw-r--r--kernel/printk.c6
-rw-r--r--kernel/ptrace.c77
-rw-r--r--kernel/rcupdate.c49
-rw-r--r--kernel/rcutorture.c99
-rw-r--r--kernel/sched.c7
-rw-r--r--kernel/signal.c137
-rw-r--r--kernel/sys.c62
-rw-r--r--kernel/sys_ni.c24
-rw-r--r--kernel/sysctl.c22
-rw-r--r--kernel/timer.c1
-rw-r--r--kernel/workqueue.c40
-rw-r--r--lib/Kconfig.debug2
-rw-r--r--lib/bitmap.c89
-rw-r--r--lib/dec_and_lock.c49
-rw-r--r--lib/find_next_bit.c3
-rw-r--r--lib/radix-tree.c143
-rw-r--r--mm/Kconfig7
-rw-r--r--mm/Makefile6
-rw-r--r--mm/fadvise.c5
-rw-r--r--mm/filemap.c48
-rw-r--r--mm/hugetlb.c4
-rw-r--r--mm/memory.c2
-rw-r--r--mm/mempolicy.c561
-rw-r--r--mm/oom_kill.c5
-rw-r--r--mm/page_alloc.c129
-rw-r--r--mm/pdflush.c2
-rw-r--r--mm/rmap.c7
-rw-r--r--mm/slab.c1139
-rw-r--r--mm/slob.c385
-rw-r--r--mm/sparse.c4
-rw-r--r--mm/swap_state.c4
-rw-r--r--mm/swapfile.c12
-rw-r--r--mm/truncate.c1
-rw-r--r--mm/util.c39
-rw-r--r--mm/vmscan.c343
-rw-r--r--net/802/Makefile4
-rw-r--r--net/dccp/ipv4.c1
-rw-r--r--net/dccp/ipv6.c3
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c61
-rw-r--r--net/ieee80211/ieee80211_tx.c2
-rw-r--r--net/ieee80211/ieee80211_wx.c2
-rw-r--r--net/ipv4/ip_gre.c1
-rw-r--r--net/ipv4/ip_input.c15
-rw-r--r--net/ipv4/ip_output.c10
-rw-r--r--net/ipv4/ipip.c1
-rw-r--r--net/ipv4/netfilter.c15
-rw-r--r--net/ipv4/netfilter/Kconfig10
-rw-r--r--net/ipv4/netfilter/Makefile1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_sctp.c1
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c109
-rw-r--r--net/ipv4/netfilter/ipt_policy.c170
-rw-r--r--net/ipv4/raw.c1
-rw-r--r--net/ipv4/tcp_ipv4.c1
-rw-r--r--net/ipv4/udp.c2
-rw-r--r--net/ipv4/xfrm4_input.c31
-rw-r--r--net/ipv4/xfrm4_output.c72
-rw-r--r--net/ipv6/addrconf.c2
-rw-r--r--net/ipv6/af_inet6.c4
-rw-r--r--net/ipv6/exthdrs.c19
-rw-r--r--net/ipv6/icmp.c4
-rw-r--r--net/ipv6/inet6_connection_sock.c1
-rw-r--r--net/ipv6/ip6_input.c23
-rw-r--r--net/ipv6/ip6_tunnel.c2
-rw-r--r--net/ipv6/netfilter.c9
-rw-r--r--net/ipv6/netfilter/Kconfig10
-rw-r--r--net/ipv6/netfilter/Makefile1
-rw-r--r--net/ipv6/netfilter/ip6t_policy.c175
-rw-r--r--net/ipv6/reassembly.c11
-rw-r--r--net/ipv6/sit.c2
-rw-r--r--net/ipv6/tcp_ipv6.c2
-rw-r--r--net/ipv6/udp.c2
-rw-r--r--net/ipv6/xfrm6_input.c21
-rw-r--r--net/ipv6/xfrm6_output.c76
-rw-r--r--net/ipv6/xfrm6_tunnel.c6
-rw-r--r--net/netlink/af_netlink.c2
-rw-r--r--net/sctp/input.c1
-rw-r--r--net/sctp/ipv6.c2
-rw-r--r--net/sunrpc/rpc_pipe.c2
-rw-r--r--net/xfrm/xfrm_policy.c11
-rw-r--r--scripts/bloat-o-meter58
-rw-r--r--scripts/kconfig/conf.c18
-rw-r--r--scripts/kconfig/qconf.h6
-rw-r--r--security/keys/compat.c6
-rw-r--r--security/keys/internal.h5
-rw-r--r--security/keys/keyctl.c151
-rw-r--r--security/keys/keyring.c132
-rw-r--r--security/keys/permission.c32
-rw-r--r--security/keys/process_keys.c71
-rw-r--r--security/keys/request_key.c108
-rw-r--r--security/keys/request_key_auth.c192
-rw-r--r--security/selinux/hooks.c2
-rw-r--r--security/selinux/selinuxfs.c2
-rw-r--r--security/selinux/xfrm.c2
-rw-r--r--sound/isa/wavefront/wavefront_synth.c7
-rw-r--r--sound/oss/dmasound/dmasound_awacs.c81
-rw-r--r--sound/oss/i810_audio.c18
-rw-r--r--sound/ppc/pmac.c100
-rw-r--r--sound/ppc/pmac.h3
1131 files changed, 56307 insertions, 20111 deletions
diff --git a/CREDITS b/CREDITS
index 521f00d1b549..8e577ce4abeb 100644
--- a/CREDITS
+++ b/CREDITS
@@ -3203,7 +3203,7 @@ N: Eugene Surovegin
3203E: ebs@ebshome.net 3203E: ebs@ebshome.net
3204W: http://kernel.ebshome.net/ 3204W: http://kernel.ebshome.net/
3205P: 1024D/AE5467F1 FF22 39F1 6728 89F6 6E6C 2365 7602 F33D AE54 67F1 3205P: 1024D/AE5467F1 FF22 39F1 6728 89F6 6E6C 2365 7602 F33D AE54 67F1
3206D: Embedded PowerPC 4xx: I2C, PIC and random hacks/fixes 3206D: Embedded PowerPC 4xx: EMAC, I2C, PIC and random hacks/fixes
3207S: Sunnyvale, California 94085 3207S: Sunnyvale, California 94085
3208S: USA 3208S: USA
3209 3209
diff --git a/Documentation/Changes b/Documentation/Changes
index 86b86399d61d..fe5ae0f55020 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -31,8 +31,6 @@ al español de este documento en varios formatos.
31Eine deutsche Version dieser Datei finden Sie unter 31Eine deutsche Version dieser Datei finden Sie unter
32<http://www.stefan-winter.de/Changes-2.4.0.txt>. 32<http://www.stefan-winter.de/Changes-2.4.0.txt>.
33 33
34Last updated: October 29th, 2002
35
36Chris Ricker (kaboom@gatech.edu or chris.ricker@genetics.utah.edu). 34Chris Ricker (kaboom@gatech.edu or chris.ricker@genetics.utah.edu).
37 35
38Current Minimal Requirements 36Current Minimal Requirements
@@ -48,7 +46,7 @@ necessary on all systems; obviously, if you don't have any ISDN
48hardware, for example, you probably needn't concern yourself with 46hardware, for example, you probably needn't concern yourself with
49isdn4k-utils. 47isdn4k-utils.
50 48
51o Gnu C 2.95.3 # gcc --version 49o Gnu C 3.2 # gcc --version
52o Gnu make 3.79.1 # make --version 50o Gnu make 3.79.1 # make --version
53o binutils 2.12 # ld -v 51o binutils 2.12 # ld -v
54o util-linux 2.10o # fdformat --version 52o util-linux 2.10o # fdformat --version
@@ -74,26 +72,7 @@ GCC
74--- 72---
75 73
76The gcc version requirements may vary depending on the type of CPU in your 74The gcc version requirements may vary depending on the type of CPU in your
77computer. The next paragraph applies to users of x86 CPUs, but not 75computer.
78necessarily to users of other CPUs. Users of other CPUs should obtain
79information about their gcc version requirements from another source.
80
81The recommended compiler for the kernel is gcc 2.95.x (x >= 3), and it
82should be used when you need absolute stability. You may use gcc 3.0.x
83instead if you wish, although it may cause problems. Later versions of gcc
84have not received much testing for Linux kernel compilation, and there are
85almost certainly bugs (mainly, but not exclusively, in the kernel) that
86will need to be fixed in order to use these compilers. In any case, using
87pgcc instead of plain gcc is just asking for trouble.
88
89The Red Hat gcc 2.96 compiler subtree can also be used to build this tree.
90You should ensure you use gcc-2.96-74 or later. gcc-2.96-54 will not build
91the kernel correctly.
92
93In addition, please pay attention to compiler optimization. Anything
94greater than -O2 may not be wise. Similarly, if you choose to use gcc-2.95.x
95or derivatives, be sure not to use -fstrict-aliasing (which, depending on
96your version of gcc 2.95.x, may necessitate using -fno-strict-aliasing).
97 76
98Make 77Make
99---- 78----
@@ -322,9 +301,9 @@ Getting updated software
322Kernel compilation 301Kernel compilation
323****************** 302******************
324 303
325gcc 2.95.3 304gcc
326---------- 305---
327o <ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3.tar.gz> 306o <ftp://ftp.gnu.org/gnu/gcc/>
328 307
329Make 308Make
330---- 309----
diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle
index eb7db3c19227..ce780ef648f1 100644
--- a/Documentation/CodingStyle
+++ b/Documentation/CodingStyle
@@ -344,7 +344,7 @@ Remember: if another thread can find your data structure, and you don't
344have a reference count on it, you almost certainly have a bug. 344have a reference count on it, you almost certainly have a bug.
345 345
346 346
347 Chapter 11: Macros, Enums, Inline functions and RTL 347 Chapter 11: Macros, Enums and RTL
348 348
349Names of macros defining constants and labels in enums are capitalized. 349Names of macros defining constants and labels in enums are capitalized.
350 350
@@ -429,7 +429,35 @@ from void pointer to any other pointer type is guaranteed by the C programming
429language. 429language.
430 430
431 431
432 Chapter 14: References 432 Chapter 14: The inline disease
433
434There appears to be a common misperception that gcc has a magic "make me
435faster" speedup option called "inline". While the use of inlines can be
436appropriate (for example as a means of replacing macros, see Chapter 11), it
437very often is not. Abundant use of the inline keyword leads to a much bigger
438kernel, which in turn slows the system as a whole down, due to a bigger
439icache footprint for the CPU and simply because there is less memory
440available for the pagecache. Just think about it; a pagecache miss causes a
441disk seek, which easily takes 5 miliseconds. There are a LOT of cpu cycles
442that can go into these 5 miliseconds.
443
444A reasonable rule of thumb is to not put inline at functions that have more
445than 3 lines of code in them. An exception to this rule are the cases where
446a parameter is known to be a compiletime constant, and as a result of this
447constantness you *know* the compiler will be able to optimize most of your
448function away at compile time. For a good example of this later case, see
449the kmalloc() inline function.
450
451Often people argue that adding inline to functions that are static and used
452only once is always a win since there is no space tradeoff. While this is
453technically correct, gcc is capable of inlining these automatically without
454help, and the maintenance issue of removing the inline when a second user
455appears outweighs the potential value of the hint that tells gcc to do
456something it would have done anyway.
457
458
459
460 Chapter 15: References
433 461
434The C Programming Language, Second Edition 462The C Programming Language, Second Edition
435by Brian W. Kernighan and Dennis M. Ritchie. 463by Brian W. Kernighan and Dennis M. Ritchie.
@@ -444,10 +472,13 @@ ISBN 0-201-61586-X.
444URL: http://cm.bell-labs.com/cm/cs/tpop/ 472URL: http://cm.bell-labs.com/cm/cs/tpop/
445 473
446GNU manuals - where in compliance with K&R and this text - for cpp, gcc, 474GNU manuals - where in compliance with K&R and this text - for cpp, gcc,
447gcc internals and indent, all available from http://www.gnu.org 475gcc internals and indent, all available from http://www.gnu.org/manual/
448 476
449WG14 is the international standardization working group for the programming 477WG14 is the international standardization working group for the programming
450language C, URL: http://std.dkuug.dk/JTC1/SC22/WG14/ 478language C, URL: http://www.open-std.org/JTC1/SC22/WG14/
479
480Kernel CodingStyle, by greg@kroah.com at OLS 2002:
481http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/
451 482
452-- 483--
453Last updated on 16 February 2004 by a community effort on LKML. 484Last updated on 30 December 2005 by a community effort on LKML.
diff --git a/Documentation/RCU/rcuref.txt b/Documentation/RCU/rcuref.txt
index a23fee66064d..3f60db41b2f0 100644
--- a/Documentation/RCU/rcuref.txt
+++ b/Documentation/RCU/rcuref.txt
@@ -1,74 +1,67 @@
1Refcounter framework for elements of lists/arrays protected by 1Refcounter design for elements of lists/arrays protected by RCU.
2RCU.
3 2
4Refcounting on elements of lists which are protected by traditional 3Refcounting on elements of lists which are protected by traditional
5reader/writer spinlocks or semaphores are straight forward as in: 4reader/writer spinlocks or semaphores are straight forward as in:
6 5
71. 2. 61. 2.
8add() search_and_reference() 7add() search_and_reference()
9{ { 8{ {
10 alloc_object read_lock(&list_lock); 9 alloc_object read_lock(&list_lock);
11 ... search_for_element 10 ... search_for_element
12 atomic_set(&el->rc, 1); atomic_inc(&el->rc); 11 atomic_set(&el->rc, 1); atomic_inc(&el->rc);
13 write_lock(&list_lock); ... 12 write_lock(&list_lock); ...
14 add_element read_unlock(&list_lock); 13 add_element read_unlock(&list_lock);
15 ... ... 14 ... ...
16 write_unlock(&list_lock); } 15 write_unlock(&list_lock); }
17} 16}
18 17
193. 4. 183. 4.
20release_referenced() delete() 19release_referenced() delete()
21{ { 20{ {
22 ... write_lock(&list_lock); 21 ... write_lock(&list_lock);
23 atomic_dec(&el->rc, relfunc) ... 22 atomic_dec(&el->rc, relfunc) ...
24 ... delete_element 23 ... delete_element
25} write_unlock(&list_lock); 24} write_unlock(&list_lock);
26 ... 25 ...
27 if (atomic_dec_and_test(&el->rc)) 26 if (atomic_dec_and_test(&el->rc))
28 kfree(el); 27 kfree(el);
29 ... 28 ...
30 } 29 }
31 30
32If this list/array is made lock free using rcu as in changing the 31If this list/array is made lock free using rcu as in changing the
33write_lock in add() and delete() to spin_lock and changing read_lock 32write_lock in add() and delete() to spin_lock and changing read_lock
34in search_and_reference to rcu_read_lock(), the rcuref_get in 33in search_and_reference to rcu_read_lock(), the atomic_get in
35search_and_reference could potentially hold reference to an element which 34search_and_reference could potentially hold reference to an element which
36has already been deleted from the list/array. rcuref_lf_get_rcu takes 35has already been deleted from the list/array. atomic_inc_not_zero takes
37care of this scenario. search_and_reference should look as; 36care of this scenario. search_and_reference should look as;
38 37
391. 2. 381. 2.
40add() search_and_reference() 39add() search_and_reference()
41{ { 40{ {
42 alloc_object rcu_read_lock(); 41 alloc_object rcu_read_lock();
43 ... search_for_element 42 ... search_for_element
44 atomic_set(&el->rc, 1); if (rcuref_inc_lf(&el->rc)) { 43 atomic_set(&el->rc, 1); if (atomic_inc_not_zero(&el->rc)) {
45 write_lock(&list_lock); rcu_read_unlock(); 44 write_lock(&list_lock); rcu_read_unlock();
46 return FAIL; 45 return FAIL;
47 add_element } 46 add_element }
48 ... ... 47 ... ...
49 write_unlock(&list_lock); rcu_read_unlock(); 48 write_unlock(&list_lock); rcu_read_unlock();
50} } 49} }
513. 4. 503. 4.
52release_referenced() delete() 51release_referenced() delete()
53{ { 52{ {
54 ... write_lock(&list_lock); 53 ... write_lock(&list_lock);
55 rcuref_dec(&el->rc, relfunc) ... 54 atomic_dec(&el->rc, relfunc) ...
56 ... delete_element 55 ... delete_element
57} write_unlock(&list_lock); 56} write_unlock(&list_lock);
58 ... 57 ...
59 if (rcuref_dec_and_test(&el->rc)) 58 if (atomic_dec_and_test(&el->rc))
60 call_rcu(&el->head, el_free); 59 call_rcu(&el->head, el_free);
61 ... 60 ...
62 } 61 }
63 62
64Sometimes, reference to the element need to be obtained in the 63Sometimes, reference to the element need to be obtained in the
65update (write) stream. In such cases, rcuref_inc_lf might be an overkill 64update (write) stream. In such cases, atomic_inc_not_zero might be an
66since the spinlock serialising list updates are held. rcuref_inc 65overkill since the spinlock serialising list updates are held. atomic_inc
67is to be used in such cases. 66is to be used in such cases.
68For arches which do not have cmpxchg rcuref_inc_lf 67
69api uses a hashed spinlock implementation and the same hashed spinlock
70is acquired in all rcuref_xxx primitives to preserve atomicity.
71Note: Use rcuref_inc api only if you need to use rcuref_inc_lf on the
72refcounter atleast at one place. Mixing rcuref_inc and atomic_xxx api
73might lead to races. rcuref_inc_lf() must be used in lockfree
74RCU critical sections only.
diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers
index c3cca924e94b..dd311cff1cc3 100644
--- a/Documentation/SubmittingDrivers
+++ b/Documentation/SubmittingDrivers
@@ -27,18 +27,17 @@ Who To Submit Drivers To
27------------------------ 27------------------------
28 28
29Linux 2.0: 29Linux 2.0:
30 No new drivers are accepted for this kernel tree 30 No new drivers are accepted for this kernel tree.
31 31
32Linux 2.2: 32Linux 2.2:
33 No new drivers are accepted for this kernel tree.
34
35Linux 2.4:
33 If the code area has a general maintainer then please submit it to 36 If the code area has a general maintainer then please submit it to
34 the maintainer listed in MAINTAINERS in the kernel file. If the 37 the maintainer listed in MAINTAINERS in the kernel file. If the
35 maintainer does not respond or you cannot find the appropriate 38 maintainer does not respond or you cannot find the appropriate
36 maintainer then please contact the 2.2 kernel maintainer: 39 maintainer then please contact Marcelo Tosatti
37 Marc-Christian Petersen <m.c.p@wolk-project.de>. 40 <marcelo.tosatti@cyclades.com>.
38
39Linux 2.4:
40 The same rules apply as 2.2. The final contact point for Linux 2.4
41 submissions is Marcelo Tosatti <marcelo.tosatti@cyclades.com>.
42 41
43Linux 2.6: 42Linux 2.6:
44 The same rules apply as 2.4 except that you should follow linux-kernel 43 The same rules apply as 2.4 except that you should follow linux-kernel
@@ -53,6 +52,7 @@ Licensing: The code must be released to us under the
53 of exclusive GPL licensing, and if you wish the driver 52 of exclusive GPL licensing, and if you wish the driver
54 to be useful to other communities such as BSD you may well 53 to be useful to other communities such as BSD you may well
55 wish to release under multiple licenses. 54 wish to release under multiple licenses.
55 See accepted licenses at include/linux/module.h
56 56
57Copyright: The copyright owner must agree to use of GPL. 57Copyright: The copyright owner must agree to use of GPL.
58 It's best if the submitter and copyright owner 58 It's best if the submitter and copyright owner
@@ -143,5 +143,13 @@ KernelNewbies:
143 http://kernelnewbies.org/ 143 http://kernelnewbies.org/
144 144
145Linux USB project: 145Linux USB project:
146 http://sourceforge.net/projects/linux-usb/ 146 http://linux-usb.sourceforge.net/
147
148How to NOT write kernel driver by arjanv@redhat.com
149 http://people.redhat.com/arjanv/olspaper.pdf
150
151Kernel Janitor:
152 http://janitor.kernelnewbies.org/
147 153
154--
155Last updated on 17 Nov 2005.
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index 1d47e6c09dc6..6198e5ebcf65 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -78,7 +78,9 @@ Randy Dunlap's patch scripts:
78http://www.xenotime.net/linux/scripts/patching-scripts-002.tar.gz 78http://www.xenotime.net/linux/scripts/patching-scripts-002.tar.gz
79 79
80Andrew Morton's patch scripts: 80Andrew Morton's patch scripts:
81http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.20 81http://www.zip.com.au/~akpm/linux/patches/
82Instead of these scripts, quilt is the recommended patch management
83tool (see above).
82 84
83 85
84 86
@@ -97,7 +99,7 @@ need to split up your patch. See #3, next.
97 99
983) Separate your changes. 1003) Separate your changes.
99 101
100Separate each logical change into its own patch. 102Separate _logical changes_ into a single patch file.
101 103
102For example, if your changes include both bug fixes and performance 104For example, if your changes include both bug fixes and performance
103enhancements for a single driver, separate those changes into two 105enhancements for a single driver, separate those changes into two
@@ -112,6 +114,10 @@ If one patch depends on another patch in order for a change to be
112complete, that is OK. Simply note "this patch depends on patch X" 114complete, that is OK. Simply note "this patch depends on patch X"
113in your patch description. 115in your patch description.
114 116
117If you cannot condense your patch set into a smaller set of patches,
118then only post say 15 or so at a time and wait for review and integration.
119
120
115 121
1164) Select e-mail destination. 1224) Select e-mail destination.
117 123
@@ -124,6 +130,10 @@ your patch to the primary Linux kernel developer's mailing list,
124linux-kernel@vger.kernel.org. Most kernel developers monitor this 130linux-kernel@vger.kernel.org. Most kernel developers monitor this
125e-mail list, and can comment on your changes. 131e-mail list, and can comment on your changes.
126 132
133
134Do not send more than 15 patches at once to the vger mailing lists!!!
135
136
127Linus Torvalds is the final arbiter of all changes accepted into the 137Linus Torvalds is the final arbiter of all changes accepted into the
128Linux kernel. His e-mail address is <torvalds@osdl.org>. He gets 138Linux kernel. His e-mail address is <torvalds@osdl.org>. He gets
129a lot of e-mail, so typically you should do your best to -avoid- sending 139a lot of e-mail, so typically you should do your best to -avoid- sending
@@ -149,6 +159,9 @@ USB, framebuffer devices, the VFS, the SCSI subsystem, etc. See the
149MAINTAINERS file for a mailing list that relates specifically to 159MAINTAINERS file for a mailing list that relates specifically to
150your change. 160your change.
151 161
162Majordomo lists of VGER.KERNEL.ORG at:
163 <http://vger.kernel.org/vger-lists.html>
164
152If changes affect userland-kernel interfaces, please send 165If changes affect userland-kernel interfaces, please send
153the MAN-PAGES maintainer (as listed in the MAINTAINERS file) 166the MAN-PAGES maintainer (as listed in the MAINTAINERS file)
154a man-pages patch, or at least a notification of the change, 167a man-pages patch, or at least a notification of the change,
@@ -373,27 +386,14 @@ a diffstat, to show what files have changed, and the number of inserted
373and deleted lines per file. A diffstat is especially useful on bigger 386and deleted lines per file. A diffstat is especially useful on bigger
374patches. Other comments relevant only to the moment or the maintainer, 387patches. Other comments relevant only to the moment or the maintainer,
375not suitable for the permanent changelog, should also go here. 388not suitable for the permanent changelog, should also go here.
389Use diffstat options "-p 1 -w 70" so that filenames are listed from the
390top of the kernel source tree and don't use too much horizontal space
391(easily fit in 80 columns, maybe with some indentation).
376 392
377See more details on the proper patch format in the following 393See more details on the proper patch format in the following
378references. 394references.
379 395
380 396
38113) More references for submitting patches
382
383Andrew Morton, "The perfect patch" (tpp).
384 <http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt>
385
386Jeff Garzik, "Linux kernel patch submission format."
387 <http://linux.yyz.us/patch-format.html>
388
389Greg KH, "How to piss off a kernel subsystem maintainer"
390 <http://www.kroah.com/log/2005/03/31/>
391
392Kernel Documentation/CodingStyle
393 <http://sosdg.org/~coywolf/lxr/source/Documentation/CodingStyle>
394
395Linus Torvald's mail on the canonical patch format:
396 <http://lkml.org/lkml/2005/4/7/183>
397 397
398 398
399----------------------------------- 399-----------------------------------
@@ -466,3 +466,30 @@ and 'extern __inline__'.
466Don't try to anticipate nebulous future cases which may or may not 466Don't try to anticipate nebulous future cases which may or may not
467be useful: "Make it as simple as you can, and no simpler." 467be useful: "Make it as simple as you can, and no simpler."
468 468
469
470
471----------------------
472SECTION 3 - REFERENCES
473----------------------
474
475Andrew Morton, "The perfect patch" (tpp).
476 <http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt>
477
478Jeff Garzik, "Linux kernel patch submission format."
479 <http://linux.yyz.us/patch-format.html>
480
481Greg Kroah, "How to piss off a kernel subsystem maintainer".
482 <http://www.kroah.com/log/2005/03/31/>
483 <http://www.kroah.com/log/2005/07/08/>
484 <http://www.kroah.com/log/2005/10/19/>
485
486NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people!.
487 <http://marc.theaimsgroup.com/?l=linux-kernel&m=112112749912944&w=2>
488
489Kernel Documentation/CodingStyle
490 <http://sosdg.org/~coywolf/lxr/source/Documentation/CodingStyle>
491
492Linus Torvald's mail on the canonical patch format:
493 <http://lkml.org/lkml/2005/4/7/183>
494--
495Last updated on 17 Nov 2005.
diff --git a/Documentation/applying-patches.txt b/Documentation/applying-patches.txt
index 681e426e2482..05a08c2c1889 100644
--- a/Documentation/applying-patches.txt
+++ b/Documentation/applying-patches.txt
@@ -2,7 +2,8 @@
2 Applying Patches To The Linux Kernel 2 Applying Patches To The Linux Kernel
3 ------------------------------------ 3 ------------------------------------
4 4
5 (Written by Jesper Juhl, August 2005) 5 Original by: Jesper Juhl, August 2005
6 Last update: 2005-12-02
6 7
7 8
8 9
@@ -118,7 +119,7 @@ wrong.
118 119
119When patch encounters a change that it can't fix up with fuzz it rejects it 120When patch encounters a change that it can't fix up with fuzz it rejects it
120outright and leaves a file with a .rej extension (a reject file). You can 121outright and leaves a file with a .rej extension (a reject file). You can
121read this file to see exactely what change couldn't be applied, so you can 122read this file to see exactly what change couldn't be applied, so you can
122go fix it up by hand if you wish. 123go fix it up by hand if you wish.
123 124
124If you don't have any third party patches applied to your kernel source, but 125If you don't have any third party patches applied to your kernel source, but
@@ -127,7 +128,7 @@ and have made no modifications yourself to the source files, then you should
127never see a fuzz or reject message from patch. If you do see such messages 128never see a fuzz or reject message from patch. If you do see such messages
128anyway, then there's a high risk that either your local source tree or the 129anyway, then there's a high risk that either your local source tree or the
129patch file is corrupted in some way. In that case you should probably try 130patch file is corrupted in some way. In that case you should probably try
130redownloading the patch and if things are still not OK then you'd be advised 131re-downloading the patch and if things are still not OK then you'd be advised
131to start with a fresh tree downloaded in full from kernel.org. 132to start with a fresh tree downloaded in full from kernel.org.
132 133
133Let's look a bit more at some of the messages patch can produce. 134Let's look a bit more at some of the messages patch can produce.
@@ -180,9 +181,11 @@ wish to apply.
180 181
181Are there any alternatives to `patch'? 182Are there any alternatives to `patch'?
182--- 183---
183 Yes there are alternatives. You can use the `interdiff' program 184 Yes there are alternatives.
184(http://cyberelk.net/tim/patchutils/) to generate a patch representing the 185
185differences between two patches and then apply the result. 186 You can use the `interdiff' program (http://cyberelk.net/tim/patchutils/) to
187generate a patch representing the differences between two patches and then
188apply the result.
186This will let you move from something like 2.6.12.2 to 2.6.12.3 in a single 189This will let you move from something like 2.6.12.2 to 2.6.12.3 in a single
187step. The -z flag to interdiff will even let you feed it patches in gzip or 190step. The -z flag to interdiff will even let you feed it patches in gzip or
188bzip2 compressed form directly without the use of zcat or bzcat or manual 191bzip2 compressed form directly without the use of zcat or bzcat or manual
@@ -197,7 +200,7 @@ do the additional steps since interdiff can get things wrong in some cases.
197 Another alternative is `ketchup', which is a python script for automatic 200 Another alternative is `ketchup', which is a python script for automatic
198downloading and applying of patches (http://www.selenic.com/ketchup/). 201downloading and applying of patches (http://www.selenic.com/ketchup/).
199 202
200Other nice tools are diffstat which shows a summary of changes made by a 203 Other nice tools are diffstat which shows a summary of changes made by a
201patch, lsdiff which displays a short listing of affected files in a patch 204patch, lsdiff which displays a short listing of affected files in a patch
202file, along with (optionally) the line numbers of the start of each patch 205file, along with (optionally) the line numbers of the start of each patch
203and grepdiff which displays a list of the files modified by a patch where 206and grepdiff which displays a list of the files modified by a patch where
@@ -258,7 +261,7 @@ $ patch -p1 -R < ../patch-2.6.11.1 # revert the 2.6.11.1 patch
258 # source dir is now 2.6.11 261 # source dir is now 2.6.11
259$ patch -p1 < ../patch-2.6.12 # apply new 2.6.12 patch 262$ patch -p1 < ../patch-2.6.12 # apply new 2.6.12 patch
260$ cd .. 263$ cd ..
261$ mv linux-2.6.11.1 inux-2.6.12 # rename source dir 264$ mv linux-2.6.11.1 linux-2.6.12 # rename source dir
262 265
263 266
264The 2.6.x.y kernels 267The 2.6.x.y kernels
@@ -433,7 +436,11 @@ $ cd ..
433$ mv linux-2.6.12-mm1 linux-2.6.13-rc3-mm3 # rename the source dir 436$ mv linux-2.6.12-mm1 linux-2.6.13-rc3-mm3 # rename the source dir
434 437
435 438
436This concludes this list of explanations of the various kernel trees and I 439This concludes this list of explanations of the various kernel trees.
437hope you are now crystal clear on how to apply the various patches and help 440I hope you are now clear on how to apply the various patches and help testing
438testing the kernel. 441the kernel.
442
443Thank you's to Randy Dunlap, Rolf Eike Beer, Linus Torvalds, Bodo Eggert,
444Johannes Stezenbach, Grant Coady, Pavel Machek and others that I may have
445forgotten for their reviews and contributions to this document.
439 446
diff --git a/Documentation/block/stat.txt b/Documentation/block/stat.txt
new file mode 100644
index 000000000000..0dbc946de2ea
--- /dev/null
+++ b/Documentation/block/stat.txt
@@ -0,0 +1,82 @@
1Block layer statistics in /sys/block/<dev>/stat
2===============================================
3
4This file documents the contents of the /sys/block/<dev>/stat file.
5
6The stat file provides several statistics about the state of block
7device <dev>.
8
9Q. Why are there multiple statistics in a single file? Doesn't sysfs
10 normally contain a single value per file?
11A. By having a single file, the kernel can guarantee that the statistics
12 represent a consistent snapshot of the state of the device. If the
13 statistics were exported as multiple files containing one statistic
14 each, it would be impossible to guarantee that a set of readings
15 represent a single point in time.
16
17The stat file consists of a single line of text containing 11 decimal
18values separated by whitespace. The fields are summarized in the
19following table, and described in more detail below.
20
21Name units description
22---- ----- -----------
23read I/Os requests number of read I/Os processed
24read merges requests number of read I/Os merged with in-queue I/O
25read sectors sectors number of sectors read
26read ticks milliseconds total wait time for read requests
27write I/Os requests number of write I/Os processed
28write merges requests number of write I/Os merged with in-queue I/O
29write sectors sectors number of sectors written
30write ticks milliseconds total wait time for write requests
31in_flight requests number of I/Os currently in flight
32io_ticks milliseconds total time this block device has been active
33time_in_queue milliseconds total wait time for all requests
34
35read I/Os, write I/Os
36=====================
37
38These values increment when an I/O request completes.
39
40read merges, write merges
41=========================
42
43These values increment when an I/O request is merged with an
44already-queued I/O request.
45
46read sectors, write sectors
47===========================
48
49These values count the number of sectors read from or written to this
50block device. The "sectors" in question are the standard UNIX 512-byte
51sectors, not any device- or filesystem-specific block size. The
52counters are incremented when the I/O completes.
53
54read ticks, write ticks
55=======================
56
57These values count the number of milliseconds that I/O requests have
58waited on this block device. If there are multiple I/O requests waiting,
59these values will increase at a rate greater than 1000/second; for
60example, if 60 read requests wait for an average of 30 ms, the read_ticks
61field will increase by 60*30 = 1800.
62
63in_flight
64=========
65
66This value counts the number of I/O requests that have been issued to
67the device driver but have not yet completed. It does not include I/O
68requests that are in the queue but not yet issued to the device driver.
69
70io_ticks
71========
72
73This value counts the number of milliseconds during which the device has
74had I/O requests queued.
75
76time_in_queue
77=============
78
79This value counts the number of milliseconds that I/O requests have waited
80on this block device. If there are multiple I/O requests waiting, this
81value will increase as the product of the number of milliseconds times the
82number of requests waiting (see "read ticks" above for an example).
diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt
new file mode 100644
index 000000000000..08c5d04f3086
--- /dev/null
+++ b/Documentation/cpu-hotplug.txt
@@ -0,0 +1,357 @@
1 CPU hotplug Support in Linux(tm) Kernel
2
3 Maintainers:
4 CPU Hotplug Core:
5 Rusty Russell <rusty@rustycorp.com.au>
6 Srivatsa Vaddagiri <vatsa@in.ibm.com>
7 i386:
8 Zwane Mwaikambo <zwane@arm.linux.org.uk>
9 ppc64:
10 Nathan Lynch <nathanl@austin.ibm.com>
11 Joel Schopp <jschopp@austin.ibm.com>
12 ia64/x86_64:
13 Ashok Raj <ashok.raj@intel.com>
14
15Authors: Ashok Raj <ashok.raj@intel.com>
16Lots of feedback: Nathan Lynch <nathanl@austin.ibm.com>,
17 Joel Schopp <jschopp@austin.ibm.com>
18
19Introduction
20
21Modern advances in system architectures have introduced advanced error
22reporting and correction capabilities in processors. CPU architectures permit
23partitioning support, where compute resources of a single CPU could be made
24available to virtual machine environments. There are couple OEMS that
25support NUMA hardware which are hot pluggable as well, where physical
26node insertion and removal require support for CPU hotplug.
27
28Such advances require CPUs available to a kernel to be removed either for
29provisioning reasons, or for RAS purposes to keep an offending CPU off
30system execution path. Hence the need for CPU hotplug support in the
31Linux kernel.
32
33A more novel use of CPU-hotplug support is its use today in suspend
34resume support for SMP. Dual-core and HT support makes even
35a laptop run SMP kernels which didn't support these methods. SMP support
36for suspend/resume is a work in progress.
37
38General Stuff about CPU Hotplug
39--------------------------------
40
41Command Line Switches
42---------------------
43maxcpus=n Restrict boot time cpus to n. Say if you have 4 cpus, using
44 maxcpus=2 will only boot 2. You can choose to bring the
45 other cpus later online, read FAQ's for more info.
46
47additional_cpus=n [x86_64 only] use this to limit hotpluggable cpus.
48 This option sets
49 cpu_possible_map = cpu_present_map + additional_cpus
50
51CPU maps and such
52-----------------
53[More on cpumaps and primitive to manipulate, please check
54include/linux/cpumask.h that has more descriptive text.]
55
56cpu_possible_map: Bitmap of possible CPUs that can ever be available in the
57system. This is used to allocate some boot time memory for per_cpu variables
58that aren't designed to grow/shrink as CPUs are made available or removed.
59Once set during boot time discovery phase, the map is static, i.e no bits
60are added or removed anytime. Trimming it accurately for your system needs
61upfront can save some boot time memory. See below for how we use heuristics
62in x86_64 case to keep this under check.
63
64cpu_online_map: Bitmap of all CPUs currently online. Its set in __cpu_up()
65after a cpu is available for kernel scheduling and ready to receive
66interrupts from devices. Its cleared when a cpu is brought down using
67__cpu_disable(), before which all OS services including interrupts are
68migrated to another target CPU.
69
70cpu_present_map: Bitmap of CPUs currently present in the system. Not all
71of them may be online. When physical hotplug is processed by the relevant
72subsystem (e.g ACPI) can change and new bit either be added or removed
73from the map depending on the event is hot-add/hot-remove. There are currently
74no locking rules as of now. Typical usage is to init topology during boot,
75at which time hotplug is disabled.
76
77You really dont need to manipulate any of the system cpu maps. They should
78be read-only for most use. When setting up per-cpu resources almost always use
79cpu_possible_map/for_each_cpu() to iterate.
80
81Never use anything other than cpumask_t to represent bitmap of CPUs.
82
83#include <linux/cpumask.h>
84
85for_each_cpu - Iterate over cpu_possible_map
86for_each_online_cpu - Iterate over cpu_online_map
87for_each_present_cpu - Iterate over cpu_present_map
88for_each_cpu_mask(x,mask) - Iterate over some random collection of cpu mask.
89
90#include <linux/cpu.h>
91lock_cpu_hotplug() and unlock_cpu_hotplug():
92
93The above calls are used to inhibit cpu hotplug operations. While holding the
94cpucontrol mutex, cpu_online_map will not change. If you merely need to avoid
95cpus going away, you could also use preempt_disable() and preempt_enable()
96for those sections. Just remember the critical section cannot call any
97function that can sleep or schedule this process away. The preempt_disable()
98will work as long as stop_machine_run() is used to take a cpu down.
99
100CPU Hotplug - Frequently Asked Questions.
101
102Q: How to i enable my kernel to support CPU hotplug?
103A: When doing make defconfig, Enable CPU hotplug support
104
105 "Processor type and Features" -> Support for Hotpluggable CPUs
106
107Make sure that you have CONFIG_HOTPLUG, and CONFIG_SMP turned on as well.
108
109You would need to enable CONFIG_HOTPLUG_CPU for SMP suspend/resume support
110as well.
111
112Q: What architectures support CPU hotplug?
113A: As of 2.6.14, the following architectures support CPU hotplug.
114
115i386 (Intel), ppc, ppc64, parisc, s390, ia64 and x86_64
116
117Q: How to test if hotplug is supported on the newly built kernel?
118A: You should now notice an entry in sysfs.
119
120Check if sysfs is mounted, using the "mount" command. You should notice
121an entry as shown below in the output.
122
123....
124none on /sys type sysfs (rw)
125....
126
127if this is not mounted, do the following.
128
129#mkdir /sysfs
130#mount -t sysfs sys /sys
131
132now you should see entries for all present cpu, the following is an example
133in a 8-way system.
134
135#pwd
136#/sys/devices/system/cpu
137#ls -l
138total 0
139drwxr-xr-x 10 root root 0 Sep 19 07:44 .
140drwxr-xr-x 13 root root 0 Sep 19 07:45 ..
141drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu0
142drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu1
143drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu2
144drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu3
145drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu4
146drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu5
147drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu6
148drwxr-xr-x 3 root root 0 Sep 19 07:48 cpu7
149
150Under each directory you would find an "online" file which is the control
151file to logically online/offline a processor.
152
153Q: Does hot-add/hot-remove refer to physical add/remove of cpus?
154A: The usage of hot-add/remove may not be very consistently used in the code.
155CONFIG_CPU_HOTPLUG enables logical online/offline capability in the kernel.
156To support physical addition/removal, one would need some BIOS hooks and
157the platform should have something like an attention button in PCI hotplug.
158CONFIG_ACPI_HOTPLUG_CPU enables ACPI support for physical add/remove of CPUs.
159
160Q: How do i logically offline a CPU?
161A: Do the following.
162
163#echo 0 > /sys/devices/system/cpu/cpuX/online
164
165once the logical offline is successful, check
166
167#cat /proc/interrupts
168
169you should now not see the CPU that you removed. Also online file will report
170the state as 0 when a cpu if offline and 1 when its online.
171
172#To display the current cpu state.
173#cat /sys/devices/system/cpu/cpuX/online
174
175Q: Why cant i remove CPU0 on some systems?
176A: Some architectures may have some special dependency on a certain CPU.
177
178For e.g in IA64 platforms we have ability to sent platform interrupts to the
179OS. a.k.a Corrected Platform Error Interrupts (CPEI). In current ACPI
180specifications, we didn't have a way to change the target CPU. Hence if the
181current ACPI version doesn't support such re-direction, we disable that CPU
182by making it not-removable.
183
184In such cases you will also notice that the online file is missing under cpu0.
185
186Q: How do i find out if a particular CPU is not removable?
187A: Depending on the implementation, some architectures may show this by the
188absence of the "online" file. This is done if it can be determined ahead of
189time that this CPU cannot be removed.
190
191In some situations, this can be a run time check, i.e if you try to remove the
192last CPU, this will not be permitted. You can find such failures by
193investigating the return value of the "echo" command.
194
195Q: What happens when a CPU is being logically offlined?
196A: The following happen, listed in no particular order :-)
197
198- A notification is sent to in-kernel registered modules by sending an event
199 CPU_DOWN_PREPARE
200- All process is migrated away from this outgoing CPU to a new CPU
201- All interrupts targeted to this CPU is migrated to a new CPU
202- timers/bottom half/task lets are also migrated to a new CPU
203- Once all services are migrated, kernel calls an arch specific routine
204 __cpu_disable() to perform arch specific cleanup.
205- Once this is successful, an event for successful cleanup is sent by an event
206 CPU_DEAD.
207
208 "It is expected that each service cleans up when the CPU_DOWN_PREPARE
209 notifier is called, when CPU_DEAD is called its expected there is nothing
210 running on behalf of this CPU that was offlined"
211
212Q: If i have some kernel code that needs to be aware of CPU arrival and
213 departure, how to i arrange for proper notification?
214A: This is what you would need in your kernel code to receive notifications.
215
216 #include <linux/cpu.h>
217 static int __cpuinit foobar_cpu_callback(struct notifier_block *nfb,
218 unsigned long action, void *hcpu)
219 {
220 unsigned int cpu = (unsigned long)hcpu;
221
222 switch (action) {
223 case CPU_ONLINE:
224 foobar_online_action(cpu);
225 break;
226 case CPU_DEAD:
227 foobar_dead_action(cpu);
228 break;
229 }
230 return NOTIFY_OK;
231 }
232
233 static struct notifier_block foobar_cpu_notifer =
234 {
235 .notifier_call = foobar_cpu_callback,
236 };
237
238
239In your init function,
240
241 register_cpu_notifier(&foobar_cpu_notifier);
242
243You can fail PREPARE notifiers if something doesn't work to prepare resources.
244This will stop the activity and send a following CANCELED event back.
245
246CPU_DEAD should not be failed, its just a goodness indication, but bad
247things will happen if a notifier in path sent a BAD notify code.
248
249Q: I don't see my action being called for all CPUs already up and running?
250A: Yes, CPU notifiers are called only when new CPUs are on-lined or offlined.
251 If you need to perform some action for each cpu already in the system, then
252
253 for_each_online_cpu(i) {
254 foobar_cpu_callback(&foobar_cpu_notifier, CPU_UP_PREPARE, i);
255 foobar_cpu_callback(&foobar-cpu_notifier, CPU_ONLINE, i);
256 }
257
258Q: If i would like to develop cpu hotplug support for a new architecture,
259 what do i need at a minimum?
260A: The following are what is required for CPU hotplug infrastructure to work
261 correctly.
262
263 - Make sure you have an entry in Kconfig to enable CONFIG_HOTPLUG_CPU
264 - __cpu_up() - Arch interface to bring up a CPU
265 - __cpu_disable() - Arch interface to shutdown a CPU, no more interrupts
266 can be handled by the kernel after the routine
267 returns. Including local APIC timers etc are
268 shutdown.
269 - __cpu_die() - This actually supposed to ensure death of the CPU.
270 Actually look at some example code in other arch
271 that implement CPU hotplug. The processor is taken
272 down from the idle() loop for that specific
273 architecture. __cpu_die() typically waits for some
274 per_cpu state to be set, to ensure the processor
275 dead routine is called to be sure positively.
276
277Q: I need to ensure that a particular cpu is not removed when there is some
278 work specific to this cpu is in progress.
279A: First switch the current thread context to preferred cpu
280
281 int my_func_on_cpu(int cpu)
282 {
283 cpumask_t saved_mask, new_mask = CPU_MASK_NONE;
284 int curr_cpu, err = 0;
285
286 saved_mask = current->cpus_allowed;
287 cpu_set(cpu, new_mask);
288 err = set_cpus_allowed(current, new_mask);
289
290 if (err)
291 return err;
292
293 /*
294 * If we got scheduled out just after the return from
295 * set_cpus_allowed() before running the work, this ensures
296 * we stay locked.
297 */
298 curr_cpu = get_cpu();
299
300 if (curr_cpu != cpu) {
301 err = -EAGAIN;
302 goto ret;
303 } else {
304 /*
305 * Do work : But cant sleep, since get_cpu() disables preempt
306 */
307 }
308 ret:
309 put_cpu();
310 set_cpus_allowed(current, saved_mask);
311 return err;
312 }
313
314
315Q: How do we determine how many CPUs are available for hotplug.
316A: There is no clear spec defined way from ACPI that can give us that
317 information today. Based on some input from Natalie of Unisys,
318 that the ACPI MADT (Multiple APIC Description Tables) marks those possible
319 CPUs in a system with disabled status.
320
321 Andi implemented some simple heuristics that count the number of disabled
322 CPUs in MADT as hotpluggable CPUS. In the case there are no disabled CPUS
323 we assume 1/2 the number of CPUs currently present can be hotplugged.
324
325 Caveat: Today's ACPI MADT can only provide 256 entries since the apicid field
326 in MADT is only 8 bits.
327
328User Space Notification
329
330Hotplug support for devices is common in Linux today. Its being used today to
331support automatic configuration of network, usb and pci devices. A hotplug
332event can be used to invoke an agent script to perform the configuration task.
333
334You can add /etc/hotplug/cpu.agent to handle hotplug notification user space
335scripts.
336
337 #!/bin/bash
338 # $Id: cpu.agent
339 # Kernel hotplug params include:
340 #ACTION=%s [online or offline]
341 #DEVPATH=%s
342 #
343 cd /etc/hotplug
344 . ./hotplug.functions
345
346 case $ACTION in
347 online)
348 echo `date` ":cpu.agent" add cpu >> /tmp/hotplug.txt
349 ;;
350 offline)
351 echo `date` ":cpu.agent" remove cpu >>/tmp/hotplug.txt
352 ;;
353 *)
354 debug_mesg CPU $ACTION event not supported
355 exit 1
356 ;;
357 esac
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index a09a8eb80665..9e49b1c35729 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -14,7 +14,10 @@ CONTENTS:
14 1.1 What are cpusets ? 14 1.1 What are cpusets ?
15 1.2 Why are cpusets needed ? 15 1.2 Why are cpusets needed ?
16 1.3 How are cpusets implemented ? 16 1.3 How are cpusets implemented ?
17 1.4 How do I use cpusets ? 17 1.4 What are exclusive cpusets ?
18 1.5 What does notify_on_release do ?
19 1.6 What is memory_pressure ?
20 1.7 How do I use cpusets ?
182. Usage Examples and Syntax 212. Usage Examples and Syntax
19 2.1 Basic Usage 22 2.1 Basic Usage
20 2.2 Adding/removing cpus 23 2.2 Adding/removing cpus
@@ -49,29 +52,6 @@ its cpus_allowed vector, and the kernel page allocator will not
49allocate a page on a node that is not allowed in the requesting tasks 52allocate a page on a node that is not allowed in the requesting tasks
50mems_allowed vector. 53mems_allowed vector.
51 54
52If a cpuset is cpu or mem exclusive, no other cpuset, other than a direct
53ancestor or descendent, may share any of the same CPUs or Memory Nodes.
54A cpuset that is cpu exclusive has a sched domain associated with it.
55The sched domain consists of all cpus in the current cpuset that are not
56part of any exclusive child cpusets.
57This ensures that the scheduler load balacing code only balances
58against the cpus that are in the sched domain as defined above and not
59all of the cpus in the system. This removes any overhead due to
60load balancing code trying to pull tasks outside of the cpu exclusive
61cpuset only to be prevented by the tasks' cpus_allowed mask.
62
63A cpuset that is mem_exclusive restricts kernel allocations for
64page, buffer and other data commonly shared by the kernel across
65multiple users. All cpusets, whether mem_exclusive or not, restrict
66allocations of memory for user space. This enables configuring a
67system so that several independent jobs can share common kernel
68data, such as file system pages, while isolating each jobs user
69allocation in its own cpuset. To do this, construct a large
70mem_exclusive cpuset to hold all the jobs, and construct child,
71non-mem_exclusive cpusets for each individual job. Only a small
72amount of typical kernel memory, such as requests from interrupt
73handlers, is allowed to be taken outside even a mem_exclusive cpuset.
74
75User level code may create and destroy cpusets by name in the cpuset 55User level code may create and destroy cpusets by name in the cpuset
76virtual file system, manage the attributes and permissions of these 56virtual file system, manage the attributes and permissions of these
77cpusets and which CPUs and Memory Nodes are assigned to each cpuset, 57cpusets and which CPUs and Memory Nodes are assigned to each cpuset,
@@ -192,9 +172,15 @@ containing the following files describing that cpuset:
192 172
193 - cpus: list of CPUs in that cpuset 173 - cpus: list of CPUs in that cpuset
194 - mems: list of Memory Nodes in that cpuset 174 - mems: list of Memory Nodes in that cpuset
175 - memory_migrate flag: if set, move pages to cpusets nodes
195 - cpu_exclusive flag: is cpu placement exclusive? 176 - cpu_exclusive flag: is cpu placement exclusive?
196 - mem_exclusive flag: is memory placement exclusive? 177 - mem_exclusive flag: is memory placement exclusive?
197 - tasks: list of tasks (by pid) attached to that cpuset 178 - tasks: list of tasks (by pid) attached to that cpuset
179 - notify_on_release flag: run /sbin/cpuset_release_agent on exit?
180 - memory_pressure: measure of how much paging pressure in cpuset
181
182In addition, the root cpuset only has the following file:
183 - memory_pressure_enabled flag: compute memory_pressure?
198 184
199New cpusets are created using the mkdir system call or shell 185New cpusets are created using the mkdir system call or shell
200command. The properties of a cpuset, such as its flags, allowed 186command. The properties of a cpuset, such as its flags, allowed
@@ -228,7 +214,108 @@ exclusive cpuset. Also, the use of a Linux virtual file system (vfs)
228to represent the cpuset hierarchy provides for a familiar permission 214to represent the cpuset hierarchy provides for a familiar permission
229and name space for cpusets, with a minimum of additional kernel code. 215and name space for cpusets, with a minimum of additional kernel code.
230 216
2311.4 How do I use cpusets ? 217
2181.4 What are exclusive cpusets ?
219--------------------------------
220
221If a cpuset is cpu or mem exclusive, no other cpuset, other than
222a direct ancestor or descendent, may share any of the same CPUs or
223Memory Nodes.
224
225A cpuset that is cpu_exclusive has a scheduler (sched) domain
226associated with it. The sched domain consists of all CPUs in the
227current cpuset that are not part of any exclusive child cpusets.
228This ensures that the scheduler load balancing code only balances
229against the CPUs that are in the sched domain as defined above and
230not all of the CPUs in the system. This removes any overhead due to
231load balancing code trying to pull tasks outside of the cpu_exclusive
232cpuset only to be prevented by the tasks' cpus_allowed mask.
233
234A cpuset that is mem_exclusive restricts kernel allocations for
235page, buffer and other data commonly shared by the kernel across
236multiple users. All cpusets, whether mem_exclusive or not, restrict
237allocations of memory for user space. This enables configuring a
238system so that several independent jobs can share common kernel data,
239such as file system pages, while isolating each jobs user allocation in
240its own cpuset. To do this, construct a large mem_exclusive cpuset to
241hold all the jobs, and construct child, non-mem_exclusive cpusets for
242each individual job. Only a small amount of typical kernel memory,
243such as requests from interrupt handlers, is allowed to be taken
244outside even a mem_exclusive cpuset.
245
246
2471.5 What does notify_on_release do ?
248------------------------------------
249
250If the notify_on_release flag is enabled (1) in a cpuset, then whenever
251the last task in the cpuset leaves (exits or attaches to some other
252cpuset) and the last child cpuset of that cpuset is removed, then
253the kernel runs the command /sbin/cpuset_release_agent, supplying the
254pathname (relative to the mount point of the cpuset file system) of the
255abandoned cpuset. This enables automatic removal of abandoned cpusets.
256The default value of notify_on_release in the root cpuset at system
257boot is disabled (0). The default value of other cpusets at creation
258is the current value of their parents notify_on_release setting.
259
260
2611.6 What is memory_pressure ?
262-----------------------------
263The memory_pressure of a cpuset provides a simple per-cpuset metric
264of the rate that the tasks in a cpuset are attempting to free up in
265use memory on the nodes of the cpuset to satisfy additional memory
266requests.
267
268This enables batch managers monitoring jobs running in dedicated
269cpusets to efficiently detect what level of memory pressure that job
270is causing.
271
272This is useful both on tightly managed systems running a wide mix of
273submitted jobs, which may choose to terminate or re-prioritize jobs that
274are trying to use more memory than allowed on the nodes assigned them,
275and with tightly coupled, long running, massively parallel scientific
276computing jobs that will dramatically fail to meet required performance
277goals if they start to use more memory than allowed to them.
278
279This mechanism provides a very economical way for the batch manager
280to monitor a cpuset for signs of memory pressure. It's up to the
281batch manager or other user code to decide what to do about it and
282take action.
283
284==> Unless this feature is enabled by writing "1" to the special file
285 /dev/cpuset/memory_pressure_enabled, the hook in the rebalance
286 code of __alloc_pages() for this metric reduces to simply noticing
287 that the cpuset_memory_pressure_enabled flag is zero. So only
288 systems that enable this feature will compute the metric.
289
290Why a per-cpuset, running average:
291
292 Because this meter is per-cpuset, rather than per-task or mm,
293 the system load imposed by a batch scheduler monitoring this
294 metric is sharply reduced on large systems, because a scan of
295 the tasklist can be avoided on each set of queries.
296
297 Because this meter is a running average, instead of an accumulating
298 counter, a batch scheduler can detect memory pressure with a
299 single read, instead of having to read and accumulate results
300 for a period of time.
301
302 Because this meter is per-cpuset rather than per-task or mm,
303 the batch scheduler can obtain the key information, memory
304 pressure in a cpuset, with a single read, rather than having to
305 query and accumulate results over all the (dynamically changing)
306 set of tasks in the cpuset.
307
308A per-cpuset simple digital filter (requires a spinlock and 3 words
309of data per-cpuset) is kept, and updated by any task attached to that
310cpuset, if it enters the synchronous (direct) page reclaim code.
311
312A per-cpuset file provides an integer number representing the recent
313(half-life of 10 seconds) rate of direct page reclaims caused by
314the tasks in the cpuset, in units of reclaims attempted per second,
315times 1000.
316
317
3181.7 How do I use cpusets ?
232-------------------------- 319--------------------------
233 320
234In order to minimize the impact of cpusets on critical kernel 321In order to minimize the impact of cpusets on critical kernel
@@ -277,6 +364,30 @@ rewritten to the 'tasks' file of its cpuset. This is done to avoid
277impacting the scheduler code in the kernel with a check for changes 364impacting the scheduler code in the kernel with a check for changes
278in a tasks processor placement. 365in a tasks processor placement.
279 366
367Normally, once a page is allocated (given a physical page
368of main memory) then that page stays on whatever node it
369was allocated, so long as it remains allocated, even if the
370cpusets memory placement policy 'mems' subsequently changes.
371If the cpuset flag file 'memory_migrate' is set true, then when
372tasks are attached to that cpuset, any pages that task had
373allocated to it on nodes in its previous cpuset are migrated
374to the tasks new cpuset. Depending on the implementation,
375this migration may either be done by swapping the page out,
376so that the next time the page is referenced, it will be paged
377into the tasks new cpuset, usually on the node where it was
378referenced, or this migration may be done by directly copying
379the pages from the tasks previous cpuset to the new cpuset,
380where possible to the same node, relative to the new cpuset,
381as the node that held the page, relative to the old cpuset.
382Also if 'memory_migrate' is set true, then if that cpusets
383'mems' file is modified, pages allocated to tasks in that
384cpuset, that were on nodes in the previous setting of 'mems',
385will be moved to nodes in the new setting of 'mems.' Again,
386depending on the implementation, this might be done by swapping,
387or by direct copying. In either case, pages that were not in
388the tasks prior cpuset, or in the cpusets prior 'mems' setting,
389will not be moved.
390
280There is an exception to the above. If hotplug functionality is used 391There is an exception to the above. If hotplug functionality is used
281to remove all the CPUs that are currently assigned to a cpuset, 392to remove all the CPUs that are currently assigned to a cpuset,
282then the kernel will automatically update the cpus_allowed of all 393then the kernel will automatically update the cpus_allowed of all
diff --git a/Documentation/dvb/avermedia.txt b/Documentation/dvb/avermedia.txt
index 2dc260b2b0a4..068070ff13cd 100644
--- a/Documentation/dvb/avermedia.txt
+++ b/Documentation/dvb/avermedia.txt
@@ -150,7 +150,8 @@ Getting the card going
150 150
151 The frontend module sp887x.o, requires an external firmware. 151 The frontend module sp887x.o, requires an external firmware.
152 Please use the command "get_dvb_firmware sp887x" to download 152 Please use the command "get_dvb_firmware sp887x" to download
153 it. Then copy it to /usr/lib/hotplug/firmware. 153 it. Then copy it to /usr/lib/hotplug/firmware or /lib/firmware/
154 (depending on configuration of firmware hotplug).
154 155
155Receiving DVB-T in Australia 156Receiving DVB-T in Australia
156 157
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index be6eb4c75991..75c28a174092 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -23,7 +23,7 @@ use IO::Handle;
23 23
24@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t", 24@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t",
25 "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004", 25 "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
26 "or51211", "or51132_qam", "or51132_vsb"); 26 "or51211", "or51132_qam", "or51132_vsb", "bluebird");
27 27
28# Check args 28# Check args
29syntax() if (scalar(@ARGV) != 1); 29syntax() if (scalar(@ARGV) != 1);
@@ -34,7 +34,11 @@ for ($i=0; $i < scalar(@components); $i++) {
34 if ($cid eq $components[$i]) { 34 if ($cid eq $components[$i]) {
35 $outfile = eval($cid); 35 $outfile = eval($cid);
36 die $@ if $@; 36 die $@ if $@;
37 print STDERR "Firmware $outfile extracted successfully. Now copy it to either /lib/firmware or /usr/lib/hotplug/firmware/ (depending on your hotplug version).\n"; 37 print STDERR <<EOF;
38Firmware $outfile extracted successfully.
39Now copy it to either /usr/lib/hotplug/firmware or /lib/firmware
40(depending on configuration of firmware hotplug).
41EOF
38 exit(0); 42 exit(0);
39 } 43 }
40} 44}
@@ -243,7 +247,7 @@ sub nxt2002 {
243 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); 247 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
244 248
245 checkstandard(); 249 checkstandard();
246 250
247 wgetfile($sourcefile, $url); 251 wgetfile($sourcefile, $url);
248 unzip($sourcefile, $tmpdir); 252 unzip($sourcefile, $tmpdir);
249 verify("$tmpdir/SkyNETU.sys", $hash); 253 verify("$tmpdir/SkyNETU.sys", $hash);
@@ -308,6 +312,19 @@ sub or51132_vsb {
308 $fwfile; 312 $fwfile;
309} 313}
310 314
315sub bluebird {
316 my $url = "http://www.linuxtv.org/download/dvb/firmware/dvb-usb-bluebird-01.fw";
317 my $outfile = "dvb-usb-bluebird-01.fw";
318 my $hash = "658397cb9eba9101af9031302671f49d";
319
320 checkstandard();
321
322 wgetfile($outfile, $url);
323 verify($outfile,$hash);
324
325 $outfile;
326}
327
311# --------------------------------------------------------------- 328# ---------------------------------------------------------------
312# Utilities 329# Utilities
313 330
diff --git a/Documentation/dvb/ttusb-dec.txt b/Documentation/dvb/ttusb-dec.txt
index 5c1e984c26a7..b2f271cd784b 100644
--- a/Documentation/dvb/ttusb-dec.txt
+++ b/Documentation/dvb/ttusb-dec.txt
@@ -41,4 +41,5 @@ Hotplug Firmware Loading for 2.6 kernels
41For 2.6 kernels the firmware is loaded at the point that the driver module is 41For 2.6 kernels the firmware is loaded at the point that the driver module is
42loaded. See linux/Documentation/dvb/firmware.txt for more information. 42loaded. See linux/Documentation/dvb/firmware.txt for more information.
43 43
44Copy the three files downloaded above into the /usr/lib/hotplug/firmware directory. 44Copy the three files downloaded above into the /usr/lib/hotplug/firmware or
45/lib/firmware directory (depending on configuration of firmware hotplug).
diff --git a/Documentation/fb/cyblafb/bugs b/Documentation/fb/cyblafb/bugs
index f90cc66ea919..9443a6d72cdd 100644
--- a/Documentation/fb/cyblafb/bugs
+++ b/Documentation/fb/cyblafb/bugs
@@ -11,4 +11,3 @@ Untested features
11 11
12All LCD stuff is untested. If it worked in tridentfb, it should work in 12All LCD stuff is untested. If it worked in tridentfb, it should work in
13cyblafb. Please test and report the results to Knut_Petersen@t-online.de. 13cyblafb. Please test and report the results to Knut_Petersen@t-online.de.
14
diff --git a/Documentation/fb/cyblafb/fb.modes b/Documentation/fb/cyblafb/fb.modes
index cf4351fc32ff..fe0e5223ba86 100644
--- a/Documentation/fb/cyblafb/fb.modes
+++ b/Documentation/fb/cyblafb/fb.modes
@@ -14,142 +14,141 @@
14# 14#
15 15
16mode "640x480-50" 16mode "640x480-50"
17 geometry 640 480 640 3756 8 17 geometry 640 480 2048 4096 8
18 timings 47619 4294967256 24 17 0 216 3 18 timings 47619 4294967256 24 17 0 216 3
19endmode 19endmode
20 20
21mode "640x480-60" 21mode "640x480-60"
22 geometry 640 480 640 3756 8 22 geometry 640 480 2048 4096 8
23 timings 39682 4294967256 24 17 0 216 3 23 timings 39682 4294967256 24 17 0 216 3
24endmode 24endmode
25 25
26mode "640x480-70" 26mode "640x480-70"
27 geometry 640 480 640 3756 8 27 geometry 640 480 2048 4096 8
28 timings 34013 4294967256 24 17 0 216 3 28 timings 34013 4294967256 24 17 0 216 3
29endmode 29endmode
30 30
31mode "640x480-72" 31mode "640x480-72"
32 geometry 640 480 640 3756 8 32 geometry 640 480 2048 4096 8
33 timings 33068 4294967256 24 17 0 216 3 33 timings 33068 4294967256 24 17 0 216 3
34endmode 34endmode
35 35
36mode "640x480-75" 36mode "640x480-75"
37 geometry 640 480 640 3756 8 37 geometry 640 480 2048 4096 8
38 timings 31746 4294967256 24 17 0 216 3 38 timings 31746 4294967256 24 17 0 216 3
39endmode 39endmode
40 40
41mode "640x480-80" 41mode "640x480-80"
42 geometry 640 480 640 3756 8 42 geometry 640 480 2048 4096 8
43 timings 29761 4294967256 24 17 0 216 3 43 timings 29761 4294967256 24 17 0 216 3
44endmode 44endmode
45 45
46mode "640x480-85" 46mode "640x480-85"
47 geometry 640 480 640 3756 8 47 geometry 640 480 2048 4096 8
48 timings 28011 4294967256 24 17 0 216 3 48 timings 28011 4294967256 24 17 0 216 3
49endmode 49endmode
50 50
51mode "800x600-50" 51mode "800x600-50"
52 geometry 800 600 800 3221 8 52 geometry 800 600 2048 4096 8
53 timings 30303 96 24 14 0 136 11 53 timings 30303 96 24 14 0 136 11
54endmode 54endmode
55 55
56mode "800x600-60" 56mode "800x600-60"
57 geometry 800 600 800 3221 8 57 geometry 800 600 2048 4096 8
58 timings 25252 96 24 14 0 136 11 58 timings 25252 96 24 14 0 136 11
59endmode 59endmode
60 60
61mode "800x600-70" 61mode "800x600-70"
62 geometry 800 600 800 3221 8 62 geometry 800 600 2048 4096 8
63 timings 21645 96 24 14 0 136 11 63 timings 21645 96 24 14 0 136 11
64endmode 64endmode
65 65
66mode "800x600-72" 66mode "800x600-72"
67 geometry 800 600 800 3221 8 67 geometry 800 600 2048 4096 8
68 timings 21043 96 24 14 0 136 11 68 timings 21043 96 24 14 0 136 11
69endmode 69endmode
70 70
71mode "800x600-75" 71mode "800x600-75"
72 geometry 800 600 800 3221 8 72 geometry 800 600 2048 4096 8
73 timings 20202 96 24 14 0 136 11 73 timings 20202 96 24 14 0 136 11
74endmode 74endmode
75 75
76mode "800x600-80" 76mode "800x600-80"
77 geometry 800 600 800 3221 8 77 geometry 800 600 2048 4096 8
78 timings 18939 96 24 14 0 136 11 78 timings 18939 96 24 14 0 136 11
79endmode 79endmode
80 80
81mode "800x600-85" 81mode "800x600-85"
82 geometry 800 600 800 3221 8 82 geometry 800 600 2048 4096 8
83 timings 17825 96 24 14 0 136 11 83 timings 17825 96 24 14 0 136 11
84endmode 84endmode
85 85
86mode "1024x768-50" 86mode "1024x768-50"
87 geometry 1024 768 1024 2815 8 87 geometry 1024 768 2048 4096 8
88 timings 19054 144 24 29 0 120 3 88 timings 19054 144 24 29 0 120 3
89endmode 89endmode
90 90
91mode "1024x768-60" 91mode "1024x768-60"
92 geometry 1024 768 1024 2815 8 92 geometry 1024 768 2048 4096 8
93 timings 15880 144 24 29 0 120 3 93 timings 15880 144 24 29 0 120 3
94endmode 94endmode
95 95
96mode "1024x768-70" 96mode "1024x768-70"
97 geometry 1024 768 1024 2815 8 97 geometry 1024 768 2048 4096 8
98 timings 13610 144 24 29 0 120 3 98 timings 13610 144 24 29 0 120 3
99endmode 99endmode
100 100
101mode "1024x768-72" 101mode "1024x768-72"
102 geometry 1024 768 1024 2815 8 102 geometry 1024 768 2048 4096 8
103 timings 13232 144 24 29 0 120 3 103 timings 13232 144 24 29 0 120 3
104endmode 104endmode
105 105
106mode "1024x768-75" 106mode "1024x768-75"
107 geometry 1024 768 1024 2815 8 107 geometry 1024 768 2048 4096 8
108 timings 12703 144 24 29 0 120 3 108 timings 12703 144 24 29 0 120 3
109endmode 109endmode
110 110
111mode "1024x768-80" 111mode "1024x768-80"
112 geometry 1024 768 1024 2815 8 112 geometry 1024 768 2048 4096 8
113 timings 11910 144 24 29 0 120 3 113 timings 11910 144 24 29 0 120 3
114endmode 114endmode
115 115
116mode "1024x768-85" 116mode "1024x768-85"
117 geometry 1024 768 1024 2815 8 117 geometry 1024 768 2048 4096 8
118 timings 11209 144 24 29 0 120 3 118 timings 11209 144 24 29 0 120 3
119endmode 119endmode
120 120
121mode "1280x1024-50" 121mode "1280x1024-50"
122 geometry 1280 1024 1280 2662 8 122 geometry 1280 1024 2048 4096 8
123 timings 11114 232 16 39 0 160 3 123 timings 11114 232 16 39 0 160 3
124endmode 124endmode
125 125
126mode "1280x1024-60" 126mode "1280x1024-60"
127 geometry 1280 1024 1280 2662 8 127 geometry 1280 1024 2048 4096 8
128 timings 9262 232 16 39 0 160 3 128 timings 9262 232 16 39 0 160 3
129endmode 129endmode
130 130
131mode "1280x1024-70" 131mode "1280x1024-70"
132 geometry 1280 1024 1280 2662 8 132 geometry 1280 1024 2048 4096 8
133 timings 7939 232 16 39 0 160 3 133 timings 7939 232 16 39 0 160 3
134endmode 134endmode
135 135
136mode "1280x1024-72" 136mode "1280x1024-72"
137 geometry 1280 1024 1280 2662 8 137 geometry 1280 1024 2048 4096 8
138 timings 7719 232 16 39 0 160 3 138 timings 7719 232 16 39 0 160 3
139endmode 139endmode
140 140
141mode "1280x1024-75" 141mode "1280x1024-75"
142 geometry 1280 1024 1280 2662 8 142 geometry 1280 1024 2048 4096 8
143 timings 7410 232 16 39 0 160 3 143 timings 7410 232 16 39 0 160 3
144endmode 144endmode
145 145
146mode "1280x1024-80" 146mode "1280x1024-80"
147 geometry 1280 1024 1280 2662 8 147 geometry 1280 1024 2048 4096 8
148 timings 6946 232 16 39 0 160 3 148 timings 6946 232 16 39 0 160 3
149endmode 149endmode
150 150
151mode "1280x1024-85" 151mode "1280x1024-85"
152 geometry 1280 1024 1280 2662 8 152 geometry 1280 1024 2048 4096 8
153 timings 6538 232 16 39 0 160 3 153 timings 6538 232 16 39 0 160 3
154endmode 154endmode
155
diff --git a/Documentation/fb/cyblafb/performance b/Documentation/fb/cyblafb/performance
index eb4e47a9cea6..8d15d5dfc6b3 100644
--- a/Documentation/fb/cyblafb/performance
+++ b/Documentation/fb/cyblafb/performance
@@ -77,4 +77,3 @@ patch that speeds up kernel bitblitting a lot ( > 20%).
77| | | | | 77| | | | |
78| | | | | 78| | | | |
79+-----------+-----------------+-----------------+-----------------+ 79+-----------+-----------------+-----------------+-----------------+
80
diff --git a/Documentation/fb/cyblafb/todo b/Documentation/fb/cyblafb/todo
index 80fb2f89b6c1..c5f6d0eae545 100644
--- a/Documentation/fb/cyblafb/todo
+++ b/Documentation/fb/cyblafb/todo
@@ -22,11 +22,10 @@ accelerated color blitting Who needs it? The console driver does use color
22 everything else is done using color expanding 22 everything else is done using color expanding
23 blitting of 1bpp character bitmaps. 23 blitting of 1bpp character bitmaps.
24 24
25xpanning Who needs it?
26
27ioctls Who needs it? 25ioctls Who needs it?
28 26
29TV-out Will be done later 27TV-out Will be done later. Use "vga= " at boot time
28 to set a suitable video mode.
30 29
31??? Feel free to contact me if you have any 30??? Feel free to contact me if you have any
32 feature requests 31 feature requests
diff --git a/Documentation/fb/cyblafb/usage b/Documentation/fb/cyblafb/usage
index e627c8f54211..a39bb3d402a2 100644
--- a/Documentation/fb/cyblafb/usage
+++ b/Documentation/fb/cyblafb/usage
@@ -40,6 +40,16 @@ Selecting Modes
40 None of the modes possible to select as startup modes are affected by 40 None of the modes possible to select as startup modes are affected by
41 the problems described at the end of the next subsection. 41 the problems described at the end of the next subsection.
42 42
43 For all startup modes cyblafb chooses a virtual x resolution of 2048,
44 the only exception is mode 1280x1024 in combination with 32 bpp. This
45 allows ywrap scrolling for all those modes if rotation is 0 or 2, and
46 also fast scrolling if rotation is 1 or 3. The default virtual y reso-
47 lution is 4096 for bpp == 8, 2048 for bpp==16 and 1024 for bpp == 32,
48 again with the only exception of 1280x1024 at 32 bpp.
49
50 Please do set your video memory size to 8 Mb in the Bios setup. Other
51 values will work, but performace is decreased for a lot of modes.
52
43 Mode changes using fbset 53 Mode changes using fbset
44 ======================== 54 ========================
45 55
@@ -54,20 +64,26 @@ Selecting Modes
54 - if a flat panel is found, cyblafb does not allow you 64 - if a flat panel is found, cyblafb does not allow you
55 to program a resolution higher than the physical 65 to program a resolution higher than the physical
56 resolution of the flat panel monitor 66 resolution of the flat panel monitor
57 - cyblafb does not allow xres to differ from xres_virtual
58 - cyblafb does not allow vclk to exceed 230 MHz. As 32 bpp 67 - cyblafb does not allow vclk to exceed 230 MHz. As 32 bpp
59 and (currently) 24 bit modes use a doubled vclk internally, 68 and (currently) 24 bit modes use a doubled vclk internally,
60 the dotclock limit as seen by fbset is 115 MHz for those 69 the dotclock limit as seen by fbset is 115 MHz for those
61 modes and 230 MHz for 8 and 16 bpp modes. 70 modes and 230 MHz for 8 and 16 bpp modes.
71 - cyblafb will allow you to select very high resolutions as
72 long as the hardware can be programmed to these modes. The
73 documented limit 1600x1200 is not enforced, but don't expect
74 perfect signal quality.
62 75
63 Any request that violates the rules given above will be ignored and 76 Any request that violates the rules given above will be either changed
64 fbset will return an error. 77 to something the hardware supports or an error value will be returned.
65 78
66 If you program a virtual y resolution higher than the hardware limit, 79 If you program a virtual y resolution higher than the hardware limit,
67 cyblafb will silently decrease that value to the highest possible 80 cyblafb will silently decrease that value to the highest possible
68 value. 81 value. The same is true for a virtual x resolution that is not
82 supported by the hardware. Cyblafb tries to adapt vyres first because
83 vxres decides if ywrap scrolling is possible or not.
69 84
70 Attempts to disable acceleration are ignored. 85 Attempts to disable acceleration are ignored, I believe that this is
86 safe.
71 87
72 Some video modes that should work do not work as expected. If you use 88 Some video modes that should work do not work as expected. If you use
73 the standard fb.modes, fbset 640x480-60 will program that mode, but 89 the standard fb.modes, fbset 640x480-60 will program that mode, but
@@ -129,10 +145,6 @@ mode 640x480 or 800x600 or 1024x768 or 1280x1024
129verbosity 0 is the default, increase to at least 2 for every 145verbosity 0 is the default, increase to at least 2 for every
130 bug report! 146 bug report!
131 147
132vesafb allows cyblafb to be loaded after vesafb has been
133 loaded. See sections "Module unloading ...".
134
135
136Development hints 148Development hints
137================= 149=================
138 150
@@ -195,7 +207,7 @@ a graphics mode.
195After booting, load cyblafb without any mode and bpp parameter and assign 207After booting, load cyblafb without any mode and bpp parameter and assign
196cyblafb to individual ttys using con2fb, e.g.: 208cyblafb to individual ttys using con2fb, e.g.:
197 209
198 modprobe cyblafb vesafb=1 210 modprobe cyblafb
199 con2fb /dev/fb1 /dev/tty1 211 con2fb /dev/fb1 /dev/tty1
200 212
201Unloading cyblafb works without problems after you assign vesafb to all 213Unloading cyblafb works without problems after you assign vesafb to all
@@ -203,4 +215,3 @@ ttys again, e.g.:
203 215
204 con2fb /dev/fb0 /dev/tty1 216 con2fb /dev/fb0 /dev/tty1
205 rmmod cyblafb 217 rmmod cyblafb
206
diff --git a/Documentation/fb/cyblafb/whatsnew b/Documentation/fb/cyblafb/whatsnew
new file mode 100644
index 000000000000..76c07a26e044
--- /dev/null
+++ b/Documentation/fb/cyblafb/whatsnew
@@ -0,0 +1,29 @@
10.62
2====
3
4 - the vesafb parameter has been removed as I decided to allow the
5 feature without any special parameter.
6
7 - Cyblafb does not use the vga style of panning any longer, now the
8 "right view" register in the graphics engine IO space is used. Without
9 that change it was impossible to use all available memory, and without
10 access to all available memory it is impossible to ywrap.
11
12 - The imageblit function now uses hardware acceleration for all font
13 widths. Hardware blitting across pixel column 2048 is broken in the
14 cyberblade/i1 graphics core, but we work around that hardware bug.
15
16 - modes with vxres != xres are supported now.
17
18 - ywrap scrolling is supported now and the default. This is a big
19 performance gain.
20
21 - default video modes use vyres > yres and vxres > xres to allow
22 almost optimal scrolling speed for normal and rotated screens
23
24 - some features mainly usefull for debugging the upper layers of the
25 framebuffer system have been added, have a look at the code
26
27 - fixed: Oops after unloading cyblafb when reading /proc/io*
28
29 - we work around some bugs of the higher framebuffer layers.
diff --git a/Documentation/filesystems/ext3.txt b/Documentation/filesystems/ext3.txt
index 9840d5b8d5b9..22e4040564d5 100644
--- a/Documentation/filesystems/ext3.txt
+++ b/Documentation/filesystems/ext3.txt
@@ -22,6 +22,11 @@ journal=inum When a journal already exists, this option is
22 the inode which will represent the ext3 file 22 the inode which will represent the ext3 file
23 system's journal file. 23 system's journal file.
24 24
25journal_dev=devnum When the external journal device's major/minor numbers
26 have changed, this option allows to specify the new
27 journal location. The journal device is identified
28 through its new major/minor numbers encoded in devnum.
29
25noload Don't load the journal on mounting. 30noload Don't load the journal on mounting.
26 31
27data=journal All data are committed into the journal prior 32data=journal All data are committed into the journal prior
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index d4773565ea2f..a4dcf42c2fd9 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -1302,6 +1302,23 @@ VM has token based thrashing control mechanism and uses the token to prevent
1302unnecessary page faults in thrashing situation. The unit of the value is 1302unnecessary page faults in thrashing situation. The unit of the value is
1303second. The value would be useful to tune thrashing behavior. 1303second. The value would be useful to tune thrashing behavior.
1304 1304
1305drop_caches
1306-----------
1307
1308Writing to this will cause the kernel to drop clean caches, dentries and
1309inodes from memory, causing that memory to become free.
1310
1311To free pagecache:
1312 echo 1 > /proc/sys/vm/drop_caches
1313To free dentries and inodes:
1314 echo 2 > /proc/sys/vm/drop_caches
1315To free pagecache, dentries and inodes:
1316 echo 3 > /proc/sys/vm/drop_caches
1317
1318As this is a non-destructive operation and dirty objects are not freeable, the
1319user should run `sync' first.
1320
1321
13052.5 /proc/sys/dev - Device specific parameters 13222.5 /proc/sys/dev - Device specific parameters
1306---------------------------------------------- 1323----------------------------------------------
1307 1324
diff --git a/Documentation/filesystems/ramfs-rootfs-initramfs.txt b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
index b3404a032596..60ab61e54e8a 100644
--- a/Documentation/filesystems/ramfs-rootfs-initramfs.txt
+++ b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
@@ -143,12 +143,26 @@ as the following example:
143 dir /mnt 755 0 0 143 dir /mnt 755 0 0
144 file /init initramfs/init.sh 755 0 0 144 file /init initramfs/init.sh 755 0 0
145 145
146Run "usr/gen_init_cpio" (after the kernel build) to get a usage message
147documenting the above file format.
148
146One advantage of the text file is that root access is not required to 149One advantage of the text file is that root access is not required to
147set permissions or create device nodes in the new archive. (Note that those 150set permissions or create device nodes in the new archive. (Note that those
148two example "file" entries expect to find files named "init.sh" and "busybox" in 151two example "file" entries expect to find files named "init.sh" and "busybox" in
149a directory called "initramfs", under the linux-2.6.* directory. See 152a directory called "initramfs", under the linux-2.6.* directory. See
150Documentation/early-userspace/README for more details.) 153Documentation/early-userspace/README for more details.)
151 154
155The kernel does not depend on external cpio tools, gen_init_cpio is created
156from usr/gen_init_cpio.c which is entirely self-contained, and the kernel's
157boot-time extractor is also (obviously) self-contained. However, if you _do_
158happen to have cpio installed, the following command line can extract the
159generated cpio image back into its component files:
160
161 cpio -i -d -H newc -F initramfs_data.cpio --no-absolute-filenames
162
163Contents of initramfs:
164----------------------
165
152If you don't already understand what shared libraries, devices, and paths 166If you don't already understand what shared libraries, devices, and paths
153you need to get a minimal root filesystem up and running, here are some 167you need to get a minimal root filesystem up and running, here are some
154references: 168references:
@@ -161,13 +175,69 @@ designed to be a tiny C library to statically link early userspace
161code against, along with some related utilities. It is BSD licensed. 175code against, along with some related utilities. It is BSD licensed.
162 176
163I use uClibc (http://www.uclibc.org) and busybox (http://www.busybox.net) 177I use uClibc (http://www.uclibc.org) and busybox (http://www.busybox.net)
164myself. These are LGPL and GPL, respectively. 178myself. These are LGPL and GPL, respectively. (A self-contained initramfs
179package is planned for the busybox 1.2 release.)
165 180
166In theory you could use glibc, but that's not well suited for small embedded 181In theory you could use glibc, but that's not well suited for small embedded
167uses like this. (A "hello world" program statically linked against glibc is 182uses like this. (A "hello world" program statically linked against glibc is
168over 400k. With uClibc it's 7k. Also note that glibc dlopens libnss to do 183over 400k. With uClibc it's 7k. Also note that glibc dlopens libnss to do
169name lookups, even when otherwise statically linked.) 184name lookups, even when otherwise statically linked.)
170 185
186Why cpio rather than tar?
187-------------------------
188
189This decision was made back in December, 2001. The discussion started here:
190
191 http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1538.html
192
193And spawned a second thread (specifically on tar vs cpio), starting here:
194
195 http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1587.html
196
197The quick and dirty summary version (which is no substitute for reading
198the above threads) is:
199
2001) cpio is a standard. It's decades old (from the AT&T days), and already
201 widely used on Linux (inside RPM, Red Hat's device driver disks). Here's
202 a Linux Journal article about it from 1996:
203
204 http://www.linuxjournal.com/article/1213
205
206 It's not as popular as tar because the traditional cpio command line tools
207 require _truly_hideous_ command line arguments. But that says nothing
208 either way about the archive format, and there are alternative tools,
209 such as:
210
211 http://freshmeat.net/projects/afio/
212
2132) The cpio archive format chosen by the kernel is simpler and cleaner (and
214 thus easier to create and parse) than any of the (literally dozens of)
215 various tar archive formats. The complete initramfs archive format is
216 explained in buffer-format.txt, created in usr/gen_init_cpio.c, and
217 extracted in init/initramfs.c. All three together come to less than 26k
218 total of human-readable text.
219
2203) The GNU project standardizing on tar is approximately as relevant as
221 Windows standardizing on zip. Linux is not part of either, and is free
222 to make its own technical decisions.
223
2244) Since this is a kernel internal format, it could easily have been
225 something brand new. The kernel provides its own tools to create and
226 extract this format anyway. Using an existing standard was preferable,
227 but not essential.
228
2295) Al Viro made the decision (quote: "tar is ugly as hell and not going to be
230 supported on the kernel side"):
231
232 http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1540.html
233
234 explained his reasoning:
235
236 http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1550.html
237 http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1638.html
238
239 and, most importantly, designed and implemented the initramfs code.
240
171Future directions: 241Future directions:
172------------------ 242------------------
173 243
diff --git a/Documentation/filesystems/relayfs.txt b/Documentation/filesystems/relayfs.txt
index d803abed29f0..5832377b7340 100644
--- a/Documentation/filesystems/relayfs.txt
+++ b/Documentation/filesystems/relayfs.txt
@@ -44,30 +44,41 @@ relayfs can operate in a mode where it will overwrite data not yet
44collected by userspace, and not wait for it to consume it. 44collected by userspace, and not wait for it to consume it.
45 45
46relayfs itself does not provide for communication of such data between 46relayfs itself does not provide for communication of such data between
47userspace and kernel, allowing the kernel side to remain simple and not 47userspace and kernel, allowing the kernel side to remain simple and
48impose a single interface on userspace. It does provide a separate 48not impose a single interface on userspace. It does provide a set of
49helper though, described below. 49examples and a separate helper though, described below.
50
51klog and relay-apps example code
52================================
53
54relayfs itself is ready to use, but to make things easier, a couple
55simple utility functions and a set of examples are provided.
56
57The relay-apps example tarball, available on the relayfs sourceforge
58site, contains a set of self-contained examples, each consisting of a
59pair of .c files containing boilerplate code for each of the user and
60kernel sides of a relayfs application; combined these two sets of
61boilerplate code provide glue to easily stream data to disk, without
62having to bother with mundane housekeeping chores.
63
64The 'klog debugging functions' patch (klog.patch in the relay-apps
65tarball) provides a couple of high-level logging functions to the
66kernel which allow writing formatted text or raw data to a channel,
67regardless of whether a channel to write into exists or not, or
68whether relayfs is compiled into the kernel or is configured as a
69module. These functions allow you to put unconditional 'trace'
70statements anywhere in the kernel or kernel modules; only when there
71is a 'klog handler' registered will data actually be logged (see the
72klog and kleak examples for details).
73
74It is of course possible to use relayfs from scratch i.e. without
75using any of the relay-apps example code or klog, but you'll have to
76implement communication between userspace and kernel, allowing both to
77convey the state of buffers (full, empty, amount of padding).
78
79klog and the relay-apps examples can be found in the relay-apps
80tarball on http://relayfs.sourceforge.net
50 81
51klog, relay-app & librelay
52==========================
53
54relayfs itself is ready to use, but to make things easier, two
55additional systems are provided. klog is a simple wrapper to make
56writing formatted text or raw data to a channel simpler, regardless of
57whether a channel to write into exists or not, or whether relayfs is
58compiled into the kernel or is configured as a module. relay-app is
59the kernel counterpart of userspace librelay.c, combined these two
60files provide glue to easily stream data to disk, without having to
61bother with housekeeping. klog and relay-app can be used together,
62with klog providing high-level logging functions to the kernel and
63relay-app taking care of kernel-user control and disk-logging chores.
64
65It is possible to use relayfs without relay-app & librelay, but you'll
66have to implement communication between userspace and kernel, allowing
67both to convey the state of buffers (full, empty, amount of padding).
68
69klog, relay-app and librelay can be found in the relay-apps tarball on
70http://relayfs.sourceforge.net
71 82
72The relayfs user space API 83The relayfs user space API
73========================== 84==========================
@@ -125,6 +136,8 @@ Here's a summary of the API relayfs provides to in-kernel clients:
125 relay_reset(chan) 136 relay_reset(chan)
126 relayfs_create_dir(name, parent) 137 relayfs_create_dir(name, parent)
127 relayfs_remove_dir(dentry) 138 relayfs_remove_dir(dentry)
139 relayfs_create_file(name, parent, mode, fops, data)
140 relayfs_remove_file(dentry)
128 141
129 channel management typically called on instigation of userspace: 142 channel management typically called on instigation of userspace:
130 143
@@ -141,6 +154,8 @@ Here's a summary of the API relayfs provides to in-kernel clients:
141 subbuf_start(buf, subbuf, prev_subbuf, prev_padding) 154 subbuf_start(buf, subbuf, prev_subbuf, prev_padding)
142 buf_mapped(buf, filp) 155 buf_mapped(buf, filp)
143 buf_unmapped(buf, filp) 156 buf_unmapped(buf, filp)
157 create_buf_file(filename, parent, mode, buf, is_global)
158 remove_buf_file(dentry)
144 159
145 helper functions: 160 helper functions:
146 161
@@ -320,6 +335,71 @@ forces a sub-buffer switch on all the channel buffers, and can be used
320to finalize and process the last sub-buffers before the channel is 335to finalize and process the last sub-buffers before the channel is
321closed. 336closed.
322 337
338Creating non-relay files
339------------------------
340
341relay_open() automatically creates files in the relayfs filesystem to
342represent the per-cpu kernel buffers; it's often useful for
343applications to be able to create their own files alongside the relay
344files in the relayfs filesystem as well e.g. 'control' files much like
345those created in /proc or debugfs for similar purposes, used to
346communicate control information between the kernel and user sides of a
347relayfs application. For this purpose the relayfs_create_file() and
348relayfs_remove_file() API functions exist. For relayfs_create_file(),
349the caller passes in a set of user-defined file operations to be used
350for the file and an optional void * to a user-specified data item,
351which will be accessible via inode->u.generic_ip (see the relay-apps
352tarball for examples). The file_operations are a required parameter
353to relayfs_create_file() and thus the semantics of these files are
354completely defined by the caller.
355
356See the relay-apps tarball at http://relayfs.sourceforge.net for
357examples of how these non-relay files are meant to be used.
358
359Creating relay files in other filesystems
360-----------------------------------------
361
362By default of course, relay_open() creates relay files in the relayfs
363filesystem. Because relay_file_operations is exported, however, it's
364also possible to create and use relay files in other pseudo-filesytems
365such as debugfs.
366
367For this purpose, two callback functions are provided,
368create_buf_file() and remove_buf_file(). create_buf_file() is called
369once for each per-cpu buffer from relay_open() to allow the client to
370create a file to be used to represent the corresponding buffer; if
371this callback is not defined, the default implementation will create
372and return a file in the relayfs filesystem to represent the buffer.
373The callback should return the dentry of the file created to represent
374the relay buffer. Note that the parent directory passed to
375relay_open() (and passed along to the callback), if specified, must
376exist in the same filesystem the new relay file is created in. If
377create_buf_file() is defined, remove_buf_file() must also be defined;
378it's responsible for deleting the file(s) created in create_buf_file()
379and is called during relay_close().
380
381The create_buf_file() implementation can also be defined in such a way
382as to allow the creation of a single 'global' buffer instead of the
383default per-cpu set. This can be useful for applications interested
384mainly in seeing the relative ordering of system-wide events without
385the need to bother with saving explicit timestamps for the purpose of
386merging/sorting per-cpu files in a postprocessing step.
387
388To have relay_open() create a global buffer, the create_buf_file()
389implementation should set the value of the is_global outparam to a
390non-zero value in addition to creating the file that will be used to
391represent the single buffer. In the case of a global buffer,
392create_buf_file() and remove_buf_file() will be called only once. The
393normal channel-writing functions e.g. relay_write() can still be used
394- writes from any cpu will transparently end up in the global buffer -
395but since it is a global buffer, callers should make sure they use the
396proper locking for such a buffer, either by wrapping writes in a
397spinlock, or by copying a write function from relayfs_fs.h and
398creating a local version that internally does the proper locking.
399
400See the 'exported-relayfile' examples in the relay-apps tarball for
401examples of creating and using relay files in debugfs.
402
323Misc 403Misc
324---- 404----
325 405
diff --git a/Documentation/filesystems/spufs.txt b/Documentation/filesystems/spufs.txt
new file mode 100644
index 000000000000..8edc3952eff4
--- /dev/null
+++ b/Documentation/filesystems/spufs.txt
@@ -0,0 +1,521 @@
1SPUFS(2) Linux Programmer's Manual SPUFS(2)
2
3
4
5NAME
6 spufs - the SPU file system
7
8
9DESCRIPTION
10 The SPU file system is used on PowerPC machines that implement the Cell
11 Broadband Engine Architecture in order to access Synergistic Processor
12 Units (SPUs).
13
14 The file system provides a name space similar to posix shared memory or
15 message queues. Users that have write permissions on the file system
16 can use spu_create(2) to establish SPU contexts in the spufs root.
17
18 Every SPU context is represented by a directory containing a predefined
19 set of files. These files can be used for manipulating the state of the
20 logical SPU. Users can change permissions on those files, but not actu-
21 ally add or remove files.
22
23
24MOUNT OPTIONS
25 uid=<uid>
26 set the user owning the mount point, the default is 0 (root).
27
28 gid=<gid>
29 set the group owning the mount point, the default is 0 (root).
30
31
32FILES
33 The files in spufs mostly follow the standard behavior for regular sys-
34 tem calls like read(2) or write(2), but often support only a subset of
35 the operations supported on regular file systems. This list details the
36 supported operations and the deviations from the behaviour in the
37 respective man pages.
38
39 All files that support the read(2) operation also support readv(2) and
40 all files that support the write(2) operation also support writev(2).
41 All files support the access(2) and stat(2) family of operations, but
42 only the st_mode, st_nlink, st_uid and st_gid fields of struct stat
43 contain reliable information.
44
45 All files support the chmod(2)/fchmod(2) and chown(2)/fchown(2) opera-
46 tions, but will not be able to grant permissions that contradict the
47 possible operations, e.g. read access on the wbox file.
48
49 The current set of files is:
50
51
52 /mem
53 the contents of the local storage memory of the SPU. This can be
54 accessed like a regular shared memory file and contains both code and
55 data in the address space of the SPU. The possible operations on an
56 open mem file are:
57
58 read(2), pread(2), write(2), pwrite(2), lseek(2)
59 These operate as documented, with the exception that seek(2),
60 write(2) and pwrite(2) are not supported beyond the end of the
61 file. The file size is the size of the local storage of the SPU,
62 which normally is 256 kilobytes.
63
64 mmap(2)
65 Mapping mem into the process address space gives access to the
66 SPU local storage within the process address space. Only
67 MAP_SHARED mappings are allowed.
68
69
70 /mbox
71 The first SPU to CPU communication mailbox. This file is read-only and
72 can be read in units of 32 bits. The file can only be used in non-
73 blocking mode and it even poll() will not block on it. The possible
74 operations on an open mbox file are:
75
76 read(2)
77 If a count smaller than four is requested, read returns -1 and
78 sets errno to EINVAL. If there is no data available in the mail
79 box, the return value is set to -1 and errno becomes EAGAIN.
80 When data has been read successfully, four bytes are placed in
81 the data buffer and the value four is returned.
82
83
84 /ibox
85 The second SPU to CPU communication mailbox. This file is similar to
86 the first mailbox file, but can be read in blocking I/O mode, and the
87 poll familiy of system calls can be used to wait for it. The possible
88 operations on an open ibox file are:
89
90 read(2)
91 If a count smaller than four is requested, read returns -1 and
92 sets errno to EINVAL. If there is no data available in the mail
93 box and the file descriptor has been opened with O_NONBLOCK, the
94 return value is set to -1 and errno becomes EAGAIN.
95
96 If there is no data available in the mail box and the file
97 descriptor has been opened without O_NONBLOCK, the call will
98 block until the SPU writes to its interrupt mailbox channel.
99 When data has been read successfully, four bytes are placed in
100 the data buffer and the value four is returned.
101
102 poll(2)
103 Poll on the ibox file returns (POLLIN | POLLRDNORM) whenever
104 data is available for reading.
105
106
107 /wbox
108 The CPU to SPU communation mailbox. It is write-only can can be written
109 in units of 32 bits. If the mailbox is full, write() will block and
110 poll can be used to wait for it becoming empty again. The possible
111 operations on an open wbox file are: write(2) If a count smaller than
112 four is requested, write returns -1 and sets errno to EINVAL. If there
113 is no space available in the mail box and the file descriptor has been
114 opened with O_NONBLOCK, the return value is set to -1 and errno becomes
115 EAGAIN.
116
117 If there is no space available in the mail box and the file descriptor
118 has been opened without O_NONBLOCK, the call will block until the SPU
119 reads from its PPE mailbox channel. When data has been read success-
120 fully, four bytes are placed in the data buffer and the value four is
121 returned.
122
123 poll(2)
124 Poll on the ibox file returns (POLLOUT | POLLWRNORM) whenever
125 space is available for writing.
126
127
128 /mbox_stat
129 /ibox_stat
130 /wbox_stat
131 Read-only files that contain the length of the current queue, i.e. how
132 many words can be read from mbox or ibox or how many words can be
133 written to wbox without blocking. The files can be read only in 4-byte
134 units and return a big-endian binary integer number. The possible
135 operations on an open *box_stat file are:
136
137 read(2)
138 If a count smaller than four is requested, read returns -1 and
139 sets errno to EINVAL. Otherwise, a four byte value is placed in
140 the data buffer, containing the number of elements that can be
141 read from (for mbox_stat and ibox_stat) or written to (for
142 wbox_stat) the respective mail box without blocking or resulting
143 in EAGAIN.
144
145
146 /npc
147 /decr
148 /decr_status
149 /spu_tag_mask
150 /event_mask
151 /srr0
152 Internal registers of the SPU. The representation is an ASCII string
153 with the numeric value of the next instruction to be executed. These
154 can be used in read/write mode for debugging, but normal operation of
155 programs should not rely on them because access to any of them except
156 npc requires an SPU context save and is therefore very inefficient.
157
158 The contents of these files are:
159
160 npc Next Program Counter
161
162 decr SPU Decrementer
163
164 decr_status Decrementer Status
165
166 spu_tag_mask MFC tag mask for SPU DMA
167
168 event_mask Event mask for SPU interrupts
169
170 srr0 Interrupt Return address register
171
172
173 The possible operations on an open npc, decr, decr_status,
174 spu_tag_mask, event_mask or srr0 file are:
175
176 read(2)
177 When the count supplied to the read call is shorter than the
178 required length for the pointer value plus a newline character,
179 subsequent reads from the same file descriptor will result in
180 completing the string, regardless of changes to the register by
181 a running SPU task. When a complete string has been read, all
182 subsequent read operations will return zero bytes and a new file
183 descriptor needs to be opened to read the value again.
184
185 write(2)
186 A write operation on the file results in setting the register to
187 the value given in the string. The string is parsed from the
188 beginning to the first non-numeric character or the end of the
189 buffer. Subsequent writes to the same file descriptor overwrite
190 the previous setting.
191
192
193 /fpcr
194 This file gives access to the Floating Point Status and Control Regis-
195 ter as a four byte long file. The operations on the fpcr file are:
196
197 read(2)
198 If a count smaller than four is requested, read returns -1 and
199 sets errno to EINVAL. Otherwise, a four byte value is placed in
200 the data buffer, containing the current value of the fpcr regis-
201 ter.
202
203 write(2)
204 If a count smaller than four is requested, write returns -1 and
205 sets errno to EINVAL. Otherwise, a four byte value is copied
206 from the data buffer, updating the value of the fpcr register.
207
208
209 /signal1
210 /signal2
211 The two signal notification channels of an SPU. These are read-write
212 files that operate on a 32 bit word. Writing to one of these files
213 triggers an interrupt on the SPU. The value writting to the signal
214 files can be read from the SPU through a channel read or from host user
215 space through the file. After the value has been read by the SPU, it
216 is reset to zero. The possible operations on an open signal1 or sig-
217 nal2 file are:
218
219 read(2)
220 If a count smaller than four is requested, read returns -1 and
221 sets errno to EINVAL. Otherwise, a four byte value is placed in
222 the data buffer, containing the current value of the specified
223 signal notification register.
224
225 write(2)
226 If a count smaller than four is requested, write returns -1 and
227 sets errno to EINVAL. Otherwise, a four byte value is copied
228 from the data buffer, updating the value of the specified signal
229 notification register. The signal notification register will
230 either be replaced with the input data or will be updated to the
231 bitwise OR or the old value and the input data, depending on the
232 contents of the signal1_type, or signal2_type respectively,
233 file.
234
235
236 /signal1_type
237 /signal2_type
238 These two files change the behavior of the signal1 and signal2 notifi-
239 cation files. The contain a numerical ASCII string which is read as
240 either "1" or "0". In mode 0 (overwrite), the hardware replaces the
241 contents of the signal channel with the data that is written to it. in
242 mode 1 (logical OR), the hardware accumulates the bits that are subse-
243 quently written to it. The possible operations on an open signal1_type
244 or signal2_type file are:
245
246 read(2)
247 When the count supplied to the read call is shorter than the
248 required length for the digit plus a newline character, subse-
249 quent reads from the same file descriptor will result in com-
250 pleting the string. When a complete string has been read, all
251 subsequent read operations will return zero bytes and a new file
252 descriptor needs to be opened to read the value again.
253
254 write(2)
255 A write operation on the file results in setting the register to
256 the value given in the string. The string is parsed from the
257 beginning to the first non-numeric character or the end of the
258 buffer. Subsequent writes to the same file descriptor overwrite
259 the previous setting.
260
261
262EXAMPLES
263 /etc/fstab entry
264 none /spu spufs gid=spu 0 0
265
266
267AUTHORS
268 Arnd Bergmann <arndb@de.ibm.com>, Mark Nutter <mnutter@us.ibm.com>,
269 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
270
271SEE ALSO
272 capabilities(7), close(2), spu_create(2), spu_run(2), spufs(7)
273
274
275
276Linux 2005-09-28 SPUFS(2)
277
278------------------------------------------------------------------------------
279
280SPU_RUN(2) Linux Programmer's Manual SPU_RUN(2)
281
282
283
284NAME
285 spu_run - execute an spu context
286
287
288SYNOPSIS
289 #include <sys/spu.h>
290
291 int spu_run(int fd, unsigned int *npc, unsigned int *event);
292
293DESCRIPTION
294 The spu_run system call is used on PowerPC machines that implement the
295 Cell Broadband Engine Architecture in order to access Synergistic Pro-
296 cessor Units (SPUs). It uses the fd that was returned from spu_cre-
297 ate(2) to address a specific SPU context. When the context gets sched-
298 uled to a physical SPU, it starts execution at the instruction pointer
299 passed in npc.
300
301 Execution of SPU code happens synchronously, meaning that spu_run does
302 not return while the SPU is still running. If there is a need to exe-
303 cute SPU code in parallel with other code on either the main CPU or
304 other SPUs, you need to create a new thread of execution first, e.g.
305 using the pthread_create(3) call.
306
307 When spu_run returns, the current value of the SPU instruction pointer
308 is written back to npc, so you can call spu_run again without updating
309 the pointers.
310
311 event can be a NULL pointer or point to an extended status code that
312 gets filled when spu_run returns. It can be one of the following con-
313 stants:
314
315 SPE_EVENT_DMA_ALIGNMENT
316 A DMA alignment error
317
318 SPE_EVENT_SPE_DATA_SEGMENT
319 A DMA segmentation error
320
321 SPE_EVENT_SPE_DATA_STORAGE
322 A DMA storage error
323
324 If NULL is passed as the event argument, these errors will result in a
325 signal delivered to the calling process.
326
327RETURN VALUE
328 spu_run returns the value of the spu_status register or -1 to indicate
329 an error and set errno to one of the error codes listed below. The
330 spu_status register value contains a bit mask of status codes and
331 optionally a 14 bit code returned from the stop-and-signal instruction
332 on the SPU. The bit masks for the status codes are:
333
334 0x02 SPU was stopped by stop-and-signal.
335
336 0x04 SPU was stopped by halt.
337
338 0x08 SPU is waiting for a channel.
339
340 0x10 SPU is in single-step mode.
341
342 0x20 SPU has tried to execute an invalid instruction.
343
344 0x40 SPU has tried to access an invalid channel.
345
346 0x3fff0000
347 The bits masked with this value contain the code returned from
348 stop-and-signal.
349
350 There are always one or more of the lower eight bits set or an error
351 code is returned from spu_run.
352
353ERRORS
354 EAGAIN or EWOULDBLOCK
355 fd is in non-blocking mode and spu_run would block.
356
357 EBADF fd is not a valid file descriptor.
358
359 EFAULT npc is not a valid pointer or status is neither NULL nor a valid
360 pointer.
361
362 EINTR A signal occured while spu_run was in progress. The npc value
363 has been updated to the new program counter value if necessary.
364
365 EINVAL fd is not a file descriptor returned from spu_create(2).
366
367 ENOMEM Insufficient memory was available to handle a page fault result-
368 ing from an MFC direct memory access.
369
370 ENOSYS the functionality is not provided by the current system, because
371 either the hardware does not provide SPUs or the spufs module is
372 not loaded.
373
374
375NOTES
376 spu_run is meant to be used from libraries that implement a more
377 abstract interface to SPUs, not to be used from regular applications.
378 See http://www.bsc.es/projects/deepcomputing/linuxoncell/ for the rec-
379 ommended libraries.
380
381
382CONFORMING TO
383 This call is Linux specific and only implemented by the ppc64 architec-
384 ture. Programs using this system call are not portable.
385
386
387BUGS
388 The code does not yet fully implement all features lined out here.
389
390
391AUTHOR
392 Arnd Bergmann <arndb@de.ibm.com>
393
394SEE ALSO
395 capabilities(7), close(2), spu_create(2), spufs(7)
396
397
398
399Linux 2005-09-28 SPU_RUN(2)
400
401------------------------------------------------------------------------------
402
403SPU_CREATE(2) Linux Programmer's Manual SPU_CREATE(2)
404
405
406
407NAME
408 spu_create - create a new spu context
409
410
411SYNOPSIS
412 #include <sys/types.h>
413 #include <sys/spu.h>
414
415 int spu_create(const char *pathname, int flags, mode_t mode);
416
417DESCRIPTION
418 The spu_create system call is used on PowerPC machines that implement
419 the Cell Broadband Engine Architecture in order to access Synergistic
420 Processor Units (SPUs). It creates a new logical context for an SPU in
421 pathname and returns a handle to associated with it. pathname must
422 point to a non-existing directory in the mount point of the SPU file
423 system (spufs). When spu_create is successful, a directory gets cre-
424 ated on pathname and it is populated with files.
425
426 The returned file handle can only be passed to spu_run(2) or closed,
427 other operations are not defined on it. When it is closed, all associ-
428 ated directory entries in spufs are removed. When the last file handle
429 pointing either inside of the context directory or to this file
430 descriptor is closed, the logical SPU context is destroyed.
431
432 The parameter flags can be zero or any bitwise or'd combination of the
433 following constants:
434
435 SPU_RAWIO
436 Allow mapping of some of the hardware registers of the SPU into
437 user space. This flag requires the CAP_SYS_RAWIO capability, see
438 capabilities(7).
439
440 The mode parameter specifies the permissions used for creating the new
441 directory in spufs. mode is modified with the user's umask(2) value
442 and then used for both the directory and the files contained in it. The
443 file permissions mask out some more bits of mode because they typically
444 support only read or write access. See stat(2) for a full list of the
445 possible mode values.
446
447
448RETURN VALUE
449 spu_create returns a new file descriptor. It may return -1 to indicate
450 an error condition and set errno to one of the error codes listed
451 below.
452
453
454ERRORS
455 EACCESS
456 The current user does not have write access on the spufs mount
457 point.
458
459 EEXIST An SPU context already exists at the given path name.
460
461 EFAULT pathname is not a valid string pointer in the current address
462 space.
463
464 EINVAL pathname is not a directory in the spufs mount point.
465
466 ELOOP Too many symlinks were found while resolving pathname.
467
468 EMFILE The process has reached its maximum open file limit.
469
470 ENAMETOOLONG
471 pathname was too long.
472
473 ENFILE The system has reached the global open file limit.
474
475 ENOENT Part of pathname could not be resolved.
476
477 ENOMEM The kernel could not allocate all resources required.
478
479 ENOSPC There are not enough SPU resources available to create a new
480 context or the user specific limit for the number of SPU con-
481 texts has been reached.
482
483 ENOSYS the functionality is not provided by the current system, because
484 either the hardware does not provide SPUs or the spufs module is
485 not loaded.
486
487 ENOTDIR
488 A part of pathname is not a directory.
489
490
491
492NOTES
493 spu_create is meant to be used from libraries that implement a more
494 abstract interface to SPUs, not to be used from regular applications.
495 See http://www.bsc.es/projects/deepcomputing/linuxoncell/ for the rec-
496 ommended libraries.
497
498
499FILES
500 pathname must point to a location beneath the mount point of spufs. By
501 convention, it gets mounted in /spu.
502
503
504CONFORMING TO
505 This call is Linux specific and only implemented by the ppc64 architec-
506 ture. Programs using this system call are not portable.
507
508
509BUGS
510 The code does not yet fully implement all features lined out here.
511
512
513AUTHOR
514 Arnd Bergmann <arndb@de.ibm.com>
515
516SEE ALSO
517 capabilities(7), close(2), spu_run(2), spufs(7)
518
519
520
521Linux 2005-09-28 SPU_CREATE(2)
diff --git a/Documentation/keys-request-key.txt b/Documentation/keys-request-key.txt
index 5f2b9c5edbb5..22488d791168 100644
--- a/Documentation/keys-request-key.txt
+++ b/Documentation/keys-request-key.txt
@@ -56,10 +56,12 @@ A request proceeds in the following manner:
56 (4) request_key() then forks and executes /sbin/request-key with a new session 56 (4) request_key() then forks and executes /sbin/request-key with a new session
57 keyring that contains a link to auth key V. 57 keyring that contains a link to auth key V.
58 58
59 (5) /sbin/request-key execs an appropriate program to perform the actual 59 (5) /sbin/request-key assumes the authority associated with key U.
60
61 (6) /sbin/request-key execs an appropriate program to perform the actual
60 instantiation. 62 instantiation.
61 63
62 (6) The program may want to access another key from A's context (say a 64 (7) The program may want to access another key from A's context (say a
63 Kerberos TGT key). It just requests the appropriate key, and the keyring 65 Kerberos TGT key). It just requests the appropriate key, and the keyring
64 search notes that the session keyring has auth key V in its bottom level. 66 search notes that the session keyring has auth key V in its bottom level.
65 67
@@ -67,19 +69,19 @@ A request proceeds in the following manner:
67 UID, GID, groups and security info of process A as if it was process A, 69 UID, GID, groups and security info of process A as if it was process A,
68 and come up with key W. 70 and come up with key W.
69 71
70 (7) The program then does what it must to get the data with which to 72 (8) The program then does what it must to get the data with which to
71 instantiate key U, using key W as a reference (perhaps it contacts a 73 instantiate key U, using key W as a reference (perhaps it contacts a
72 Kerberos server using the TGT) and then instantiates key U. 74 Kerberos server using the TGT) and then instantiates key U.
73 75
74 (8) Upon instantiating key U, auth key V is automatically revoked so that it 76 (9) Upon instantiating key U, auth key V is automatically revoked so that it
75 may not be used again. 77 may not be used again.
76 78
77 (9) The program then exits 0 and request_key() deletes key V and returns key 79(10) The program then exits 0 and request_key() deletes key V and returns key
78 U to the caller. 80 U to the caller.
79 81
80This also extends further. If key W (step 5 above) didn't exist, key W would be 82This also extends further. If key W (step 7 above) didn't exist, key W would be
81created uninstantiated, another auth key (X) would be created [as per step 3] 83created uninstantiated, another auth key (X) would be created (as per step 3)
82and another copy of /sbin/request-key spawned [as per step 4]; but the context 84and another copy of /sbin/request-key spawned (as per step 4); but the context
83specified by auth key X will still be process A, as it was in auth key V. 85specified by auth key X will still be process A, as it was in auth key V.
84 86
85This is because process A's keyrings can't simply be attached to 87This is because process A's keyrings can't simply be attached to
@@ -138,8 +140,8 @@ until one succeeds:
138 140
139 (3) The process's session keyring is searched. 141 (3) The process's session keyring is searched.
140 142
141 (4) If the process has a request_key() authorisation key in its session 143 (4) If the process has assumed the authority associated with a request_key()
142 keyring then: 144 authorisation key then:
143 145
144 (a) If extant, the calling process's thread keyring is searched. 146 (a) If extant, the calling process's thread keyring is searched.
145 147
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index 6304db59bfe4..aaa01b0e3ee9 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -308,6 +308,8 @@ process making the call:
308 KEY_SPEC_USER_KEYRING -4 UID-specific keyring 308 KEY_SPEC_USER_KEYRING -4 UID-specific keyring
309 KEY_SPEC_USER_SESSION_KEYRING -5 UID-session keyring 309 KEY_SPEC_USER_SESSION_KEYRING -5 UID-session keyring
310 KEY_SPEC_GROUP_KEYRING -6 GID-specific keyring 310 KEY_SPEC_GROUP_KEYRING -6 GID-specific keyring
311 KEY_SPEC_REQKEY_AUTH_KEY -7 assumed request_key()
312 authorisation key
311 313
312 314
313The main syscalls are: 315The main syscalls are:
@@ -498,7 +500,11 @@ The keyctl syscall functions are:
498 keyring is full, error ENFILE will result. 500 keyring is full, error ENFILE will result.
499 501
500 The link procedure checks the nesting of the keyrings, returning ELOOP if 502 The link procedure checks the nesting of the keyrings, returning ELOOP if
501 it appears to deep or EDEADLK if the link would introduce a cycle. 503 it appears too deep or EDEADLK if the link would introduce a cycle.
504
505 Any links within the keyring to keys that match the new key in terms of
506 type and description will be discarded from the keyring as the new one is
507 added.
502 508
503 509
504 (*) Unlink a key or keyring from another keyring: 510 (*) Unlink a key or keyring from another keyring:
@@ -628,6 +634,41 @@ The keyctl syscall functions are:
628 there is one, otherwise the user default session keyring. 634 there is one, otherwise the user default session keyring.
629 635
630 636
637 (*) Set the timeout on a key.
638
639 long keyctl(KEYCTL_SET_TIMEOUT, key_serial_t key, unsigned timeout);
640
641 This sets or clears the timeout on a key. The timeout can be 0 to clear
642 the timeout or a number of seconds to set the expiry time that far into
643 the future.
644
645 The process must have attribute modification access on a key to set its
646 timeout. Timeouts may not be set with this function on negative, revoked
647 or expired keys.
648
649
650 (*) Assume the authority granted to instantiate a key
651
652 long keyctl(KEYCTL_ASSUME_AUTHORITY, key_serial_t key);
653
654 This assumes or divests the authority required to instantiate the
655 specified key. Authority can only be assumed if the thread has the
656 authorisation key associated with the specified key in its keyrings
657 somewhere.
658
659 Once authority is assumed, searches for keys will also search the
660 requester's keyrings using the requester's security label, UID, GID and
661 groups.
662
663 If the requested authority is unavailable, error EPERM will be returned,
664 likewise if the authority has been revoked because the target key is
665 already instantiated.
666
667 If the specified key is 0, then any assumed authority will be divested.
668
669 The assumed authorititive key is inherited across fork and exec.
670
671
631=============== 672===============
632KERNEL SERVICES 673KERNEL SERVICES
633=============== 674===============
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 0541fe1de704..0ea5a0c6e827 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -411,7 +411,8 @@ int init_module(void)
411 printk("Couldn't find %s to plant kprobe\n", "do_fork"); 411 printk("Couldn't find %s to plant kprobe\n", "do_fork");
412 return -1; 412 return -1;
413 } 413 }
414 if ((ret = register_kprobe(&kp) < 0)) { 414 ret = register_kprobe(&kp);
415 if (ret < 0) {
415 printk("register_kprobe failed, returned %d\n", ret); 416 printk("register_kprobe failed, returned %d\n", ret);
416 return -1; 417 return -1;
417 } 418 }
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index b0fe41da007b..8d8b4e5ea184 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -945,7 +945,6 @@ bond0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4
945 collisions:0 txqueuelen:0 945 collisions:0 txqueuelen:0
946 946
947eth0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 947eth0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4
948 inet addr:XXX.XXX.XXX.YYY Bcast:XXX.XXX.XXX.255 Mask:255.255.252.0
949 UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1 948 UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1
950 RX packets:3573025 errors:0 dropped:0 overruns:0 frame:0 949 RX packets:3573025 errors:0 dropped:0 overruns:0 frame:0
951 TX packets:1643167 errors:1 dropped:0 overruns:1 carrier:0 950 TX packets:1643167 errors:1 dropped:0 overruns:1 carrier:0
@@ -953,7 +952,6 @@ eth0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4
953 Interrupt:10 Base address:0x1080 952 Interrupt:10 Base address:0x1080
954 953
955eth1 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 954eth1 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4
956 inet addr:XXX.XXX.XXX.YYY Bcast:XXX.XXX.XXX.255 Mask:255.255.252.0
957 UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1 955 UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1
958 RX packets:3651769 errors:0 dropped:0 overruns:0 frame:0 956 RX packets:3651769 errors:0 dropped:0 overruns:0 frame:0
959 TX packets:1643480 errors:0 dropped:0 overruns:0 carrier:0 957 TX packets:1643480 errors:0 dropped:0 overruns:0 carrier:0
diff --git a/Documentation/powerpc/00-INDEX b/Documentation/powerpc/00-INDEX
index e7bea0a407b4..d6d65b9bcfe3 100644
--- a/Documentation/powerpc/00-INDEX
+++ b/Documentation/powerpc/00-INDEX
@@ -8,12 +8,18 @@ please mail me.
8cpu_features.txt 8cpu_features.txt
9 - info on how we support a variety of CPUs with minimal compile-time 9 - info on how we support a variety of CPUs with minimal compile-time
10 options. 10 options.
11eeh-pci-error-recovery.txt
12 - info on PCI Bus EEH Error Recovery
13hvcs.txt
14 - IBM "Hypervisor Virtual Console Server" Installation Guide
15mpc52xx.txt
16 - Linux 2.6.x on MPC52xx family
11ppc_htab.txt 17ppc_htab.txt
12 - info about the Linux/PPC /proc/ppc_htab entry 18 - info about the Linux/PPC /proc/ppc_htab entry
13smp.txt
14 - use and state info about Linux/PPC on MP machines
15SBC8260_memory_mapping.txt 19SBC8260_memory_mapping.txt
16 - EST SBC8260 board info 20 - EST SBC8260 board info
21smp.txt
22 - use and state info about Linux/PPC on MP machines
17sound.txt 23sound.txt
18 - info on sound support under Linux/PPC 24 - info on sound support under Linux/PPC
19zImage_layout.txt 25zImage_layout.txt
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
index 2f1aae32a5d9..6910c0136f8d 100644
--- a/Documentation/sysctl/vm.txt
+++ b/Documentation/sysctl/vm.txt
@@ -26,12 +26,13 @@ Currently, these files are in /proc/sys/vm:
26- min_free_kbytes 26- min_free_kbytes
27- laptop_mode 27- laptop_mode
28- block_dump 28- block_dump
29- drop-caches
29 30
30============================================================== 31==============================================================
31 32
32dirty_ratio, dirty_background_ratio, dirty_expire_centisecs, 33dirty_ratio, dirty_background_ratio, dirty_expire_centisecs,
33dirty_writeback_centisecs, vfs_cache_pressure, laptop_mode, 34dirty_writeback_centisecs, vfs_cache_pressure, laptop_mode,
34block_dump, swap_token_timeout: 35block_dump, swap_token_timeout, drop-caches:
35 36
36See Documentation/filesystems/proc.txt 37See Documentation/filesystems/proc.txt
37 38
@@ -102,3 +103,20 @@ This is used to force the Linux VM to keep a minimum number
102of kilobytes free. The VM uses this number to compute a pages_min 103of kilobytes free. The VM uses this number to compute a pages_min
103value for each lowmem zone in the system. Each lowmem zone gets 104value for each lowmem zone in the system. Each lowmem zone gets
104a number of reserved free pages based proportionally on its size. 105a number of reserved free pages based proportionally on its size.
106
107==============================================================
108
109percpu_pagelist_fraction
110
111This is the fraction of pages at most (high mark pcp->high) in each zone that
112are allocated for each per cpu page list. The min value for this is 8. It
113means that we don't allow more than 1/8th of pages in each zone to be
114allocated in any single per_cpu_pagelist. This entry only changes the value
115of hot per cpu pagelists. User can specify a number like 100 to allocate
1161/100th of each zone to each per cpu page list.
117
118The batch value of each per cpu pagelist is also updated as a result. It is
119set to pcp->high/4. The upper limit of batch is (PAGE_SHIFT * 8)
120
121The initial value is zero. Kernel does not use this value at boot time to set
122the high water marks for each per cpu page list.
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index 330246ac80f8..74fb085e178b 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -141,3 +141,4 @@
141140 -> Osprey 440 [0070:ff07] 141140 -> Osprey 440 [0070:ff07]
142141 -> Asound Skyeye PCTV 142141 -> Asound Skyeye PCTV
143142 -> Sabrent TV-FM (bttv version) 143142 -> Sabrent TV-FM (bttv version)
144143 -> Hauppauge ImpactVCB (bt878) [0070:13eb]
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index a1017d1a85d4..34b6e59f2968 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -16,7 +16,7 @@
16 15 -> DViCO FusionHDTV DVB-T1 [18ac:db00] 16 15 -> DViCO FusionHDTV DVB-T1 [18ac:db00]
17 16 -> KWorld LTV883RF 17 16 -> KWorld LTV883RF
18 17 -> DViCO FusionHDTV 3 Gold-Q [18ac:d810] 18 17 -> DViCO FusionHDTV 3 Gold-Q [18ac:d810]
19 18 -> Hauppauge Nova-T DVB-T [0070:9002] 19 18 -> Hauppauge Nova-T DVB-T [0070:9002,0070:9001]
20 19 -> Conexant DVB-T reference design [14f1:0187] 20 19 -> Conexant DVB-T reference design [14f1:0187]
21 20 -> Provideo PV259 [1540:2580] 21 20 -> Provideo PV259 [1540:2580]
22 21 -> DViCO FusionHDTV DVB-T Plus [18ac:db10] 22 21 -> DViCO FusionHDTV DVB-T Plus [18ac:db10]
@@ -35,3 +35,11 @@
35 34 -> ATI HDTV Wonder [1002:a101] 35 34 -> ATI HDTV Wonder [1002:a101]
36 35 -> WinFast DTV1000-T [107d:665f] 36 35 -> WinFast DTV1000-T [107d:665f]
37 36 -> AVerTV 303 (M126) [1461:000a] 37 36 -> AVerTV 303 (M126) [1461:000a]
38 37 -> Hauppauge Nova-S-Plus DVB-S [0070:9201,0070:9202]
39 38 -> Hauppauge Nova-SE2 DVB-S [0070:9200]
40 39 -> KWorld DVB-S 100 [17de:08b2]
41 40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid [0070:9400,0070:9402]
42 41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802]
43 42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025]
44 43 -> KWorld/VStream XPert DVB-T with cx22702 [17de:08a1]
45 44 -> DViCO FusionHDTV DVB-T Dual Digital [18ac:db50]
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index efb708ec116a..cb3a59bbeb17 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -56,7 +56,7 @@
56 55 -> LifeView FlyDVB-T DUO [5168:0502,5168:0306] 56 55 -> LifeView FlyDVB-T DUO [5168:0502,5168:0306]
57 56 -> Avermedia AVerTV 307 [1461:a70a] 57 56 -> Avermedia AVerTV 307 [1461:a70a]
58 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] 58 57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
59 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0370,1421:1370] 59 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370]
60 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134 60 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134
61 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus [4e42:0502] 61 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus [4e42:0502]
62 61 -> Philips TOUGH DVB-T reference design [1131:2004] 62 61 -> Philips TOUGH DVB-T reference design [1131:2004]
@@ -81,4 +81,5 @@
81 80 -> ASUS Digimatrix TV [1043:0210] 81 80 -> ASUS Digimatrix TV [1043:0210]
82 81 -> Philips Tiger reference design [1131:2018] 82 81 -> Philips Tiger reference design [1131:2018]
83 82 -> MSI TV@Anywhere plus [1462:6231] 83 82 -> MSI TV@Anywhere plus [1462:6231]
84 84 83 -> Terratec Cinergy 250 PCI TV [153b:1160]
85 84 -> LifeView FlyDVB Trio [5168:0319]
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index 9d6544ea9f41..0bf3d5bf9ef8 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -40,7 +40,7 @@ tuner=38 - Philips PAL/SECAM multi (FM1216ME MK3)
40tuner=39 - LG NTSC (newer TAPC series) 40tuner=39 - LG NTSC (newer TAPC series)
41tuner=40 - HITACHI V7-J180AT 41tuner=40 - HITACHI V7-J180AT
42tuner=41 - Philips PAL_MK (FI1216 MK) 42tuner=41 - Philips PAL_MK (FI1216 MK)
43tuner=42 - Philips 1236D ATSC/NTSC daul in 43tuner=42 - Philips 1236D ATSC/NTSC dual in
44tuner=43 - Philips NTSC MK3 (FM1236MK3 or FM1236/F) 44tuner=43 - Philips NTSC MK3 (FM1236MK3 or FM1236/F)
45tuner=44 - Philips 4 in 1 (ATI TV Wonder Pro/Conexant) 45tuner=44 - Philips 4 in 1 (ATI TV Wonder Pro/Conexant)
46tuner=45 - Microtune 4049 FM5 46tuner=45 - Microtune 4049 FM5
@@ -50,7 +50,7 @@ tuner=48 - Tenna TNF 8831 BGFF)
50tuner=49 - Microtune 4042 FI5 ATSC/NTSC dual in 50tuner=49 - Microtune 4042 FI5 ATSC/NTSC dual in
51tuner=50 - TCL 2002N 51tuner=50 - TCL 2002N
52tuner=51 - Philips PAL/SECAM_D (FM 1256 I-H3) 52tuner=51 - Philips PAL/SECAM_D (FM 1256 I-H3)
53tuner=52 - Thomson DDT 7610 (ATSC/NTSC) 53tuner=52 - Thomson DTT 7610 (ATSC/NTSC)
54tuner=53 - Philips FQ1286 54tuner=53 - Philips FQ1286
55tuner=54 - tda8290+75 55tuner=54 - tda8290+75
56tuner=55 - TCL 2002MB 56tuner=55 - TCL 2002MB
@@ -58,7 +58,7 @@ tuner=56 - Philips PAL/SECAM multi (FQ1216AME MK4)
58tuner=57 - Philips FQ1236A MK4 58tuner=57 - Philips FQ1236A MK4
59tuner=58 - Ymec TVision TVF-8531MF/8831MF/8731MF 59tuner=58 - Ymec TVision TVF-8531MF/8831MF/8731MF
60tuner=59 - Ymec TVision TVF-5533MF 60tuner=59 - Ymec TVision TVF-5533MF
61tuner=60 - Thomson DDT 7611 (ATSC/NTSC) 61tuner=60 - Thomson DTT 761X (ATSC/NTSC)
62tuner=61 - Tena TNF9533-D/IF/TNF9533-B/DF 62tuner=61 - Tena TNF9533-D/IF/TNF9533-B/DF
63tuner=62 - Philips TEA5767HN FM Radio 63tuner=62 - Philips TEA5767HN FM Radio
64tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner 64tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner
diff --git a/MAINTAINERS b/MAINTAINERS
index 7e780906d34c..270e28c0506a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -927,7 +927,6 @@ S: Maintained
927FARSYNC SYNCHRONOUS DRIVER 927FARSYNC SYNCHRONOUS DRIVER
928P: Kevin Curtis 928P: Kevin Curtis
929M: kevin.curtis@farsite.co.uk 929M: kevin.curtis@farsite.co.uk
930M: kevin.curtis@farsite.co.uk
931W: http://www.farsite.co.uk/ 930W: http://www.farsite.co.uk/
932S: Supported 931S: Supported
933 932
@@ -1698,7 +1697,6 @@ S: Maintained
1698 1697
1699MARVELL MV64340 ETHERNET DRIVER 1698MARVELL MV64340 ETHERNET DRIVER
1700P: Manish Lachwani 1699P: Manish Lachwani
1701M: Manish_Lachwani@pmc-sierra.com
1702L: linux-mips@linux-mips.org 1700L: linux-mips@linux-mips.org
1703L: netdev@vger.kernel.org 1701L: netdev@vger.kernel.org
1704S: Supported 1702S: Supported
diff --git a/README b/README
index 61c4f7429233..cd5e2eb6213b 100644
--- a/README
+++ b/README
@@ -183,11 +183,8 @@ CONFIGURING the kernel:
183 183
184COMPILING the kernel: 184COMPILING the kernel:
185 185
186 - Make sure you have gcc 2.95.3 available. 186 - Make sure you have at least gcc 3.2 available.
187 gcc 2.91.66 (egcs-1.1.2), and gcc 2.7.2.3 are known to miscompile 187 For more information, refer to Documentation/Changes.
188 some parts of the kernel, and are *no longer supported*.
189 Also remember to upgrade your binutils package (for as/ld/nm and company)
190 if necessary. For more information, refer to Documentation/Changes.
191 188
192 Please note that you can still run a.out user programs with this kernel. 189 Please note that you can still run a.out user programs with this kernel.
193 190
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 153337ff1d7b..eedf41bf7057 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -18,9 +18,6 @@ config MMU
18 bool 18 bool
19 default y 19 default y
20 20
21config UID16
22 bool
23
24config RWSEM_GENERIC_SPINLOCK 21config RWSEM_GENERIC_SPINLOCK
25 bool 22 bool
26 23
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index a8682612abc0..abb739b88ed1 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -43,6 +43,11 @@
43#include "proto.h" 43#include "proto.h"
44#include "pci_impl.h" 44#include "pci_impl.h"
45 45
46/*
47 * Power off function, if any
48 */
49void (*pm_power_off)(void) = machine_power_off;
50
46void 51void
47cpu_idle(void) 52cpu_idle(void)
48{ 53{
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index bbd37536d14e..9969d212e94d 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -265,30 +265,16 @@ do_sys_ptrace(long request, long pid, long addr, long data,
265 lock_kernel(); 265 lock_kernel();
266 DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n", 266 DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n",
267 request, pid, addr, data)); 267 request, pid, addr, data));
268 ret = -EPERM;
269 if (request == PTRACE_TRACEME) { 268 if (request == PTRACE_TRACEME) {
270 /* are we already being traced? */ 269 ret = ptrace_traceme();
271 if (current->ptrace & PT_PTRACED)
272 goto out_notsk;
273 ret = security_ptrace(current->parent, current);
274 if (ret)
275 goto out_notsk;
276 /* set the ptrace bit in the process ptrace flags. */
277 current->ptrace |= PT_PTRACED;
278 ret = 0;
279 goto out_notsk; 270 goto out_notsk;
280 } 271 }
281 if (pid == 1) /* you may not mess with init */
282 goto out_notsk;
283 272
284 ret = -ESRCH; 273 child = ptrace_get_task_struct(pid);
285 read_lock(&tasklist_lock); 274 if (IS_ERR(child)) {
286 child = find_task_by_pid(pid); 275 ret = PTR_ERR(child);
287 if (child)
288 get_task_struct(child);
289 read_unlock(&tasklist_lock);
290 if (!child)
291 goto out_notsk; 276 goto out_notsk;
277 }
292 278
293 if (request == PTRACE_ATTACH) { 279 if (request == PTRACE_ATTACH) {
294 ret = ptrace_attach(child); 280 ret = ptrace_attach(child);
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 16a5d522b2f2..7a74e3e5f916 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -46,10 +46,6 @@ config MCA
46 <file:Documentation/mca.txt> (and especially the web page given 46 <file:Documentation/mca.txt> (and especially the web page given
47 there) before attempting to build an MCA bus kernel. 47 there) before attempting to build an MCA bus kernel.
48 48
49config UID16
50 bool
51 default y
52
53config RWSEM_GENERIC_SPINLOCK 49config RWSEM_GENERIC_SPINLOCK
54 bool 50 bool
55 default y 51 default y
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index b6de43e73699..a2dfe0b0f1ec 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/string.h> 15#include <linux/string.h>
16#include <linux/slab.h>
16#include <linux/platform_device.h> 17#include <linux/platform_device.h>
17#include <asm/io.h> 18#include <asm/io.h>
18#include <asm/hardware/scoop.h> 19#include <asm/hardware/scoop.h>
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 04d3082a7b94..0abbce8c70bc 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -23,20 +23,15 @@
23#error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32 23#error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32
24#endif 24#endif
25/* 25/*
26 * GCC 2.95.1, 2.95.2: ignores register clobber list in asm().
27 * GCC 3.0, 3.1: general bad code generation. 26 * GCC 3.0, 3.1: general bad code generation.
28 * GCC 3.2.0: incorrect function argument offset calculation. 27 * GCC 3.2.0: incorrect function argument offset calculation.
29 * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c 28 * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c
30 * (http://gcc.gnu.org/PR8896) and incorrect structure 29 * (http://gcc.gnu.org/PR8896) and incorrect structure
31 * initialisation in fs/jffs2/erase.c 30 * initialisation in fs/jffs2/erase.c
32 */ 31 */
33#if __GNUC__ < 2 || \ 32#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
34 (__GNUC__ == 2 && __GNUC_MINOR__ < 95) || \
35 (__GNUC__ == 2 && __GNUC_MINOR__ == 95 && __GNUC_PATCHLEVEL__ != 0 && \
36 __GNUC_PATCHLEVEL__ < 3) || \
37 (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
38#error Your compiler is too buggy; it is known to miscompile kernels. 33#error Your compiler is too buggy; it is known to miscompile kernels.
39#error Known good compilers: 2.95.3, 2.95.4, 2.96, 3.3 34#error Known good compilers: 3.3
40#endif 35#endif
41 36
42/* Use marker if you need to separate the values later */ 37/* Use marker if you need to separate the values later */
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 869c466e6258..b5645c4462cf 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -684,8 +684,12 @@ int setup_irq(unsigned int irq, struct irqaction *new)
684 spin_lock_irqsave(&irq_controller_lock, flags); 684 spin_lock_irqsave(&irq_controller_lock, flags);
685 p = &desc->action; 685 p = &desc->action;
686 if ((old = *p) != NULL) { 686 if ((old = *p) != NULL) {
687 /* Can't share interrupts unless both agree to */ 687 /*
688 if (!(old->flags & new->flags & SA_SHIRQ)) { 688 * Can't share interrupts unless both agree to and are
689 * the same type.
690 */
691 if (!(old->flags & new->flags & SA_SHIRQ) ||
692 (~old->flags & new->flags) & SA_TRIGGER_MASK) {
689 spin_unlock_irqrestore(&irq_controller_lock, flags); 693 spin_unlock_irqrestore(&irq_controller_lock, flags);
690 return -EBUSY; 694 return -EBUSY;
691 } 695 }
@@ -705,6 +709,12 @@ int setup_irq(unsigned int irq, struct irqaction *new)
705 desc->running = 0; 709 desc->running = 0;
706 desc->pending = 0; 710 desc->pending = 0;
707 desc->disable_depth = 1; 711 desc->disable_depth = 1;
712
713 if (new->flags & SA_TRIGGER_MASK) {
714 unsigned int type = new->flags & SA_TRIGGER_MASK;
715 desc->chip->set_type(irq, type);
716 }
717
708 if (!desc->noautoenable) { 718 if (!desc->noautoenable) {
709 desc->disable_depth = 0; 719 desc->disable_depth = 0;
710 desc->chip->unmask(irq); 720 desc->chip->unmask(irq);
diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c
index 775f85fc8513..9e563de465b5 100644
--- a/arch/arm/mach-footbridge/netwinder-hw.c
+++ b/arch/arm/mach-footbridge/netwinder-hw.c
@@ -601,6 +601,7 @@ EXPORT_SYMBOL(gpio_lock);
601EXPORT_SYMBOL(gpio_modify_op); 601EXPORT_SYMBOL(gpio_modify_op);
602EXPORT_SYMBOL(gpio_modify_io); 602EXPORT_SYMBOL(gpio_modify_io);
603EXPORT_SYMBOL(cpld_modify); 603EXPORT_SYMBOL(cpld_modify);
604EXPORT_SYMBOL(gpio_read);
604 605
605/* 606/*
606 * Initialise any other hardware after we've got the PCI bus 607 * Initialise any other hardware after we've got the PCI bus
diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c
index 9f46aaef8968..3c22c16b38bf 100644
--- a/arch/arm/mach-integrator/time.c
+++ b/arch/arm/mach-integrator/time.c
@@ -96,7 +96,8 @@ static struct rtc_ops rtc_ops = {
96 .set_alarm = rtc_set_alarm, 96 .set_alarm = rtc_set_alarm,
97}; 97};
98 98
99static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) 99static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id,
100 struct pt_regs *regs)
100{ 101{
101 writel(0, rtc_base + RTC_EOI); 102 writel(0, rtc_base + RTC_EOI);
102 return IRQ_HANDLED; 103 return IRQ_HANDLED;
@@ -124,7 +125,7 @@ static int rtc_probe(struct amba_device *dev, void *id)
124 125
125 xtime.tv_sec = __raw_readl(rtc_base + RTC_DR); 126 xtime.tv_sec = __raw_readl(rtc_base + RTC_DR);
126 127
127 ret = request_irq(dev->irq[0], rtc_interrupt, SA_INTERRUPT, 128 ret = request_irq(dev->irq[0], arm_rtc_interrupt, SA_INTERRUPT,
128 "rtc-pl030", dev); 129 "rtc-pl030", dev);
129 if (ret) 130 if (ret)
130 goto map_out; 131 goto map_out;
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index fcfb81d13cfe..7a68f098a025 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -252,9 +252,8 @@ static void __init omap_serial_set_port_wakeup(int gpio_nr)
252 return; 252 return;
253 } 253 }
254 omap_set_gpio_direction(gpio_nr, 1); 254 omap_set_gpio_direction(gpio_nr, 1);
255 set_irq_type(OMAP_GPIO_IRQ(gpio_nr), IRQT_RISING);
256 ret = request_irq(OMAP_GPIO_IRQ(gpio_nr), &omap_serial_wake_interrupt, 255 ret = request_irq(OMAP_GPIO_IRQ(gpio_nr), &omap_serial_wake_interrupt,
257 0, "serial wakeup", NULL); 256 SA_TRIGGER_RISING, "serial wakeup", NULL);
258 if (ret) { 257 if (ret) {
259 omap_free_gpio(gpio_nr); 258 omap_free_gpio(gpio_nr);
260 printk(KERN_ERR "No interrupt for UART wake GPIO: %i\n", 259 printk(KERN_ERR "No interrupt for UART wake GPIO: %i\n",
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 100fb31b5156..5a7b873f29b3 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -213,15 +213,14 @@ static int corgi_mci_init(struct device *dev, irqreturn_t (*corgi_detect_int)(in
213 213
214 corgi_mci_platform_data.detect_delay = msecs_to_jiffies(250); 214 corgi_mci_platform_data.detect_delay = msecs_to_jiffies(250);
215 215
216 err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int, SA_INTERRUPT, 216 err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int,
217 "MMC card detect", data); 217 SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
218 "MMC card detect", data);
218 if (err) { 219 if (err) {
219 printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 220 printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
220 return -1; 221 return -1;
221 } 222 }
222 223
223 set_irq_type(CORGI_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
224
225 return 0; 224 return 0;
226} 225}
227 226
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index eef3de26ad37..663c95005985 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -146,15 +146,14 @@ static int poodle_mci_init(struct device *dev, irqreturn_t (*poodle_detect_int)(
146 146
147 poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250); 147 poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250);
148 148
149 err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int, SA_INTERRUPT, 149 err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int,
150 "MMC card detect", data); 150 SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
151 "MMC card detect", data);
151 if (err) { 152 if (err) {
152 printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 153 printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
153 return -1; 154 return -1;
154 } 155 }
155 156
156 set_irq_type(POODLE_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
157
158 return 0; 157 return 0;
159} 158}
160 159
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index f2007db0cda5..a9eacc06555f 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -296,15 +296,14 @@ static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(in
296 296
297 spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250); 297 spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250);
298 298
299 err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int, SA_INTERRUPT, 299 err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int,
300 "MMC card detect", data); 300 SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
301 "MMC card detect", data);
301 if (err) { 302 if (err) {
302 printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 303 printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
303 return -1; 304 return -1;
304 } 305 }
305 306
306 set_irq_type(SPITZ_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
307
308 return 0; 307 return 0;
309} 308}
310 309
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c
index c9d7c596b200..caf6b8bb6c95 100644
--- a/arch/arm/mach-realview/localtimer.c
+++ b/arch/arm/mach-realview/localtimer.c
@@ -13,6 +13,7 @@
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/smp.h> 15#include <linux/smp.h>
16#include <linux/jiffies.h>
16 17
17#include <asm/mach/time.h> 18#include <asm/mach/time.h>
18#include <asm/hardware/arm_twd.h> 19#include <asm/hardware/arm_twd.h>
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
index 5098b50158a3..495f8c6ffcb6 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.c
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -84,13 +84,13 @@ static void usb_simtec_enableoc(struct s3c2410_hcd_info *info, int on)
84 int ret; 84 int ret;
85 85
86 if (on) { 86 if (on) {
87 ret = request_irq(IRQ_USBOC, usb_simtec_ocirq, SA_INTERRUPT, 87 ret = request_irq(IRQ_USBOC, usb_simtec_ocirq,
88 SA_INTERRUPT | SA_TRIGGER_RISING |
89 SA_TRIGGER_FALLING,
88 "USB Over-current", info); 90 "USB Over-current", info);
89 if (ret != 0) { 91 if (ret != 0) {
90 printk(KERN_ERR "failed to request usb oc irq\n"); 92 printk(KERN_ERR "failed to request usb oc irq\n");
91 } 93 }
92
93 set_irq_type(IRQ_USBOC, IRQT_BOTHEDGE);
94 } else { 94 } else {
95 free_irq(IRQ_USBOC, info); 95 free_irq(IRQ_USBOC, info);
96 } 96 }
diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig
index 1f00b3d03a07..274e07019b46 100644
--- a/arch/arm26/Kconfig
+++ b/arch/arm26/Kconfig
@@ -34,10 +34,6 @@ config FORCE_MAX_ZONEORDER
34 int 34 int
35 default 9 35 default 9
36 36
37config UID16
38 bool
39 default y
40
41config RWSEM_GENERIC_SPINLOCK 37config RWSEM_GENERIC_SPINLOCK
42 bool 38 bool
43 default y 39 default y
diff --git a/arch/arm26/kernel/asm-offsets.c b/arch/arm26/kernel/asm-offsets.c
index 4ccacaef94df..ac682d5fd039 100644
--- a/arch/arm26/kernel/asm-offsets.c
+++ b/arch/arm26/kernel/asm-offsets.c
@@ -25,13 +25,6 @@
25#if defined(__APCS_32__) && defined(CONFIG_CPU_26) 25#if defined(__APCS_32__) && defined(CONFIG_CPU_26)
26#error Sorry, your compiler targets APCS-32 but this kernel requires APCS-26 26#error Sorry, your compiler targets APCS-32 but this kernel requires APCS-26
27#endif 27#endif
28#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95)
29#error Sorry, your compiler is known to miscompile kernels. Only use gcc 2.95.3 and later.
30#endif
31#if __GNUC__ == 2 && __GNUC_MINOR__ == 95
32/* shame we can't detect the .1 or .2 releases */
33#warning GCC 2.95.2 and earlier miscompiles kernels.
34#endif
35 28
36/* Use marker if you need to separate the values later */ 29/* Use marker if you need to separate the values later */
37 30
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index e5979d68e352..b83261949737 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -9,10 +9,6 @@ config MMU
9 bool 9 bool
10 default y 10 default y
11 11
12config UID16
13 bool
14 default y
15
16config RWSEM_GENERIC_SPINLOCK 12config RWSEM_GENERIC_SPINLOCK
17 bool 13 bool
18 default y 14 default y
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index ec85c0d6c6da..61261b78ced7 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -274,6 +274,11 @@ config GPREL_DATA_NONE
274 274
275endchoice 275endchoice
276 276
277config FRV_ONCPU_SERIAL
278 bool "Use on-CPU serial ports"
279 select SERIAL_8250
280 default y
281
277config PCI 282config PCI
278 bool "Use PCI" 283 bool "Use PCI"
279 depends on MB93090_MB00 284 depends on MB93090_MB00
@@ -305,23 +310,7 @@ config RESERVE_DMA_COHERENT
305 310
306source "drivers/pci/Kconfig" 311source "drivers/pci/Kconfig"
307 312
308config PCMCIA 313source "drivers/pcmcia/Kconfig"
309 tristate "Use PCMCIA"
310 help
311 Say Y here if you want to attach PCMCIA- or PC-cards to your FR-V
312 board. These are credit-card size devices such as network cards,
313 modems or hard drives often used with laptops computers. There are
314 actually two varieties of these cards: the older 16 bit PCMCIA cards
315 and the newer 32 bit CardBus cards. If you want to use CardBus
316 cards, you need to say Y here and also to "CardBus support" below.
317
318 To use your PC-cards, you will need supporting software from David
319 Hinds pcmcia-cs package (see the file <file:Documentation/Changes>
320 for location). Please also read the PCMCIA-HOWTO, available from
321 <http://www.tldp.org/docs.html#howto>.
322
323 To compile this driver as modules, choose M here: the
324 modules will be called pcmcia_core and ds.
325 314
326#config MATH_EMULATION 315#config MATH_EMULATION
327# bool "Math emulation support (EXPERIMENTAL)" 316# bool "Math emulation support (EXPERIMENTAL)"
diff --git a/arch/frv/Kconfig.debug b/arch/frv/Kconfig.debug
index 0034b654995d..211f01bc4caa 100644
--- a/arch/frv/Kconfig.debug
+++ b/arch/frv/Kconfig.debug
@@ -2,32 +2,10 @@ menu "Kernel hacking"
2 2
3source "lib/Kconfig.debug" 3source "lib/Kconfig.debug"
4 4
5config EARLY_PRINTK
6 bool "Early printk"
7 depends on EMBEDDED && DEBUG_KERNEL
8 default n
9 help
10 Write kernel log output directly into the VGA buffer or to a serial
11 port.
12
13 This is useful for kernel debugging when your machine crashes very
14 early before the console code is initialized. For normal operation
15 it is not recommended because it looks ugly and doesn't cooperate
16 with klogd/syslogd or the X server. You should normally N here,
17 unless you want to debug such a crash.
18
19config DEBUG_STACKOVERFLOW 5config DEBUG_STACKOVERFLOW
20 bool "Check for stack overflows" 6 bool "Check for stack overflows"
21 depends on DEBUG_KERNEL 7 depends on DEBUG_KERNEL
22 8
23config DEBUG_PAGEALLOC
24 bool "Page alloc debugging"
25 depends on DEBUG_KERNEL
26 help
27 Unmap pages from the kernel linear mapping after free_pages().
28 This results in a large slowdown, but helps to find certain types
29 of memory corruptions.
30
31config GDBSTUB 9config GDBSTUB
32 bool "Remote GDB kernel debugging" 10 bool "Remote GDB kernel debugging"
33 depends on DEBUG_KERNEL 11 depends on DEBUG_KERNEL
diff --git a/arch/frv/Makefile b/arch/frv/Makefile
index 54046d2386f5..90c0fb8d9dc3 100644
--- a/arch/frv/Makefile
+++ b/arch/frv/Makefile
@@ -109,10 +109,10 @@ bootstrap:
109 $(Q)$(MAKEBOOT) bootstrap 109 $(Q)$(MAKEBOOT) bootstrap
110 110
111archmrproper: 111archmrproper:
112 $(Q)$(MAKE) -C arch/frv/boot mrproper 112 $(Q)$(MAKE) $(build)=arch/frv/boot mrproper
113 113
114archclean: 114archclean:
115 $(Q)$(MAKE) -C arch/frv/boot clean 115 $(Q)$(MAKE) $(build)=arch/frv/boot clean
116 116
117archdep: scripts/mkdep symlinks 117archdep: scripts/mkdep symlinks
118 $(Q)$(MAKE) -C arch/frv/boot dep 118 $(Q)$(MAKE) $(build)=arch/frv/boot dep
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile
index 422f30ede575..5a827b349b5e 100644
--- a/arch/frv/kernel/Makefile
+++ b/arch/frv/kernel/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_PM) += pm.o cmode.o
21obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o 21obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o
22obj-$(CONFIG_SYSCTL) += sysctl.o 22obj-$(CONFIG_SYSCTL) += sysctl.o
23obj-$(CONFIG_FUTEX) += futex.o 23obj-$(CONFIG_FUTEX) += futex.o
24obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c
index 1a76d5247190..5f118c89d091 100644
--- a/arch/frv/kernel/frv_ksyms.c
+++ b/arch/frv/kernel/frv_ksyms.c
@@ -16,10 +16,11 @@
16#include <asm/semaphore.h> 16#include <asm/semaphore.h>
17#include <asm/checksum.h> 17#include <asm/checksum.h>
18#include <asm/hardirq.h> 18#include <asm/hardirq.h>
19#include <asm/current.h> 19#include <asm/cacheflush.h>
20 20
21extern void dump_thread(struct pt_regs *, struct user *); 21extern void dump_thread(struct pt_regs *, struct user *);
22extern long __memcpy_user(void *dst, const void *src, size_t count); 22extern long __memcpy_user(void *dst, const void *src, size_t count);
23extern long __memset_user(void *dst, const void *src, size_t count);
23 24
24/* platform dependent support */ 25/* platform dependent support */
25 26
@@ -50,7 +51,11 @@ EXPORT_SYMBOL(disable_irq);
50EXPORT_SYMBOL(__res_bus_clock_speed_HZ); 51EXPORT_SYMBOL(__res_bus_clock_speed_HZ);
51EXPORT_SYMBOL(__page_offset); 52EXPORT_SYMBOL(__page_offset);
52EXPORT_SYMBOL(__memcpy_user); 53EXPORT_SYMBOL(__memcpy_user);
53EXPORT_SYMBOL(flush_dcache_page); 54EXPORT_SYMBOL(__memset_user);
55EXPORT_SYMBOL(frv_dcache_writeback);
56EXPORT_SYMBOL(frv_cache_invalidate);
57EXPORT_SYMBOL(frv_icache_invalidate);
58EXPORT_SYMBOL(frv_cache_wback_inv);
54 59
55#ifndef CONFIG_MMU 60#ifndef CONFIG_MMU
56EXPORT_SYMBOL(memory_start); 61EXPORT_SYMBOL(memory_start);
@@ -72,6 +77,9 @@ EXPORT_SYMBOL(memcmp);
72EXPORT_SYMBOL(memscan); 77EXPORT_SYMBOL(memscan);
73EXPORT_SYMBOL(memmove); 78EXPORT_SYMBOL(memmove);
74 79
80EXPORT_SYMBOL(__outsl_ns);
81EXPORT_SYMBOL(__insl_ns);
82
75EXPORT_SYMBOL(get_wchan); 83EXPORT_SYMBOL(get_wchan);
76 84
77#ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS 85#ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
@@ -80,14 +88,13 @@ EXPORT_SYMBOL(atomic_test_and_OR_mask);
80EXPORT_SYMBOL(atomic_test_and_XOR_mask); 88EXPORT_SYMBOL(atomic_test_and_XOR_mask);
81EXPORT_SYMBOL(atomic_add_return); 89EXPORT_SYMBOL(atomic_add_return);
82EXPORT_SYMBOL(atomic_sub_return); 90EXPORT_SYMBOL(atomic_sub_return);
83EXPORT_SYMBOL(__xchg_8);
84EXPORT_SYMBOL(__xchg_16);
85EXPORT_SYMBOL(__xchg_32); 91EXPORT_SYMBOL(__xchg_32);
86EXPORT_SYMBOL(__cmpxchg_8);
87EXPORT_SYMBOL(__cmpxchg_16);
88EXPORT_SYMBOL(__cmpxchg_32); 92EXPORT_SYMBOL(__cmpxchg_32);
89#endif 93#endif
90 94
95EXPORT_SYMBOL(__debug_bug_printk);
96EXPORT_SYMBOL(__delay_loops_MHz);
97
91/* 98/*
92 * libgcc functions - functions that are used internally by the 99 * libgcc functions - functions that are used internally by the
93 * compiler... (prototypes are not correct though, but that 100 * compiler... (prototypes are not correct though, but that
@@ -101,6 +108,8 @@ extern void __divdi3(void);
101extern void __lshrdi3(void); 108extern void __lshrdi3(void);
102extern void __moddi3(void); 109extern void __moddi3(void);
103extern void __muldi3(void); 110extern void __muldi3(void);
111extern void __mulll(void);
112extern void __umulll(void);
104extern void __negdi2(void); 113extern void __negdi2(void);
105extern void __ucmpdi2(void); 114extern void __ucmpdi2(void);
106extern void __udivdi3(void); 115extern void __udivdi3(void);
@@ -116,8 +125,10 @@ EXPORT_SYMBOL(__ashrdi3);
116EXPORT_SYMBOL(__lshrdi3); 125EXPORT_SYMBOL(__lshrdi3);
117//EXPORT_SYMBOL(__moddi3); 126//EXPORT_SYMBOL(__moddi3);
118EXPORT_SYMBOL(__muldi3); 127EXPORT_SYMBOL(__muldi3);
128EXPORT_SYMBOL(__mulll);
129EXPORT_SYMBOL(__umulll);
119EXPORT_SYMBOL(__negdi2); 130EXPORT_SYMBOL(__negdi2);
120//EXPORT_SYMBOL(__ucmpdi2); 131EXPORT_SYMBOL(__ucmpdi2);
121//EXPORT_SYMBOL(__udivdi3); 132//EXPORT_SYMBOL(__udivdi3);
122//EXPORT_SYMBOL(__udivmoddi4); 133//EXPORT_SYMBOL(__udivmoddi4);
123//EXPORT_SYMBOL(__umoddi3); 134//EXPORT_SYMBOL(__umoddi3);
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 8c524cdd2717..59580c59c62c 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -32,6 +32,7 @@
32#include <linux/irq.h> 32#include <linux/irq.h>
33#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
34#include <linux/seq_file.h> 34#include <linux/seq_file.h>
35#include <linux/module.h>
35 36
36#include <asm/atomic.h> 37#include <asm/atomic.h>
37#include <asm/io.h> 38#include <asm/io.h>
@@ -178,6 +179,8 @@ void disable_irq_nosync(unsigned int irq)
178 spin_unlock_irqrestore(&level->lock, flags); 179 spin_unlock_irqrestore(&level->lock, flags);
179} 180}
180 181
182EXPORT_SYMBOL(disable_irq_nosync);
183
181/** 184/**
182 * disable_irq - disable an irq and wait for completion 185 * disable_irq - disable an irq and wait for completion
183 * @irq: Interrupt to disable 186 * @irq: Interrupt to disable
@@ -204,6 +207,8 @@ void disable_irq(unsigned int irq)
204#endif 207#endif
205} 208}
206 209
210EXPORT_SYMBOL(disable_irq);
211
207/** 212/**
208 * enable_irq - enable handling of an irq 213 * enable_irq - enable handling of an irq
209 * @irq: Interrupt to enable 214 * @irq: Interrupt to enable
@@ -268,6 +273,8 @@ void enable_irq(unsigned int irq)
268 spin_unlock_irqrestore(&level->lock, flags); 273 spin_unlock_irqrestore(&level->lock, flags);
269} 274}
270 275
276EXPORT_SYMBOL(enable_irq);
277
271/*****************************************************************************/ 278/*****************************************************************************/
272/* 279/*
273 * handles all normal device IRQ's 280 * handles all normal device IRQ's
@@ -425,6 +432,8 @@ int request_irq(unsigned int irq,
425 return retval; 432 return retval;
426} 433}
427 434
435EXPORT_SYMBOL(request_irq);
436
428/** 437/**
429 * free_irq - free an interrupt 438 * free_irq - free an interrupt
430 * @irq: Interrupt line to free 439 * @irq: Interrupt line to free
@@ -496,6 +505,8 @@ void free_irq(unsigned int irq, void *dev_id)
496 } 505 }
497} 506}
498 507
508EXPORT_SYMBOL(free_irq);
509
499/* 510/*
500 * IRQ autodetection code.. 511 * IRQ autodetection code..
501 * 512 *
@@ -519,6 +530,8 @@ unsigned long probe_irq_on(void)
519 return 0; 530 return 0;
520} 531}
521 532
533EXPORT_SYMBOL(probe_irq_on);
534
522/* 535/*
523 * Return a mask of triggered interrupts (this 536 * Return a mask of triggered interrupts (this
524 * can handle only legacy ISA interrupts). 537 * can handle only legacy ISA interrupts).
@@ -542,6 +555,8 @@ unsigned int probe_irq_mask(unsigned long xmask)
542 return 0; 555 return 0;
543} 556}
544 557
558EXPORT_SYMBOL(probe_irq_mask);
559
545/* 560/*
546 * Return the one interrupt that triggered (this can 561 * Return the one interrupt that triggered (this can
547 * handle any interrupt source). 562 * handle any interrupt source).
@@ -571,6 +586,8 @@ int probe_irq_off(unsigned long xmask)
571 return -1; 586 return -1;
572} 587}
573 588
589EXPORT_SYMBOL(probe_irq_off);
590
574/* this was setup_x86_irq but it seems pretty generic */ 591/* this was setup_x86_irq but it seems pretty generic */
575int setup_irq(unsigned int irq, struct irqaction *new) 592int setup_irq(unsigned int irq, struct irqaction *new)
576{ 593{
diff --git a/arch/frv/kernel/module.c b/arch/frv/kernel/module.c
new file mode 100644
index 000000000000..850d168f69fc
--- /dev/null
+++ b/arch/frv/kernel/module.c
@@ -0,0 +1,80 @@
1/* module.c: FRV specific module loading bits
2 *
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 * - Derived from arch/i386/kernel/module.c, Copyright (C) 2001 Rusty Russell.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12#include <linux/moduleloader.h>
13#include <linux/elf.h>
14#include <linux/vmalloc.h>
15#include <linux/fs.h>
16#include <linux/string.h>
17#include <linux/kernel.h>
18
19#if 0
20#define DEBUGP printk
21#else
22#define DEBUGP(fmt...)
23#endif
24
25void *module_alloc(unsigned long size)
26{
27 if (size == 0)
28 return NULL;
29
30 return vmalloc_exec(size);
31}
32
33
34/* Free memory returned from module_alloc */
35void module_free(struct module *mod, void *module_region)
36{
37 vfree(module_region);
38 /* FIXME: If module_region == mod->init_region, trim exception
39 table entries. */
40}
41
42/* We don't need anything special. */
43int module_frob_arch_sections(Elf_Ehdr *hdr,
44 Elf_Shdr *sechdrs,
45 char *secstrings,
46 struct module *mod)
47{
48 return 0;
49}
50
51int apply_relocate(Elf32_Shdr *sechdrs,
52 const char *strtab,
53 unsigned int symindex,
54 unsigned int relsec,
55 struct module *me)
56{
57 printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", me->name);
58 return -ENOEXEC;
59}
60
61int apply_relocate_add(Elf32_Shdr *sechdrs,
62 const char *strtab,
63 unsigned int symindex,
64 unsigned int relsec,
65 struct module *me)
66{
67 printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", me->name);
68 return -ENOEXEC;
69}
70
71int module_finalize(const Elf_Ehdr *hdr,
72 const Elf_Shdr *sechdrs,
73 struct module *me)
74{
75 return 0;
76}
77
78void module_arch_cleanup(struct module *mod)
79{
80}
diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c
index 712c3c24c954..f0b8fff3e733 100644
--- a/arch/frv/kernel/pm.c
+++ b/arch/frv/kernel/pm.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/module.h>
16#include <linux/pm.h> 17#include <linux/pm.h>
17#include <linux/pm_legacy.h> 18#include <linux/pm_legacy.h>
18#include <linux/sched.h> 19#include <linux/sched.h>
@@ -27,6 +28,7 @@
27#include "local.h" 28#include "local.h"
28 29
29void (*pm_power_off)(void); 30void (*pm_power_off)(void);
31EXPORT_SYMBOL(pm_power_off);
30 32
31extern void frv_change_cmode(int); 33extern void frv_change_cmode(int);
32 34
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c
index 767ebb55bd83..5908deae9607 100644
--- a/arch/frv/kernel/setup.c
+++ b/arch/frv/kernel/setup.c
@@ -787,6 +787,7 @@ void __init setup_arch(char **cmdline_p)
787#endif 787#endif
788 788
789 /* register those serial ports that are available */ 789 /* register those serial ports that are available */
790#ifdef CONFIG_FRV_ONCPU_SERIAL
790#ifndef CONFIG_GDBSTUB_UART0 791#ifndef CONFIG_GDBSTUB_UART0
791 __reg(UART0_BASE + UART_IER * 8) = 0; 792 __reg(UART0_BASE + UART_IER * 8) = 0;
792 early_serial_setup(&__frv_uart0); 793 early_serial_setup(&__frv_uart0);
@@ -795,6 +796,7 @@ void __init setup_arch(char **cmdline_p)
795 __reg(UART1_BASE + UART_IER * 8) = 0; 796 __reg(UART1_BASE + UART_IER * 8) = 0;
796 early_serial_setup(&__frv_uart1); 797 early_serial_setup(&__frv_uart1);
797#endif 798#endif
799#endif
798 800
799#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) 801#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
800 /* we need to initialize the Flashrom device here since we might 802 /* we need to initialize the Flashrom device here since we might
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index 2e9741227b73..24cf85f89e40 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -189,6 +189,8 @@ void do_gettimeofday(struct timeval *tv)
189 tv->tv_usec = usec; 189 tv->tv_usec = usec;
190} 190}
191 191
192EXPORT_SYMBOL(do_gettimeofday);
193
192int do_settimeofday(struct timespec *tv) 194int do_settimeofday(struct timespec *tv)
193{ 195{
194 time_t wtm_sec, sec = tv->tv_sec; 196 time_t wtm_sec, sec = tv->tv_sec;
@@ -218,6 +220,7 @@ int do_settimeofday(struct timespec *tv)
218 clock_was_set(); 220 clock_was_set();
219 return 0; 221 return 0;
220} 222}
223
221EXPORT_SYMBOL(do_settimeofday); 224EXPORT_SYMBOL(do_settimeofday);
222 225
223/* 226/*
diff --git a/arch/frv/kernel/traps.c b/arch/frv/kernel/traps.c
index 89073cae4b5d..9eb84b2e6abc 100644
--- a/arch/frv/kernel/traps.c
+++ b/arch/frv/kernel/traps.c
@@ -19,6 +19,7 @@
19#include <linux/string.h> 19#include <linux/string.h>
20#include <linux/linkage.h> 20#include <linux/linkage.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/module.h>
22 23
23#include <asm/setup.h> 24#include <asm/setup.h>
24#include <asm/fpu.h> 25#include <asm/fpu.h>
@@ -250,6 +251,8 @@ void dump_stack(void)
250 show_stack(NULL, NULL); 251 show_stack(NULL, NULL);
251} 252}
252 253
254EXPORT_SYMBOL(dump_stack);
255
253void show_stack(struct task_struct *task, unsigned long *sp) 256void show_stack(struct task_struct *task, unsigned long *sp)
254{ 257{
255} 258}
diff --git a/arch/frv/kernel/uaccess.c b/arch/frv/kernel/uaccess.c
index f3fd58a5bc4a..9b751c0f0e84 100644
--- a/arch/frv/kernel/uaccess.c
+++ b/arch/frv/kernel/uaccess.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/module.h>
13#include <asm/uaccess.h> 14#include <asm/uaccess.h>
14 15
15/*****************************************************************************/ 16/*****************************************************************************/
@@ -58,8 +59,11 @@ long strncpy_from_user(char *dst, const char *src, long count)
58 memset(p, 0, count); /* clear remainder of buffer [security] */ 59 memset(p, 0, count); /* clear remainder of buffer [security] */
59 60
60 return err; 61 return err;
62
61} /* end strncpy_from_user() */ 63} /* end strncpy_from_user() */
62 64
65EXPORT_SYMBOL(strncpy_from_user);
66
63/*****************************************************************************/ 67/*****************************************************************************/
64/* 68/*
65 * Return the size of a string (including the ending 0) 69 * Return the size of a string (including the ending 0)
@@ -92,4 +96,7 @@ long strnlen_user(const char *src, long count)
92 } 96 }
93 97
94 return p - src + 1; /* return length including NUL */ 98 return p - src + 1; /* return length including NUL */
99
95} /* end strnlen_user() */ 100} /* end strnlen_user() */
101
102EXPORT_SYMBOL(strnlen_user);
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
index fceafd2cc202..f474534ba78a 100644
--- a/arch/frv/kernel/vmlinux.lds.S
+++ b/arch/frv/kernel/vmlinux.lds.S
@@ -112,6 +112,7 @@ SECTIONS
112#endif 112#endif
113 ) 113 )
114 SCHED_TEXT 114 SCHED_TEXT
115 LOCK_TEXT
115 *(.fixup) 116 *(.fixup)
116 *(.gnu.warning) 117 *(.gnu.warning)
117 *(.exitcall.exit) 118 *(.exitcall.exit)
diff --git a/arch/frv/lib/Makefile b/arch/frv/lib/Makefile
index 19be2626d5e6..08be305c9f44 100644
--- a/arch/frv/lib/Makefile
+++ b/arch/frv/lib/Makefile
@@ -3,6 +3,6 @@
3# 3#
4 4
5lib-y := \ 5lib-y := \
6 __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o \ 6 __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o __ucmpdi2.o \
7 checksum.o memcpy.o memset.o atomic-ops.o \ 7 checksum.o memcpy.o memset.o atomic-ops.o \
8 outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o 8 outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o
diff --git a/arch/frv/lib/__ucmpdi2.S b/arch/frv/lib/__ucmpdi2.S
new file mode 100644
index 000000000000..d892f16ffaa9
--- /dev/null
+++ b/arch/frv/lib/__ucmpdi2.S
@@ -0,0 +1,45 @@
1/* __ucmpdi2.S: 64-bit unsigned compare
2 *
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12
13 .text
14 .p2align 4
15
16###############################################################################
17#
18# int __ucmpdi2(unsigned long long a [GR8:GR9],
19# unsigned long long b [GR10:GR11])
20#
21# - returns 0, 1, or 2 as a <, =, > b respectively.
22#
23###############################################################################
24 .globl __ucmpdi2
25 .type __ucmpdi2,@function
26__ucmpdi2:
27 or.p gr8,gr0,gr4
28 subcc gr8,gr10,gr0,icc0
29 setlos.p #0,gr8
30 bclr icc0,#2 ; a.msw < b.msw
31
32 setlos.p #2,gr8
33 bhilr icc0,#0 ; a.msw > b.msw
34
35 subcc.p gr9,gr11,gr0,icc1
36 setlos #0,gr8
37 setlos.p #2,gr9
38 setlos #1,gr7
39 cknc icc1,cc6
40 cor.p gr9,gr0,gr8, cc6,#1
41 cckls icc1,cc4, cc6,#1
42 andcr cc6,cc4,cc4
43 cor gr7,gr0,gr8, cc4,#1
44 bralr
45 .size __ucmpdi2, .-__ucmpdi2
diff --git a/arch/frv/lib/atomic-ops.S b/arch/frv/lib/atomic-ops.S
index b03d510a89e4..545cd325ac57 100644
--- a/arch/frv/lib/atomic-ops.S
+++ b/arch/frv/lib/atomic-ops.S
@@ -129,48 +129,6 @@ atomic_sub_return:
129 129
130############################################################################### 130###############################################################################
131# 131#
132# uint8_t __xchg_8(uint8_t i, uint8_t *v)
133#
134###############################################################################
135 .globl __xchg_8
136 .type __xchg_8,@function
137__xchg_8:
138 or.p gr8,gr8,gr10
1390:
140 orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
141 ckeq icc3,cc7
142 ldub.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
143 orcr cc7,cc7,cc3 /* set CC3 to true */
144 cstb.p gr10,@(gr9,gr0) ,cc3,#1
145 corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
146 beq icc3,#0,0b
147 bralr
148
149 .size __xchg_8, .-__xchg_8
150
151###############################################################################
152#
153# uint16_t __xchg_16(uint16_t i, uint16_t *v)
154#
155###############################################################################
156 .globl __xchg_16
157 .type __xchg_16,@function
158__xchg_16:
159 or.p gr8,gr8,gr10
1600:
161 orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
162 ckeq icc3,cc7
163 lduh.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
164 orcr cc7,cc7,cc3 /* set CC3 to true */
165 csth.p gr10,@(gr9,gr0) ,cc3,#1
166 corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
167 beq icc3,#0,0b
168 bralr
169
170 .size __xchg_16, .-__xchg_16
171
172###############################################################################
173#
174# uint32_t __xchg_32(uint32_t i, uint32_t *v) 132# uint32_t __xchg_32(uint32_t i, uint32_t *v)
175# 133#
176############################################################################### 134###############################################################################
@@ -192,56 +150,6 @@ __xchg_32:
192 150
193############################################################################### 151###############################################################################
194# 152#
195# uint8_t __cmpxchg_8(uint8_t *v, uint8_t test, uint8_t new)
196#
197###############################################################################
198 .globl __cmpxchg_8
199 .type __cmpxchg_8,@function
200__cmpxchg_8:
201 or.p gr8,gr8,gr11
2020:
203 orcc gr0,gr0,gr0,icc3
204 ckeq icc3,cc7
205 ldub.p @(gr11,gr0),gr8
206 orcr cc7,cc7,cc3
207 sub gr8,gr9,gr7
208 sllicc gr7,#24,gr0,icc0
209 bne icc0,#0,1f
210 cstb.p gr10,@(gr11,gr0) ,cc3,#1
211 corcc gr29,gr29,gr0 ,cc3,#1
212 beq icc3,#0,0b
2131:
214 bralr
215
216 .size __cmpxchg_8, .-__cmpxchg_8
217
218###############################################################################
219#
220# uint16_t __cmpxchg_16(uint16_t *v, uint16_t test, uint16_t new)
221#
222###############################################################################
223 .globl __cmpxchg_16
224 .type __cmpxchg_16,@function
225__cmpxchg_16:
226 or.p gr8,gr8,gr11
2270:
228 orcc gr0,gr0,gr0,icc3
229 ckeq icc3,cc7
230 lduh.p @(gr11,gr0),gr8
231 orcr cc7,cc7,cc3
232 sub gr8,gr9,gr7
233 sllicc gr7,#16,gr0,icc0
234 bne icc0,#0,1f
235 csth.p gr10,@(gr11,gr0) ,cc3,#1
236 corcc gr29,gr29,gr0 ,cc3,#1
237 beq icc3,#0,0b
2381:
239 bralr
240
241 .size __cmpxchg_16, .-__cmpxchg_16
242
243###############################################################################
244#
245# uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new) 153# uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new)
246# 154#
247############################################################################### 155###############################################################################
diff --git a/arch/frv/lib/checksum.c b/arch/frv/lib/checksum.c
index 7bf5bd6cac8a..20e7dfc474ef 100644
--- a/arch/frv/lib/checksum.c
+++ b/arch/frv/lib/checksum.c
@@ -33,6 +33,7 @@
33 33
34#include <net/checksum.h> 34#include <net/checksum.h>
35#include <asm/checksum.h> 35#include <asm/checksum.h>
36#include <linux/module.h>
36 37
37static inline unsigned short from32to16(unsigned long x) 38static inline unsigned short from32to16(unsigned long x)
38{ 39{
@@ -115,34 +116,52 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
115 return result; 116 return result;
116} 117}
117 118
119EXPORT_SYMBOL(csum_partial);
120
118/* 121/*
119 * this routine is used for miscellaneous IP-like checksums, mainly 122 * this routine is used for miscellaneous IP-like checksums, mainly
120 * in icmp.c 123 * in icmp.c
121 */ 124 */
122unsigned short ip_compute_csum(const unsigned char * buff, int len) 125unsigned short ip_compute_csum(const unsigned char * buff, int len)
123{ 126{
124 return ~do_csum(buff,len); 127 return ~do_csum(buff, len);
125} 128}
126 129
130EXPORT_SYMBOL(ip_compute_csum);
131
127/* 132/*
128 * copy from fs while checksumming, otherwise like csum_partial 133 * copy from fs while checksumming, otherwise like csum_partial
129 */ 134 */
130
131unsigned int 135unsigned int
132csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err) 136csum_partial_copy_from_user(const char __user *src, char *dst,
137 int len, int sum, int *csum_err)
133{ 138{
134 if (csum_err) *csum_err = 0; 139 int rem;
135 memcpy(dst, src, len); 140
141 if (csum_err)
142 *csum_err = 0;
143
144 rem = copy_from_user(dst, src, len);
145 if (rem != 0) {
146 if (csum_err)
147 *csum_err = -EFAULT;
148 memset(dst + len - rem, 0, rem);
149 len = rem;
150 }
151
136 return csum_partial(dst, len, sum); 152 return csum_partial(dst, len, sum);
137} 153}
138 154
155EXPORT_SYMBOL(csum_partial_copy_from_user);
156
139/* 157/*
140 * copy from ds while checksumming, otherwise like csum_partial 158 * copy from ds while checksumming, otherwise like csum_partial
141 */ 159 */
142
143unsigned int 160unsigned int
144csum_partial_copy(const char *src, char *dst, int len, int sum) 161csum_partial_copy(const char *src, char *dst, int len, int sum)
145{ 162{
146 memcpy(dst, src, len); 163 memcpy(dst, src, len);
147 return csum_partial(dst, len, sum); 164 return csum_partial(dst, len, sum);
148} 165}
166
167EXPORT_SYMBOL(csum_partial_copy);
diff --git a/arch/frv/mb93090-mb00/Makefile b/arch/frv/mb93090-mb00/Makefile
index 3faf0f8cf9b5..76595e870733 100644
--- a/arch/frv/mb93090-mb00/Makefile
+++ b/arch/frv/mb93090-mb00/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5ifeq "$(CONFIG_PCI)" "y" 5ifeq "$(CONFIG_PCI)" "y"
6obj-y := pci-frv.o pci-irq.o pci-vdk.o 6obj-y := pci-frv.o pci-irq.o pci-vdk.o pci-iomap.o
7 7
8ifeq "$(CONFIG_MMU)" "y" 8ifeq "$(CONFIG_MMU)" "y"
9obj-y += pci-dma.o 9obj-y += pci-dma.o
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index 2082a9647f4f..4985466b1a7c 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -83,6 +83,8 @@ void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_hand
83 return NULL; 83 return NULL;
84} 84}
85 85
86EXPORT_SYMBOL(dma_alloc_coherent);
87
86void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) 88void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
87{ 89{
88 struct dma_alloc_record *rec; 90 struct dma_alloc_record *rec;
@@ -102,6 +104,8 @@ void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_
102 BUG(); 104 BUG();
103} 105}
104 106
107EXPORT_SYMBOL(dma_free_coherent);
108
105/* 109/*
106 * Map a single buffer of the indicated size for DMA in streaming mode. 110 * Map a single buffer of the indicated size for DMA in streaming mode.
107 * The 32-bit bus address to use is returned. 111 * The 32-bit bus address to use is returned.
@@ -120,6 +124,8 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
120 return virt_to_bus(ptr); 124 return virt_to_bus(ptr);
121} 125}
122 126
127EXPORT_SYMBOL(dma_map_single);
128
123/* 129/*
124 * Map a set of buffers described by scatterlist in streaming 130 * Map a set of buffers described by scatterlist in streaming
125 * mode for DMA. This is the scather-gather version of the 131 * mode for DMA. This is the scather-gather version of the
@@ -150,3 +156,5 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
150 156
151 return nents; 157 return nents;
152} 158}
159
160EXPORT_SYMBOL(dma_map_sg);
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index 86fbdadc51b6..671ce1e8434f 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -28,11 +28,15 @@ void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_hand
28 return ret; 28 return ret;
29} 29}
30 30
31EXPORT_SYMBOL(dma_alloc_coherent);
32
31void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) 33void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
32{ 34{
33 consistent_free(vaddr); 35 consistent_free(vaddr);
34} 36}
35 37
38EXPORT_SYMBOL(dma_free_coherent);
39
36/* 40/*
37 * Map a single buffer of the indicated size for DMA in streaming mode. 41 * Map a single buffer of the indicated size for DMA in streaming mode.
38 * The 32-bit bus address to use is returned. 42 * The 32-bit bus address to use is returned.
@@ -51,6 +55,8 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
51 return virt_to_bus(ptr); 55 return virt_to_bus(ptr);
52} 56}
53 57
58EXPORT_SYMBOL(dma_map_single);
59
54/* 60/*
55 * Map a set of buffers described by scatterlist in streaming 61 * Map a set of buffers described by scatterlist in streaming
56 * mode for DMA. This is the scather-gather version of the 62 * mode for DMA. This is the scather-gather version of the
@@ -96,6 +102,8 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
96 return nents; 102 return nents;
97} 103}
98 104
105EXPORT_SYMBOL(dma_map_sg);
106
99dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset, 107dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
100 size_t size, enum dma_data_direction direction) 108 size_t size, enum dma_data_direction direction)
101{ 109{
@@ -103,3 +111,5 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long off
103 flush_dcache_page(page); 111 flush_dcache_page(page);
104 return (dma_addr_t) page_to_phys(page) + offset; 112 return (dma_addr_t) page_to_phys(page) + offset;
105} 113}
114
115EXPORT_SYMBOL(dma_map_page);
diff --git a/arch/frv/mb93090-mb00/pci-iomap.c b/arch/frv/mb93090-mb00/pci-iomap.c
new file mode 100644
index 000000000000..068fa04bd527
--- /dev/null
+++ b/arch/frv/mb93090-mb00/pci-iomap.c
@@ -0,0 +1,29 @@
1/* pci-iomap.c: description
2 *
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#include <linux/pci.h>
12#include <linux/module.h>
13
14void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
15{
16 unsigned long start = pci_resource_start(dev, bar);
17 unsigned long len = pci_resource_len(dev, bar);
18 unsigned long flags = pci_resource_flags(dev, bar);
19
20 if (!len || !start)
21 return NULL;
22
23 if ((flags & IORESOURCE_IO) || (flags & IORESOURCE_MEM))
24 return (void __iomem *) start;
25
26 return NULL;
27}
28
29EXPORT_SYMBOL(pci_iomap);
diff --git a/arch/frv/mm/cache-page.c b/arch/frv/mm/cache-page.c
index 683b5e344318..0261cbe153b5 100644
--- a/arch/frv/mm/cache-page.c
+++ b/arch/frv/mm/cache-page.c
@@ -11,6 +11,7 @@
11#include <linux/sched.h> 11#include <linux/sched.h>
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/highmem.h> 13#include <linux/highmem.h>
14#include <linux/module.h>
14#include <asm/pgalloc.h> 15#include <asm/pgalloc.h>
15 16
16/*****************************************************************************/ 17/*****************************************************************************/
@@ -38,6 +39,8 @@ void flush_dcache_page(struct page *page)
38 39
39} /* end flush_dcache_page() */ 40} /* end flush_dcache_page() */
40 41
42EXPORT_SYMBOL(flush_dcache_page);
43
41/*****************************************************************************/ 44/*****************************************************************************/
42/* 45/*
43 * ICI takes a virtual address and the page may not currently have one 46 * ICI takes a virtual address and the page may not currently have one
@@ -64,3 +67,5 @@ void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
64 } 67 }
65 68
66} /* end flush_icache_user_range() */ 69} /* end flush_icache_user_range() */
70
71EXPORT_SYMBOL(flush_icache_user_range);
diff --git a/arch/frv/mm/extable.c b/arch/frv/mm/extable.c
index 41be1128dc64..caacf030ac75 100644
--- a/arch/frv/mm/extable.c
+++ b/arch/frv/mm/extable.c
@@ -43,7 +43,7 @@ static inline unsigned long search_one_table(const struct exception_table_entry
43 */ 43 */
44unsigned long search_exception_table(unsigned long pc) 44unsigned long search_exception_table(unsigned long pc)
45{ 45{
46 unsigned long ret = 0; 46 const struct exception_table_entry *extab;
47 47
48 /* determine if the fault lay during a memcpy_user or a memset_user */ 48 /* determine if the fault lay during a memcpy_user or a memset_user */
49 if (__frame->lr == (unsigned long) &__memset_user_error_lr && 49 if (__frame->lr == (unsigned long) &__memset_user_error_lr &&
@@ -55,9 +55,10 @@ unsigned long search_exception_table(unsigned long pc)
55 */ 55 */
56 return (unsigned long) &__memset_user_error_handler; 56 return (unsigned long) &__memset_user_error_handler;
57 } 57 }
58 else if (__frame->lr == (unsigned long) &__memcpy_user_error_lr && 58
59 (unsigned long) &memcpy <= pc && pc < (unsigned long) &__memcpy_end 59 if (__frame->lr == (unsigned long) &__memcpy_user_error_lr &&
60 ) { 60 (unsigned long) &memcpy <= pc && pc < (unsigned long) &__memcpy_end
61 ) {
61 /* the fault occurred in a protected memset 62 /* the fault occurred in a protected memset
62 * - we search for the return address (in LR) instead of the program counter 63 * - we search for the return address (in LR) instead of the program counter
63 * - it was probably during a copy_to/from_user() 64 * - it was probably during a copy_to/from_user()
@@ -65,27 +66,10 @@ unsigned long search_exception_table(unsigned long pc)
65 return (unsigned long) &__memcpy_user_error_handler; 66 return (unsigned long) &__memcpy_user_error_handler;
66 } 67 }
67 68
68#ifndef CONFIG_MODULES 69 extab = search_exception_tables(pc);
69 /* there is only the kernel to search. */ 70 if (extab)
70 ret = search_one_table(__start___ex_table, __stop___ex_table - 1, pc); 71 return extab->fixup;
71 return ret;
72
73#else
74 /* the kernel is the last "module" -- no need to treat it special */
75 unsigned long flags;
76 struct module *mp;
77 72
78 spin_lock_irqsave(&modlist_lock, flags); 73 return 0;
79
80 for (mp = module_list; mp != NULL; mp = mp->next) {
81 if (mp->ex_table_start == NULL || !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
82 continue;
83 ret = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, pc);
84 if (ret)
85 break;
86 }
87 74
88 spin_unlock_irqrestore(&modlist_lock, flags);
89 return ret;
90#endif
91} /* end search_exception_table() */ 75} /* end search_exception_table() */
diff --git a/arch/frv/mm/highmem.c b/arch/frv/mm/highmem.c
index 7dc8fbf3af97..7f77db7fabc7 100644
--- a/arch/frv/mm/highmem.c
+++ b/arch/frv/mm/highmem.c
@@ -9,6 +9,7 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11#include <linux/highmem.h> 11#include <linux/highmem.h>
12#include <linux/module.h>
12 13
13void *kmap(struct page *page) 14void *kmap(struct page *page)
14{ 15{
@@ -18,6 +19,8 @@ void *kmap(struct page *page)
18 return kmap_high(page); 19 return kmap_high(page);
19} 20}
20 21
22EXPORT_SYMBOL(kmap);
23
21void kunmap(struct page *page) 24void kunmap(struct page *page)
22{ 25{
23 if (in_interrupt()) 26 if (in_interrupt())
@@ -27,7 +30,12 @@ void kunmap(struct page *page)
27 kunmap_high(page); 30 kunmap_high(page);
28} 31}
29 32
33EXPORT_SYMBOL(kunmap);
34
30struct page *kmap_atomic_to_page(void *ptr) 35struct page *kmap_atomic_to_page(void *ptr)
31{ 36{
32 return virt_to_page(ptr); 37 return virt_to_page(ptr);
33} 38}
39
40
41EXPORT_SYMBOL(kmap_atomic_to_page);
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 26698a49f153..80940d712acf 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -21,10 +21,6 @@ config FPU
21 bool 21 bool
22 default n 22 default n
23 23
24config UID16
25 bool
26 default y
27
28config RWSEM_GENERIC_SPINLOCK 24config RWSEM_GENERIC_SPINLOCK
29 bool 25 bool
30 default y 26 default y
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 968fabd8723f..d849c6870e3a 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -29,10 +29,6 @@ config MMU
29config SBUS 29config SBUS
30 bool 30 bool
31 31
32config UID16
33 bool
34 default y
35
36config GENERIC_ISA_DMA 32config GENERIC_ISA_DMA
37 bool 33 bool
38 default y 34 default y
@@ -630,10 +626,6 @@ config REGPARM
630 and passes the first three arguments of a function call in registers. 626 and passes the first three arguments of a function call in registers.
631 This will probably break binary only modules. 627 This will probably break binary only modules.
632 628
633 This feature is only enabled for gcc-3.0 and later - earlier compilers
634 generate incorrect output with certain kernel constructs when
635 -mregparm=3 is used.
636
637config SECCOMP 629config SECCOMP
638 bool "Enable seccomp to safely compute untrusted bytecode" 630 bool "Enable seccomp to safely compute untrusted bytecode"
639 depends on PROC_FS 631 depends on PROC_FS
@@ -703,7 +695,7 @@ depends on PM && !X86_VISWS
703 695
704config APM 696config APM
705 tristate "APM (Advanced Power Management) BIOS support" 697 tristate "APM (Advanced Power Management) BIOS support"
706 depends on PM && PM_LEGACY 698 depends on PM
707 ---help--- 699 ---help---
708 APM is a BIOS specification for saving power using several different 700 APM is a BIOS specification for saving power using several different
709 techniques. This is mostly useful for battery powered laptops with 701 techniques. This is mostly useful for battery powered laptops with
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index d121ea18460f..b84119f9cc63 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -37,10 +37,7 @@ CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
37# CPU-specific tuning. Anything which can be shared with UML should go here. 37# CPU-specific tuning. Anything which can be shared with UML should go here.
38include $(srctree)/arch/i386/Makefile.cpu 38include $(srctree)/arch/i386/Makefile.cpu
39 39
40# -mregparm=3 works ok on gcc-3.0 and later 40cflags-$(CONFIG_REGPARM) += -mregparm=3
41#
42GCC_VERSION := $(call cc-version)
43cflags-$(CONFIG_REGPARM) += $(shell if [ $(GCC_VERSION) -ge 0300 ] ; then echo "-mregparm=3"; fi ;)
44 41
45# Disable unit-at-a-time mode, it makes gcc use a lot more stack 42# Disable unit-at-a-time mode, it makes gcc use a lot more stack
46# due to the lack of sharing of stacklots. 43# due to the lack of sharing of stacklots.
diff --git a/arch/i386/Makefile.cpu b/arch/i386/Makefile.cpu
index 8e51456df23d..dcd936ef45db 100644
--- a/arch/i386/Makefile.cpu
+++ b/arch/i386/Makefile.cpu
@@ -1,7 +1,7 @@
1# CPU tuning section - shared with UML. 1# CPU tuning section - shared with UML.
2# Must change only cflags-y (or [yn]), not CFLAGS! That makes a difference for UML. 2# Must change only cflags-y (or [yn]), not CFLAGS! That makes a difference for UML.
3 3
4#-mtune exists since gcc 3.4, and some -mcpu flavors didn't exist in gcc 2.95. 4#-mtune exists since gcc 3.4
5HAS_MTUNE := $(call cc-option-yn, -mtune=i386) 5HAS_MTUNE := $(call cc-option-yn, -mtune=i386)
6ifeq ($(HAS_MTUNE),y) 6ifeq ($(HAS_MTUNE),y)
7tune = $(call cc-option,-mtune=$(1),) 7tune = $(call cc-option,-mtune=$(1),)
@@ -14,7 +14,7 @@ cflags-$(CONFIG_M386) += -march=i386
14cflags-$(CONFIG_M486) += -march=i486 14cflags-$(CONFIG_M486) += -march=i486
15cflags-$(CONFIG_M586) += -march=i586 15cflags-$(CONFIG_M586) += -march=i586
16cflags-$(CONFIG_M586TSC) += -march=i586 16cflags-$(CONFIG_M586TSC) += -march=i586
17cflags-$(CONFIG_M586MMX) += $(call cc-option,-march=pentium-mmx,-march=i586) 17cflags-$(CONFIG_M586MMX) += -march=pentium-mmx
18cflags-$(CONFIG_M686) += -march=i686 18cflags-$(CONFIG_M686) += -march=i686
19cflags-$(CONFIG_MPENTIUMII) += -march=i686 $(call tune,pentium2) 19cflags-$(CONFIG_MPENTIUMII) += -march=i686 $(call tune,pentium2)
20cflags-$(CONFIG_MPENTIUMIII) += -march=i686 $(call tune,pentium3) 20cflags-$(CONFIG_MPENTIUMIII) += -march=i686 $(call tune,pentium3)
@@ -23,8 +23,8 @@ cflags-$(CONFIG_MPENTIUM4) += -march=i686 $(call tune,pentium4)
23cflags-$(CONFIG_MK6) += -march=k6 23cflags-$(CONFIG_MK6) += -march=k6
24# Please note, that patches that add -march=athlon-xp and friends are pointless. 24# Please note, that patches that add -march=athlon-xp and friends are pointless.
25# They make zero difference whatsosever to performance at this time. 25# They make zero difference whatsosever to performance at this time.
26cflags-$(CONFIG_MK7) += $(call cc-option,-march=athlon,-march=i686 $(align)-functions=4) 26cflags-$(CONFIG_MK7) += -march=athlon
27cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,$(call cc-option,-march=athlon,-march=i686 $(align)-functions=4)) 27cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,-march=athlon)
28cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 28cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
29cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 29cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
30cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586) 30cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586)
@@ -37,5 +37,5 @@ cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686)
37cflags-$(CONFIG_X86_ELAN) += -march=i486 37cflags-$(CONFIG_X86_ELAN) += -march=i486
38 38
39# Geode GX1 support 39# Geode GX1 support
40cflags-$(CONFIG_MGEODEGX1) += $(call cc-option,-march=pentium-mmx,-march=i486) 40cflags-$(CONFIG_MGEODEGX1) += -march=pentium-mmx
41 41
diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c
index 82a807f9f5e6..f19f3a7492a5 100644
--- a/arch/i386/boot/compressed/misc.c
+++ b/arch/i386/boot/compressed/misc.c
@@ -11,7 +11,7 @@
11 11
12#include <linux/linkage.h> 12#include <linux/linkage.h>
13#include <linux/vmalloc.h> 13#include <linux/vmalloc.h>
14#include <linux/tty.h> 14#include <linux/screen_info.h>
15#include <asm/io.h> 15#include <asm/io.h>
16#include <asm/page.h> 16#include <asm/page.h>
17 17
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index f10de0f2c5e6..be1880bb75b4 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -4,10 +4,10 @@
4 4
5extra-y := head.o init_task.o vmlinux.lds 5extra-y := head.o init_task.o vmlinux.lds
6 6
7obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ 7obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \
8 ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ 8 ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \
9 pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \ 9 pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \
10 doublefault.o quirks.o i8237.o 10 quirks.o i8237.o
11 11
12obj-y += cpu/ 12obj-y += cpu/
13obj-y += timers/ 13obj-y += timers/
@@ -33,6 +33,8 @@ obj-y += sysenter.o vsyscall.o
33obj-$(CONFIG_ACPI_SRAT) += srat.o 33obj-$(CONFIG_ACPI_SRAT) += srat.o
34obj-$(CONFIG_HPET_TIMER) += time_hpet.o 34obj-$(CONFIG_HPET_TIMER) += time_hpet.o
35obj-$(CONFIG_EFI) += efi.o efi_stub.o 35obj-$(CONFIG_EFI) += efi.o efi_stub.o
36obj-$(CONFIG_DOUBLEFAULT) += doublefault.o
37obj-$(CONFIG_VM86) += vm86.o
36obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 38obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
37 39
38EXTRA_AFLAGS := -traditional 40EXTRA_AFLAGS := -traditional
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 2d793d4aef1a..9d8827156e54 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -2291,7 +2291,9 @@ static int __init apm_init(void)
2291 apm_info.disabled = 1; 2291 apm_info.disabled = 1;
2292 return -ENODEV; 2292 return -ENODEV;
2293 } 2293 }
2294#ifdef CONFIG_PM_LEGACY
2294 pm_active = 1; 2295 pm_active = 1;
2296#endif
2295 2297
2296 /* 2298 /*
2297 * Set up a segment that references the real mode segment 0x40 2299 * Set up a segment that references the real mode segment 0x40
@@ -2382,7 +2384,9 @@ static void __exit apm_exit(void)
2382 exit_kapmd = 1; 2384 exit_kapmd = 1;
2383 while (kapmd_running) 2385 while (kapmd_running)
2384 schedule(); 2386 schedule();
2387#ifdef CONFIG_PM_LEGACY
2385 pm_active = 0; 2388 pm_active = 0;
2389#endif
2386} 2390}
2387 2391
2388module_init(apm_init); 2392module_init(apm_init);
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index cca655688ffc..170400879f44 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -609,8 +609,10 @@ void __devinit cpu_init(void)
609 load_TR_desc(); 609 load_TR_desc();
610 load_LDT(&init_mm.context); 610 load_LDT(&init_mm.context);
611 611
612#ifdef CONFIG_DOUBLEFAULT
612 /* Set up doublefault TSS pointer in the GDT */ 613 /* Set up doublefault TSS pointer in the GDT */
613 __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss); 614 __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss);
615#endif
614 616
615 /* Clear %fs and %gs. */ 617 /* Clear %fs and %gs. */
616 asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs"); 618 asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 607c06007508..4d704724b2f5 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -323,6 +323,7 @@ work_notifysig: # deal with pending signals and
323 323
324 ALIGN 324 ALIGN
325work_notifysig_v86: 325work_notifysig_v86:
326#ifdef CONFIG_VM86
326 pushl %ecx # save ti_flags for do_notify_resume 327 pushl %ecx # save ti_flags for do_notify_resume
327 call save_v86_state # %eax contains pt_regs pointer 328 call save_v86_state # %eax contains pt_regs pointer
328 popl %ecx 329 popl %ecx
@@ -330,6 +331,7 @@ work_notifysig_v86:
330 xorl %edx, %edx 331 xorl %edx, %edx
331 call do_notify_resume 332 call do_notify_resume
332 jmp resume_userspace 333 jmp resume_userspace
334#endif
333 335
334 # perform syscall exit tracing 336 # perform syscall exit tracing
335 ALIGN 337 ALIGN
diff --git a/arch/i386/kernel/init_task.c b/arch/i386/kernel/init_task.c
index 9caa8e8db80c..cff95d10a4d8 100644
--- a/arch/i386/kernel/init_task.c
+++ b/arch/i386/kernel/init_task.c
@@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
42 * per-CPU TSS segments. Threads are completely 'soft' on Linux, 42 * per-CPU TSS segments. Threads are completely 'soft' on Linux,
43 * no more per-task TSS's. 43 * no more per-task TSS's.
44 */ 44 */
45DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_maxaligned_in_smp = INIT_TSS; 45DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
46 46
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index 1a201a932865..f3a9c78c4a24 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -19,7 +19,7 @@
19#include <linux/cpu.h> 19#include <linux/cpu.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21 21
22DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp; 22DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_internodealigned_in_smp;
23EXPORT_PER_CPU_SYMBOL(irq_stat); 23EXPORT_PER_CPU_SYMBOL(irq_stat);
24 24
25#ifndef CONFIG_X86_LOCAL_APIC 25#ifndef CONFIG_X86_LOCAL_APIC
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 45e7f0ac4b04..035928f3f6c1 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -48,6 +48,7 @@
48#include <asm/processor.h> 48#include <asm/processor.h>
49#include <asm/i387.h> 49#include <asm/i387.h>
50#include <asm/desc.h> 50#include <asm/desc.h>
51#include <asm/vm86.h>
51#ifdef CONFIG_MATH_EMULATION 52#ifdef CONFIG_MATH_EMULATION
52#include <asm/math_emu.h> 53#include <asm/math_emu.h>
53#endif 54#endif
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index f7ba4acc20ec..6ff3e5243226 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -293,3 +293,4 @@ ENTRY(sys_call_table)
293 .long sys_inotify_init 293 .long sys_inotify_init
294 .long sys_inotify_add_watch 294 .long sys_inotify_add_watch
295 .long sys_inotify_rm_watch 295 .long sys_inotify_rm_watch
296 .long sys_migrate_pages
diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
index 9caeaa315cd7..a529f0cdce17 100644
--- a/arch/i386/kernel/time_hpet.c
+++ b/arch/i386/kernel/time_hpet.c
@@ -259,8 +259,6 @@ __setup("hpet=", hpet_setup);
259#include <linux/mc146818rtc.h> 259#include <linux/mc146818rtc.h>
260#include <linux/rtc.h> 260#include <linux/rtc.h>
261 261
262extern irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
263
264#define DEFAULT_RTC_INT_FREQ 64 262#define DEFAULT_RTC_INT_FREQ 64
265#define RTC_NUM_INTS 1 263#define RTC_NUM_INTS 1
266 264
diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
index 67932ad53082..57b047c27e46 100644
--- a/arch/ia64/Makefile
+++ b/arch/ia64/Makefile
@@ -37,10 +37,6 @@ $(error Sorry, you need a newer version of the assember, one that is built from
37 ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz) 37 ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz)
38endif 38endif
39 39
40ifneq ($(shell if [ $(GCC_VERSION) -lt 0300 ] ; then echo "bad"; fi ;),)
41$(error Sorry, your compiler is too old. GCC v2.96 is known to generate bad code.)
42endif
43
44ifeq ($(GCC_VERSION),0304) 40ifeq ($(GCC_VERSION),0304)
45 cflags-$(CONFIG_ITANIUM) += -mtune=merced 41 cflags-$(CONFIG_ITANIUM) += -mtune=merced
46 cflags-$(CONFIG_MCKINLEY) += -mtune=mckinley 42 cflags-$(CONFIG_MCKINLEY) += -mtune=mckinley
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index dc282710421a..9f8e8d558873 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -1761,21 +1761,15 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
1761 1761
1762 lock_kernel(); 1762 lock_kernel();
1763 if (request == PTRACE_TRACEME) { 1763 if (request == PTRACE_TRACEME) {
1764 ret = sys_ptrace(request, pid, addr, data); 1764 ret = ptrace_traceme();
1765 goto out; 1765 goto out;
1766 } 1766 }
1767 1767
1768 ret = -ESRCH; 1768 child = ptrace_get_task_struct(pid);
1769 read_lock(&tasklist_lock); 1769 if (IS_ERR(child)) {
1770 child = find_task_by_pid(pid); 1770 ret = PTR_ERR(child);
1771 if (child)
1772 get_task_struct(child);
1773 read_unlock(&tasklist_lock);
1774 if (!child)
1775 goto out; 1771 goto out;
1776 ret = -EPERM; 1772 }
1777 if (pid == 1) /* no messing around with init! */
1778 goto out_tsk;
1779 1773
1780 if (request == PTRACE_ATTACH) { 1774 if (request == PTRACE_ATTACH) {
1781 ret = sys_ptrace(request, pid, addr, data); 1775 ret = sys_ptrace(request, pid, addr, data);
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index a3aa45cbcfa0..c485a3b32ba8 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -247,6 +247,32 @@ typedef struct kern_memdesc {
247 247
248static kern_memdesc_t *kern_memmap; 248static kern_memdesc_t *kern_memmap;
249 249
250#define efi_md_size(md) (md->num_pages << EFI_PAGE_SHIFT)
251
252static inline u64
253kmd_end(kern_memdesc_t *kmd)
254{
255 return (kmd->start + (kmd->num_pages << EFI_PAGE_SHIFT));
256}
257
258static inline u64
259efi_md_end(efi_memory_desc_t *md)
260{
261 return (md->phys_addr + efi_md_size(md));
262}
263
264static inline int
265efi_wb(efi_memory_desc_t *md)
266{
267 return (md->attribute & EFI_MEMORY_WB);
268}
269
270static inline int
271efi_uc(efi_memory_desc_t *md)
272{
273 return (md->attribute & EFI_MEMORY_UC);
274}
275
250static void 276static void
251walk (efi_freemem_callback_t callback, void *arg, u64 attr) 277walk (efi_freemem_callback_t callback, void *arg, u64 attr)
252{ 278{
@@ -595,8 +621,8 @@ efi_get_iobase (void)
595 return 0; 621 return 0;
596} 622}
597 623
598u32 624static efi_memory_desc_t *
599efi_mem_type (unsigned long phys_addr) 625efi_memory_descriptor (unsigned long phys_addr)
600{ 626{
601 void *efi_map_start, *efi_map_end, *p; 627 void *efi_map_start, *efi_map_end, *p;
602 efi_memory_desc_t *md; 628 efi_memory_desc_t *md;
@@ -610,13 +636,13 @@ efi_mem_type (unsigned long phys_addr)
610 md = p; 636 md = p;
611 637
612 if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) 638 if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))
613 return md->type; 639 return md;
614 } 640 }
615 return 0; 641 return 0;
616} 642}
617 643
618u64 644static int
619efi_mem_attributes (unsigned long phys_addr) 645efi_memmap_has_mmio (void)
620{ 646{
621 void *efi_map_start, *efi_map_end, *p; 647 void *efi_map_start, *efi_map_end, *p;
622 efi_memory_desc_t *md; 648 efi_memory_desc_t *md;
@@ -629,36 +655,98 @@ efi_mem_attributes (unsigned long phys_addr)
629 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { 655 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
630 md = p; 656 md = p;
631 657
632 if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) 658 if (md->type == EFI_MEMORY_MAPPED_IO)
633 return md->attribute; 659 return 1;
634 } 660 }
635 return 0; 661 return 0;
636} 662}
663
664u32
665efi_mem_type (unsigned long phys_addr)
666{
667 efi_memory_desc_t *md = efi_memory_descriptor(phys_addr);
668
669 if (md)
670 return md->type;
671 return 0;
672}
673
674u64
675efi_mem_attributes (unsigned long phys_addr)
676{
677 efi_memory_desc_t *md = efi_memory_descriptor(phys_addr);
678
679 if (md)
680 return md->attribute;
681 return 0;
682}
637EXPORT_SYMBOL(efi_mem_attributes); 683EXPORT_SYMBOL(efi_mem_attributes);
638 684
685/*
686 * Determines whether the memory at phys_addr supports the desired
687 * attribute (WB, UC, etc). If this returns 1, the caller can safely
688 * access *size bytes at phys_addr with the specified attribute.
689 */
690static int
691efi_mem_attribute_range (unsigned long phys_addr, unsigned long *size, u64 attr)
692{
693 efi_memory_desc_t *md = efi_memory_descriptor(phys_addr);
694 unsigned long md_end;
695
696 if (!md || (md->attribute & attr) != attr)
697 return 0;
698
699 do {
700 md_end = efi_md_end(md);
701 if (phys_addr + *size <= md_end)
702 return 1;
703
704 md = efi_memory_descriptor(md_end);
705 if (!md || (md->attribute & attr) != attr) {
706 *size = md_end - phys_addr;
707 return 1;
708 }
709 } while (md);
710 return 0;
711}
712
713/*
714 * For /dev/mem, we only allow read & write system calls to access
715 * write-back memory, because read & write don't allow the user to
716 * control access size.
717 */
639int 718int
640valid_phys_addr_range (unsigned long phys_addr, unsigned long *size) 719valid_phys_addr_range (unsigned long phys_addr, unsigned long *size)
641{ 720{
642 void *efi_map_start, *efi_map_end, *p; 721 return efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_WB);
643 efi_memory_desc_t *md; 722}
644 u64 efi_desc_size;
645 723
646 efi_map_start = __va(ia64_boot_param->efi_memmap); 724/*
647 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; 725 * We allow mmap of anything in the EFI memory map that supports
648 efi_desc_size = ia64_boot_param->efi_memdesc_size; 726 * either write-back or uncacheable access. For uncacheable regions,
727 * the supported access sizes are system-dependent, and the user is
728 * responsible for using the correct size.
729 *
730 * Note that this doesn't currently allow access to hot-added memory,
731 * because that doesn't appear in the boot-time EFI memory map.
732 */
733int
734valid_mmap_phys_addr_range (unsigned long phys_addr, unsigned long *size)
735{
736 if (efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_WB))
737 return 1;
649 738
650 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { 739 if (efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_UC))
651 md = p; 740 return 1;
652 741
653 if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) { 742 /*
654 if (!(md->attribute & EFI_MEMORY_WB)) 743 * Some firmware doesn't report MMIO regions in the EFI memory map.
655 return 0; 744 * The Intel BigSur (a.k.a. HP i2000) has this problem. In this
745 * case, we can't use the EFI memory map to validate mmap requests.
746 */
747 if (!efi_memmap_has_mmio())
748 return 1;
656 749
657 if (*size > md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - phys_addr)
658 *size = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - phys_addr;
659 return 1;
660 }
661 }
662 return 0; 750 return 0;
663} 751}
664 752
@@ -707,32 +795,6 @@ efi_uart_console_only(void)
707 return 0; 795 return 0;
708} 796}
709 797
710#define efi_md_size(md) (md->num_pages << EFI_PAGE_SHIFT)
711
712static inline u64
713kmd_end(kern_memdesc_t *kmd)
714{
715 return (kmd->start + (kmd->num_pages << EFI_PAGE_SHIFT));
716}
717
718static inline u64
719efi_md_end(efi_memory_desc_t *md)
720{
721 return (md->phys_addr + efi_md_size(md));
722}
723
724static inline int
725efi_wb(efi_memory_desc_t *md)
726{
727 return (md->attribute & EFI_MEMORY_WB);
728}
729
730static inline int
731efi_uc(efi_memory_desc_t *md)
732{
733 return (md->attribute & EFI_MEMORY_UC);
734}
735
736/* 798/*
737 * Look for the first granule aligned memory descriptor memory 799 * Look for the first granule aligned memory descriptor memory
738 * that is big enough to hold EFI memory map. Make sure this 800 * that is big enough to hold EFI memory map. Make sure this
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 0741b066b98f..7a6ffd613789 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1600,5 +1600,6 @@ sys_call_table:
1600 data8 sys_inotify_init 1600 data8 sys_inotify_init
1601 data8 sys_inotify_add_watch 1601 data8 sys_inotify_add_watch
1602 data8 sys_inotify_rm_watch 1602 data8 sys_inotify_rm_watch
1603 data8 sys_migrate_pages // 1280
1603 1604
1604 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls 1605 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
index bfe65b2e8621..fbc7ea35dd57 100644
--- a/arch/ia64/kernel/head.S
+++ b/arch/ia64/kernel/head.S
@@ -1060,7 +1060,7 @@ SET_REG(b5);
1060 * the clobber lists for spin_lock() in include/asm-ia64/spinlock.h. 1060 * the clobber lists for spin_lock() in include/asm-ia64/spinlock.h.
1061 */ 1061 */
1062 1062
1063#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) 1063#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
1064 1064
1065GLOBAL_ENTRY(ia64_spinlock_contention_pre3_4) 1065GLOBAL_ENTRY(ia64_spinlock_contention_pre3_4)
1066 .prologue 1066 .prologue
diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
index 5db9d3bcbbcb..e72de580ebbf 100644
--- a/arch/ia64/kernel/ia64_ksyms.c
+++ b/arch/ia64/kernel/ia64_ksyms.c
@@ -103,7 +103,7 @@ EXPORT_SYMBOL(unw_init_running);
103 103
104#ifdef ASM_SUPPORTED 104#ifdef ASM_SUPPORTED
105# ifdef CONFIG_SMP 105# ifdef CONFIG_SMP
106# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) 106# if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
107/* 107/*
108 * This is not a normal routine and we don't want a function descriptor for it, so we use 108 * This is not a normal routine and we don't want a function descriptor for it, so we use
109 * a fake declaration here. 109 * a fake declaration here.
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 4b19d0410632..8d88eeea02d1 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -1422,14 +1422,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
1422 lock_kernel(); 1422 lock_kernel();
1423 ret = -EPERM; 1423 ret = -EPERM;
1424 if (request == PTRACE_TRACEME) { 1424 if (request == PTRACE_TRACEME) {
1425 /* are we already being traced? */ 1425 ret = ptrace_traceme();
1426 if (current->ptrace & PT_PTRACED)
1427 goto out;
1428 ret = security_ptrace(current->parent, current);
1429 if (ret)
1430 goto out;
1431 current->ptrace |= PT_PTRACED;
1432 ret = 0;
1433 goto out; 1426 goto out;
1434 } 1427 }
1435 1428
diff --git a/arch/ia64/oprofile/backtrace.c b/arch/ia64/oprofile/backtrace.c
index b7dabbfb0d61..adb01566bd57 100644
--- a/arch/ia64/oprofile/backtrace.c
+++ b/arch/ia64/oprofile/backtrace.c
@@ -32,7 +32,7 @@ typedef struct
32 u64 *prev_pfs_loc; /* state for WAR for old spinlock ool code */ 32 u64 *prev_pfs_loc; /* state for WAR for old spinlock ool code */
33} ia64_backtrace_t; 33} ia64_backtrace_t;
34 34
35#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) 35#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
36/* 36/*
37 * Returns non-zero if the PC is in the spinlock contention out-of-line code 37 * Returns non-zero if the PC is in the spinlock contention out-of-line code
38 * with non-standard calling sequence (on older compilers). 38 * with non-standard calling sequence (on older compilers).
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
index cc4b571e5db7..3bf55d92933f 100644
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -50,6 +50,10 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
50 * Powermanagement idle function, if any.. 50 * Powermanagement idle function, if any..
51 */ 51 */
52void (*pm_idle)(void) = NULL; 52void (*pm_idle)(void) = NULL;
53EXPORT_SYMBOL(pm_idle);
54
55void (*pm_power_off)(void) = NULL;
56EXPORT_SYMBOL(pm_power_off);
53 57
54void disable_hlt(void) 58void disable_hlt(void)
55{ 59{
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index 078d2a0e71c2..9b75caaf5cec 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -762,28 +762,16 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
762 int ret; 762 int ret;
763 763
764 lock_kernel(); 764 lock_kernel();
765 ret = -EPERM;
766 if (request == PTRACE_TRACEME) { 765 if (request == PTRACE_TRACEME) {
767 /* are we already being traced? */ 766 ret = ptrace_traceme();
768 if (current->ptrace & PT_PTRACED)
769 goto out;
770 /* set the ptrace bit in the process flags. */
771 current->ptrace |= PT_PTRACED;
772 ret = 0;
773 goto out; 767 goto out;
774 } 768 }
775 ret = -ESRCH;
776 read_lock(&tasklist_lock);
777 child = find_task_by_pid(pid);
778 if (child)
779 get_task_struct(child);
780 read_unlock(&tasklist_lock);
781 if (!child)
782 goto out;
783 769
784 ret = -EPERM; 770 child = ptrace_get_task_struct(pid);
785 if (pid == 1) /* you may not mess with init */ 771 if (IS_ERR(child)) {
772 ret = PTR_ERR(child);
786 goto out; 773 goto out;
774 }
787 775
788 if (request == PTRACE_ATTACH) { 776 if (request == PTRACE_ATTACH) {
789 ret = ptrace_attach(child); 777 ret = ptrace_attach(child);
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 1dd5d18b2201..96b919828053 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -10,10 +10,6 @@ config MMU
10 bool 10 bool
11 default y 11 default y
12 12
13config UID16
14 bool
15 default y
16
17config RWSEM_GENERIC_SPINLOCK 13config RWSEM_GENERIC_SPINLOCK
18 bool 14 bool
19 default y 15 default y
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index b96498120fe9..e2a6e8648960 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -17,10 +17,6 @@ config FPU
17 bool 17 bool
18 default n 18 default n
19 19
20config UID16
21 bool
22 default y
23
24config RWSEM_GENERIC_SPINLOCK 20config RWSEM_GENERIC_SPINLOCK
25 bool 21 bool
26 default y 22 default y
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 9a9b04972132..7e55457a491f 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -57,30 +57,16 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
57 (unsigned long) data); 57 (unsigned long) data);
58#endif 58#endif
59 lock_kernel(); 59 lock_kernel();
60 ret = -EPERM;
61 if (request == PTRACE_TRACEME) { 60 if (request == PTRACE_TRACEME) {
62 /* are we already being traced? */ 61 ret = ptrace_traceme();
63 if (current->ptrace & PT_PTRACED)
64 goto out;
65 if ((ret = security_ptrace(current->parent, current)))
66 goto out;
67 /* set the ptrace bit in the process flags. */
68 current->ptrace |= PT_PTRACED;
69 ret = 0;
70 goto out; 62 goto out;
71 } 63 }
72 ret = -ESRCH;
73 read_lock(&tasklist_lock);
74 child = find_task_by_pid(pid);
75 if (child)
76 get_task_struct(child);
77 read_unlock(&tasklist_lock);
78 if (!child)
79 goto out;
80 64
81 ret = -EPERM; 65 child = ptrace_get_task_struct(pid);
82 if (pid == 1) /* you may not mess with init */ 66 if (IS_ERR(child)) {
83 goto out_tsk; 67 ret = PTR_ERR(child);
68 goto out;
69 }
84 70
85 if (request == PTRACE_ATTACH) { 71 if (request == PTRACE_ATTACH) {
86 ret = ptrace_attach(child); 72 ret = ptrace_attach(child);
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 06be405be399..9c89eebc356f 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -1171,7 +1171,8 @@ static int __init vpe_module_init(void)
1171 return -ENODEV; 1171 return -ENODEV;
1172 } 1172 }
1173 1173
1174 if ((major = register_chrdev(0, module_name, &vpe_fops) < 0)) { 1174 major = register_chrdev(0, module_name, &vpe_fops);
1175 if (major < 0) {
1175 printk("VPE loader: unable to register character device\n"); 1176 printk("VPE loader: unable to register character device\n");
1176 return major; 1177 return major;
1177 } 1178 }
diff --git a/arch/mips/sgi-ip27/ip27-berr.c b/arch/mips/sgi-ip27/ip27-berr.c
index 07631a97670b..ce907eda221b 100644
--- a/arch/mips/sgi-ip27/ip27-berr.c
+++ b/arch/mips/sgi-ip27/ip27-berr.c
@@ -11,6 +11,7 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/signal.h> /* for SIGBUS */ 13#include <linux/signal.h> /* for SIGBUS */
14#include <linux/sched.h> /* schow_regs(), force_sig() */
14 15
15#include <asm/module.h> 16#include <asm/module.h>
16#include <asm/sn/addrs.h> 17#include <asm/sn/addrs.h>
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 874a283edb95..e77a06e9621e 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -19,9 +19,6 @@ config MMU
19config STACK_GROWSUP 19config STACK_GROWSUP
20 def_bool y 20 def_bool y
21 21
22config UID16
23 bool
24
25config RWSEM_GENERIC_SPINLOCK 22config RWSEM_GENERIC_SPINLOCK
26 def_bool y 23 def_bool y
27 24
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index db93dbc0e21a..28004f002ec9 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -26,9 +26,6 @@ config MMU
26 bool 26 bool
27 default y 27 default y
28 28
29config UID16
30 bool
31
32config GENERIC_HARDIRQS 29config GENERIC_HARDIRQS
33 bool 30 bool
34 default y 31 default y
@@ -50,7 +47,7 @@ config PPC
50 47
51config EARLY_PRINTK 48config EARLY_PRINTK
52 bool 49 bool
53 default y if PPC64 50 default y
54 51
55config COMPAT 52config COMPAT
56 bool 53 bool
@@ -300,6 +297,7 @@ config PPC_PMAC64
300 bool 297 bool
301 depends on PPC_PMAC && POWER4 298 depends on PPC_PMAC && POWER4
302 select U3_DART 299 select U3_DART
300 select MPIC_BROKEN_U3
303 select GENERIC_TBSYNC 301 select GENERIC_TBSYNC
304 default y 302 default y
305 303
@@ -328,9 +326,7 @@ config PPC_CELL
328 select MMIO_NVRAM 326 select MMIO_NVRAM
329 327
330config PPC_OF 328config PPC_OF
331 bool 329 def_bool y
332 depends on PPC_MULTIPLATFORM # for now
333 default y
334 330
335config XICS 331config XICS
336 depends on PPC_PSERIES 332 depends on PPC_PSERIES
@@ -379,11 +375,28 @@ config CELL_IIC
379 bool 375 bool
380 default y 376 default y
381 377
378config CRASH_DUMP
379 bool "kernel crash dumps (EXPERIMENTAL)"
380 depends on PPC_MULTIPLATFORM
381 depends on EXPERIMENTAL
382 help
383 Build a kernel suitable for use as a kdump capture kernel.
384 The kernel will be linked at a different address than normal, and
385 so can only be used for Kdump.
386
387 Don't change this unless you know what you are doing.
388
382config IBMVIO 389config IBMVIO
383 depends on PPC_PSERIES || PPC_ISERIES 390 depends on PPC_PSERIES || PPC_ISERIES
384 bool 391 bool
385 default y 392 default y
386 393
394config IBMEBUS
395 depends on PPC_PSERIES
396 bool "Support for GX bus based adapters"
397 help
398 Bus device driver for GX bus based adapters.
399
387config PPC_MPC106 400config PPC_MPC106
388 bool 401 bool
389 default n 402 default n
@@ -475,6 +488,7 @@ source arch/powerpc/platforms/embedded6xx/Kconfig
475source arch/powerpc/platforms/4xx/Kconfig 488source arch/powerpc/platforms/4xx/Kconfig
476source arch/powerpc/platforms/85xx/Kconfig 489source arch/powerpc/platforms/85xx/Kconfig
477source arch/powerpc/platforms/8xx/Kconfig 490source arch/powerpc/platforms/8xx/Kconfig
491source arch/powerpc/platforms/cell/Kconfig
478 492
479menu "Kernel options" 493menu "Kernel options"
480 494
@@ -578,11 +592,12 @@ config ARCH_SELECT_MEMORY_MODEL
578 depends on PPC64 592 depends on PPC64
579 593
580config ARCH_FLATMEM_ENABLE 594config ARCH_FLATMEM_ENABLE
581 def_bool y 595 def_bool y
582 depends on PPC64 && !NUMA 596 depends on (PPC64 && !NUMA) || PPC32
583 597
584config ARCH_SPARSEMEM_ENABLE 598config ARCH_SPARSEMEM_ENABLE
585 def_bool y 599 def_bool y
600 depends on PPC64
586 601
587config ARCH_SPARSEMEM_DEFAULT 602config ARCH_SPARSEMEM_DEFAULT
588 def_bool y 603 def_bool y
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index a13eb575f834..5f80e58e5cb3 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -151,7 +151,7 @@ CPPFLAGS_vmlinux.lds := -Upowerpc
151# All the instructions talk about "make bzImage". 151# All the instructions talk about "make bzImage".
152bzImage: zImage 152bzImage: zImage
153 153
154BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm 154BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage
155 155
156.PHONY: $(BOOT_TARGETS) 156.PHONY: $(BOOT_TARGETS)
157 157
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 9770f587af73..22726aefc8ea 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -143,6 +143,36 @@ $(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote
143 @cp -f $< $@ 143 @cp -f $< $@
144 $(call if_changed,addnote) 144 $(call if_changed,addnote)
145 145
146#-----------------------------------------------------------
147# build u-boot images
148#-----------------------------------------------------------
149quiet_cmd_mygzip = GZIP $@
150cmd_mygzip = gzip -f -9 < $< > $@.$$$$ && mv $@.$$$$ $@
151
152quiet_cmd_objbin = OBJCOPY $@
153 cmd_objbin = $(OBJCOPY) -O binary $< $@
154
155quiet_cmd_uimage = UIMAGE $@
156 cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \
157 -C gzip -a 00000000 -e 00000000 -n 'Linux-$(KERNELRELEASE)' \
158 -d $< $@
159
160MKIMAGE := $(srctree)/scripts/mkuboot.sh
161targets += uImage
162extra-y += vmlinux.bin vmlinux.gz
163
164$(obj)/vmlinux.bin: vmlinux FORCE
165 $(call if_changed,objbin)
166
167$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
168 $(call if_changed,mygzip)
169
170$(obj)/uImage: $(obj)/vmlinux.gz
171 $(Q)rm -f $@
172 $(call cmd,uimage)
173 @echo -n ' Image: $@ '
174 @if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi
175
146install: $(CONFIGURE) $(BOOTIMAGE) 176install: $(CONFIGURE) $(BOOTIMAGE)
147 sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)" 177 sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)"
148 178
diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig
new file mode 100644
index 000000000000..398203bd98eb
--- /dev/null
+++ b/arch/powerpc/configs/pmac32_defconfig
@@ -0,0 +1,1729 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.15-rc5
4# Tue Dec 13 17:24:05 2005
5#
6# CONFIG_PPC64 is not set
7CONFIG_PPC32=y
8CONFIG_PPC_MERGE=y
9CONFIG_MMU=y
10CONFIG_GENERIC_HARDIRQS=y
11CONFIG_RWSEM_XCHGADD_ALGORITHM=y
12CONFIG_GENERIC_CALIBRATE_DELAY=y
13CONFIG_PPC=y
14CONFIG_EARLY_PRINTK=y
15CONFIG_GENERIC_NVRAM=y
16CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
17CONFIG_ARCH_MAY_HAVE_PC_FDC=y
18
19#
20# Processor support
21#
22CONFIG_6xx=y
23# CONFIG_PPC_52xx is not set
24# CONFIG_PPC_82xx is not set
25# CONFIG_PPC_83xx is not set
26# CONFIG_40x is not set
27# CONFIG_44x is not set
28# CONFIG_8xx is not set
29# CONFIG_E200 is not set
30# CONFIG_E500 is not set
31CONFIG_PPC_FPU=y
32CONFIG_ALTIVEC=y
33CONFIG_PPC_STD_MMU=y
34CONFIG_PPC_STD_MMU_32=y
35# CONFIG_SMP is not set
36
37#
38# Code maturity level options
39#
40CONFIG_EXPERIMENTAL=y
41CONFIG_CLEAN_COMPILE=y
42CONFIG_BROKEN_ON_SMP=y
43CONFIG_INIT_ENV_ARG_LIMIT=32
44
45#
46# General setup
47#
48CONFIG_LOCALVERSION=""
49# CONFIG_LOCALVERSION_AUTO is not set
50CONFIG_SWAP=y
51CONFIG_SYSVIPC=y
52CONFIG_POSIX_MQUEUE=y
53# CONFIG_BSD_PROCESS_ACCT is not set
54CONFIG_SYSCTL=y
55# CONFIG_AUDIT is not set
56CONFIG_HOTPLUG=y
57CONFIG_KOBJECT_UEVENT=y
58CONFIG_IKCONFIG=y
59CONFIG_IKCONFIG_PROC=y
60CONFIG_INITRAMFS_SOURCE=""
61# CONFIG_EMBEDDED is not set
62CONFIG_KALLSYMS=y
63# CONFIG_KALLSYMS_ALL is not set
64# CONFIG_KALLSYMS_EXTRA_PASS is not set
65CONFIG_PRINTK=y
66CONFIG_BUG=y
67CONFIG_BASE_FULL=y
68CONFIG_FUTEX=y
69CONFIG_EPOLL=y
70CONFIG_SHMEM=y
71CONFIG_CC_ALIGN_FUNCTIONS=0
72CONFIG_CC_ALIGN_LABELS=0
73CONFIG_CC_ALIGN_LOOPS=0
74CONFIG_CC_ALIGN_JUMPS=0
75# CONFIG_TINY_SHMEM is not set
76CONFIG_BASE_SMALL=0
77
78#
79# Loadable module support
80#
81CONFIG_MODULES=y
82CONFIG_MODULE_UNLOAD=y
83CONFIG_MODULE_FORCE_UNLOAD=y
84CONFIG_OBSOLETE_MODPARM=y
85# CONFIG_MODVERSIONS is not set
86# CONFIG_MODULE_SRCVERSION_ALL is not set
87CONFIG_KMOD=y
88
89#
90# Block layer
91#
92CONFIG_LBD=y
93
94#
95# IO Schedulers
96#
97CONFIG_IOSCHED_NOOP=y
98CONFIG_IOSCHED_AS=y
99CONFIG_IOSCHED_DEADLINE=y
100CONFIG_IOSCHED_CFQ=y
101CONFIG_DEFAULT_AS=y
102# CONFIG_DEFAULT_DEADLINE is not set
103# CONFIG_DEFAULT_CFQ is not set
104# CONFIG_DEFAULT_NOOP is not set
105CONFIG_DEFAULT_IOSCHED="anticipatory"
106
107#
108# Platform support
109#
110CONFIG_PPC_MULTIPLATFORM=y
111# CONFIG_PPC_ISERIES is not set
112# CONFIG_EMBEDDED6xx is not set
113# CONFIG_APUS is not set
114# CONFIG_PPC_CHRP is not set
115CONFIG_PPC_PMAC=y
116CONFIG_PPC_OF=y
117CONFIG_MPIC=y
118# CONFIG_PPC_RTAS is not set
119# CONFIG_MMIO_NVRAM is not set
120# CONFIG_CRASH_DUMP is not set
121CONFIG_PPC_MPC106=y
122# CONFIG_GENERIC_TBSYNC is not set
123CONFIG_CPU_FREQ=y
124CONFIG_CPU_FREQ_TABLE=y
125# CONFIG_CPU_FREQ_DEBUG is not set
126CONFIG_CPU_FREQ_STAT=y
127# CONFIG_CPU_FREQ_STAT_DETAILS is not set
128CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
129# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
130CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
131CONFIG_CPU_FREQ_GOV_POWERSAVE=y
132CONFIG_CPU_FREQ_GOV_USERSPACE=y
133# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
134# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
135CONFIG_CPU_FREQ_PMAC=y
136CONFIG_PPC601_SYNC_FIX=y
137# CONFIG_TAU is not set
138# CONFIG_WANT_EARLY_SERIAL is not set
139
140#
141# Kernel options
142#
143# CONFIG_HIGHMEM is not set
144# CONFIG_HZ_100 is not set
145CONFIG_HZ_250=y
146# CONFIG_HZ_1000 is not set
147CONFIG_HZ=250
148CONFIG_PREEMPT_NONE=y
149# CONFIG_PREEMPT_VOLUNTARY is not set
150# CONFIG_PREEMPT is not set
151CONFIG_BINFMT_ELF=y
152CONFIG_BINFMT_MISC=m
153# CONFIG_KEXEC is not set
154CONFIG_ARCH_FLATMEM_ENABLE=y
155CONFIG_SELECT_MEMORY_MODEL=y
156CONFIG_FLATMEM_MANUAL=y
157# CONFIG_DISCONTIGMEM_MANUAL is not set
158# CONFIG_SPARSEMEM_MANUAL is not set
159CONFIG_FLATMEM=y
160CONFIG_FLAT_NODE_MEM_MAP=y
161# CONFIG_SPARSEMEM_STATIC is not set
162CONFIG_SPLIT_PTLOCK_CPUS=4
163CONFIG_PROC_DEVICETREE=y
164# CONFIG_CMDLINE_BOOL is not set
165CONFIG_PM=y
166# CONFIG_PM_LEGACY is not set
167CONFIG_PM_DEBUG=y
168CONFIG_SOFTWARE_SUSPEND=y
169CONFIG_PM_STD_PARTITION=""
170CONFIG_SECCOMP=y
171CONFIG_ISA_DMA_API=y
172
173#
174# Bus options
175#
176CONFIG_GENERIC_ISA_DMA=y
177# CONFIG_PPC_I8259 is not set
178CONFIG_PPC_INDIRECT_PCI=y
179CONFIG_PCI=y
180CONFIG_PCI_DOMAINS=y
181CONFIG_PCI_LEGACY_PROC=y
182# CONFIG_PCI_DEBUG is not set
183
184#
185# PCCARD (PCMCIA/CardBus) support
186#
187CONFIG_PCCARD=m
188# CONFIG_PCMCIA_DEBUG is not set
189CONFIG_PCMCIA=m
190CONFIG_PCMCIA_LOAD_CIS=y
191CONFIG_PCMCIA_IOCTL=y
192CONFIG_CARDBUS=y
193
194#
195# PC-card bridges
196#
197CONFIG_YENTA=m
198# CONFIG_PD6729 is not set
199# CONFIG_I82092 is not set
200CONFIG_PCCARD_NONSTATIC=m
201
202#
203# PCI Hotplug Support
204#
205# CONFIG_HOTPLUG_PCI is not set
206
207#
208# Advanced setup
209#
210# CONFIG_ADVANCED_OPTIONS is not set
211
212#
213# Default settings for advanced configuration options are used
214#
215CONFIG_HIGHMEM_START=0xfe000000
216CONFIG_LOWMEM_SIZE=0x30000000
217CONFIG_KERNEL_START=0xc0000000
218CONFIG_TASK_SIZE=0x80000000
219CONFIG_BOOT_LOAD=0x00800000
220
221#
222# Networking
223#
224CONFIG_NET=y
225
226#
227# Networking options
228#
229CONFIG_PACKET=y
230# CONFIG_PACKET_MMAP is not set
231CONFIG_UNIX=y
232# CONFIG_NET_KEY is not set
233CONFIG_INET=y
234CONFIG_IP_MULTICAST=y
235# CONFIG_IP_ADVANCED_ROUTER is not set
236CONFIG_IP_FIB_HASH=y
237# CONFIG_IP_PNP is not set
238# CONFIG_NET_IPIP is not set
239# CONFIG_NET_IPGRE is not set
240# CONFIG_IP_MROUTE is not set
241# CONFIG_ARPD is not set
242CONFIG_SYN_COOKIES=y
243# CONFIG_INET_AH is not set
244# CONFIG_INET_ESP is not set
245# CONFIG_INET_IPCOMP is not set
246# CONFIG_INET_TUNNEL is not set
247CONFIG_INET_DIAG=y
248CONFIG_INET_TCP_DIAG=y
249# CONFIG_TCP_CONG_ADVANCED is not set
250CONFIG_TCP_CONG_BIC=y
251
252#
253# IP: Virtual Server Configuration
254#
255# CONFIG_IP_VS is not set
256# CONFIG_IPV6 is not set
257CONFIG_NETFILTER=y
258# CONFIG_NETFILTER_DEBUG is not set
259
260#
261# Core Netfilter Configuration
262#
263# CONFIG_NETFILTER_NETLINK is not set
264
265#
266# IP: Netfilter Configuration
267#
268CONFIG_IP_NF_CONNTRACK=m
269# CONFIG_IP_NF_CT_ACCT is not set
270# CONFIG_IP_NF_CONNTRACK_MARK is not set
271# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
272# CONFIG_IP_NF_CT_PROTO_SCTP is not set
273CONFIG_IP_NF_FTP=m
274CONFIG_IP_NF_IRC=m
275CONFIG_IP_NF_NETBIOS_NS=m
276CONFIG_IP_NF_TFTP=m
277CONFIG_IP_NF_AMANDA=m
278CONFIG_IP_NF_PPTP=m
279# CONFIG_IP_NF_QUEUE is not set
280CONFIG_IP_NF_IPTABLES=m
281CONFIG_IP_NF_MATCH_LIMIT=m
282CONFIG_IP_NF_MATCH_IPRANGE=m
283CONFIG_IP_NF_MATCH_MAC=m
284CONFIG_IP_NF_MATCH_PKTTYPE=m
285CONFIG_IP_NF_MATCH_MARK=m
286CONFIG_IP_NF_MATCH_MULTIPORT=m
287CONFIG_IP_NF_MATCH_TOS=m
288CONFIG_IP_NF_MATCH_RECENT=m
289CONFIG_IP_NF_MATCH_ECN=m
290CONFIG_IP_NF_MATCH_DSCP=m
291CONFIG_IP_NF_MATCH_AH_ESP=m
292CONFIG_IP_NF_MATCH_LENGTH=m
293CONFIG_IP_NF_MATCH_TTL=m
294CONFIG_IP_NF_MATCH_TCPMSS=m
295CONFIG_IP_NF_MATCH_HELPER=m
296CONFIG_IP_NF_MATCH_STATE=m
297CONFIG_IP_NF_MATCH_CONNTRACK=m
298CONFIG_IP_NF_MATCH_OWNER=m
299# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
300# CONFIG_IP_NF_MATCH_REALM is not set
301# CONFIG_IP_NF_MATCH_SCTP is not set
302CONFIG_IP_NF_MATCH_DCCP=m
303# CONFIG_IP_NF_MATCH_COMMENT is not set
304# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
305CONFIG_IP_NF_MATCH_STRING=m
306CONFIG_IP_NF_FILTER=m
307CONFIG_IP_NF_TARGET_REJECT=m
308# CONFIG_IP_NF_TARGET_LOG is not set
309CONFIG_IP_NF_TARGET_ULOG=m
310CONFIG_IP_NF_TARGET_TCPMSS=m
311# CONFIG_IP_NF_TARGET_NFQUEUE is not set
312CONFIG_IP_NF_NAT=m
313CONFIG_IP_NF_NAT_NEEDED=y
314CONFIG_IP_NF_TARGET_MASQUERADE=m
315CONFIG_IP_NF_TARGET_REDIRECT=m
316CONFIG_IP_NF_TARGET_NETMAP=m
317CONFIG_IP_NF_TARGET_SAME=m
318CONFIG_IP_NF_NAT_SNMP_BASIC=m
319CONFIG_IP_NF_NAT_IRC=m
320CONFIG_IP_NF_NAT_FTP=m
321CONFIG_IP_NF_NAT_TFTP=m
322CONFIG_IP_NF_NAT_AMANDA=m
323CONFIG_IP_NF_NAT_PPTP=m
324# CONFIG_IP_NF_MANGLE is not set
325CONFIG_IP_NF_RAW=m
326CONFIG_IP_NF_TARGET_NOTRACK=m
327CONFIG_IP_NF_ARPTABLES=m
328CONFIG_IP_NF_ARPFILTER=m
329CONFIG_IP_NF_ARP_MANGLE=m
330
331#
332# DCCP Configuration (EXPERIMENTAL)
333#
334CONFIG_IP_DCCP=m
335CONFIG_INET_DCCP_DIAG=m
336
337#
338# DCCP CCIDs Configuration (EXPERIMENTAL)
339#
340CONFIG_IP_DCCP_CCID3=m
341CONFIG_IP_DCCP_TFRC_LIB=m
342
343#
344# DCCP Kernel Hacking
345#
346# CONFIG_IP_DCCP_DEBUG is not set
347# CONFIG_IP_DCCP_UNLOAD_HACK is not set
348
349#
350# SCTP Configuration (EXPERIMENTAL)
351#
352# CONFIG_IP_SCTP is not set
353# CONFIG_ATM is not set
354# CONFIG_BRIDGE is not set
355# CONFIG_VLAN_8021Q is not set
356# CONFIG_DECNET is not set
357# CONFIG_LLC2 is not set
358# CONFIG_IPX is not set
359# CONFIG_ATALK is not set
360# CONFIG_X25 is not set
361# CONFIG_LAPB is not set
362# CONFIG_NET_DIVERT is not set
363# CONFIG_ECONET is not set
364# CONFIG_WAN_ROUTER is not set
365
366#
367# QoS and/or fair queueing
368#
369# CONFIG_NET_SCHED is not set
370
371#
372# Network testing
373#
374# CONFIG_NET_PKTGEN is not set
375# CONFIG_HAMRADIO is not set
376CONFIG_IRDA=m
377
378#
379# IrDA protocols
380#
381CONFIG_IRLAN=m
382CONFIG_IRNET=m
383CONFIG_IRCOMM=m
384# CONFIG_IRDA_ULTRA is not set
385
386#
387# IrDA options
388#
389CONFIG_IRDA_CACHE_LAST_LSAP=y
390CONFIG_IRDA_FAST_RR=y
391# CONFIG_IRDA_DEBUG is not set
392
393#
394# Infrared-port device drivers
395#
396
397#
398# SIR device drivers
399#
400CONFIG_IRTTY_SIR=m
401
402#
403# Dongle support
404#
405# CONFIG_DONGLE is not set
406
407#
408# Old SIR device drivers
409#
410# CONFIG_IRPORT_SIR is not set
411
412#
413# Old Serial dongle support
414#
415
416#
417# FIR device drivers
418#
419# CONFIG_USB_IRDA is not set
420# CONFIG_SIGMATEL_FIR is not set
421# CONFIG_NSC_FIR is not set
422# CONFIG_WINBOND_FIR is not set
423# CONFIG_TOSHIBA_FIR is not set
424# CONFIG_SMC_IRCC_FIR is not set
425# CONFIG_ALI_FIR is not set
426# CONFIG_VLSI_FIR is not set
427# CONFIG_VIA_FIR is not set
428CONFIG_BT=m
429CONFIG_BT_L2CAP=m
430CONFIG_BT_SCO=m
431CONFIG_BT_RFCOMM=m
432CONFIG_BT_RFCOMM_TTY=y
433CONFIG_BT_BNEP=m
434CONFIG_BT_BNEP_MC_FILTER=y
435CONFIG_BT_BNEP_PROTO_FILTER=y
436CONFIG_BT_HIDP=m
437
438#
439# Bluetooth device drivers
440#
441CONFIG_BT_HCIUSB=m
442# CONFIG_BT_HCIUSB_SCO is not set
443# CONFIG_BT_HCIUART is not set
444CONFIG_BT_HCIBCM203X=m
445# CONFIG_BT_HCIBPA10X is not set
446CONFIG_BT_HCIBFUSB=m
447# CONFIG_BT_HCIDTL1 is not set
448# CONFIG_BT_HCIBT3C is not set
449# CONFIG_BT_HCIBLUECARD is not set
450# CONFIG_BT_HCIBTUART is not set
451# CONFIG_BT_HCIVHCI is not set
452CONFIG_IEEE80211=m
453# CONFIG_IEEE80211_DEBUG is not set
454CONFIG_IEEE80211_CRYPT_WEP=m
455CONFIG_IEEE80211_CRYPT_CCMP=m
456CONFIG_IEEE80211_CRYPT_TKIP=m
457
458#
459# Device Drivers
460#
461
462#
463# Generic Driver Options
464#
465# CONFIG_STANDALONE is not set
466CONFIG_PREVENT_FIRMWARE_BUILD=y
467CONFIG_FW_LOADER=m
468# CONFIG_DEBUG_DRIVER is not set
469
470#
471# Connector - unified userspace <-> kernelspace linker
472#
473CONFIG_CONNECTOR=y
474CONFIG_PROC_EVENTS=y
475
476#
477# Memory Technology Devices (MTD)
478#
479# CONFIG_MTD is not set
480
481#
482# Parallel port support
483#
484# CONFIG_PARPORT is not set
485
486#
487# Plug and Play support
488#
489
490#
491# Block devices
492#
493# CONFIG_BLK_DEV_FD is not set
494CONFIG_MAC_FLOPPY=y
495# CONFIG_BLK_CPQ_DA is not set
496# CONFIG_BLK_CPQ_CISS_DA is not set
497# CONFIG_BLK_DEV_DAC960 is not set
498# CONFIG_BLK_DEV_UMEM is not set
499# CONFIG_BLK_DEV_COW_COMMON is not set
500CONFIG_BLK_DEV_LOOP=y
501# CONFIG_BLK_DEV_CRYPTOLOOP is not set
502# CONFIG_BLK_DEV_NBD is not set
503# CONFIG_BLK_DEV_SX8 is not set
504CONFIG_BLK_DEV_UB=m
505CONFIG_BLK_DEV_RAM=y
506CONFIG_BLK_DEV_RAM_COUNT=16
507CONFIG_BLK_DEV_RAM_SIZE=4096
508CONFIG_BLK_DEV_INITRD=y
509# CONFIG_CDROM_PKTCDVD is not set
510# CONFIG_ATA_OVER_ETH is not set
511
512#
513# ATA/ATAPI/MFM/RLL support
514#
515CONFIG_IDE=y
516CONFIG_BLK_DEV_IDE=y
517
518#
519# Please see Documentation/ide.txt for help/info on IDE drives
520#
521# CONFIG_BLK_DEV_IDE_SATA is not set
522CONFIG_BLK_DEV_IDEDISK=y
523# CONFIG_IDEDISK_MULTI_MODE is not set
524CONFIG_BLK_DEV_IDECS=m
525CONFIG_BLK_DEV_IDECD=y
526# CONFIG_BLK_DEV_IDETAPE is not set
527CONFIG_BLK_DEV_IDEFLOPPY=y
528CONFIG_BLK_DEV_IDESCSI=y
529# CONFIG_IDE_TASK_IOCTL is not set
530
531#
532# IDE chipset support/bugfixes
533#
534# CONFIG_IDE_GENERIC is not set
535CONFIG_BLK_DEV_IDEPCI=y
536CONFIG_IDEPCI_SHARE_IRQ=y
537# CONFIG_BLK_DEV_OFFBOARD is not set
538CONFIG_BLK_DEV_GENERIC=y
539# CONFIG_BLK_DEV_OPTI621 is not set
540CONFIG_BLK_DEV_SL82C105=y
541CONFIG_BLK_DEV_IDEDMA_PCI=y
542# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
543CONFIG_IDEDMA_PCI_AUTO=y
544# CONFIG_IDEDMA_ONLYDISK is not set
545# CONFIG_BLK_DEV_AEC62XX is not set
546# CONFIG_BLK_DEV_ALI15X3 is not set
547# CONFIG_BLK_DEV_AMD74XX is not set
548# CONFIG_BLK_DEV_CMD64X is not set
549# CONFIG_BLK_DEV_TRIFLEX is not set
550# CONFIG_BLK_DEV_CY82C693 is not set
551# CONFIG_BLK_DEV_CS5520 is not set
552# CONFIG_BLK_DEV_CS5530 is not set
553# CONFIG_BLK_DEV_HPT34X is not set
554# CONFIG_BLK_DEV_HPT366 is not set
555# CONFIG_BLK_DEV_SC1200 is not set
556# CONFIG_BLK_DEV_PIIX is not set
557# CONFIG_BLK_DEV_IT821X is not set
558# CONFIG_BLK_DEV_NS87415 is not set
559# CONFIG_BLK_DEV_PDC202XX_OLD is not set
560CONFIG_BLK_DEV_PDC202XX_NEW=y
561# CONFIG_PDC202XX_FORCE is not set
562# CONFIG_BLK_DEV_SVWKS is not set
563# CONFIG_BLK_DEV_SIIMAGE is not set
564# CONFIG_BLK_DEV_SLC90E66 is not set
565# CONFIG_BLK_DEV_TRM290 is not set
566# CONFIG_BLK_DEV_VIA82CXXX is not set
567CONFIG_BLK_DEV_IDE_PMAC=y
568CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
569CONFIG_BLK_DEV_IDEDMA_PMAC=y
570CONFIG_BLK_DEV_IDE_PMAC_BLINK=y
571# CONFIG_IDE_ARM is not set
572CONFIG_BLK_DEV_IDEDMA=y
573# CONFIG_IDEDMA_IVB is not set
574CONFIG_IDEDMA_AUTO=y
575# CONFIG_BLK_DEV_HD is not set
576
577#
578# SCSI device support
579#
580# CONFIG_RAID_ATTRS is not set
581CONFIG_SCSI=y
582CONFIG_SCSI_PROC_FS=y
583
584#
585# SCSI support type (disk, tape, CD-ROM)
586#
587CONFIG_BLK_DEV_SD=y
588CONFIG_CHR_DEV_ST=y
589# CONFIG_CHR_DEV_OSST is not set
590CONFIG_BLK_DEV_SR=y
591CONFIG_BLK_DEV_SR_VENDOR=y
592CONFIG_CHR_DEV_SG=y
593# CONFIG_CHR_DEV_SCH is not set
594
595#
596# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
597#
598# CONFIG_SCSI_MULTI_LUN is not set
599CONFIG_SCSI_CONSTANTS=y
600# CONFIG_SCSI_LOGGING is not set
601
602#
603# SCSI Transport Attributes
604#
605CONFIG_SCSI_SPI_ATTRS=y
606# CONFIG_SCSI_FC_ATTRS is not set
607# CONFIG_SCSI_ISCSI_ATTRS is not set
608# CONFIG_SCSI_SAS_ATTRS is not set
609
610#
611# SCSI low-level drivers
612#
613# CONFIG_ISCSI_TCP is not set
614# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
615# CONFIG_SCSI_3W_9XXX is not set
616# CONFIG_SCSI_ACARD is not set
617# CONFIG_SCSI_AACRAID is not set
618CONFIG_SCSI_AIC7XXX=m
619CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
620CONFIG_AIC7XXX_RESET_DELAY_MS=15000
621CONFIG_AIC7XXX_DEBUG_ENABLE=y
622CONFIG_AIC7XXX_DEBUG_MASK=0
623CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
624CONFIG_SCSI_AIC7XXX_OLD=m
625# CONFIG_SCSI_AIC79XX is not set
626# CONFIG_SCSI_DPT_I2O is not set
627# CONFIG_MEGARAID_NEWGEN is not set
628# CONFIG_MEGARAID_LEGACY is not set
629# CONFIG_MEGARAID_SAS is not set
630# CONFIG_SCSI_SATA is not set
631# CONFIG_SCSI_BUSLOGIC is not set
632# CONFIG_SCSI_DMX3191D is not set
633# CONFIG_SCSI_EATA is not set
634# CONFIG_SCSI_FUTURE_DOMAIN is not set
635# CONFIG_SCSI_GDTH is not set
636# CONFIG_SCSI_IPS is not set
637# CONFIG_SCSI_INITIO is not set
638# CONFIG_SCSI_INIA100 is not set
639CONFIG_SCSI_SYM53C8XX_2=y
640CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
641CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
642CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
643# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
644# CONFIG_SCSI_IPR is not set
645# CONFIG_SCSI_QLOGIC_FC is not set
646# CONFIG_SCSI_QLOGIC_1280 is not set
647CONFIG_SCSI_QLA2XXX=y
648# CONFIG_SCSI_QLA21XX is not set
649# CONFIG_SCSI_QLA22XX is not set
650# CONFIG_SCSI_QLA2300 is not set
651# CONFIG_SCSI_QLA2322 is not set
652# CONFIG_SCSI_QLA6312 is not set
653# CONFIG_SCSI_QLA24XX is not set
654# CONFIG_SCSI_LPFC is not set
655# CONFIG_SCSI_DC395x is not set
656# CONFIG_SCSI_DC390T is not set
657# CONFIG_SCSI_NSP32 is not set
658# CONFIG_SCSI_DEBUG is not set
659CONFIG_SCSI_MESH=y
660CONFIG_SCSI_MESH_SYNC_RATE=5
661CONFIG_SCSI_MESH_RESET_DELAY_MS=1000
662CONFIG_SCSI_MAC53C94=y
663
664#
665# PCMCIA SCSI adapter support
666#
667# CONFIG_PCMCIA_AHA152X is not set
668# CONFIG_PCMCIA_FDOMAIN is not set
669# CONFIG_PCMCIA_NINJA_SCSI is not set
670# CONFIG_PCMCIA_QLOGIC is not set
671# CONFIG_PCMCIA_SYM53C500 is not set
672
673#
674# Multi-device support (RAID and LVM)
675#
676CONFIG_MD=y
677CONFIG_BLK_DEV_MD=m
678CONFIG_MD_LINEAR=m
679CONFIG_MD_RAID0=m
680CONFIG_MD_RAID1=m
681# CONFIG_MD_RAID10 is not set
682CONFIG_MD_RAID5=m
683CONFIG_MD_RAID6=m
684CONFIG_MD_MULTIPATH=m
685CONFIG_MD_FAULTY=m
686CONFIG_BLK_DEV_DM=m
687CONFIG_DM_CRYPT=m
688# CONFIG_DM_SNAPSHOT is not set
689# CONFIG_DM_MIRROR is not set
690# CONFIG_DM_ZERO is not set
691# CONFIG_DM_MULTIPATH is not set
692
693#
694# Fusion MPT device support
695#
696# CONFIG_FUSION is not set
697# CONFIG_FUSION_SPI is not set
698# CONFIG_FUSION_FC is not set
699# CONFIG_FUSION_SAS is not set
700
701#
702# IEEE 1394 (FireWire) support
703#
704CONFIG_IEEE1394=m
705
706#
707# Subsystem Options
708#
709# CONFIG_IEEE1394_VERBOSEDEBUG is not set
710# CONFIG_IEEE1394_OUI_DB is not set
711CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
712CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
713# CONFIG_IEEE1394_EXPORT_FULL_API is not set
714
715#
716# Device Drivers
717#
718# CONFIG_IEEE1394_PCILYNX is not set
719CONFIG_IEEE1394_OHCI1394=m
720
721#
722# Protocol Drivers
723#
724CONFIG_IEEE1394_VIDEO1394=m
725CONFIG_IEEE1394_SBP2=m
726# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
727CONFIG_IEEE1394_ETH1394=m
728CONFIG_IEEE1394_DV1394=m
729CONFIG_IEEE1394_RAWIO=m
730# CONFIG_IEEE1394_CMP is not set
731
732#
733# I2O device support
734#
735# CONFIG_I2O is not set
736
737#
738# Macintosh device drivers
739#
740CONFIG_ADB=y
741CONFIG_ADB_CUDA=y
742CONFIG_ADB_PMU=y
743CONFIG_PMAC_APM_EMU=y
744CONFIG_PMAC_MEDIABAY=y
745CONFIG_PMAC_BACKLIGHT=y
746CONFIG_INPUT_ADBHID=y
747CONFIG_MAC_EMUMOUSEBTN=y
748CONFIG_THERM_WINDTUNNEL=m
749CONFIG_THERM_ADT746X=m
750# CONFIG_WINDFARM is not set
751# CONFIG_ANSLCD is not set
752
753#
754# Network device support
755#
756CONFIG_NETDEVICES=y
757# CONFIG_DUMMY is not set
758# CONFIG_BONDING is not set
759# CONFIG_EQUALIZER is not set
760# CONFIG_TUN is not set
761
762#
763# ARCnet devices
764#
765# CONFIG_ARCNET is not set
766
767#
768# PHY device support
769#
770# CONFIG_PHYLIB is not set
771
772#
773# Ethernet (10 or 100Mbit)
774#
775CONFIG_NET_ETHERNET=y
776CONFIG_MII=y
777CONFIG_MACE=y
778# CONFIG_MACE_AAUI_PORT is not set
779CONFIG_BMAC=y
780# CONFIG_HAPPYMEAL is not set
781CONFIG_SUNGEM=y
782# CONFIG_CASSINI is not set
783# CONFIG_NET_VENDOR_3COM is not set
784
785#
786# Tulip family network device support
787#
788# CONFIG_NET_TULIP is not set
789# CONFIG_HP100 is not set
790CONFIG_NET_PCI=y
791CONFIG_PCNET32=y
792# CONFIG_AMD8111_ETH is not set
793# CONFIG_ADAPTEC_STARFIRE is not set
794# CONFIG_B44 is not set
795# CONFIG_FORCEDETH is not set
796# CONFIG_DGRS is not set
797# CONFIG_EEPRO100 is not set
798# CONFIG_E100 is not set
799# CONFIG_FEALNX is not set
800# CONFIG_NATSEMI is not set
801# CONFIG_NE2K_PCI is not set
802# CONFIG_8139CP is not set
803# CONFIG_8139TOO is not set
804# CONFIG_SIS900 is not set
805# CONFIG_EPIC100 is not set
806# CONFIG_SUNDANCE is not set
807# CONFIG_TLAN is not set
808# CONFIG_VIA_RHINE is not set
809
810#
811# Ethernet (1000 Mbit)
812#
813# CONFIG_ACENIC is not set
814# CONFIG_DL2K is not set
815# CONFIG_E1000 is not set
816# CONFIG_NS83820 is not set
817# CONFIG_HAMACHI is not set
818# CONFIG_YELLOWFIN is not set
819# CONFIG_R8169 is not set
820# CONFIG_SIS190 is not set
821# CONFIG_SKGE is not set
822# CONFIG_SK98LIN is not set
823# CONFIG_VIA_VELOCITY is not set
824# CONFIG_TIGON3 is not set
825# CONFIG_BNX2 is not set
826# CONFIG_MV643XX_ETH is not set
827
828#
829# Ethernet (10000 Mbit)
830#
831# CONFIG_CHELSIO_T1 is not set
832# CONFIG_IXGB is not set
833# CONFIG_S2IO is not set
834
835#
836# Token Ring devices
837#
838# CONFIG_TR is not set
839
840#
841# Wireless LAN (non-hamradio)
842#
843CONFIG_NET_RADIO=y
844
845#
846# Obsolete Wireless cards support (pre-802.11)
847#
848# CONFIG_STRIP is not set
849# CONFIG_PCMCIA_WAVELAN is not set
850# CONFIG_PCMCIA_NETWAVE is not set
851
852#
853# Wireless 802.11 Frequency Hopping cards support
854#
855# CONFIG_PCMCIA_RAYCS is not set
856
857#
858# Wireless 802.11b ISA/PCI cards support
859#
860# CONFIG_IPW2100 is not set
861# CONFIG_IPW2200 is not set
862# CONFIG_AIRO is not set
863CONFIG_HERMES=m
864CONFIG_APPLE_AIRPORT=m
865# CONFIG_PLX_HERMES is not set
866# CONFIG_TMD_HERMES is not set
867# CONFIG_NORTEL_HERMES is not set
868# CONFIG_PCI_HERMES is not set
869# CONFIG_ATMEL is not set
870
871#
872# Wireless 802.11b Pcmcia/Cardbus cards support
873#
874# CONFIG_PCMCIA_HERMES is not set
875# CONFIG_PCMCIA_SPECTRUM is not set
876# CONFIG_AIRO_CS is not set
877# CONFIG_PCMCIA_WL3501 is not set
878
879#
880# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
881#
882CONFIG_PRISM54=m
883# CONFIG_HOSTAP is not set
884CONFIG_NET_WIRELESS=y
885
886#
887# PCMCIA network device support
888#
889# CONFIG_NET_PCMCIA is not set
890
891#
892# Wan interfaces
893#
894# CONFIG_WAN is not set
895# CONFIG_FDDI is not set
896# CONFIG_HIPPI is not set
897CONFIG_PPP=y
898CONFIG_PPP_MULTILINK=y
899# CONFIG_PPP_FILTER is not set
900CONFIG_PPP_ASYNC=y
901CONFIG_PPP_SYNC_TTY=m
902CONFIG_PPP_DEFLATE=y
903CONFIG_PPP_BSDCOMP=m
904# CONFIG_PPP_MPPE is not set
905# CONFIG_PPPOE is not set
906# CONFIG_SLIP is not set
907# CONFIG_NET_FC is not set
908# CONFIG_SHAPER is not set
909# CONFIG_NETCONSOLE is not set
910# CONFIG_NETPOLL is not set
911# CONFIG_NET_POLL_CONTROLLER is not set
912
913#
914# ISDN subsystem
915#
916# CONFIG_ISDN is not set
917
918#
919# Telephony Support
920#
921# CONFIG_PHONE is not set
922
923#
924# Input device support
925#
926CONFIG_INPUT=y
927
928#
929# Userland interfaces
930#
931CONFIG_INPUT_MOUSEDEV=y
932CONFIG_INPUT_MOUSEDEV_PSAUX=y
933CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
934CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
935# CONFIG_INPUT_JOYDEV is not set
936# CONFIG_INPUT_TSDEV is not set
937CONFIG_INPUT_EVDEV=y
938# CONFIG_INPUT_EVBUG is not set
939
940#
941# Input Device Drivers
942#
943CONFIG_INPUT_KEYBOARD=y
944# CONFIG_KEYBOARD_ATKBD is not set
945# CONFIG_KEYBOARD_SUNKBD is not set
946# CONFIG_KEYBOARD_LKKBD is not set
947# CONFIG_KEYBOARD_XTKBD is not set
948# CONFIG_KEYBOARD_NEWTON is not set
949CONFIG_INPUT_MOUSE=y
950# CONFIG_MOUSE_PS2 is not set
951# CONFIG_MOUSE_SERIAL is not set
952# CONFIG_MOUSE_VSXXXAA is not set
953# CONFIG_INPUT_JOYSTICK is not set
954# CONFIG_INPUT_TOUCHSCREEN is not set
955# CONFIG_INPUT_MISC is not set
956
957#
958# Hardware I/O ports
959#
960CONFIG_SERIO=y
961# CONFIG_SERIO_I8042 is not set
962# CONFIG_SERIO_SERPORT is not set
963# CONFIG_SERIO_PCIPS2 is not set
964# CONFIG_SERIO_RAW is not set
965# CONFIG_GAMEPORT is not set
966
967#
968# Character devices
969#
970CONFIG_VT=y
971CONFIG_VT_CONSOLE=y
972CONFIG_HW_CONSOLE=y
973# CONFIG_SERIAL_NONSTANDARD is not set
974
975#
976# Serial drivers
977#
978CONFIG_SERIAL_8250=m
979# CONFIG_SERIAL_8250_CS is not set
980CONFIG_SERIAL_8250_NR_UARTS=4
981# CONFIG_SERIAL_8250_EXTENDED is not set
982
983#
984# Non-8250 serial port support
985#
986CONFIG_SERIAL_CORE=m
987# CONFIG_SERIAL_PMACZILOG is not set
988# CONFIG_SERIAL_JSM is not set
989CONFIG_UNIX98_PTYS=y
990CONFIG_LEGACY_PTYS=y
991CONFIG_LEGACY_PTY_COUNT=256
992
993#
994# IPMI
995#
996# CONFIG_IPMI_HANDLER is not set
997
998#
999# Watchdog Cards
1000#
1001# CONFIG_WATCHDOG is not set
1002CONFIG_NVRAM=y
1003CONFIG_GEN_RTC=y
1004# CONFIG_GEN_RTC_X is not set
1005# CONFIG_DTLK is not set
1006# CONFIG_R3964 is not set
1007# CONFIG_APPLICOM is not set
1008
1009#
1010# Ftape, the floppy tape device driver
1011#
1012CONFIG_AGP=m
1013CONFIG_AGP_UNINORTH=m
1014CONFIG_DRM=m
1015# CONFIG_DRM_TDFX is not set
1016CONFIG_DRM_R128=m
1017CONFIG_DRM_RADEON=m
1018# CONFIG_DRM_MGA is not set
1019# CONFIG_DRM_SIS is not set
1020# CONFIG_DRM_VIA is not set
1021# CONFIG_DRM_SAVAGE is not set
1022
1023#
1024# PCMCIA character devices
1025#
1026# CONFIG_SYNCLINK_CS is not set
1027# CONFIG_CARDMAN_4000 is not set
1028# CONFIG_CARDMAN_4040 is not set
1029# CONFIG_RAW_DRIVER is not set
1030
1031#
1032# TPM devices
1033#
1034# CONFIG_TCG_TPM is not set
1035# CONFIG_TELCLOCK is not set
1036
1037#
1038# I2C support
1039#
1040CONFIG_I2C=y
1041CONFIG_I2C_CHARDEV=m
1042
1043#
1044# I2C Algorithms
1045#
1046CONFIG_I2C_ALGOBIT=y
1047# CONFIG_I2C_ALGOPCF is not set
1048# CONFIG_I2C_ALGOPCA is not set
1049
1050#
1051# I2C Hardware Bus support
1052#
1053# CONFIG_I2C_ALI1535 is not set
1054# CONFIG_I2C_ALI1563 is not set
1055# CONFIG_I2C_ALI15X3 is not set
1056# CONFIG_I2C_AMD756 is not set
1057# CONFIG_I2C_AMD8111 is not set
1058# CONFIG_I2C_I801 is not set
1059# CONFIG_I2C_I810 is not set
1060# CONFIG_I2C_PIIX4 is not set
1061CONFIG_I2C_KEYWEST=m
1062# CONFIG_I2C_MPC is not set
1063# CONFIG_I2C_NFORCE2 is not set
1064# CONFIG_I2C_PARPORT_LIGHT is not set
1065# CONFIG_I2C_PROSAVAGE is not set
1066# CONFIG_I2C_SAVAGE4 is not set
1067# CONFIG_SCx200_ACB is not set
1068# CONFIG_I2C_SIS5595 is not set
1069# CONFIG_I2C_SIS630 is not set
1070# CONFIG_I2C_SIS96X is not set
1071# CONFIG_I2C_STUB is not set
1072# CONFIG_I2C_VIA is not set
1073# CONFIG_I2C_VIAPRO is not set
1074# CONFIG_I2C_VOODOO3 is not set
1075# CONFIG_I2C_PCA_ISA is not set
1076
1077#
1078# Miscellaneous I2C Chip support
1079#
1080# CONFIG_SENSORS_DS1337 is not set
1081# CONFIG_SENSORS_DS1374 is not set
1082# CONFIG_SENSORS_EEPROM is not set
1083# CONFIG_SENSORS_PCF8574 is not set
1084# CONFIG_SENSORS_PCA9539 is not set
1085# CONFIG_SENSORS_PCF8591 is not set
1086# CONFIG_SENSORS_RTC8564 is not set
1087# CONFIG_SENSORS_M41T00 is not set
1088# CONFIG_SENSORS_MAX6875 is not set
1089# CONFIG_RTC_X1205_I2C is not set
1090# CONFIG_I2C_DEBUG_CORE is not set
1091# CONFIG_I2C_DEBUG_ALGO is not set
1092# CONFIG_I2C_DEBUG_BUS is not set
1093# CONFIG_I2C_DEBUG_CHIP is not set
1094
1095#
1096# Dallas's 1-wire bus
1097#
1098# CONFIG_W1 is not set
1099
1100#
1101# Hardware Monitoring support
1102#
1103# CONFIG_HWMON is not set
1104# CONFIG_HWMON_VID is not set
1105
1106#
1107# Misc devices
1108#
1109
1110#
1111# Multimedia Capabilities Port drivers
1112#
1113
1114#
1115# Multimedia devices
1116#
1117# CONFIG_VIDEO_DEV is not set
1118
1119#
1120# Digital Video Broadcasting Devices
1121#
1122# CONFIG_DVB is not set
1123
1124#
1125# Graphics support
1126#
1127CONFIG_FB=y
1128CONFIG_FB_CFB_FILLRECT=y
1129CONFIG_FB_CFB_COPYAREA=y
1130CONFIG_FB_CFB_IMAGEBLIT=y
1131CONFIG_FB_MACMODES=y
1132CONFIG_FB_MODE_HELPERS=y
1133CONFIG_FB_TILEBLITTING=y
1134# CONFIG_FB_CIRRUS is not set
1135# CONFIG_FB_PM2 is not set
1136# CONFIG_FB_CYBER2000 is not set
1137CONFIG_FB_OF=y
1138CONFIG_FB_CONTROL=y
1139CONFIG_FB_PLATINUM=y
1140CONFIG_FB_VALKYRIE=y
1141CONFIG_FB_CT65550=y
1142# CONFIG_FB_ASILIANT is not set
1143CONFIG_FB_IMSTT=y
1144# CONFIG_FB_VGA16 is not set
1145# CONFIG_FB_S1D13XXX is not set
1146CONFIG_FB_NVIDIA=y
1147CONFIG_FB_NVIDIA_I2C=y
1148# CONFIG_FB_RIVA is not set
1149CONFIG_FB_MATROX=y
1150CONFIG_FB_MATROX_MILLENIUM=y
1151CONFIG_FB_MATROX_MYSTIQUE=y
1152# CONFIG_FB_MATROX_G is not set
1153# CONFIG_FB_MATROX_I2C is not set
1154# CONFIG_FB_MATROX_MULTIHEAD is not set
1155# CONFIG_FB_RADEON_OLD is not set
1156CONFIG_FB_RADEON=y
1157CONFIG_FB_RADEON_I2C=y
1158# CONFIG_FB_RADEON_DEBUG is not set
1159CONFIG_FB_ATY128=y
1160CONFIG_FB_ATY=y
1161CONFIG_FB_ATY_CT=y
1162# CONFIG_FB_ATY_GENERIC_LCD is not set
1163# CONFIG_FB_ATY_XL_INIT is not set
1164CONFIG_FB_ATY_GX=y
1165# CONFIG_FB_SAVAGE is not set
1166# CONFIG_FB_SIS is not set
1167# CONFIG_FB_NEOMAGIC is not set
1168# CONFIG_FB_KYRO is not set
1169CONFIG_FB_3DFX=y
1170# CONFIG_FB_3DFX_ACCEL is not set
1171# CONFIG_FB_VOODOO1 is not set
1172# CONFIG_FB_CYBLA is not set
1173# CONFIG_FB_TRIDENT is not set
1174# CONFIG_FB_VIRTUAL is not set
1175
1176#
1177# Console display driver support
1178#
1179# CONFIG_VGA_CONSOLE is not set
1180CONFIG_DUMMY_CONSOLE=y
1181CONFIG_FRAMEBUFFER_CONSOLE=y
1182# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1183# CONFIG_FONTS is not set
1184CONFIG_FONT_8x8=y
1185CONFIG_FONT_8x16=y
1186
1187#
1188# Logo configuration
1189#
1190CONFIG_LOGO=y
1191CONFIG_LOGO_LINUX_MONO=y
1192CONFIG_LOGO_LINUX_VGA16=y
1193CONFIG_LOGO_LINUX_CLUT224=y
1194# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
1195
1196#
1197# Sound
1198#
1199CONFIG_SOUND=m
1200CONFIG_DMASOUND_PMAC=m
1201CONFIG_DMASOUND=m
1202
1203#
1204# Advanced Linux Sound Architecture
1205#
1206CONFIG_SND=m
1207CONFIG_SND_TIMER=m
1208CONFIG_SND_PCM=m
1209CONFIG_SND_HWDEP=m
1210CONFIG_SND_RAWMIDI=m
1211CONFIG_SND_SEQUENCER=m
1212CONFIG_SND_SEQ_DUMMY=m
1213CONFIG_SND_OSSEMUL=y
1214CONFIG_SND_MIXER_OSS=m
1215CONFIG_SND_PCM_OSS=m
1216CONFIG_SND_SEQUENCER_OSS=y
1217# CONFIG_SND_VERBOSE_PRINTK is not set
1218# CONFIG_SND_DEBUG is not set
1219CONFIG_SND_GENERIC_DRIVER=y
1220
1221#
1222# Generic devices
1223#
1224CONFIG_SND_DUMMY=m
1225# CONFIG_SND_VIRMIDI is not set
1226# CONFIG_SND_MTPAV is not set
1227# CONFIG_SND_SERIAL_U16550 is not set
1228# CONFIG_SND_MPU401 is not set
1229
1230#
1231# PCI devices
1232#
1233# CONFIG_SND_ALI5451 is not set
1234# CONFIG_SND_ATIIXP is not set
1235# CONFIG_SND_ATIIXP_MODEM is not set
1236# CONFIG_SND_AU8810 is not set
1237# CONFIG_SND_AU8820 is not set
1238# CONFIG_SND_AU8830 is not set
1239# CONFIG_SND_AZT3328 is not set
1240# CONFIG_SND_BT87X is not set
1241# CONFIG_SND_CS46XX is not set
1242# CONFIG_SND_CS4281 is not set
1243# CONFIG_SND_EMU10K1 is not set
1244# CONFIG_SND_EMU10K1X is not set
1245# CONFIG_SND_CA0106 is not set
1246# CONFIG_SND_KORG1212 is not set
1247# CONFIG_SND_MIXART is not set
1248# CONFIG_SND_NM256 is not set
1249# CONFIG_SND_RME32 is not set
1250# CONFIG_SND_RME96 is not set
1251# CONFIG_SND_RME9652 is not set
1252# CONFIG_SND_HDSP is not set
1253# CONFIG_SND_HDSPM is not set
1254# CONFIG_SND_TRIDENT is not set
1255# CONFIG_SND_YMFPCI is not set
1256# CONFIG_SND_AD1889 is not set
1257# CONFIG_SND_ALS4000 is not set
1258# CONFIG_SND_CMIPCI is not set
1259# CONFIG_SND_ENS1370 is not set
1260# CONFIG_SND_ENS1371 is not set
1261# CONFIG_SND_ES1938 is not set
1262# CONFIG_SND_ES1968 is not set
1263# CONFIG_SND_MAESTRO3 is not set
1264# CONFIG_SND_FM801 is not set
1265# CONFIG_SND_ICE1712 is not set
1266# CONFIG_SND_ICE1724 is not set
1267# CONFIG_SND_INTEL8X0 is not set
1268# CONFIG_SND_INTEL8X0M is not set
1269# CONFIG_SND_SONICVIBES is not set
1270# CONFIG_SND_VIA82XX is not set
1271# CONFIG_SND_VIA82XX_MODEM is not set
1272# CONFIG_SND_VX222 is not set
1273# CONFIG_SND_HDA_INTEL is not set
1274
1275#
1276# ALSA PowerMac devices
1277#
1278CONFIG_SND_POWERMAC=m
1279# CONFIG_SND_POWERMAC_AUTO_DRC is not set
1280
1281#
1282# USB devices
1283#
1284CONFIG_SND_USB_AUDIO=m
1285# CONFIG_SND_USB_USX2Y is not set
1286
1287#
1288# PCMCIA devices
1289#
1290
1291#
1292# Open Sound System
1293#
1294# CONFIG_SOUND_PRIME is not set
1295
1296#
1297# USB support
1298#
1299CONFIG_USB_ARCH_HAS_HCD=y
1300CONFIG_USB_ARCH_HAS_OHCI=y
1301CONFIG_USB=y
1302# CONFIG_USB_DEBUG is not set
1303
1304#
1305# Miscellaneous USB options
1306#
1307CONFIG_USB_DEVICEFS=y
1308# CONFIG_USB_BANDWIDTH is not set
1309CONFIG_USB_DYNAMIC_MINORS=y
1310# CONFIG_USB_SUSPEND is not set
1311# CONFIG_USB_OTG is not set
1312
1313#
1314# USB Host Controller Drivers
1315#
1316# CONFIG_USB_EHCI_HCD is not set
1317# CONFIG_USB_ISP116X_HCD is not set
1318CONFIG_USB_OHCI_HCD=y
1319# CONFIG_USB_OHCI_BIG_ENDIAN is not set
1320CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1321# CONFIG_USB_UHCI_HCD is not set
1322# CONFIG_USB_SL811_HCD is not set
1323
1324#
1325# USB Device Class drivers
1326#
1327# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
1328CONFIG_USB_ACM=m
1329CONFIG_USB_PRINTER=m
1330
1331#
1332# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1333#
1334
1335#
1336# may also be needed; see USB_STORAGE Help for more information
1337#
1338# CONFIG_USB_STORAGE is not set
1339
1340#
1341# USB Input Devices
1342#
1343CONFIG_USB_HID=y
1344CONFIG_USB_HIDINPUT=y
1345# CONFIG_HID_FF is not set
1346# CONFIG_USB_HIDDEV is not set
1347# CONFIG_USB_AIPTEK is not set
1348# CONFIG_USB_WACOM is not set
1349# CONFIG_USB_ACECAD is not set
1350# CONFIG_USB_KBTAB is not set
1351# CONFIG_USB_POWERMATE is not set
1352# CONFIG_USB_MTOUCH is not set
1353# CONFIG_USB_ITMTOUCH is not set
1354# CONFIG_USB_EGALAX is not set
1355# CONFIG_USB_YEALINK is not set
1356# CONFIG_USB_XPAD is not set
1357# CONFIG_USB_ATI_REMOTE is not set
1358# CONFIG_USB_KEYSPAN_REMOTE is not set
1359CONFIG_USB_APPLETOUCH=y
1360
1361#
1362# USB Imaging devices
1363#
1364# CONFIG_USB_MDC800 is not set
1365# CONFIG_USB_MICROTEK is not set
1366
1367#
1368# USB Multimedia devices
1369#
1370# CONFIG_USB_DABUSB is not set
1371
1372#
1373# Video4Linux support is needed for USB Multimedia device support
1374#
1375
1376#
1377# USB Network Adapters
1378#
1379# CONFIG_USB_CATC is not set
1380# CONFIG_USB_KAWETH is not set
1381# CONFIG_USB_PEGASUS is not set
1382# CONFIG_USB_RTL8150 is not set
1383CONFIG_USB_USBNET=m
1384CONFIG_USB_NET_AX8817X=m
1385CONFIG_USB_NET_CDCETHER=m
1386# CONFIG_USB_NET_GL620A is not set
1387CONFIG_USB_NET_NET1080=m
1388# CONFIG_USB_NET_PLUSB is not set
1389# CONFIG_USB_NET_RNDIS_HOST is not set
1390# CONFIG_USB_NET_CDC_SUBSET is not set
1391CONFIG_USB_NET_ZAURUS=m
1392# CONFIG_USB_ZD1201 is not set
1393CONFIG_USB_MON=y
1394
1395#
1396# USB port drivers
1397#
1398
1399#
1400# USB Serial Converter support
1401#
1402CONFIG_USB_SERIAL=m
1403# CONFIG_USB_SERIAL_GENERIC is not set
1404# CONFIG_USB_SERIAL_AIRPRIME is not set
1405# CONFIG_USB_SERIAL_ANYDATA is not set
1406# CONFIG_USB_SERIAL_BELKIN is not set
1407# CONFIG_USB_SERIAL_WHITEHEAT is not set
1408# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
1409# CONFIG_USB_SERIAL_CP2101 is not set
1410# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
1411# CONFIG_USB_SERIAL_EMPEG is not set
1412# CONFIG_USB_SERIAL_FTDI_SIO is not set
1413CONFIG_USB_SERIAL_VISOR=m
1414CONFIG_USB_SERIAL_IPAQ=m
1415# CONFIG_USB_SERIAL_IR is not set
1416# CONFIG_USB_SERIAL_EDGEPORT is not set
1417# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
1418# CONFIG_USB_SERIAL_GARMIN is not set
1419# CONFIG_USB_SERIAL_IPW is not set
1420CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1421CONFIG_USB_SERIAL_KEYSPAN=m
1422CONFIG_USB_SERIAL_KEYSPAN_MPR=y
1423CONFIG_USB_SERIAL_KEYSPAN_USA28=y
1424CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
1425CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
1426CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
1427CONFIG_USB_SERIAL_KEYSPAN_USA19=y
1428CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
1429CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
1430CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
1431CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
1432CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
1433CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
1434# CONFIG_USB_SERIAL_KLSI is not set
1435# CONFIG_USB_SERIAL_KOBIL_SCT is not set
1436# CONFIG_USB_SERIAL_MCT_U232 is not set
1437# CONFIG_USB_SERIAL_PL2303 is not set
1438# CONFIG_USB_SERIAL_HP4X is not set
1439# CONFIG_USB_SERIAL_SAFE is not set
1440# CONFIG_USB_SERIAL_TI is not set
1441# CONFIG_USB_SERIAL_CYBERJACK is not set
1442# CONFIG_USB_SERIAL_XIRCOM is not set
1443# CONFIG_USB_SERIAL_OPTION is not set
1444# CONFIG_USB_SERIAL_OMNINET is not set
1445CONFIG_USB_EZUSB=y
1446
1447#
1448# USB Miscellaneous drivers
1449#
1450# CONFIG_USB_EMI62 is not set
1451# CONFIG_USB_EMI26 is not set
1452# CONFIG_USB_AUERSWALD is not set
1453# CONFIG_USB_RIO500 is not set
1454# CONFIG_USB_LEGOTOWER is not set
1455# CONFIG_USB_LCD is not set
1456# CONFIG_USB_LED is not set
1457# CONFIG_USB_CYTHERM is not set
1458# CONFIG_USB_PHIDGETKIT is not set
1459# CONFIG_USB_PHIDGETSERVO is not set
1460# CONFIG_USB_IDMOUSE is not set
1461# CONFIG_USB_LD is not set
1462# CONFIG_USB_TEST is not set
1463
1464#
1465# USB DSL modem support
1466#
1467
1468#
1469# USB Gadget Support
1470#
1471# CONFIG_USB_GADGET is not set
1472
1473#
1474# MMC/SD Card support
1475#
1476# CONFIG_MMC is not set
1477
1478#
1479# InfiniBand support
1480#
1481# CONFIG_INFINIBAND is not set
1482
1483#
1484# SN Devices
1485#
1486
1487#
1488# File systems
1489#
1490CONFIG_EXT2_FS=y
1491# CONFIG_EXT2_FS_XATTR is not set
1492# CONFIG_EXT2_FS_XIP is not set
1493CONFIG_EXT3_FS=y
1494CONFIG_EXT3_FS_XATTR=y
1495# CONFIG_EXT3_FS_POSIX_ACL is not set
1496# CONFIG_EXT3_FS_SECURITY is not set
1497CONFIG_JBD=y
1498# CONFIG_JBD_DEBUG is not set
1499CONFIG_FS_MBCACHE=y
1500# CONFIG_REISERFS_FS is not set
1501# CONFIG_JFS_FS is not set
1502# CONFIG_FS_POSIX_ACL is not set
1503# CONFIG_XFS_FS is not set
1504# CONFIG_MINIX_FS is not set
1505# CONFIG_ROMFS_FS is not set
1506CONFIG_INOTIFY=y
1507# CONFIG_QUOTA is not set
1508CONFIG_DNOTIFY=y
1509# CONFIG_AUTOFS_FS is not set
1510# CONFIG_AUTOFS4_FS is not set
1511CONFIG_FUSE_FS=m
1512
1513#
1514# CD-ROM/DVD Filesystems
1515#
1516CONFIG_ISO9660_FS=y
1517CONFIG_JOLIET=y
1518CONFIG_ZISOFS=y
1519CONFIG_ZISOFS_FS=y
1520CONFIG_UDF_FS=m
1521CONFIG_UDF_NLS=y
1522
1523#
1524# DOS/FAT/NT Filesystems
1525#
1526CONFIG_FAT_FS=m
1527CONFIG_MSDOS_FS=m
1528CONFIG_VFAT_FS=m
1529CONFIG_FAT_DEFAULT_CODEPAGE=437
1530CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1531# CONFIG_NTFS_FS is not set
1532
1533#
1534# Pseudo filesystems
1535#
1536CONFIG_PROC_FS=y
1537CONFIG_PROC_KCORE=y
1538CONFIG_SYSFS=y
1539CONFIG_TMPFS=y
1540# CONFIG_HUGETLB_PAGE is not set
1541CONFIG_RAMFS=y
1542CONFIG_RELAYFS_FS=m
1543
1544#
1545# Miscellaneous filesystems
1546#
1547# CONFIG_ADFS_FS is not set
1548# CONFIG_AFFS_FS is not set
1549CONFIG_HFS_FS=m
1550CONFIG_HFSPLUS_FS=m
1551# CONFIG_BEFS_FS is not set
1552# CONFIG_BFS_FS is not set
1553# CONFIG_EFS_FS is not set
1554# CONFIG_CRAMFS is not set
1555# CONFIG_VXFS_FS is not set
1556# CONFIG_HPFS_FS is not set
1557# CONFIG_QNX4FS_FS is not set
1558# CONFIG_SYSV_FS is not set
1559# CONFIG_UFS_FS is not set
1560
1561#
1562# Network File Systems
1563#
1564CONFIG_NFS_FS=y
1565# CONFIG_NFS_V3 is not set
1566# CONFIG_NFS_V4 is not set
1567# CONFIG_NFS_DIRECTIO is not set
1568CONFIG_NFSD=y
1569# CONFIG_NFSD_V3 is not set
1570# CONFIG_NFSD_TCP is not set
1571CONFIG_LOCKD=y
1572CONFIG_EXPORTFS=y
1573CONFIG_NFS_COMMON=y
1574CONFIG_SUNRPC=y
1575# CONFIG_RPCSEC_GSS_KRB5 is not set
1576# CONFIG_RPCSEC_GSS_SPKM3 is not set
1577CONFIG_SMB_FS=m
1578# CONFIG_SMB_NLS_DEFAULT is not set
1579# CONFIG_CIFS is not set
1580# CONFIG_NCP_FS is not set
1581# CONFIG_CODA_FS is not set
1582# CONFIG_AFS_FS is not set
1583# CONFIG_9P_FS is not set
1584
1585#
1586# Partition Types
1587#
1588CONFIG_PARTITION_ADVANCED=y
1589# CONFIG_ACORN_PARTITION is not set
1590# CONFIG_OSF_PARTITION is not set
1591# CONFIG_AMIGA_PARTITION is not set
1592# CONFIG_ATARI_PARTITION is not set
1593CONFIG_MAC_PARTITION=y
1594CONFIG_MSDOS_PARTITION=y
1595# CONFIG_BSD_DISKLABEL is not set
1596# CONFIG_MINIX_SUBPARTITION is not set
1597# CONFIG_SOLARIS_X86_PARTITION is not set
1598# CONFIG_UNIXWARE_DISKLABEL is not set
1599# CONFIG_LDM_PARTITION is not set
1600# CONFIG_SGI_PARTITION is not set
1601# CONFIG_ULTRIX_PARTITION is not set
1602# CONFIG_SUN_PARTITION is not set
1603# CONFIG_EFI_PARTITION is not set
1604
1605#
1606# Native Language Support
1607#
1608CONFIG_NLS=y
1609CONFIG_NLS_DEFAULT="iso8859-1"
1610CONFIG_NLS_CODEPAGE_437=m
1611# CONFIG_NLS_CODEPAGE_737 is not set
1612# CONFIG_NLS_CODEPAGE_775 is not set
1613# CONFIG_NLS_CODEPAGE_850 is not set
1614# CONFIG_NLS_CODEPAGE_852 is not set
1615# CONFIG_NLS_CODEPAGE_855 is not set
1616# CONFIG_NLS_CODEPAGE_857 is not set
1617# CONFIG_NLS_CODEPAGE_860 is not set
1618# CONFIG_NLS_CODEPAGE_861 is not set
1619# CONFIG_NLS_CODEPAGE_862 is not set
1620# CONFIG_NLS_CODEPAGE_863 is not set
1621# CONFIG_NLS_CODEPAGE_864 is not set
1622# CONFIG_NLS_CODEPAGE_865 is not set
1623# CONFIG_NLS_CODEPAGE_866 is not set
1624# CONFIG_NLS_CODEPAGE_869 is not set
1625# CONFIG_NLS_CODEPAGE_936 is not set
1626# CONFIG_NLS_CODEPAGE_950 is not set
1627# CONFIG_NLS_CODEPAGE_932 is not set
1628# CONFIG_NLS_CODEPAGE_949 is not set
1629# CONFIG_NLS_CODEPAGE_874 is not set
1630# CONFIG_NLS_ISO8859_8 is not set
1631# CONFIG_NLS_CODEPAGE_1250 is not set
1632# CONFIG_NLS_CODEPAGE_1251 is not set
1633# CONFIG_NLS_ASCII is not set
1634CONFIG_NLS_ISO8859_1=m
1635# CONFIG_NLS_ISO8859_2 is not set
1636# CONFIG_NLS_ISO8859_3 is not set
1637# CONFIG_NLS_ISO8859_4 is not set
1638# CONFIG_NLS_ISO8859_5 is not set
1639# CONFIG_NLS_ISO8859_6 is not set
1640# CONFIG_NLS_ISO8859_7 is not set
1641# CONFIG_NLS_ISO8859_9 is not set
1642# CONFIG_NLS_ISO8859_13 is not set
1643# CONFIG_NLS_ISO8859_14 is not set
1644# CONFIG_NLS_ISO8859_15 is not set
1645# CONFIG_NLS_KOI8_R is not set
1646# CONFIG_NLS_KOI8_U is not set
1647CONFIG_NLS_UTF8=m
1648
1649#
1650# Library routines
1651#
1652CONFIG_CRC_CCITT=y
1653CONFIG_CRC16=y
1654CONFIG_CRC32=y
1655# CONFIG_LIBCRC32C is not set
1656CONFIG_ZLIB_INFLATE=y
1657CONFIG_ZLIB_DEFLATE=y
1658CONFIG_TEXTSEARCH=y
1659CONFIG_TEXTSEARCH_KMP=m
1660CONFIG_TEXTSEARCH_BM=m
1661CONFIG_TEXTSEARCH_FSM=m
1662
1663#
1664# Instrumentation Support
1665#
1666CONFIG_PROFILING=y
1667CONFIG_OPROFILE=y
1668
1669#
1670# Kernel hacking
1671#
1672# CONFIG_PRINTK_TIME is not set
1673CONFIG_DEBUG_KERNEL=y
1674# CONFIG_MAGIC_SYSRQ is not set
1675CONFIG_LOG_BUF_SHIFT=14
1676CONFIG_DETECT_SOFTLOCKUP=y
1677# CONFIG_SCHEDSTATS is not set
1678# CONFIG_DEBUG_SLAB is not set
1679# CONFIG_DEBUG_SPINLOCK is not set
1680# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1681# CONFIG_DEBUG_KOBJECT is not set
1682# CONFIG_DEBUG_INFO is not set
1683# CONFIG_DEBUG_FS is not set
1684# CONFIG_DEBUG_VM is not set
1685# CONFIG_RCU_TORTURE_TEST is not set
1686CONFIG_DEBUGGER=y
1687CONFIG_XMON=y
1688CONFIG_XMON_DEFAULT=y
1689# CONFIG_BDI_SWITCH is not set
1690CONFIG_BOOTX_TEXT=y
1691
1692#
1693# Security options
1694#
1695# CONFIG_KEYS is not set
1696# CONFIG_SECURITY is not set
1697
1698#
1699# Cryptographic options
1700#
1701CONFIG_CRYPTO=y
1702# CONFIG_CRYPTO_HMAC is not set
1703# CONFIG_CRYPTO_NULL is not set
1704# CONFIG_CRYPTO_MD4 is not set
1705# CONFIG_CRYPTO_MD5 is not set
1706# CONFIG_CRYPTO_SHA1 is not set
1707# CONFIG_CRYPTO_SHA256 is not set
1708# CONFIG_CRYPTO_SHA512 is not set
1709# CONFIG_CRYPTO_WP512 is not set
1710# CONFIG_CRYPTO_TGR192 is not set
1711# CONFIG_CRYPTO_DES is not set
1712# CONFIG_CRYPTO_BLOWFISH is not set
1713# CONFIG_CRYPTO_TWOFISH is not set
1714# CONFIG_CRYPTO_SERPENT is not set
1715CONFIG_CRYPTO_AES=m
1716# CONFIG_CRYPTO_CAST5 is not set
1717# CONFIG_CRYPTO_CAST6 is not set
1718# CONFIG_CRYPTO_TEA is not set
1719CONFIG_CRYPTO_ARC4=m
1720# CONFIG_CRYPTO_KHAZAD is not set
1721# CONFIG_CRYPTO_ANUBIS is not set
1722# CONFIG_CRYPTO_DEFLATE is not set
1723CONFIG_CRYPTO_MICHAEL_MIC=m
1724# CONFIG_CRYPTO_CRC32C is not set
1725# CONFIG_CRYPTO_TEST is not set
1726
1727#
1728# Hardware crypto devices
1729#
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 9ed551b6c172..6e03b595b6c8 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -17,11 +17,11 @@ obj-y += vdso32/
17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ 17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
18 signal_64.o ptrace32.o systbl.o \ 18 signal_64.o ptrace32.o systbl.o \
19 paca.o ioctl32.o cpu_setup_power4.o \ 19 paca.o ioctl32.o cpu_setup_power4.o \
20 firmware.o sysfs.o udbg.o idle_64.o 20 firmware.o sysfs.o idle_64.o
21obj-$(CONFIG_PPC64) += vdso64/ 21obj-$(CONFIG_PPC64) += vdso64/
22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
23obj-$(CONFIG_POWER4) += idle_power4.o 23obj-$(CONFIG_POWER4) += idle_power4.o
24obj-$(CONFIG_PPC_OF) += of_device.o 24obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o
25procfs-$(CONFIG_PPC64) := proc_ppc64.o 25procfs-$(CONFIG_PPC64) := proc_ppc64.o
26obj-$(CONFIG_PROC_FS) += $(procfs-y) 26obj-$(CONFIG_PROC_FS) += $(procfs-y)
27rtaspci-$(CONFIG_PPC64) := rtas_pci.o 27rtaspci-$(CONFIG_PPC64) := rtas_pci.o
@@ -30,12 +30,10 @@ obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
30obj-$(CONFIG_RTAS_PROC) += rtas-proc.o 30obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
31obj-$(CONFIG_LPARCFG) += lparcfg.o 31obj-$(CONFIG_LPARCFG) += lparcfg.o
32obj-$(CONFIG_IBMVIO) += vio.o 32obj-$(CONFIG_IBMVIO) += vio.o
33obj-$(CONFIG_IBMEBUS) += ibmebus.o
33obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o 34obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
34obj-$(CONFIG_PPC_PSERIES) += udbg_16550.o
35obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o
36udbgscc-$(CONFIG_PPC64) := udbg_scc.o
37obj-$(CONFIG_PPC_PMAC) += $(udbgscc-y)
38obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o 35obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o
36obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
39 37
40ifeq ($(CONFIG_PPC_MERGE),y) 38ifeq ($(CONFIG_PPC_MERGE),y)
41 39
@@ -48,25 +46,25 @@ extra-$(CONFIG_8xx) := head_8xx.o
48extra-y += vmlinux.lds 46extra-y += vmlinux.lds
49 47
50obj-y += process.o init_task.o time.o \ 48obj-y += process.o init_task.o time.o \
51 prom.o traps.o setup-common.o 49 prom.o traps.o setup-common.o udbg.o
52obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o 50obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o
53obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o 51obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
54obj-$(CONFIG_PPC_OF) += prom_init.o 52obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
55obj-$(CONFIG_MODULES) += ppc_ksyms.o 53obj-$(CONFIG_MODULES) += ppc_ksyms.o
56obj-$(CONFIG_BOOTX_TEXT) += btext.o 54obj-$(CONFIG_BOOTX_TEXT) += btext.o
57obj-$(CONFIG_6xx) += idle_6xx.o 55obj-$(CONFIG_6xx) += idle_6xx.o
58obj-$(CONFIG_SMP) += smp.o 56obj-$(CONFIG_SMP) += smp.o
59obj-$(CONFIG_KPROBES) += kprobes.o 57obj-$(CONFIG_KPROBES) += kprobes.o
60 58obj-$(CONFIG_SERIAL_8250) += legacy_serial.o udbg_16550.o
61module-$(CONFIG_PPC64) += module_64.o 59module-$(CONFIG_PPC64) += module_64.o
62obj-$(CONFIG_MODULES) += $(module-y) 60obj-$(CONFIG_MODULES) += $(module-y)
63 61
64pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \ 62pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \
65 pci_direct_iommu.o iomap.o 63 pci_direct_iommu.o iomap.o
66obj-$(CONFIG_PCI) += $(pci64-y) 64obj-$(CONFIG_PCI) += $(pci64-y)
67 65kexec-$(CONFIG_PPC64) := machine_kexec_64.o
68kexec64-$(CONFIG_PPC64) += machine_kexec_64.o 66kexec-$(CONFIG_PPC32) := machine_kexec_32.o
69obj-$(CONFIG_KEXEC) += $(kexec64-y) 67obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o $(kexec-y)
70 68
71ifeq ($(CONFIG_PPC_ISERIES),y) 69ifeq ($(CONFIG_PPC_ISERIES),y)
72$(obj)/head_64.o: $(obj)/lparmap.s 70$(obj)/head_64.o: $(obj)/lparmap.s
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 91538d2445bf..56399c5c931a 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -92,9 +92,9 @@ int main(void)
92 92
93 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); 93 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
94 DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); 94 DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
95 DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror)); 95 DEFINE(TI_SIGFRAME, offsetof(struct thread_info, nvgprs_frame));
96#ifdef CONFIG_PPC32
97 DEFINE(TI_TASK, offsetof(struct thread_info, task)); 96 DEFINE(TI_TASK, offsetof(struct thread_info, task));
97#ifdef CONFIG_PPC32
98 DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); 98 DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
99 DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); 99 DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
100#endif /* CONFIG_PPC32 */ 100#endif /* CONFIG_PPC32 */
@@ -131,11 +131,9 @@ int main(void)
131 DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas)); 131 DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas));
132 DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas)); 132 DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas));
133#endif /* CONFIG_HUGETLB_PAGE */ 133#endif /* CONFIG_HUGETLB_PAGE */
134 DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr));
135 DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen)); 134 DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
136 DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc)); 135 DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
137 DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb)); 136 DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
138 DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi));
139 DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp)); 137 DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
140 DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca)); 138 DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca));
141 DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); 139 DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
index bdfba92b2b38..6223d39177cb 100644
--- a/arch/powerpc/kernel/btext.c
+++ b/arch/powerpc/kernel/btext.c
@@ -31,15 +31,18 @@ static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
31static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb); 31static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb);
32static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb); 32static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
33 33
34static int g_loc_X; 34#define __force_data __attribute__((__section__(".data")))
35static int g_loc_Y;
36static int g_max_loc_X;
37static int g_max_loc_Y;
38 35
39static int dispDeviceRowBytes; 36static int g_loc_X __force_data;
40static int dispDeviceDepth; 37static int g_loc_Y __force_data;
41static int dispDeviceRect[4]; 38static int g_max_loc_X __force_data;
42static unsigned char *dispDeviceBase, *logicalDisplayBase; 39static int g_max_loc_Y __force_data;
40
41static int dispDeviceRowBytes __force_data;
42static int dispDeviceDepth __force_data;
43static int dispDeviceRect[4] __force_data;
44static unsigned char *dispDeviceBase __force_data;
45static unsigned char *logicalDisplayBase __force_data;
43 46
44unsigned long disp_BAT[2] __initdata = {0, 0}; 47unsigned long disp_BAT[2] __initdata = {0, 0};
45 48
@@ -47,7 +50,7 @@ unsigned long disp_BAT[2] __initdata = {0, 0};
47 50
48static unsigned char vga_font[cmapsz]; 51static unsigned char vga_font[cmapsz];
49 52
50int boot_text_mapped; 53int boot_text_mapped __force_data = 0;
51int force_printk_to_btext = 0; 54int force_printk_to_btext = 0;
52 55
53#ifdef CONFIG_PPC32 56#ifdef CONFIG_PPC32
@@ -57,7 +60,7 @@ int force_printk_to_btext = 0;
57 * 60 *
58 * The display is mapped to virtual address 0xD0000000, rather 61 * The display is mapped to virtual address 0xD0000000, rather
59 * than 1:1, because some some CHRP machines put the frame buffer 62 * than 1:1, because some some CHRP machines put the frame buffer
60 * in the region starting at 0xC0000000 (KERNELBASE). 63 * in the region starting at 0xC0000000 (PAGE_OFFSET).
61 * This mapping is temporary and will disappear as soon as the 64 * This mapping is temporary and will disappear as soon as the
62 * setup done by MMU_Init() is applied. 65 * setup done by MMU_Init() is applied.
63 * 66 *
@@ -66,10 +69,9 @@ int force_printk_to_btext = 0;
66 * is really badly aligned, but I didn't encounter this case 69 * is really badly aligned, but I didn't encounter this case
67 * yet. 70 * yet.
68 */ 71 */
69void __init 72void __init btext_prepare_BAT(void)
70btext_prepare_BAT(void)
71{ 73{
72 unsigned long vaddr = KERNELBASE + 0x10000000; 74 unsigned long vaddr = PAGE_OFFSET + 0x10000000;
73 unsigned long addr; 75 unsigned long addr;
74 unsigned long lowbits; 76 unsigned long lowbits;
75 77
@@ -95,12 +97,13 @@ btext_prepare_BAT(void)
95} 97}
96#endif 98#endif
97 99
98/* This function will enable the early boot text when doing OF booting. This 100
99 * way, xmon output should work too 101/* This function can be used to enable the early boot text when doing
102 * OF booting or within bootx init. It must be followed by a btext_unmap()
103 * call before the logical address becomes unuseable
100 */ 104 */
101void __init 105void __init btext_setup_display(int width, int height, int depth, int pitch,
102btext_setup_display(int width, int height, int depth, int pitch, 106 unsigned long address)
103 unsigned long address)
104{ 107{
105 g_loc_X = 0; 108 g_loc_X = 0;
106 g_loc_Y = 0; 109 g_loc_Y = 0;
@@ -116,6 +119,11 @@ btext_setup_display(int width, int height, int depth, int pitch,
116 boot_text_mapped = 1; 119 boot_text_mapped = 1;
117} 120}
118 121
122void __init btext_unmap(void)
123{
124 boot_text_mapped = 0;
125}
126
119/* Here's a small text engine to use during early boot 127/* Here's a small text engine to use during early boot
120 * or for debugging purposes 128 * or for debugging purposes
121 * 129 *
@@ -127,7 +135,7 @@ btext_setup_display(int width, int height, int depth, int pitch,
127 * changes. 135 * changes.
128 */ 136 */
129 137
130void map_boot_text(void) 138static void map_boot_text(void)
131{ 139{
132 unsigned long base, offset, size; 140 unsigned long base, offset, size;
133 unsigned char *vbase; 141 unsigned char *vbase;
@@ -175,8 +183,9 @@ int btext_initialize(struct device_node *np)
175 if (prop) 183 if (prop)
176 address = *prop; 184 address = *prop;
177 185
178 /* FIXME: Add support for PCI reg properties */ 186 /* FIXME: Add support for PCI reg properties. Right now, only
179 187 * reliable on macs
188 */
180 if (address == 0) 189 if (address == 0)
181 return -EINVAL; 190 return -EINVAL;
182 191
@@ -184,7 +193,6 @@ int btext_initialize(struct device_node *np)
184 g_loc_Y = 0; 193 g_loc_Y = 0;
185 g_max_loc_X = width / 8; 194 g_max_loc_X = width / 8;
186 g_max_loc_Y = height / 16; 195 g_max_loc_Y = height / 16;
187 logicalDisplayBase = (unsigned char *)address;
188 dispDeviceBase = (unsigned char *)address; 196 dispDeviceBase = (unsigned char *)address;
189 dispDeviceRowBytes = pitch; 197 dispDeviceRowBytes = pitch;
190 dispDeviceDepth = depth; 198 dispDeviceDepth = depth;
@@ -197,14 +205,12 @@ int btext_initialize(struct device_node *np)
197 return 0; 205 return 0;
198} 206}
199 207
200void __init init_boot_display(void) 208int __init btext_find_display(int allow_nonstdout)
201{ 209{
202 char *name; 210 char *name;
203 struct device_node *np = NULL; 211 struct device_node *np = NULL;
204 int rc = -ENODEV; 212 int rc = -ENODEV;
205 213
206 printk("trying to initialize btext ...\n");
207
208 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 214 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
209 if (name != NULL) { 215 if (name != NULL) {
210 np = of_find_node_by_path(name); 216 np = of_find_node_by_path(name);
@@ -218,8 +224,8 @@ void __init init_boot_display(void)
218 } 224 }
219 if (np) 225 if (np)
220 rc = btext_initialize(np); 226 rc = btext_initialize(np);
221 if (rc == 0) 227 if (rc == 0 || !allow_nonstdout)
222 return; 228 return rc;
223 229
224 for (np = NULL; (np = of_find_node_by_type(np, "display"));) { 230 for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
225 if (get_property(np, "linux,opened", NULL)) { 231 if (get_property(np, "linux,opened", NULL)) {
@@ -228,8 +234,9 @@ void __init init_boot_display(void)
228 printk("result: %d\n", rc); 234 printk("result: %d\n", rc);
229 } 235 }
230 if (rc == 0) 236 if (rc == 0)
231 return; 237 break;
232 } 238 }
239 return rc;
233} 240}
234 241
235/* Calc the base address of a given point (x,y) */ 242/* Calc the base address of a given point (x,y) */
@@ -277,44 +284,83 @@ EXPORT_SYMBOL(btext_update_display);
277 284
278void btext_clearscreen(void) 285void btext_clearscreen(void)
279{ 286{
280 unsigned long *base = (unsigned long *)calc_base(0, 0); 287 unsigned int *base = (unsigned int *)calc_base(0, 0);
281 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * 288 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
282 (dispDeviceDepth >> 3)) >> 3; 289 (dispDeviceDepth >> 3)) >> 2;
283 int i,j; 290 int i,j;
284 291
285 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++) 292 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
286 { 293 {
287 unsigned long *ptr = base; 294 unsigned int *ptr = base;
288 for(j=width; j; --j) 295 for(j=width; j; --j)
289 *(ptr++) = 0; 296 *(ptr++) = 0;
290 base += (dispDeviceRowBytes >> 3); 297 base += (dispDeviceRowBytes >> 2);
291 } 298 }
292} 299}
293 300
301void btext_flushscreen(void)
302{
303 unsigned int *base = (unsigned int *)calc_base(0, 0);
304 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
305 (dispDeviceDepth >> 3)) >> 2;
306 int i,j;
307
308 for (i=0; i < (dispDeviceRect[3] - dispDeviceRect[1]); i++)
309 {
310 unsigned int *ptr = base;
311 for(j = width; j > 0; j -= 8) {
312 __asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
313 ptr += 8;
314 }
315 base += (dispDeviceRowBytes >> 2);
316 }
317 __asm__ __volatile__ ("sync" ::: "memory");
318}
319
320void btext_flushline(void)
321{
322 unsigned int *base = (unsigned int *)calc_base(0, g_loc_Y << 4);
323 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
324 (dispDeviceDepth >> 3)) >> 2;
325 int i,j;
326
327 for (i=0; i < 16; i++)
328 {
329 unsigned int *ptr = base;
330 for(j = width; j > 0; j -= 8) {
331 __asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
332 ptr += 8;
333 }
334 base += (dispDeviceRowBytes >> 2);
335 }
336 __asm__ __volatile__ ("sync" ::: "memory");
337}
338
339
294#ifndef NO_SCROLL 340#ifndef NO_SCROLL
295static void scrollscreen(void) 341static void scrollscreen(void)
296{ 342{
297 unsigned long *src = (unsigned long *)calc_base(0,16); 343 unsigned int *src = (unsigned int *)calc_base(0,16);
298 unsigned long *dst = (unsigned long *)calc_base(0,0); 344 unsigned int *dst = (unsigned int *)calc_base(0,0);
299 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * 345 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
300 (dispDeviceDepth >> 3)) >> 3; 346 (dispDeviceDepth >> 3)) >> 2;
301 int i,j; 347 int i,j;
302 348
303 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++) 349 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
304 { 350 {
305 unsigned long *src_ptr = src; 351 unsigned int *src_ptr = src;
306 unsigned long *dst_ptr = dst; 352 unsigned int *dst_ptr = dst;
307 for(j=width; j; --j) 353 for(j=width; j; --j)
308 *(dst_ptr++) = *(src_ptr++); 354 *(dst_ptr++) = *(src_ptr++);
309 src += (dispDeviceRowBytes >> 3); 355 src += (dispDeviceRowBytes >> 2);
310 dst += (dispDeviceRowBytes >> 3); 356 dst += (dispDeviceRowBytes >> 2);
311 } 357 }
312 for (i=0; i<16; i++) 358 for (i=0; i<16; i++)
313 { 359 {
314 unsigned long *dst_ptr = dst; 360 unsigned int *dst_ptr = dst;
315 for(j=width; j; --j) 361 for(j=width; j; --j)
316 *(dst_ptr++) = 0; 362 *(dst_ptr++) = 0;
317 dst += (dispDeviceRowBytes >> 3); 363 dst += (dispDeviceRowBytes >> 2);
318 } 364 }
319} 365}
320#endif /* ndef NO_SCROLL */ 366#endif /* ndef NO_SCROLL */
@@ -377,6 +423,14 @@ void btext_drawstring(const char *c)
377 btext_drawchar(*c++); 423 btext_drawchar(*c++);
378} 424}
379 425
426void btext_drawtext(const char *c, unsigned int len)
427{
428 if (!boot_text_mapped)
429 return;
430 while (len--)
431 btext_drawchar(*c++);
432}
433
380void btext_drawhex(unsigned long v) 434void btext_drawhex(unsigned long v)
381{ 435{
382 char *hex_table = "0123456789abcdef"; 436 char *hex_table = "0123456789abcdef";
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 1d85cedbbb7b..43c74a6b07b1 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -78,10 +78,8 @@ struct cpu_spec cpu_specs[] = {
78 .dcache_bsize = 128, 78 .dcache_bsize = 128,
79 .num_pmcs = 8, 79 .num_pmcs = 8,
80 .cpu_setup = __setup_cpu_power3, 80 .cpu_setup = __setup_cpu_power3,
81#ifdef CONFIG_OPROFILE
82 .oprofile_cpu_type = "ppc64/power3", 81 .oprofile_cpu_type = "ppc64/power3",
83 .oprofile_model = &op_model_rs64, 82 .oprofile_type = RS64,
84#endif
85 }, 83 },
86 { /* Power3+ */ 84 { /* Power3+ */
87 .pvr_mask = 0xffff0000, 85 .pvr_mask = 0xffff0000,
@@ -93,10 +91,8 @@ struct cpu_spec cpu_specs[] = {
93 .dcache_bsize = 128, 91 .dcache_bsize = 128,
94 .num_pmcs = 8, 92 .num_pmcs = 8,
95 .cpu_setup = __setup_cpu_power3, 93 .cpu_setup = __setup_cpu_power3,
96#ifdef CONFIG_OPROFILE
97 .oprofile_cpu_type = "ppc64/power3", 94 .oprofile_cpu_type = "ppc64/power3",
98 .oprofile_model = &op_model_rs64, 95 .oprofile_type = RS64,
99#endif
100 }, 96 },
101 { /* Northstar */ 97 { /* Northstar */
102 .pvr_mask = 0xffff0000, 98 .pvr_mask = 0xffff0000,
@@ -108,10 +104,8 @@ struct cpu_spec cpu_specs[] = {
108 .dcache_bsize = 128, 104 .dcache_bsize = 128,
109 .num_pmcs = 8, 105 .num_pmcs = 8,
110 .cpu_setup = __setup_cpu_power3, 106 .cpu_setup = __setup_cpu_power3,
111#ifdef CONFIG_OPROFILE
112 .oprofile_cpu_type = "ppc64/rs64", 107 .oprofile_cpu_type = "ppc64/rs64",
113 .oprofile_model = &op_model_rs64, 108 .oprofile_type = RS64,
114#endif
115 }, 109 },
116 { /* Pulsar */ 110 { /* Pulsar */
117 .pvr_mask = 0xffff0000, 111 .pvr_mask = 0xffff0000,
@@ -123,10 +117,8 @@ struct cpu_spec cpu_specs[] = {
123 .dcache_bsize = 128, 117 .dcache_bsize = 128,
124 .num_pmcs = 8, 118 .num_pmcs = 8,
125 .cpu_setup = __setup_cpu_power3, 119 .cpu_setup = __setup_cpu_power3,
126#ifdef CONFIG_OPROFILE
127 .oprofile_cpu_type = "ppc64/rs64", 120 .oprofile_cpu_type = "ppc64/rs64",
128 .oprofile_model = &op_model_rs64, 121 .oprofile_type = RS64,
129#endif
130 }, 122 },
131 { /* I-star */ 123 { /* I-star */
132 .pvr_mask = 0xffff0000, 124 .pvr_mask = 0xffff0000,
@@ -138,10 +130,8 @@ struct cpu_spec cpu_specs[] = {
138 .dcache_bsize = 128, 130 .dcache_bsize = 128,
139 .num_pmcs = 8, 131 .num_pmcs = 8,
140 .cpu_setup = __setup_cpu_power3, 132 .cpu_setup = __setup_cpu_power3,
141#ifdef CONFIG_OPROFILE
142 .oprofile_cpu_type = "ppc64/rs64", 133 .oprofile_cpu_type = "ppc64/rs64",
143 .oprofile_model = &op_model_rs64, 134 .oprofile_type = RS64,
144#endif
145 }, 135 },
146 { /* S-star */ 136 { /* S-star */
147 .pvr_mask = 0xffff0000, 137 .pvr_mask = 0xffff0000,
@@ -153,10 +143,8 @@ struct cpu_spec cpu_specs[] = {
153 .dcache_bsize = 128, 143 .dcache_bsize = 128,
154 .num_pmcs = 8, 144 .num_pmcs = 8,
155 .cpu_setup = __setup_cpu_power3, 145 .cpu_setup = __setup_cpu_power3,
156#ifdef CONFIG_OPROFILE
157 .oprofile_cpu_type = "ppc64/rs64", 146 .oprofile_cpu_type = "ppc64/rs64",
158 .oprofile_model = &op_model_rs64, 147 .oprofile_type = RS64,
159#endif
160 }, 148 },
161 { /* Power4 */ 149 { /* Power4 */
162 .pvr_mask = 0xffff0000, 150 .pvr_mask = 0xffff0000,
@@ -168,10 +156,8 @@ struct cpu_spec cpu_specs[] = {
168 .dcache_bsize = 128, 156 .dcache_bsize = 128,
169 .num_pmcs = 8, 157 .num_pmcs = 8,
170 .cpu_setup = __setup_cpu_power4, 158 .cpu_setup = __setup_cpu_power4,
171#ifdef CONFIG_OPROFILE
172 .oprofile_cpu_type = "ppc64/power4", 159 .oprofile_cpu_type = "ppc64/power4",
173 .oprofile_model = &op_model_rs64, 160 .oprofile_type = POWER4,
174#endif
175 }, 161 },
176 { /* Power4+ */ 162 { /* Power4+ */
177 .pvr_mask = 0xffff0000, 163 .pvr_mask = 0xffff0000,
@@ -183,10 +169,8 @@ struct cpu_spec cpu_specs[] = {
183 .dcache_bsize = 128, 169 .dcache_bsize = 128,
184 .num_pmcs = 8, 170 .num_pmcs = 8,
185 .cpu_setup = __setup_cpu_power4, 171 .cpu_setup = __setup_cpu_power4,
186#ifdef CONFIG_OPROFILE
187 .oprofile_cpu_type = "ppc64/power4", 172 .oprofile_cpu_type = "ppc64/power4",
188 .oprofile_model = &op_model_power4, 173 .oprofile_type = POWER4,
189#endif
190 }, 174 },
191 { /* PPC970 */ 175 { /* PPC970 */
192 .pvr_mask = 0xffff0000, 176 .pvr_mask = 0xffff0000,
@@ -199,10 +183,8 @@ struct cpu_spec cpu_specs[] = {
199 .dcache_bsize = 128, 183 .dcache_bsize = 128,
200 .num_pmcs = 8, 184 .num_pmcs = 8,
201 .cpu_setup = __setup_cpu_ppc970, 185 .cpu_setup = __setup_cpu_ppc970,
202#ifdef CONFIG_OPROFILE
203 .oprofile_cpu_type = "ppc64/970", 186 .oprofile_cpu_type = "ppc64/970",
204 .oprofile_model = &op_model_power4, 187 .oprofile_type = POWER4,
205#endif
206 }, 188 },
207#endif /* CONFIG_PPC64 */ 189#endif /* CONFIG_PPC64 */
208#if defined(CONFIG_PPC64) || defined(CONFIG_POWER4) 190#if defined(CONFIG_PPC64) || defined(CONFIG_POWER4)
@@ -221,10 +203,8 @@ struct cpu_spec cpu_specs[] = {
221 .dcache_bsize = 128, 203 .dcache_bsize = 128,
222 .num_pmcs = 8, 204 .num_pmcs = 8,
223 .cpu_setup = __setup_cpu_ppc970, 205 .cpu_setup = __setup_cpu_ppc970,
224#ifdef CONFIG_OPROFILE
225 .oprofile_cpu_type = "ppc64/970", 206 .oprofile_cpu_type = "ppc64/970",
226 .oprofile_model = &op_model_power4, 207 .oprofile_type = POWER4,
227#endif
228 }, 208 },
229#endif /* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */ 209#endif /* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */
230#ifdef CONFIG_PPC64 210#ifdef CONFIG_PPC64
@@ -238,10 +218,8 @@ struct cpu_spec cpu_specs[] = {
238 .icache_bsize = 128, 218 .icache_bsize = 128,
239 .dcache_bsize = 128, 219 .dcache_bsize = 128,
240 .cpu_setup = __setup_cpu_ppc970, 220 .cpu_setup = __setup_cpu_ppc970,
241#ifdef CONFIG_OPROFILE
242 .oprofile_cpu_type = "ppc64/970", 221 .oprofile_cpu_type = "ppc64/970",
243 .oprofile_model = &op_model_power4, 222 .oprofile_type = POWER4,
244#endif
245 }, 223 },
246 { /* Power5 GR */ 224 { /* Power5 GR */
247 .pvr_mask = 0xffff0000, 225 .pvr_mask = 0xffff0000,
@@ -253,27 +231,23 @@ struct cpu_spec cpu_specs[] = {
253 .dcache_bsize = 128, 231 .dcache_bsize = 128,
254 .num_pmcs = 6, 232 .num_pmcs = 6,
255 .cpu_setup = __setup_cpu_power4, 233 .cpu_setup = __setup_cpu_power4,
256#ifdef CONFIG_OPROFILE
257 .oprofile_cpu_type = "ppc64/power5", 234 .oprofile_cpu_type = "ppc64/power5",
258 .oprofile_model = &op_model_power4, 235 .oprofile_type = POWER4,
259#endif
260 }, 236 },
261 { /* Power5 GS */ 237 { /* Power5 GS */
262 .pvr_mask = 0xffff0000, 238 .pvr_mask = 0xffff0000,
263 .pvr_value = 0x003b0000, 239 .pvr_value = 0x003b0000,
264 .cpu_name = "POWER5 (gs)", 240 .cpu_name = "POWER5+ (gs)",
265 .cpu_features = CPU_FTRS_POWER5, 241 .cpu_features = CPU_FTRS_POWER5,
266 .cpu_user_features = COMMON_USER_POWER5_PLUS, 242 .cpu_user_features = COMMON_USER_POWER5_PLUS,
267 .icache_bsize = 128, 243 .icache_bsize = 128,
268 .dcache_bsize = 128, 244 .dcache_bsize = 128,
269 .num_pmcs = 6, 245 .num_pmcs = 6,
270 .cpu_setup = __setup_cpu_power4, 246 .cpu_setup = __setup_cpu_power4,
271#ifdef CONFIG_OPROFILE 247 .oprofile_cpu_type = "ppc64/power5+",
272 .oprofile_cpu_type = "ppc64/power5", 248 .oprofile_type = POWER4,
273 .oprofile_model = &op_model_power4,
274#endif
275 }, 249 },
276 { /* BE DD1.x */ 250 { /* Cell Broadband Engine */
277 .pvr_mask = 0xffff0000, 251 .pvr_mask = 0xffff0000,
278 .pvr_value = 0x00700000, 252 .pvr_value = 0x00700000,
279 .cpu_name = "Cell Broadband Engine", 253 .cpu_name = "Cell Broadband Engine",
@@ -545,7 +519,9 @@ struct cpu_spec cpu_specs[] = {
545 .icache_bsize = 32, 519 .icache_bsize = 32,
546 .dcache_bsize = 32, 520 .dcache_bsize = 32,
547 .num_pmcs = 6, 521 .num_pmcs = 6,
548 .cpu_setup = __setup_cpu_745x 522 .cpu_setup = __setup_cpu_745x,
523 .oprofile_cpu_type = "ppc/7450",
524 .oprofile_type = G4,
549 }, 525 },
550 { /* 7450 2.1 */ 526 { /* 7450 2.1 */
551 .pvr_mask = 0xffffffff, 527 .pvr_mask = 0xffffffff,
@@ -556,7 +532,9 @@ struct cpu_spec cpu_specs[] = {
556 .icache_bsize = 32, 532 .icache_bsize = 32,
557 .dcache_bsize = 32, 533 .dcache_bsize = 32,
558 .num_pmcs = 6, 534 .num_pmcs = 6,
559 .cpu_setup = __setup_cpu_745x 535 .cpu_setup = __setup_cpu_745x,
536 .oprofile_cpu_type = "ppc/7450",
537 .oprofile_type = G4,
560 }, 538 },
561 { /* 7450 2.3 and newer */ 539 { /* 7450 2.3 and newer */
562 .pvr_mask = 0xffff0000, 540 .pvr_mask = 0xffff0000,
@@ -567,7 +545,9 @@ struct cpu_spec cpu_specs[] = {
567 .icache_bsize = 32, 545 .icache_bsize = 32,
568 .dcache_bsize = 32, 546 .dcache_bsize = 32,
569 .num_pmcs = 6, 547 .num_pmcs = 6,
570 .cpu_setup = __setup_cpu_745x 548 .cpu_setup = __setup_cpu_745x,
549 .oprofile_cpu_type = "ppc/7450",
550 .oprofile_type = G4,
571 }, 551 },
572 { /* 7455 rev 1.x */ 552 { /* 7455 rev 1.x */
573 .pvr_mask = 0xffffff00, 553 .pvr_mask = 0xffffff00,
@@ -578,7 +558,9 @@ struct cpu_spec cpu_specs[] = {
578 .icache_bsize = 32, 558 .icache_bsize = 32,
579 .dcache_bsize = 32, 559 .dcache_bsize = 32,
580 .num_pmcs = 6, 560 .num_pmcs = 6,
581 .cpu_setup = __setup_cpu_745x 561 .cpu_setup = __setup_cpu_745x,
562 .oprofile_cpu_type = "ppc/7450",
563 .oprofile_type = G4,
582 }, 564 },
583 { /* 7455 rev 2.0 */ 565 { /* 7455 rev 2.0 */
584 .pvr_mask = 0xffffffff, 566 .pvr_mask = 0xffffffff,
@@ -589,7 +571,9 @@ struct cpu_spec cpu_specs[] = {
589 .icache_bsize = 32, 571 .icache_bsize = 32,
590 .dcache_bsize = 32, 572 .dcache_bsize = 32,
591 .num_pmcs = 6, 573 .num_pmcs = 6,
592 .cpu_setup = __setup_cpu_745x 574 .cpu_setup = __setup_cpu_745x,
575 .oprofile_cpu_type = "ppc/7450",
576 .oprofile_type = G4,
593 }, 577 },
594 { /* 7455 others */ 578 { /* 7455 others */
595 .pvr_mask = 0xffff0000, 579 .pvr_mask = 0xffff0000,
@@ -600,7 +584,9 @@ struct cpu_spec cpu_specs[] = {
600 .icache_bsize = 32, 584 .icache_bsize = 32,
601 .dcache_bsize = 32, 585 .dcache_bsize = 32,
602 .num_pmcs = 6, 586 .num_pmcs = 6,
603 .cpu_setup = __setup_cpu_745x 587 .cpu_setup = __setup_cpu_745x,
588 .oprofile_cpu_type = "ppc/7450",
589 .oprofile_type = G4,
604 }, 590 },
605 { /* 7447/7457 Rev 1.0 */ 591 { /* 7447/7457 Rev 1.0 */
606 .pvr_mask = 0xffffffff, 592 .pvr_mask = 0xffffffff,
@@ -611,7 +597,9 @@ struct cpu_spec cpu_specs[] = {
611 .icache_bsize = 32, 597 .icache_bsize = 32,
612 .dcache_bsize = 32, 598 .dcache_bsize = 32,
613 .num_pmcs = 6, 599 .num_pmcs = 6,
614 .cpu_setup = __setup_cpu_745x 600 .cpu_setup = __setup_cpu_745x,
601 .oprofile_cpu_type = "ppc/7450",
602 .oprofile_type = G4,
615 }, 603 },
616 { /* 7447/7457 Rev 1.1 */ 604 { /* 7447/7457 Rev 1.1 */
617 .pvr_mask = 0xffffffff, 605 .pvr_mask = 0xffffffff,
@@ -622,7 +610,9 @@ struct cpu_spec cpu_specs[] = {
622 .icache_bsize = 32, 610 .icache_bsize = 32,
623 .dcache_bsize = 32, 611 .dcache_bsize = 32,
624 .num_pmcs = 6, 612 .num_pmcs = 6,
625 .cpu_setup = __setup_cpu_745x 613 .cpu_setup = __setup_cpu_745x,
614 .oprofile_cpu_type = "ppc/7450",
615 .oprofile_type = G4,
626 }, 616 },
627 { /* 7447/7457 Rev 1.2 and later */ 617 { /* 7447/7457 Rev 1.2 and later */
628 .pvr_mask = 0xffff0000, 618 .pvr_mask = 0xffff0000,
@@ -633,7 +623,9 @@ struct cpu_spec cpu_specs[] = {
633 .icache_bsize = 32, 623 .icache_bsize = 32,
634 .dcache_bsize = 32, 624 .dcache_bsize = 32,
635 .num_pmcs = 6, 625 .num_pmcs = 6,
636 .cpu_setup = __setup_cpu_745x 626 .cpu_setup = __setup_cpu_745x,
627 .oprofile_cpu_type = "ppc/7450",
628 .oprofile_type = G4,
637 }, 629 },
638 { /* 7447A */ 630 { /* 7447A */
639 .pvr_mask = 0xffff0000, 631 .pvr_mask = 0xffff0000,
@@ -644,7 +636,9 @@ struct cpu_spec cpu_specs[] = {
644 .icache_bsize = 32, 636 .icache_bsize = 32,
645 .dcache_bsize = 32, 637 .dcache_bsize = 32,
646 .num_pmcs = 6, 638 .num_pmcs = 6,
647 .cpu_setup = __setup_cpu_745x 639 .cpu_setup = __setup_cpu_745x,
640 .oprofile_cpu_type = "ppc/7450",
641 .oprofile_type = G4,
648 }, 642 },
649 { /* 7448 */ 643 { /* 7448 */
650 .pvr_mask = 0xffff0000, 644 .pvr_mask = 0xffff0000,
@@ -655,7 +649,9 @@ struct cpu_spec cpu_specs[] = {
655 .icache_bsize = 32, 649 .icache_bsize = 32,
656 .dcache_bsize = 32, 650 .dcache_bsize = 32,
657 .num_pmcs = 6, 651 .num_pmcs = 6,
658 .cpu_setup = __setup_cpu_745x 652 .cpu_setup = __setup_cpu_745x,
653 .oprofile_cpu_type = "ppc/7450",
654 .oprofile_type = G4,
659 }, 655 },
660 { /* 82xx (8240, 8245, 8260 are all 603e cores) */ 656 { /* 82xx (8240, 8245, 8260 are all 603e cores) */
661 .pvr_mask = 0x7fff0000, 657 .pvr_mask = 0x7fff0000,
@@ -979,6 +975,8 @@ struct cpu_spec cpu_specs[] = {
979 .icache_bsize = 32, 975 .icache_bsize = 32,
980 .dcache_bsize = 32, 976 .dcache_bsize = 32,
981 .num_pmcs = 4, 977 .num_pmcs = 4,
978 .oprofile_cpu_type = "ppc/e500",
979 .oprofile_type = BOOKE,
982 }, 980 },
983 { /* e500v2 */ 981 { /* e500v2 */
984 .pvr_mask = 0xffff0000, 982 .pvr_mask = 0xffff0000,
@@ -992,6 +990,8 @@ struct cpu_spec cpu_specs[] = {
992 .icache_bsize = 32, 990 .icache_bsize = 32,
993 .dcache_bsize = 32, 991 .dcache_bsize = 32,
994 .num_pmcs = 4, 992 .num_pmcs = 4,
993 .oprofile_cpu_type = "ppc/e500",
994 .oprofile_type = BOOKE,
995 }, 995 },
996#endif 996#endif
997#if !CLASSIC_PPC 997#if !CLASSIC_PPC
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
new file mode 100644
index 000000000000..4681155121ef
--- /dev/null
+++ b/arch/powerpc/kernel/crash.c
@@ -0,0 +1,264 @@
1/*
2 * Architecture specific (PPC64) functions for kexec based crash dumps.
3 *
4 * Copyright (C) 2005, IBM Corp.
5 *
6 * Created by: Haren Myneni
7 *
8 * This source code is licensed under the GNU General Public License,
9 * Version 2. See the file COPYING for more details.
10 *
11 */
12
13#undef DEBUG
14
15#include <linux/kernel.h>
16#include <linux/smp.h>
17#include <linux/reboot.h>
18#include <linux/kexec.h>
19#include <linux/bootmem.h>
20#include <linux/crash_dump.h>
21#include <linux/irq.h>
22#include <linux/delay.h>
23#include <linux/elf.h>
24#include <linux/elfcore.h>
25#include <linux/init.h>
26#include <linux/types.h>
27
28#include <asm/processor.h>
29#include <asm/machdep.h>
30#include <asm/kdump.h>
31#include <asm/lmb.h>
32#include <asm/firmware.h>
33
34#ifdef DEBUG
35#include <asm/udbg.h>
36#define DBG(fmt...) udbg_printf(fmt)
37#else
38#define DBG(fmt...)
39#endif
40
41/* This keeps a track of which one is crashing cpu. */
42int crashing_cpu = -1;
43
44static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
45 size_t data_len)
46{
47 struct elf_note note;
48
49 note.n_namesz = strlen(name) + 1;
50 note.n_descsz = data_len;
51 note.n_type = type;
52 memcpy(buf, &note, sizeof(note));
53 buf += (sizeof(note) +3)/4;
54 memcpy(buf, name, note.n_namesz);
55 buf += (note.n_namesz + 3)/4;
56 memcpy(buf, data, note.n_descsz);
57 buf += (note.n_descsz + 3)/4;
58
59 return buf;
60}
61
62static void final_note(u32 *buf)
63{
64 struct elf_note note;
65
66 note.n_namesz = 0;
67 note.n_descsz = 0;
68 note.n_type = 0;
69 memcpy(buf, &note, sizeof(note));
70}
71
72static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
73{
74 struct elf_prstatus prstatus;
75 u32 *buf;
76
77 if ((cpu < 0) || (cpu >= NR_CPUS))
78 return;
79
80 /* Using ELF notes here is opportunistic.
81 * I need a well defined structure format
82 * for the data I pass, and I need tags
83 * on the data to indicate what information I have
84 * squirrelled away. ELF notes happen to provide
85 * all of that that no need to invent something new.
86 */
87 buf = &crash_notes[cpu][0];
88 memset(&prstatus, 0, sizeof(prstatus));
89 prstatus.pr_pid = current->pid;
90 elf_core_copy_regs(&prstatus.pr_reg, regs);
91 buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
92 sizeof(prstatus));
93 final_note(buf);
94}
95
96/* FIXME Merge this with xmon_save_regs ?? */
97static inline void crash_get_current_regs(struct pt_regs *regs)
98{
99 unsigned long tmp1, tmp2;
100
101 __asm__ __volatile__ (
102 "std 0,0(%2)\n"
103 "std 1,8(%2)\n"
104 "std 2,16(%2)\n"
105 "std 3,24(%2)\n"
106 "std 4,32(%2)\n"
107 "std 5,40(%2)\n"
108 "std 6,48(%2)\n"
109 "std 7,56(%2)\n"
110 "std 8,64(%2)\n"
111 "std 9,72(%2)\n"
112 "std 10,80(%2)\n"
113 "std 11,88(%2)\n"
114 "std 12,96(%2)\n"
115 "std 13,104(%2)\n"
116 "std 14,112(%2)\n"
117 "std 15,120(%2)\n"
118 "std 16,128(%2)\n"
119 "std 17,136(%2)\n"
120 "std 18,144(%2)\n"
121 "std 19,152(%2)\n"
122 "std 20,160(%2)\n"
123 "std 21,168(%2)\n"
124 "std 22,176(%2)\n"
125 "std 23,184(%2)\n"
126 "std 24,192(%2)\n"
127 "std 25,200(%2)\n"
128 "std 26,208(%2)\n"
129 "std 27,216(%2)\n"
130 "std 28,224(%2)\n"
131 "std 29,232(%2)\n"
132 "std 30,240(%2)\n"
133 "std 31,248(%2)\n"
134 "mfmsr %0\n"
135 "std %0, 264(%2)\n"
136 "mfctr %0\n"
137 "std %0, 280(%2)\n"
138 "mflr %0\n"
139 "std %0, 288(%2)\n"
140 "bl 1f\n"
141 "1: mflr %1\n"
142 "std %1, 256(%2)\n"
143 "mtlr %0\n"
144 "mfxer %0\n"
145 "std %0, 296(%2)\n"
146 : "=&r" (tmp1), "=&r" (tmp2)
147 : "b" (regs));
148}
149
150/* We may have saved_regs from where the error came from
151 * or it is NULL if via a direct panic().
152 */
153static void crash_save_self(struct pt_regs *saved_regs)
154{
155 struct pt_regs regs;
156 int cpu;
157
158 cpu = smp_processor_id();
159 if (saved_regs)
160 memcpy(&regs, saved_regs, sizeof(regs));
161 else
162 crash_get_current_regs(&regs);
163 crash_save_this_cpu(&regs, cpu);
164}
165
166#ifdef CONFIG_SMP
167static atomic_t waiting_for_crash_ipi;
168
169void crash_ipi_callback(struct pt_regs *regs)
170{
171 int cpu = smp_processor_id();
172
173 if (cpu == crashing_cpu)
174 return;
175
176 if (!cpu_online(cpu))
177 return;
178
179 if (ppc_md.kexec_cpu_down)
180 ppc_md.kexec_cpu_down(1, 1);
181
182 local_irq_disable();
183
184 crash_save_this_cpu(regs, cpu);
185 atomic_dec(&waiting_for_crash_ipi);
186 kexec_smp_wait();
187 /* NOTREACHED */
188}
189
190static void crash_kexec_prepare_cpus(void)
191{
192 unsigned int msecs;
193
194 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
195
196 crash_send_ipi(crash_ipi_callback);
197 smp_wmb();
198
199 /*
200 * FIXME: Until we will have the way to stop other CPUSs reliabally,
201 * the crash CPU will send an IPI and wait for other CPUs to
202 * respond. If not, proceed the kexec boot even though we failed to
203 * capture other CPU states.
204 */
205 msecs = 1000000;
206 while ((atomic_read(&waiting_for_crash_ipi) > 0) && (--msecs > 0)) {
207 barrier();
208 mdelay(1);
209 }
210
211 /* Would it be better to replace the trap vector here? */
212
213 /*
214 * FIXME: In case if we do not get all CPUs, one possibility: ask the
215 * user to do soft reset such that we get all.
216 * IPI handler is already set by the panic cpu initially. Therefore,
217 * all cpus could invoke this handler from die() and the panic CPU
218 * will call machine_kexec() directly from this handler to do
219 * kexec boot.
220 */
221 if (atomic_read(&waiting_for_crash_ipi))
222 printk(KERN_ALERT "done waiting: %d cpus not responding\n",
223 atomic_read(&waiting_for_crash_ipi));
224 /* Leave the IPI callback set */
225}
226#else
227static void crash_kexec_prepare_cpus(void)
228{
229 /*
230 * move the secondarys to us so that we can copy
231 * the new kernel 0-0x100 safely
232 *
233 * do this if kexec in setup.c ?
234 */
235 smp_release_cpus();
236}
237
238#endif
239
240void default_machine_crash_shutdown(struct pt_regs *regs)
241{
242 /*
243 * This function is only called after the system
244 * has paniced or is otherwise in a critical state.
245 * The minimum amount of code to allow a kexec'd kernel
246 * to run successfully needs to happen here.
247 *
248 * In practice this means stopping other cpus in
249 * an SMP system.
250 * The kernel is broken so disable interrupts.
251 */
252 local_irq_disable();
253
254 if (ppc_md.kexec_cpu_down)
255 ppc_md.kexec_cpu_down(1, 0);
256
257 /*
258 * Make a note of crashing cpu. Will be used in machine_kexec
259 * such that another IPI will not be sent.
260 */
261 crashing_cpu = smp_processor_id();
262 crash_kexec_prepare_cpus();
263 crash_save_self(regs);
264}
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
new file mode 100644
index 000000000000..87effa3f21a7
--- /dev/null
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -0,0 +1,109 @@
1/*
2 * Routines for doing kexec-based kdump.
3 *
4 * Copyright (C) 2005, IBM Corp.
5 *
6 * Created by: Michael Ellerman
7 *
8 * This source code is licensed under the GNU General Public License,
9 * Version 2. See the file COPYING for more details.
10 */
11
12#undef DEBUG
13
14#include <linux/crash_dump.h>
15#include <linux/bootmem.h>
16#include <asm/kdump.h>
17#include <asm/lmb.h>
18#include <asm/firmware.h>
19#include <asm/uaccess.h>
20
21#ifdef DEBUG
22#include <asm/udbg.h>
23#define DBG(fmt...) udbg_printf(fmt)
24#else
25#define DBG(fmt...)
26#endif
27
28static void __init create_trampoline(unsigned long addr)
29{
30 /* The maximum range of a single instruction branch, is the current
31 * instruction's address + (32 MB - 4) bytes. For the trampoline we
32 * need to branch to current address + 32 MB. So we insert a nop at
33 * the trampoline address, then the next instruction (+ 4 bytes)
34 * does a branch to (32 MB - 4). The net effect is that when we
35 * branch to "addr" we jump to ("addr" + 32 MB). Although it requires
36 * two instructions it doesn't require any registers.
37 */
38 create_instruction(addr, 0x60000000); /* nop */
39 create_branch(addr + 4, addr + PHYSICAL_START, 0);
40}
41
42void __init kdump_setup(void)
43{
44 unsigned long i;
45
46 DBG(" -> kdump_setup()\n");
47
48 for (i = KDUMP_TRAMPOLINE_START; i < KDUMP_TRAMPOLINE_END; i += 8) {
49 create_trampoline(i);
50 }
51
52 create_trampoline(__pa(system_reset_fwnmi) - PHYSICAL_START);
53 create_trampoline(__pa(machine_check_fwnmi) - PHYSICAL_START);
54
55 DBG(" <- kdump_setup()\n");
56}
57
58static int __init parse_elfcorehdr(char *p)
59{
60 if (p)
61 elfcorehdr_addr = memparse(p, &p);
62
63 return 0;
64}
65__setup("elfcorehdr=", parse_elfcorehdr);
66
67static int __init parse_savemaxmem(char *p)
68{
69 if (p)
70 saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1;
71
72 return 0;
73}
74__setup("savemaxmem=", parse_savemaxmem);
75
76/*
77 * copy_oldmem_page - copy one page from "oldmem"
78 * @pfn: page frame number to be copied
79 * @buf: target memory address for the copy; this can be in kernel address
80 * space or user address space (see @userbuf)
81 * @csize: number of bytes to copy
82 * @offset: offset in bytes into the page (based on pfn) to begin the copy
83 * @userbuf: if set, @buf is in user address space, use copy_to_user(),
84 * otherwise @buf is in kernel address space, use memcpy().
85 *
86 * Copy a page from "oldmem". For this page, there is no pte mapped
87 * in the current kernel. We stitch up a pte, similar to kmap_atomic.
88 */
89ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
90 size_t csize, unsigned long offset, int userbuf)
91{
92 void *vaddr;
93
94 if (!csize)
95 return 0;
96
97 vaddr = __ioremap(pfn << PAGE_SHIFT, PAGE_SIZE, 0);
98
99 if (userbuf) {
100 if (copy_to_user((char __user *)buf, (vaddr + offset), csize)) {
101 iounmap(vaddr);
102 return -EFAULT;
103 }
104 } else
105 memcpy(buf, (vaddr + offset), csize);
106
107 iounmap(vaddr);
108 return csize;
109}
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 7c3419656ccc..36aaa7663f02 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -10,6 +10,7 @@
10/* Include the busses we support */ 10/* Include the busses we support */
11#include <linux/pci.h> 11#include <linux/pci.h>
12#include <asm/vio.h> 12#include <asm/vio.h>
13#include <asm/ibmebus.h>
13#include <asm/scatterlist.h> 14#include <asm/scatterlist.h>
14#include <asm/bug.h> 15#include <asm/bug.h>
15 16
@@ -23,6 +24,10 @@ static struct dma_mapping_ops *get_dma_ops(struct device *dev)
23 if (dev->bus == &vio_bus_type) 24 if (dev->bus == &vio_bus_type)
24 return &vio_dma_ops; 25 return &vio_dma_ops;
25#endif 26#endif
27#ifdef CONFIG_IBMEBUS
28 if (dev->bus == &ibmebus_bus_type)
29 return &ibmebus_dma_ops;
30#endif
26 return NULL; 31 return NULL;
27} 32}
28 33
@@ -47,6 +52,10 @@ int dma_set_mask(struct device *dev, u64 dma_mask)
47 if (dev->bus == &vio_bus_type) 52 if (dev->bus == &vio_bus_type)
48 return -EIO; 53 return -EIO;
49#endif /* CONFIG_IBMVIO */ 54#endif /* CONFIG_IBMVIO */
55#ifdef CONFIG_IBMEBUS
56 if (dev->bus == &ibmebus_bus_type)
57 return -EIO;
58#endif
50 BUG(); 59 BUG();
51 return 0; 60 return 0;
52} 61}
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 2e99ae41723c..036b71d2adfc 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -200,8 +200,6 @@ _GLOBAL(DoSyscall)
200 bl do_show_syscall 200 bl do_show_syscall
201#endif /* SHOW_SYSCALLS */ 201#endif /* SHOW_SYSCALLS */
202 rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ 202 rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
203 li r11,0
204 stb r11,TI_SC_NOERR(r10)
205 lwz r11,TI_FLAGS(r10) 203 lwz r11,TI_FLAGS(r10)
206 andi. r11,r11,_TIF_SYSCALL_T_OR_A 204 andi. r11,r11,_TIF_SYSCALL_T_OR_A
207 bne- syscall_dotrace 205 bne- syscall_dotrace
@@ -222,25 +220,21 @@ ret_from_syscall:
222 bl do_show_syscall_exit 220 bl do_show_syscall_exit
223#endif 221#endif
224 mr r6,r3 222 mr r6,r3
225 li r11,-_LAST_ERRNO
226 cmplw 0,r3,r11
227 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ 223 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
228 blt+ 30f
229 lbz r11,TI_SC_NOERR(r12)
230 cmpwi r11,0
231 bne 30f
232 neg r3,r3
233 lwz r10,_CCR(r1) /* Set SO bit in CR */
234 oris r10,r10,0x1000
235 stw r10,_CCR(r1)
236
237 /* disable interrupts so current_thread_info()->flags can't change */ 224 /* disable interrupts so current_thread_info()->flags can't change */
23830: LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ 225 LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
239 SYNC 226 SYNC
240 MTMSRD(r10) 227 MTMSRD(r10)
241 lwz r9,TI_FLAGS(r12) 228 lwz r9,TI_FLAGS(r12)
242 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED) 229 li r8,-_LAST_ERRNO
230 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
243 bne- syscall_exit_work 231 bne- syscall_exit_work
232 cmplw 0,r3,r8
233 blt+ syscall_exit_cont
234 lwz r11,_CCR(r1) /* Load CR */
235 neg r3,r3
236 oris r11,r11,0x1000 /* Set SO bit in CR */
237 stw r11,_CCR(r1)
244syscall_exit_cont: 238syscall_exit_cont:
245#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 239#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
246 /* If the process has its own DBCR0 value, load it up. The single 240 /* If the process has its own DBCR0 value, load it up. The single
@@ -292,46 +286,113 @@ syscall_dotrace:
292 b syscall_dotrace_cont 286 b syscall_dotrace_cont
293 287
294syscall_exit_work: 288syscall_exit_work:
295 stw r6,RESULT(r1) /* Save result */ 289 andi. r0,r9,_TIF_RESTOREALL
290 bne- 2f
291 cmplw 0,r3,r8
292 blt+ 1f
293 andi. r0,r9,_TIF_NOERROR
294 bne- 1f
295 lwz r11,_CCR(r1) /* Load CR */
296 neg r3,r3
297 oris r11,r11,0x1000 /* Set SO bit in CR */
298 stw r11,_CCR(r1)
299
3001: stw r6,RESULT(r1) /* Save result */
296 stw r3,GPR3(r1) /* Update return value */ 301 stw r3,GPR3(r1) /* Update return value */
297 andi. r0,r9,_TIF_SYSCALL_T_OR_A 3022: andi. r0,r9,(_TIF_PERSYSCALL_MASK)
298 beq 5f 303 beq 4f
299 ori r10,r10,MSR_EE 304
300 SYNC 305 /* Clear per-syscall TIF flags if any are set, but _leave_
301 MTMSRD(r10) /* re-enable interrupts */ 306 _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
307 yet. */
308
309 li r11,_TIF_PERSYSCALL_MASK
310 addi r12,r12,TI_FLAGS
3113: lwarx r8,0,r12
312 andc r8,r8,r11
313#ifdef CONFIG_IBM405_ERR77
314 dcbt 0,r12
315#endif
316 stwcx. r8,0,r12
317 bne- 3b
318 subi r12,r12,TI_FLAGS
319
3204: /* Anything which requires enabling interrupts? */
321 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
322 beq 7f
323
324 /* Save NVGPRS if they're not saved already */
302 lwz r4,_TRAP(r1) 325 lwz r4,_TRAP(r1)
303 andi. r4,r4,1 326 andi. r4,r4,1
304 beq 4f 327 beq 5f
305 SAVE_NVGPRS(r1) 328 SAVE_NVGPRS(r1)
306 li r4,0xc00 329 li r4,0xc00
307 stw r4,_TRAP(r1) 330 stw r4,_TRAP(r1)
3084: 331
332 /* Re-enable interrupts */
3335: ori r10,r10,MSR_EE
334 SYNC
335 MTMSRD(r10)
336
337 andi. r0,r9,_TIF_SAVE_NVGPRS
338 bne save_user_nvgprs
339
340save_user_nvgprs_cont:
341 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
342 beq 7f
343
309 addi r3,r1,STACK_FRAME_OVERHEAD 344 addi r3,r1,STACK_FRAME_OVERHEAD
310 bl do_syscall_trace_leave 345 bl do_syscall_trace_leave
311 REST_NVGPRS(r1) 346 REST_NVGPRS(r1)
3122: 347
313 lwz r3,GPR3(r1) 3486: lwz r3,GPR3(r1)
314 LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ 349 LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
315 SYNC 350 SYNC
316 MTMSRD(r10) /* disable interrupts again */ 351 MTMSRD(r10) /* disable interrupts again */
317 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ 352 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
318 lwz r9,TI_FLAGS(r12) 353 lwz r9,TI_FLAGS(r12)
3195: 3547:
320 andi. r0,r9,_TIF_NEED_RESCHED 355 andi. r0,r9,_TIF_NEED_RESCHED
321 bne 1f 356 bne 8f
322 lwz r5,_MSR(r1) 357 lwz r5,_MSR(r1)
323 andi. r5,r5,MSR_PR 358 andi. r5,r5,MSR_PR
324 beq syscall_exit_cont 359 beq ret_from_except
325 andi. r0,r9,_TIF_SIGPENDING 360 andi. r0,r9,_TIF_SIGPENDING
326 beq syscall_exit_cont 361 beq ret_from_except
327 b do_user_signal 362 b do_user_signal
3281: 3638:
329 ori r10,r10,MSR_EE 364 ori r10,r10,MSR_EE
330 SYNC 365 SYNC
331 MTMSRD(r10) /* re-enable interrupts */ 366 MTMSRD(r10) /* re-enable interrupts */
332 bl schedule 367 bl schedule
333 b 2b 368 b 6b
369
370save_user_nvgprs:
371 lwz r8,TI_SIGFRAME(r12)
372
373.macro savewords start, end
374 1: stw \start,4*(\start)(r8)
375 .section __ex_table,"a"
376 .align 2
377 .long 1b,save_user_nvgprs_fault
378 .previous
379 .if \end - \start
380 savewords "(\start+1)",\end
381 .endif
382.endm
383 savewords 14,31
384 b save_user_nvgprs_cont
385
386
387save_user_nvgprs_fault:
388 li r3,11 /* SIGSEGV */
389 lwz r4,TI_TASK(r12)
390 bl force_sigsegv
334 391
392 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
393 lwz r9,TI_FLAGS(r12)
394 b save_user_nvgprs_cont
395
335#ifdef SHOW_SYSCALLS 396#ifdef SHOW_SYSCALLS
336do_show_syscall: 397do_show_syscall:
337#ifdef SHOW_SYSCALLS_TASK 398#ifdef SHOW_SYSCALLS_TASK
@@ -401,28 +462,10 @@ show_syscalls_task:
401#endif /* SHOW_SYSCALLS */ 462#endif /* SHOW_SYSCALLS */
402 463
403/* 464/*
404 * The sigsuspend and rt_sigsuspend system calls can call do_signal 465 * The fork/clone functions need to copy the full register set into
405 * and thus put the process into the stopped state where we might 466 * the child process. Therefore we need to save all the nonvolatile
406 * want to examine its user state with ptrace. Therefore we need 467 * registers (r13 - r31) before calling the C code.
407 * to save all the nonvolatile registers (r13 - r31) before calling
408 * the C code.
409 */ 468 */
410 .globl ppc_sigsuspend
411ppc_sigsuspend:
412 SAVE_NVGPRS(r1)
413 lwz r0,_TRAP(r1)
414 rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
415 stw r0,_TRAP(r1) /* register set saved */
416 b sys_sigsuspend
417
418 .globl ppc_rt_sigsuspend
419ppc_rt_sigsuspend:
420 SAVE_NVGPRS(r1)
421 lwz r0,_TRAP(r1)
422 rlwinm r0,r0,0,0,30
423 stw r0,_TRAP(r1)
424 b sys_rt_sigsuspend
425
426 .globl ppc_fork 469 .globl ppc_fork
427ppc_fork: 470ppc_fork:
428 SAVE_NVGPRS(r1) 471 SAVE_NVGPRS(r1)
@@ -447,14 +490,6 @@ ppc_clone:
447 stw r0,_TRAP(r1) /* register set saved */ 490 stw r0,_TRAP(r1) /* register set saved */
448 b sys_clone 491 b sys_clone
449 492
450 .globl ppc_swapcontext
451ppc_swapcontext:
452 SAVE_NVGPRS(r1)
453 lwz r0,_TRAP(r1)
454 rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
455 stw r0,_TRAP(r1) /* register set saved */
456 b sys_swapcontext
457
458/* 493/*
459 * Top-level page fault handling. 494 * Top-level page fault handling.
460 * This is in assembler because if do_page_fault tells us that 495 * This is in assembler because if do_page_fault tells us that
@@ -626,16 +661,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_601)
626 .long ret_from_except 661 .long ret_from_except
627#endif 662#endif
628 663
629 .globl sigreturn_exit
630sigreturn_exit:
631 subi r1,r3,STACK_FRAME_OVERHEAD
632 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
633 lwz r9,TI_FLAGS(r12)
634 andi. r0,r9,_TIF_SYSCALL_T_OR_A
635 beq+ ret_from_except_full
636 bl do_syscall_trace_leave
637 /* fall through */
638
639 .globl ret_from_except_full 664 .globl ret_from_except_full
640ret_from_except_full: 665ret_from_except_full:
641 REST_NVGPRS(r1) 666 REST_NVGPRS(r1)
@@ -658,7 +683,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */
658 /* Check current_thread_info()->flags */ 683 /* Check current_thread_info()->flags */
659 rlwinm r9,r1,0,0,(31-THREAD_SHIFT) 684 rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
660 lwz r9,TI_FLAGS(r9) 685 lwz r9,TI_FLAGS(r9)
661 andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED) 686 andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
662 bne do_work 687 bne do_work
663 688
664restore_user: 689restore_user:
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index bce33a38399f..aacebb33e98a 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -113,9 +113,7 @@ system_call_common:
113 addi r9,r1,STACK_FRAME_OVERHEAD 113 addi r9,r1,STACK_FRAME_OVERHEAD
114#endif 114#endif
115 clrrdi r11,r1,THREAD_SHIFT 115 clrrdi r11,r1,THREAD_SHIFT
116 li r12,0
117 ld r10,TI_FLAGS(r11) 116 ld r10,TI_FLAGS(r11)
118 stb r12,TI_SC_NOERR(r11)
119 andi. r11,r10,_TIF_SYSCALL_T_OR_A 117 andi. r11,r10,_TIF_SYSCALL_T_OR_A
120 bne- syscall_dotrace 118 bne- syscall_dotrace
121syscall_dotrace_cont: 119syscall_dotrace_cont:
@@ -144,24 +142,12 @@ system_call: /* label this so stack traces look sane */
144 bctrl /* Call handler */ 142 bctrl /* Call handler */
145 143
146syscall_exit: 144syscall_exit:
145 std r3,RESULT(r1)
147#ifdef SHOW_SYSCALLS 146#ifdef SHOW_SYSCALLS
148 std r3,GPR3(r1)
149 bl .do_show_syscall_exit 147 bl .do_show_syscall_exit
150 ld r3,GPR3(r1) 148 ld r3,RESULT(r1)
151#endif 149#endif
152 std r3,RESULT(r1)
153 ld r5,_CCR(r1)
154 li r10,-_LAST_ERRNO
155 cmpld r3,r10
156 clrrdi r12,r1,THREAD_SHIFT 150 clrrdi r12,r1,THREAD_SHIFT
157 bge- syscall_error
158syscall_error_cont:
159
160 /* check for syscall tracing or audit */
161 ld r9,TI_FLAGS(r12)
162 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
163 bne- syscall_exit_trace
164syscall_exit_trace_cont:
165 151
166 /* disable interrupts so current_thread_info()->flags can't change, 152 /* disable interrupts so current_thread_info()->flags can't change,
167 and so that we don't get interrupted after loading SRR0/1. */ 153 and so that we don't get interrupted after loading SRR0/1. */
@@ -173,8 +159,13 @@ syscall_exit_trace_cont:
173 rotldi r10,r10,16 159 rotldi r10,r10,16
174 mtmsrd r10,1 160 mtmsrd r10,1
175 ld r9,TI_FLAGS(r12) 161 ld r9,TI_FLAGS(r12)
176 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED) 162 li r11,-_LAST_ERRNO
163 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR)
177 bne- syscall_exit_work 164 bne- syscall_exit_work
165 cmpld r3,r11
166 ld r5,_CCR(r1)
167 bge- syscall_error
168syscall_error_cont:
178 ld r7,_NIP(r1) 169 ld r7,_NIP(r1)
179 stdcx. r0,0,r1 /* to clear the reservation */ 170 stdcx. r0,0,r1 /* to clear the reservation */
180 andi. r6,r8,MSR_PR 171 andi. r6,r8,MSR_PR
@@ -193,21 +184,12 @@ syscall_exit_trace_cont:
193 rfid 184 rfid
194 b . /* prevent speculative execution */ 185 b . /* prevent speculative execution */
195 186
196syscall_enosys: 187syscall_error:
197 li r3,-ENOSYS
198 std r3,RESULT(r1)
199 clrrdi r12,r1,THREAD_SHIFT
200 ld r5,_CCR(r1)
201
202syscall_error:
203 lbz r11,TI_SC_NOERR(r12)
204 cmpwi 0,r11,0
205 bne- syscall_error_cont
206 neg r3,r3
207 oris r5,r5,0x1000 /* Set SO bit in CR */ 188 oris r5,r5,0x1000 /* Set SO bit in CR */
189 neg r3,r3
208 std r5,_CCR(r1) 190 std r5,_CCR(r1)
209 b syscall_error_cont 191 b syscall_error_cont
210 192
211/* Traced system call support */ 193/* Traced system call support */
212syscall_dotrace: 194syscall_dotrace:
213 bl .save_nvgprs 195 bl .save_nvgprs
@@ -225,21 +207,69 @@ syscall_dotrace:
225 ld r10,TI_FLAGS(r10) 207 ld r10,TI_FLAGS(r10)
226 b syscall_dotrace_cont 208 b syscall_dotrace_cont
227 209
228syscall_exit_trace: 210syscall_enosys:
229 std r3,GPR3(r1) 211 li r3,-ENOSYS
230 bl .save_nvgprs 212 b syscall_exit
213
214syscall_exit_work:
215 /* If TIF_RESTOREALL is set, don't scribble on either r3 or ccr.
216 If TIF_NOERROR is set, just save r3 as it is. */
217
218 andi. r0,r9,_TIF_RESTOREALL
219 bne- 2f
220 cmpld r3,r11 /* r10 is -LAST_ERRNO */
221 blt+ 1f
222 andi. r0,r9,_TIF_NOERROR
223 bne- 1f
224 ld r5,_CCR(r1)
225 neg r3,r3
226 oris r5,r5,0x1000 /* Set SO bit in CR */
227 std r5,_CCR(r1)
2281: std r3,GPR3(r1)
2292: andi. r0,r9,(_TIF_PERSYSCALL_MASK)
230 beq 4f
231
232 /* Clear per-syscall TIF flags if any are set, but _leave_
233 _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
234 yet. */
235
236 li r11,_TIF_PERSYSCALL_MASK
237 addi r12,r12,TI_FLAGS
2383: ldarx r10,0,r12
239 andc r10,r10,r11
240 stdcx. r10,0,r12
241 bne- 3b
242 subi r12,r12,TI_FLAGS
243
2444: bl .save_nvgprs
245 /* Anything else left to do? */
246 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
247 beq .ret_from_except_lite
248
249 /* Re-enable interrupts */
250 mfmsr r10
251 ori r10,r10,MSR_EE
252 mtmsrd r10,1
253
254 andi. r0,r9,_TIF_SAVE_NVGPRS
255 bne save_user_nvgprs
256
257 /* If tracing, re-enable interrupts and do it */
258save_user_nvgprs_cont:
259 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
260 beq 5f
261
231 addi r3,r1,STACK_FRAME_OVERHEAD 262 addi r3,r1,STACK_FRAME_OVERHEAD
232 bl .do_syscall_trace_leave 263 bl .do_syscall_trace_leave
233 REST_NVGPRS(r1) 264 REST_NVGPRS(r1)
234 ld r3,GPR3(r1)
235 ld r5,_CCR(r1)
236 clrrdi r12,r1,THREAD_SHIFT 265 clrrdi r12,r1,THREAD_SHIFT
237 b syscall_exit_trace_cont
238 266
239/* Stuff to do on exit from a system call. */ 267 /* Disable interrupts again and handle other work if any */
240syscall_exit_work: 2685: mfmsr r10
241 std r3,GPR3(r1) 269 rldicl r10,r10,48,1
242 std r5,_CCR(r1) 270 rotldi r10,r10,16
271 mtmsrd r10,1
272
243 b .ret_from_except_lite 273 b .ret_from_except_lite
244 274
245/* Save non-volatile GPRs, if not already saved. */ 275/* Save non-volatile GPRs, if not already saved. */
@@ -252,6 +282,52 @@ _GLOBAL(save_nvgprs)
252 std r0,_TRAP(r1) 282 std r0,_TRAP(r1)
253 blr 283 blr
254 284
285
286save_user_nvgprs:
287 ld r10,TI_SIGFRAME(r12)
288 andi. r0,r9,_TIF_32BIT
289 beq- save_user_nvgprs_64
290
291 /* 32-bit save to userspace */
292
293.macro savewords start, end
294 1: stw \start,4*(\start)(r10)
295 .section __ex_table,"a"
296 .align 3
297 .llong 1b,save_user_nvgprs_fault
298 .previous
299 .if \end - \start
300 savewords "(\start+1)",\end
301 .endif
302.endm
303 savewords 14,31
304 b save_user_nvgprs_cont
305
306save_user_nvgprs_64:
307 /* 64-bit save to userspace */
308
309.macro savelongs start, end
310 1: std \start,8*(\start)(r10)
311 .section __ex_table,"a"
312 .align 3
313 .llong 1b,save_user_nvgprs_fault
314 .previous
315 .if \end - \start
316 savelongs "(\start+1)",\end
317 .endif
318.endm
319 savelongs 14,31
320 b save_user_nvgprs_cont
321
322save_user_nvgprs_fault:
323 li r3,11 /* SIGSEGV */
324 ld r4,TI_TASK(r12)
325 bl .force_sigsegv
326
327 clrrdi r12,r1,THREAD_SHIFT
328 ld r9,TI_FLAGS(r12)
329 b save_user_nvgprs_cont
330
255/* 331/*
256 * The sigsuspend and rt_sigsuspend system calls can call do_signal 332 * The sigsuspend and rt_sigsuspend system calls can call do_signal
257 * and thus put the process into the stopped state where we might 333 * and thus put the process into the stopped state where we might
@@ -260,35 +336,6 @@ _GLOBAL(save_nvgprs)
260 * the C code. Similarly, fork, vfork and clone need the full 336 * the C code. Similarly, fork, vfork and clone need the full
261 * register state on the stack so that it can be copied to the child. 337 * register state on the stack so that it can be copied to the child.
262 */ 338 */
263_GLOBAL(ppc32_sigsuspend)
264 bl .save_nvgprs
265 bl .compat_sys_sigsuspend
266 b 70f
267
268_GLOBAL(ppc64_rt_sigsuspend)
269 bl .save_nvgprs
270 bl .sys_rt_sigsuspend
271 b 70f
272
273_GLOBAL(ppc32_rt_sigsuspend)
274 bl .save_nvgprs
275 bl .compat_sys_rt_sigsuspend
27670: cmpdi 0,r3,0
277 /* If it returned an error, we need to return via syscall_exit to set
278 the SO bit in cr0 and potentially stop for ptrace. */
279 bne syscall_exit
280 /* If sigsuspend() returns zero, we are going into a signal handler. We
281 may need to call audit_syscall_exit() to mark the exit from sigsuspend() */
282#ifdef CONFIG_AUDITSYSCALL
283 ld r3,PACACURRENT(r13)
284 ld r4,AUDITCONTEXT(r3)
285 cmpdi 0,r4,0
286 beq .ret_from_except /* No audit_context: Leave immediately. */
287 li r4, 2 /* AUDITSC_FAILURE */
288 li r5,-4 /* It's always -EINTR */
289 bl .audit_syscall_exit
290#endif
291 b .ret_from_except
292 339
293_GLOBAL(ppc_fork) 340_GLOBAL(ppc_fork)
294 bl .save_nvgprs 341 bl .save_nvgprs
@@ -305,37 +352,6 @@ _GLOBAL(ppc_clone)
305 bl .sys_clone 352 bl .sys_clone
306 b syscall_exit 353 b syscall_exit
307 354
308_GLOBAL(ppc32_swapcontext)
309 bl .save_nvgprs
310 bl .compat_sys_swapcontext
311 b 80f
312
313_GLOBAL(ppc64_swapcontext)
314 bl .save_nvgprs
315 bl .sys_swapcontext
316 b 80f
317
318_GLOBAL(ppc32_sigreturn)
319 bl .compat_sys_sigreturn
320 b 80f
321
322_GLOBAL(ppc32_rt_sigreturn)
323 bl .compat_sys_rt_sigreturn
324 b 80f
325
326_GLOBAL(ppc64_rt_sigreturn)
327 bl .sys_rt_sigreturn
328
32980: cmpdi 0,r3,0
330 blt syscall_exit
331 clrrdi r4,r1,THREAD_SHIFT
332 ld r4,TI_FLAGS(r4)
333 andi. r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
334 beq+ 81f
335 addi r3,r1,STACK_FRAME_OVERHEAD
336 bl .do_syscall_trace_leave
33781: b .ret_from_except
338
339_GLOBAL(ret_from_fork) 355_GLOBAL(ret_from_fork)
340 bl .schedule_tail 356 bl .schedule_tail
341 REST_NVGPRS(r1) 357 REST_NVGPRS(r1)
@@ -674,7 +690,7 @@ _GLOBAL(enter_rtas)
674 690
675 /* Setup our real return addr */ 691 /* Setup our real return addr */
676 SET_REG_TO_LABEL(r4,.rtas_return_loc) 692 SET_REG_TO_LABEL(r4,.rtas_return_loc)
677 SET_REG_TO_CONST(r9,KERNELBASE) 693 SET_REG_TO_CONST(r9,PAGE_OFFSET)
678 sub r4,r4,r9 694 sub r4,r4,r9
679 mtlr r4 695 mtlr r4
680 696
@@ -702,7 +718,7 @@ _GLOBAL(enter_rtas)
702_STATIC(rtas_return_loc) 718_STATIC(rtas_return_loc)
703 /* relocation is off at this point */ 719 /* relocation is off at this point */
704 mfspr r4,SPRN_SPRG3 /* Get PACA */ 720 mfspr r4,SPRN_SPRG3 /* Get PACA */
705 SET_REG_TO_CONST(r5, KERNELBASE) 721 SET_REG_TO_CONST(r5, PAGE_OFFSET)
706 sub r4,r4,r5 /* RELOC the PACA base pointer */ 722 sub r4,r4,r5 /* RELOC the PACA base pointer */
707 723
708 mfmsr r6 724 mfmsr r6
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index ccdf94731e30..03b25f9359f8 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -120,10 +120,25 @@ __start:
120 * because OF may have I/O devices mapped into that area 120 * because OF may have I/O devices mapped into that area
121 * (particularly on CHRP). 121 * (particularly on CHRP).
122 */ 122 */
123#ifdef CONFIG_PPC_MULTIPLATFORM
123 cmpwi 0,r5,0 124 cmpwi 0,r5,0
124 beq 1f 125 beq 1f
125 bl prom_init 126 bl prom_init
126 trap 127 trap
128#endif
129
130/*
131 * Check for BootX signature when supporting PowerMac and branch to
132 * appropriate trampoline if it's present
133 */
134#ifdef CONFIG_PPC_PMAC
1351: lis r31,0x426f
136 ori r31,r31,0x6f58
137 cmpw 0,r3,r31
138 bne 1f
139 bl bootx_init
140 trap
141#endif /* CONFIG_PPC_PMAC */
127 142
1281: mr r31,r3 /* save parameters */ 1431: mr r31,r3 /* save parameters */
129 mr r30,r4 144 mr r30,r4
@@ -153,6 +168,9 @@ __after_mmu_off:
153 bl flush_tlbs 168 bl flush_tlbs
154 169
155 bl initial_bats 170 bl initial_bats
171#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
172 bl setup_disp_bat
173#endif
156 174
157/* 175/*
158 * Call setup_cpu for CPU 0 and initialize 6xx Idle 176 * Call setup_cpu for CPU 0 and initialize 6xx Idle
@@ -450,16 +468,11 @@ SystemCall:
450 * by executing an altivec instruction. 468 * by executing an altivec instruction.
451 */ 469 */
452 . = 0xf00 470 . = 0xf00
453 b Trap_0f 471 b PerformanceMonitor
454 472
455 . = 0xf20 473 . = 0xf20
456 b AltiVecUnavailable 474 b AltiVecUnavailable
457 475
458Trap_0f:
459 EXCEPTION_PROLOG
460 addi r3,r1,STACK_FRAME_OVERHEAD
461 EXC_XFER_EE(0xf00, unknown_exception)
462
463/* 476/*
464 * Handle TLB miss for instruction on 603/603e. 477 * Handle TLB miss for instruction on 603/603e.
465 * Note: we get an alternate set of r0 - r3 to use automatically. 478 * Note: we get an alternate set of r0 - r3 to use automatically.
@@ -703,6 +716,11 @@ AltiVecUnavailable:
703#endif /* CONFIG_ALTIVEC */ 716#endif /* CONFIG_ALTIVEC */
704 EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception) 717 EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception)
705 718
719PerformanceMonitor:
720 EXCEPTION_PROLOG
721 addi r3,r1,STACK_FRAME_OVERHEAD
722 EXC_XFER_STD(0xf00, performance_monitor_exception)
723
706#ifdef CONFIG_ALTIVEC 724#ifdef CONFIG_ALTIVEC
707/* Note that the AltiVec support is closely modeled after the FP 725/* Note that the AltiVec support is closely modeled after the FP
708 * support. Changes to one are likely to be applicable to the 726 * support. Changes to one are likely to be applicable to the
@@ -1306,6 +1324,32 @@ initial_bats:
1306 blr 1324 blr
1307 1325
1308 1326
1327#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
1328setup_disp_bat:
1329 /*
1330 * setup the display bat prepared for us in prom.c
1331 */
1332 mflr r8
1333 bl reloc_offset
1334 mtlr r8
1335 addis r8,r3,disp_BAT@ha
1336 addi r8,r8,disp_BAT@l
1337 cmpwi cr0,r8,0
1338 beqlr
1339 lwz r11,0(r8)
1340 lwz r8,4(r8)
1341 mfspr r9,SPRN_PVR
1342 rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
1343 cmpwi 0,r9,1
1344 beq 1f
1345 mtspr SPRN_DBAT3L,r8
1346 mtspr SPRN_DBAT3U,r11
1347 blr
13481: mtspr SPRN_IBAT3L,r8
1349 mtspr SPRN_IBAT3U,r11
1350 blr
1351#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
1352
1309#ifdef CONFIG_8260 1353#ifdef CONFIG_8260
1310/* Jump into the system reset for the rom. 1354/* Jump into the system reset for the rom.
1311 * We first disable the MMU, and then jump to the ROM reset address. 1355 * We first disable the MMU, and then jump to the ROM reset address.
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 8a8bf79ef044..1c066d125375 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -154,11 +154,15 @@ _GLOBAL(__secondary_hold)
154 bne 100b 154 bne 100b
155 155
156#ifdef CONFIG_HMT 156#ifdef CONFIG_HMT
157 b .hmt_init 157 LOADADDR(r4, .hmt_init)
158 mtctr r4
159 bctr
158#else 160#else
159#ifdef CONFIG_SMP 161#ifdef CONFIG_SMP
162 LOADADDR(r4, .pSeries_secondary_smp_init)
163 mtctr r4
160 mr r3,r24 164 mr r3,r24
161 b .pSeries_secondary_smp_init 165 bctr
162#else 166#else
163 BUG_OPCODE 167 BUG_OPCODE
164#endif 168#endif
@@ -200,6 +204,20 @@ exception_marker:
200#define EX_R3 64 204#define EX_R3 64
201#define EX_LR 72 205#define EX_LR 72
202 206
207/*
208 * We're short on space and time in the exception prolog, so we can't use
209 * the normal LOADADDR macro. Normally we just need the low halfword of the
210 * address, but for Kdump we need the whole low word.
211 */
212#ifdef CONFIG_CRASH_DUMP
213#define LOAD_HANDLER(reg, label) \
214 oris reg,reg,(label)@h; /* virt addr of handler ... */ \
215 ori reg,reg,(label)@l; /* .. and the rest */
216#else
217#define LOAD_HANDLER(reg, label) \
218 ori reg,reg,(label)@l; /* virt addr of handler ... */
219#endif
220
203#define EXCEPTION_PROLOG_PSERIES(area, label) \ 221#define EXCEPTION_PROLOG_PSERIES(area, label) \
204 mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ 222 mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
205 std r9,area+EX_R9(r13); /* save r9 - r12 */ \ 223 std r9,area+EX_R9(r13); /* save r9 - r12 */ \
@@ -212,7 +230,7 @@ exception_marker:
212 clrrdi r12,r13,32; /* get high part of &label */ \ 230 clrrdi r12,r13,32; /* get high part of &label */ \
213 mfmsr r10; \ 231 mfmsr r10; \
214 mfspr r11,SPRN_SRR0; /* save SRR0 */ \ 232 mfspr r11,SPRN_SRR0; /* save SRR0 */ \
215 ori r12,r12,(label)@l; /* virt addr of handler */ \ 233 LOAD_HANDLER(r12,label) \
216 ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ 234 ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
217 mtspr SPRN_SRR0,r12; \ 235 mtspr SPRN_SRR0,r12; \
218 mfspr r12,SPRN_SRR1; /* and SRR1 */ \ 236 mfspr r12,SPRN_SRR1; /* and SRR1 */ \
@@ -553,6 +571,7 @@ slb_miss_user_pseries:
553 * Vectors for the FWNMI option. Share common code. 571 * Vectors for the FWNMI option. Share common code.
554 */ 572 */
555 .globl system_reset_fwnmi 573 .globl system_reset_fwnmi
574 .align 7
556system_reset_fwnmi: 575system_reset_fwnmi:
557 HMT_MEDIUM 576 HMT_MEDIUM
558 mtspr SPRN_SPRG1,r13 /* save r13 */ 577 mtspr SPRN_SPRG1,r13 /* save r13 */
@@ -560,6 +579,7 @@ system_reset_fwnmi:
560 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) 579 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
561 580
562 .globl machine_check_fwnmi 581 .globl machine_check_fwnmi
582 .align 7
563machine_check_fwnmi: 583machine_check_fwnmi:
564 HMT_MEDIUM 584 HMT_MEDIUM
565 mtspr SPRN_SPRG1,r13 /* save r13 */ 585 mtspr SPRN_SPRG1,r13 /* save r13 */
@@ -726,7 +746,8 @@ iSeries_secondary_smp_loop:
726decrementer_iSeries_masked: 746decrementer_iSeries_masked:
727 li r11,1 747 li r11,1
728 stb r11,PACALPPACA+LPPACADECRINT(r13) 748 stb r11,PACALPPACA+LPPACADECRINT(r13)
729 lwz r12,PACADEFAULTDECR(r13) 749 LOADBASE(r12,tb_ticks_per_jiffy)
750 lwz r12,OFF(tb_ticks_per_jiffy)(r12)
730 mtspr SPRN_DEC,r12 751 mtspr SPRN_DEC,r12
731 /* fall through */ 752 /* fall through */
732 753
@@ -1345,7 +1366,7 @@ _GLOBAL(do_stab_bolted)
1345 * fixed address (the linker can't compute (u64)&initial_stab >> 1366 * fixed address (the linker can't compute (u64)&initial_stab >>
1346 * PAGE_SHIFT). 1367 * PAGE_SHIFT).
1347 */ 1368 */
1348 . = STAB0_PHYS_ADDR /* 0x6000 */ 1369 . = STAB0_OFFSET /* 0x6000 */
1349 .globl initial_stab 1370 .globl initial_stab
1350initial_stab: 1371initial_stab:
1351 .space 4096 1372 .space 4096
@@ -1485,11 +1506,13 @@ _STATIC(__mmu_off)
1485 * 1506 *
1486 */ 1507 */
1487_GLOBAL(__start_initialization_multiplatform) 1508_GLOBAL(__start_initialization_multiplatform)
1509#ifdef CONFIG_PPC_MULTIPLATFORM
1488 /* 1510 /*
1489 * Are we booted from a PROM Of-type client-interface ? 1511 * Are we booted from a PROM Of-type client-interface ?
1490 */ 1512 */
1491 cmpldi cr0,r5,0 1513 cmpldi cr0,r5,0
1492 bne .__boot_from_prom /* yes -> prom */ 1514 bne .__boot_from_prom /* yes -> prom */
1515#endif
1493 1516
1494 /* Save parameters */ 1517 /* Save parameters */
1495 mr r31,r3 1518 mr r31,r3
@@ -1510,6 +1533,7 @@ _GLOBAL(__start_initialization_multiplatform)
1510 bl .__mmu_off 1533 bl .__mmu_off
1511 b .__after_prom_start 1534 b .__after_prom_start
1512 1535
1536#ifdef CONFIG_PPC_MULTIPLATFORM
1513_STATIC(__boot_from_prom) 1537_STATIC(__boot_from_prom)
1514 /* Save parameters */ 1538 /* Save parameters */
1515 mr r31,r3 1539 mr r31,r3
@@ -1542,6 +1566,7 @@ _STATIC(__boot_from_prom)
1542 bl .prom_init 1566 bl .prom_init
1543 /* We never return */ 1567 /* We never return */
1544 trap 1568 trap
1569#endif
1545 1570
1546/* 1571/*
1547 * At this point, r3 contains the physical address we are running at, 1572 * At this point, r3 contains the physical address we are running at,
@@ -1550,7 +1575,7 @@ _STATIC(__boot_from_prom)
1550_STATIC(__after_prom_start) 1575_STATIC(__after_prom_start)
1551 1576
1552/* 1577/*
1553 * We need to run with __start at physical address 0. 1578 * We need to run with __start at physical address PHYSICAL_START.
1554 * This will leave some code in the first 256B of 1579 * This will leave some code in the first 256B of
1555 * real memory, which are reserved for software use. 1580 * real memory, which are reserved for software use.
1556 * The remainder of the first page is loaded with the fixed 1581 * The remainder of the first page is loaded with the fixed
@@ -1565,7 +1590,7 @@ _STATIC(__after_prom_start)
1565 mr r26,r3 1590 mr r26,r3
1566 SET_REG_TO_CONST(r27,KERNELBASE) 1591 SET_REG_TO_CONST(r27,KERNELBASE)
1567 1592
1568 li r3,0 /* target addr */ 1593 LOADADDR(r3, PHYSICAL_START) /* target addr */
1569 1594
1570 // XXX FIXME: Use phys returned by OF (r30) 1595 // XXX FIXME: Use phys returned by OF (r30)
1571 add r4,r27,r26 /* source addr */ 1596 add r4,r27,r26 /* source addr */
@@ -1846,7 +1871,7 @@ _STATIC(start_here_multiplatform)
1846 mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ 1871 mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */
1847 add r13,r13,r24 /* for this processor. */ 1872 add r13,r13,r24 /* for this processor. */
1848 add r13,r13,r26 /* convert to physical addr */ 1873 add r13,r13,r26 /* convert to physical addr */
1849 mtspr SPRN_SPRG3,r13 /* PPPBBB: Temp... -Peter */ 1874 mtspr SPRN_SPRG3,r13
1850 1875
1851 /* Do very early kernel initializations, including initial hash table, 1876 /* Do very early kernel initializations, including initial hash table,
1852 * stab and slb setup before we turn on relocation. */ 1877 * stab and slb setup before we turn on relocation. */
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
new file mode 100644
index 000000000000..e47d40ac6f39
--- /dev/null
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -0,0 +1,396 @@
1/*
2 * IBM PowerPC IBM eBus Infrastructure Support.
3 *
4 * Copyright (c) 2005 IBM Corporation
5 * Heiko J Schick <schickhj@de.ibm.com>
6 *
7 * All rights reserved.
8 *
9 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
10 * BSD.
11 *
12 * OpenIB BSD License
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are met:
16 *
17 * Redistributions of source code must retain the above copyright notice, this
18 * list of conditions and the following disclaimer.
19 *
20 * Redistributions in binary form must reproduce the above copyright notice,
21 * this list of conditions and the following disclaimer in the documentation
22 * and/or other materials
23 * provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
32 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
33 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include <linux/init.h>
39#include <linux/console.h>
40#include <linux/kobject.h>
41#include <linux/dma-mapping.h>
42#include <linux/interrupt.h>
43#include <asm/ibmebus.h>
44#include <asm/abs_addr.h>
45
46static struct ibmebus_dev ibmebus_bus_device = { /* fake "parent" device */
47 .name = ibmebus_bus_device.ofdev.dev.bus_id,
48 .ofdev.dev.bus_id = "ibmebus",
49 .ofdev.dev.bus = &ibmebus_bus_type,
50};
51
52static void *ibmebus_alloc_coherent(struct device *dev,
53 size_t size,
54 dma_addr_t *dma_handle,
55 gfp_t flag)
56{
57 void *mem;
58
59 mem = kmalloc(size, flag);
60 *dma_handle = (dma_addr_t)mem;
61
62 return mem;
63}
64
65static void ibmebus_free_coherent(struct device *dev,
66 size_t size, void *vaddr,
67 dma_addr_t dma_handle)
68{
69 kfree(vaddr);
70}
71
72static dma_addr_t ibmebus_map_single(struct device *dev,
73 void *ptr,
74 size_t size,
75 enum dma_data_direction direction)
76{
77 return (dma_addr_t)(ptr);
78}
79
80static void ibmebus_unmap_single(struct device *dev,
81 dma_addr_t dma_addr,
82 size_t size,
83 enum dma_data_direction direction)
84{
85 return;
86}
87
88static int ibmebus_map_sg(struct device *dev,
89 struct scatterlist *sg,
90 int nents, enum dma_data_direction direction)
91{
92 int i;
93
94 for (i = 0; i < nents; i++) {
95 sg[i].dma_address = (dma_addr_t)page_address(sg[i].page)
96 + sg[i].offset;
97 sg[i].dma_length = sg[i].length;
98 }
99
100 return nents;
101}
102
103static void ibmebus_unmap_sg(struct device *dev,
104 struct scatterlist *sg,
105 int nents, enum dma_data_direction direction)
106{
107 return;
108}
109
110static int ibmebus_dma_supported(struct device *dev, u64 mask)
111{
112 return 1;
113}
114
115struct dma_mapping_ops ibmebus_dma_ops = {
116 .alloc_coherent = ibmebus_alloc_coherent,
117 .free_coherent = ibmebus_free_coherent,
118 .map_single = ibmebus_map_single,
119 .unmap_single = ibmebus_unmap_single,
120 .map_sg = ibmebus_map_sg,
121 .unmap_sg = ibmebus_unmap_sg,
122 .dma_supported = ibmebus_dma_supported,
123};
124
125static int ibmebus_bus_probe(struct device *dev)
126{
127 struct ibmebus_dev *ibmebusdev = to_ibmebus_dev(dev);
128 struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver);
129 const struct of_device_id *id;
130 int error = -ENODEV;
131
132 if (!ibmebusdrv->probe)
133 return error;
134
135 id = of_match_device(ibmebusdrv->id_table, &ibmebusdev->ofdev);
136 if (id) {
137 error = ibmebusdrv->probe(ibmebusdev, id);
138 }
139
140 return error;
141}
142
143static int ibmebus_bus_remove(struct device *dev)
144{
145 struct ibmebus_dev *ibmebusdev = to_ibmebus_dev(dev);
146 struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver);
147
148 if (ibmebusdrv->remove) {
149 return ibmebusdrv->remove(ibmebusdev);
150 }
151
152 return 0;
153}
154
155static void __devinit ibmebus_dev_release(struct device *dev)
156{
157 of_node_put(to_ibmebus_dev(dev)->ofdev.node);
158 kfree(to_ibmebus_dev(dev));
159}
160
161static ssize_t ibmebusdev_show_name(struct device *dev,
162 struct device_attribute *attr, char *buf)
163{
164 return sprintf(buf, "%s\n", to_ibmebus_dev(dev)->name);
165}
166static DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, ibmebusdev_show_name,
167 NULL);
168
169static struct ibmebus_dev* __devinit ibmebus_register_device_common(
170 struct ibmebus_dev *dev, char *name)
171{
172 int err = 0;
173
174 dev->name = name;
175 dev->ofdev.dev.parent = &ibmebus_bus_device.ofdev.dev;
176 dev->ofdev.dev.bus = &ibmebus_bus_type;
177 dev->ofdev.dev.release = ibmebus_dev_release;
178
179 /* An ibmebusdev is based on a of_device. We have to change the
180 * bus type to use our own DMA mapping operations.
181 */
182 if ((err = of_device_register(&dev->ofdev)) != 0) {
183 printk(KERN_ERR "%s: failed to register device (%d).\n",
184 __FUNCTION__, err);
185 return NULL;
186 }
187
188 device_create_file(&dev->ofdev.dev, &dev_attr_name);
189
190 return dev;
191}
192
193static struct ibmebus_dev* __devinit ibmebus_register_device_node(
194 struct device_node *dn)
195{
196 struct ibmebus_dev *dev;
197 char *loc_code;
198 int length;
199
200 loc_code = (char *)get_property(dn, "ibm,loc-code", NULL);
201 if (!loc_code) {
202 printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n",
203 __FUNCTION__, dn->name ? dn->name : "<unknown>");
204 return NULL;
205 }
206
207 if (strlen(loc_code) == 0) {
208 printk(KERN_WARNING "%s: 'ibm,loc-code' is invalid\n",
209 __FUNCTION__);
210 return NULL;
211 }
212
213 dev = kmalloc(sizeof(struct ibmebus_dev), GFP_KERNEL);
214 if (!dev) {
215 return NULL;
216 }
217 memset(dev, 0, sizeof(struct ibmebus_dev));
218
219 dev->ofdev.node = of_node_get(dn);
220
221 length = strlen(loc_code);
222 memcpy(dev->ofdev.dev.bus_id, loc_code
223 + (length - min(length, BUS_ID_SIZE - 1)),
224 min(length, BUS_ID_SIZE - 1));
225
226 /* Register with generic device framework. */
227 if (ibmebus_register_device_common(dev, dn->name) == NULL) {
228 kfree(dev);
229 return NULL;
230 }
231
232 return dev;
233}
234
235static void ibmebus_probe_of_nodes(char* name)
236{
237 struct device_node *dn = NULL;
238
239 while ((dn = of_find_node_by_name(dn, name))) {
240 if (ibmebus_register_device_node(dn) == NULL) {
241 of_node_put(dn);
242
243 return;
244 }
245 }
246
247 of_node_put(dn);
248
249 return;
250}
251
252static void ibmebus_add_devices_by_id(struct of_device_id *idt)
253{
254 while (strlen(idt->name) > 0) {
255 ibmebus_probe_of_nodes(idt->name);
256 idt++;
257 }
258
259 return;
260}
261
262static int ibmebus_match_helper(struct device *dev, void *data)
263{
264 if (strcmp((char*)data, to_ibmebus_dev(dev)->name) == 0)
265 return 1;
266
267 return 0;
268}
269
270static int ibmebus_unregister_device(struct device *dev)
271{
272 device_remove_file(dev, &dev_attr_name);
273 of_device_unregister(to_of_device(dev));
274
275 return 0;
276}
277
278static void ibmebus_remove_devices_by_id(struct of_device_id *idt)
279{
280 struct device *dev;
281
282 while (strlen(idt->name) > 0) {
283 while ((dev = bus_find_device(&ibmebus_bus_type, NULL,
284 (void*)idt->name,
285 ibmebus_match_helper))) {
286 ibmebus_unregister_device(dev);
287 }
288 idt++;
289
290 }
291
292 return;
293}
294
295int ibmebus_register_driver(struct ibmebus_driver *drv)
296{
297 int err = 0;
298
299 drv->driver.name = drv->name;
300 drv->driver.bus = &ibmebus_bus_type;
301 drv->driver.probe = ibmebus_bus_probe;
302 drv->driver.remove = ibmebus_bus_remove;
303
304 if ((err = driver_register(&drv->driver) != 0))
305 return err;
306
307 ibmebus_add_devices_by_id(drv->id_table);
308
309 return 0;
310}
311EXPORT_SYMBOL(ibmebus_register_driver);
312
313void ibmebus_unregister_driver(struct ibmebus_driver *drv)
314{
315 driver_unregister(&drv->driver);
316 ibmebus_remove_devices_by_id(drv->id_table);
317}
318EXPORT_SYMBOL(ibmebus_unregister_driver);
319
320int ibmebus_request_irq(struct ibmebus_dev *dev,
321 u32 ist,
322 irqreturn_t (*handler)(int, void*, struct pt_regs *),
323 unsigned long irq_flags, const char * devname,
324 void *dev_id)
325{
326 unsigned int irq = virt_irq_create_mapping(ist);
327
328 if (irq == NO_IRQ)
329 return -EINVAL;
330
331 irq = irq_offset_up(irq);
332
333 return request_irq(irq, handler,
334 irq_flags, devname, dev_id);
335}
336EXPORT_SYMBOL(ibmebus_request_irq);
337
338void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id)
339{
340 unsigned int irq = virt_irq_create_mapping(ist);
341
342 irq = irq_offset_up(irq);
343 free_irq(irq, dev_id);
344
345 return;
346}
347EXPORT_SYMBOL(ibmebus_free_irq);
348
349static int ibmebus_bus_match(struct device *dev, struct device_driver *drv)
350{
351 const struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev);
352 struct ibmebus_driver *ebus_drv = to_ibmebus_driver(drv);
353 const struct of_device_id *ids = ebus_drv->id_table;
354 const struct of_device_id *found_id;
355
356 if (!ids)
357 return 0;
358
359 found_id = of_match_device(ids, &ebus_dev->ofdev);
360 if (found_id)
361 return 1;
362
363 return 0;
364}
365
366struct bus_type ibmebus_bus_type = {
367 .name = "ibmebus",
368 .match = ibmebus_bus_match,
369};
370EXPORT_SYMBOL(ibmebus_bus_type);
371
372static int __init ibmebus_bus_init(void)
373{
374 int err;
375
376 printk(KERN_INFO "IBM eBus Device Driver\n");
377
378 err = bus_register(&ibmebus_bus_type);
379 if (err) {
380 printk(KERN_ERR ":%s: failed to register IBM eBus.\n",
381 __FUNCTION__);
382 return err;
383 }
384
385 err = device_register(&ibmebus_bus_device.ofdev.dev);
386 if (err) {
387 printk(KERN_WARNING "%s: device_register returned %i\n",
388 __FUNCTION__, err);
389 bus_unregister(&ibmebus_bus_type);
390
391 return err;
392 }
393
394 return 0;
395}
396__initcall(ibmebus_bus_init);
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 5a71ed9612fe..5651032d8706 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -31,7 +31,6 @@
31 * to reduce code space and undefined function references. 31 * to reduce code space and undefined function references.
32 */ 32 */
33 33
34#include <linux/errno.h>
35#include <linux/module.h> 34#include <linux/module.h>
36#include <linux/threads.h> 35#include <linux/threads.h>
37#include <linux/kernel_stat.h> 36#include <linux/kernel_stat.h>
@@ -44,18 +43,12 @@
44#include <linux/config.h> 43#include <linux/config.h>
45#include <linux/init.h> 44#include <linux/init.h>
46#include <linux/slab.h> 45#include <linux/slab.h>
47#include <linux/pci.h>
48#include <linux/delay.h> 46#include <linux/delay.h>
49#include <linux/irq.h> 47#include <linux/irq.h>
50#include <linux/proc_fs.h>
51#include <linux/random.h>
52#include <linux/seq_file.h> 48#include <linux/seq_file.h>
53#include <linux/cpumask.h> 49#include <linux/cpumask.h>
54#include <linux/profile.h> 50#include <linux/profile.h>
55#include <linux/bitops.h> 51#include <linux/bitops.h>
56#ifdef CONFIG_PPC64
57#include <linux/kallsyms.h>
58#endif
59 52
60#include <asm/uaccess.h> 53#include <asm/uaccess.h>
61#include <asm/system.h> 54#include <asm/system.h>
@@ -66,8 +59,7 @@
66#include <asm/prom.h> 59#include <asm/prom.h>
67#include <asm/ptrace.h> 60#include <asm/ptrace.h>
68#include <asm/machdep.h> 61#include <asm/machdep.h>
69#ifdef CONFIG_PPC64 62#ifdef CONFIG_PPC_ISERIES
70#include <asm/iseries/it_lp_queue.h>
71#include <asm/paca.h> 63#include <asm/paca.h>
72#endif 64#endif
73 65
@@ -78,10 +70,6 @@ EXPORT_SYMBOL(__irq_offset_value);
78 70
79static int ppc_spurious_interrupts; 71static int ppc_spurious_interrupts;
80 72
81#if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP)
82extern void iSeries_smp_message_recv(struct pt_regs *);
83#endif
84
85#ifdef CONFIG_PPC32 73#ifdef CONFIG_PPC32
86#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) 74#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
87 75
@@ -195,49 +183,6 @@ void fixup_irqs(cpumask_t map)
195} 183}
196#endif 184#endif
197 185
198#ifdef CONFIG_PPC_ISERIES
199void do_IRQ(struct pt_regs *regs)
200{
201 struct paca_struct *lpaca;
202
203 irq_enter();
204
205#ifdef CONFIG_DEBUG_STACKOVERFLOW
206 /* Debugging check for stack overflow: is there less than 2KB free? */
207 {
208 long sp;
209
210 sp = __get_SP() & (THREAD_SIZE-1);
211
212 if (unlikely(sp < (sizeof(struct thread_info) + 2048))) {
213 printk("do_IRQ: stack overflow: %ld\n",
214 sp - sizeof(struct thread_info));
215 dump_stack();
216 }
217 }
218#endif
219
220 lpaca = get_paca();
221#ifdef CONFIG_SMP
222 if (lpaca->lppaca.int_dword.fields.ipi_cnt) {
223 lpaca->lppaca.int_dword.fields.ipi_cnt = 0;
224 iSeries_smp_message_recv(regs);
225 }
226#endif /* CONFIG_SMP */
227 if (hvlpevent_is_pending())
228 process_hvlpevents(regs);
229
230 irq_exit();
231
232 if (lpaca->lppaca.int_dword.fields.decr_int) {
233 lpaca->lppaca.int_dword.fields.decr_int = 0;
234 /* Signal a fake decrementer interrupt */
235 timer_interrupt(regs);
236 }
237}
238
239#else /* CONFIG_PPC_ISERIES */
240
241void do_IRQ(struct pt_regs *regs) 186void do_IRQ(struct pt_regs *regs)
242{ 187{
243 int irq; 188 int irq;
@@ -286,16 +231,24 @@ void do_IRQ(struct pt_regs *regs)
286 } else 231 } else
287#endif 232#endif
288 __do_IRQ(irq, regs); 233 __do_IRQ(irq, regs);
289 } else 234 } else if (irq != -2)
290#ifdef CONFIG_PPC32 235 /* That's not SMP safe ... but who cares ? */
291 if (irq != -2) 236 ppc_spurious_interrupts++;
292#endif 237
293 /* That's not SMP safe ... but who cares ? */
294 ppc_spurious_interrupts++;
295 irq_exit(); 238 irq_exit();
296}
297 239
298#endif /* CONFIG_PPC_ISERIES */ 240#ifdef CONFIG_PPC_ISERIES
241 {
242 struct paca_struct *lpaca = get_paca();
243
244 if (lpaca->lppaca.int_dword.fields.decr_int) {
245 lpaca->lppaca.int_dword.fields.decr_int = 0;
246 /* Signal a fake decrementer interrupt */
247 timer_interrupt(regs);
248 }
249 }
250#endif
251}
299 252
300void __init init_IRQ(void) 253void __init init_IRQ(void)
301{ 254{
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
new file mode 100644
index 000000000000..f970ace208d3
--- /dev/null
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -0,0 +1,557 @@
1#include <linux/config.h>
2#include <linux/kernel.h>
3#include <linux/serial.h>
4#include <linux/serial_8250.h>
5#include <linux/serial_core.h>
6#include <linux/console.h>
7#include <linux/pci.h>
8#include <asm/io.h>
9#include <asm/mmu.h>
10#include <asm/prom.h>
11#include <asm/serial.h>
12#include <asm/udbg.h>
13#include <asm/pci-bridge.h>
14#include <asm/ppc-pci.h>
15
16#undef DEBUG
17
18#ifdef DEBUG
19#define DBG(fmt...) do { printk(fmt); } while(0)
20#else
21#define DBG(fmt...) do { } while(0)
22#endif
23
24#define MAX_LEGACY_SERIAL_PORTS 8
25
26static struct plat_serial8250_port
27legacy_serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
28static struct legacy_serial_info {
29 struct device_node *np;
30 unsigned int speed;
31 unsigned int clock;
32 phys_addr_t taddr;
33} legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS];
34static unsigned int legacy_serial_count;
35static int legacy_serial_console = -1;
36
37static int __init add_legacy_port(struct device_node *np, int want_index,
38 int iotype, phys_addr_t base,
39 phys_addr_t taddr, unsigned long irq,
40 unsigned int flags)
41{
42 u32 *clk, *spd, clock = BASE_BAUD * 16;
43 int index;
44
45 /* get clock freq. if present */
46 clk = (u32 *)get_property(np, "clock-frequency", NULL);
47 if (clk && *clk)
48 clock = *clk;
49
50 /* get default speed if present */
51 spd = (u32 *)get_property(np, "current-speed", NULL);
52
53 /* If we have a location index, then try to use it */
54 if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS)
55 index = want_index;
56 else
57 index = legacy_serial_count;
58
59 /* if our index is still out of range, that mean that
60 * array is full, we could scan for a free slot but that
61 * make little sense to bother, just skip the port
62 */
63 if (index >= MAX_LEGACY_SERIAL_PORTS)
64 return -1;
65 if (index >= legacy_serial_count)
66 legacy_serial_count = index + 1;
67
68 /* Check if there is a port who already claimed our slot */
69 if (legacy_serial_infos[index].np != 0) {
70 /* if we still have some room, move it, else override */
71 if (legacy_serial_count < MAX_LEGACY_SERIAL_PORTS) {
72 printk(KERN_INFO "Moved legacy port %d -> %d\n",
73 index, legacy_serial_count);
74 legacy_serial_ports[legacy_serial_count] =
75 legacy_serial_ports[index];
76 legacy_serial_infos[legacy_serial_count] =
77 legacy_serial_infos[index];
78 legacy_serial_count++;
79 } else {
80 printk(KERN_INFO "Replacing legacy port %d\n", index);
81 }
82 }
83
84 /* Now fill the entry */
85 memset(&legacy_serial_ports[index], 0,
86 sizeof(struct plat_serial8250_port));
87 if (iotype == UPIO_PORT)
88 legacy_serial_ports[index].iobase = base;
89 else
90 legacy_serial_ports[index].mapbase = base;
91 legacy_serial_ports[index].iotype = iotype;
92 legacy_serial_ports[index].uartclk = clock;
93 legacy_serial_ports[index].irq = irq;
94 legacy_serial_ports[index].flags = flags;
95 legacy_serial_infos[index].taddr = taddr;
96 legacy_serial_infos[index].np = of_node_get(np);
97 legacy_serial_infos[index].clock = clock;
98 legacy_serial_infos[index].speed = spd ? *spd : 0;
99
100 printk(KERN_INFO "Found legacy serial port %d for %s\n",
101 index, np->full_name);
102 printk(KERN_INFO " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n",
103 (iotype == UPIO_PORT) ? "port" : "mem",
104 (unsigned long long)base, (unsigned long long)taddr, irq,
105 legacy_serial_ports[index].uartclk,
106 legacy_serial_infos[index].speed);
107
108 return index;
109}
110
111static int __init add_legacy_soc_port(struct device_node *np,
112 struct device_node *soc_dev)
113{
114 phys_addr_t addr;
115 u32 *addrp;
116 unsigned int flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
117
118 /* We only support ports that have a clock frequency properly
119 * encoded in the device-tree.
120 */
121 if (get_property(np, "clock-frequency", NULL) == NULL)
122 return -1;
123
124 /* Get the address */
125 addrp = of_get_address(soc_dev, 0, NULL, NULL);
126 if (addrp == NULL)
127 return -1;
128
129 addr = of_translate_address(soc_dev, addrp);
130
131 /* Add port, irq will be dealt with later. We passed a translated
132 * IO port value. It will be fixed up later along with the irq
133 */
134 return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags);
135}
136
137#ifdef CONFIG_ISA
138static int __init add_legacy_isa_port(struct device_node *np,
139 struct device_node *isa_brg)
140{
141 u32 *reg;
142 char *typep;
143 int index = -1;
144 phys_addr_t taddr;
145
146 /* Get the ISA port number */
147 reg = (u32 *)get_property(np, "reg", NULL);
148 if (reg == NULL)
149 return -1;
150
151 /* Verify it's an IO port, we don't support anything else */
152 if (!(reg[0] & 0x00000001))
153 return -1;
154
155 /* Now look for an "ibm,aix-loc" property that gives us ordering
156 * if any...
157 */
158 typep = (char *)get_property(np, "ibm,aix-loc", NULL);
159
160 /* If we have a location index, then use it */
161 if (typep && *typep == 'S')
162 index = simple_strtol(typep+1, NULL, 0) - 1;
163
164 /* Translate ISA address */
165 taddr = of_translate_address(np, reg);
166
167 /* Add port, irq will be dealt with later */
168 return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, NO_IRQ, UPF_BOOT_AUTOCONF);
169
170}
171#endif
172
173#ifdef CONFIG_PCI
174static int __init add_legacy_pci_port(struct device_node *np,
175 struct device_node *pci_dev)
176{
177 phys_addr_t addr, base;
178 u32 *addrp;
179 unsigned int flags;
180 int iotype, index = -1, lindex = 0;
181
182 /* We only support ports that have a clock frequency properly
183 * encoded in the device-tree (that is have an fcode). Anything
184 * else can't be used that early and will be normally probed by
185 * the generic 8250_pci driver later on. The reason is that 8250
186 * compatible UARTs on PCI need all sort of quirks (port offsets
187 * etc...) that this code doesn't know about
188 */
189 if (get_property(np, "clock-frequency", NULL) == NULL)
190 return -1;
191
192 /* Get the PCI address. Assume BAR 0 */
193 addrp = of_get_pci_address(pci_dev, 0, NULL, &flags);
194 if (addrp == NULL)
195 return -1;
196
197 /* We only support BAR 0 for now */
198 iotype = (flags & IORESOURCE_MEM) ? UPIO_MEM : UPIO_PORT;
199 addr = of_translate_address(pci_dev, addrp);
200
201 /* Set the IO base to the same as the translated address for MMIO,
202 * or to the domain local IO base for PIO (it will be fixed up later)
203 */
204 if (iotype == UPIO_MEM)
205 base = addr;
206 else
207 base = addrp[2];
208
209 /* Try to guess an index... If we have subdevices of the pci dev,
210 * we get to their "reg" property
211 */
212 if (np != pci_dev) {
213 u32 *reg = (u32 *)get_property(np, "reg", NULL);
214 if (reg && (*reg < 4))
215 index = lindex = *reg;
216 }
217
218 /* Local index means it's the Nth port in the PCI chip. Unfortunately
219 * the offset to add here is device specific. We know about those
220 * EXAR ports and we default to the most common case. If your UART
221 * doesn't work for these settings, you'll have to add your own special
222 * cases here
223 */
224 if (device_is_compatible(pci_dev, "pci13a8,152") ||
225 device_is_compatible(pci_dev, "pci13a8,154") ||
226 device_is_compatible(pci_dev, "pci13a8,158")) {
227 addr += 0x200 * lindex;
228 base += 0x200 * lindex;
229 } else {
230 addr += 8 * lindex;
231 base += 8 * lindex;
232 }
233
234 /* Add port, irq will be dealt with later. We passed a translated
235 * IO port value. It will be fixed up later along with the irq
236 */
237 return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, UPF_BOOT_AUTOCONF);
238}
239#endif
240
241/*
242 * This is called very early, as part of setup_system() or eventually
243 * setup_arch(), basically before anything else in this file. This function
244 * will try to build a list of all the available 8250-compatible serial ports
245 * in the machine using the Open Firmware device-tree. It currently only deals
246 * with ISA and PCI busses but could be extended. It allows a very early boot
247 * console to be initialized, that list is also used later to provide 8250 with
248 * the machine non-PCI ports and to properly pick the default console port
249 */
250void __init find_legacy_serial_ports(void)
251{
252 struct device_node *np, *stdout = NULL;
253 char *path;
254 int index;
255
256 DBG(" -> find_legacy_serial_port()\n");
257
258 /* Now find out if one of these is out firmware console */
259 path = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
260 if (path != NULL) {
261 stdout = of_find_node_by_path(path);
262 if (stdout)
263 DBG("stdout is %s\n", stdout->full_name);
264 } else {
265 DBG(" no linux,stdout-path !\n");
266 }
267
268 /* First fill our array with SOC ports */
269 for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) {
270 struct device_node *soc = of_get_parent(np);
271 if (soc && !strcmp(soc->type, "soc")) {
272 index = add_legacy_soc_port(np, np);
273 if (index >= 0 && np == stdout)
274 legacy_serial_console = index;
275 }
276 of_node_put(soc);
277 }
278
279#ifdef CONFIG_ISA
280 /* First fill our array with ISA ports */
281 for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
282 struct device_node *isa = of_get_parent(np);
283 if (isa && !strcmp(isa->name, "isa")) {
284 index = add_legacy_isa_port(np, isa);
285 if (index >= 0 && np == stdout)
286 legacy_serial_console = index;
287 }
288 of_node_put(isa);
289 }
290#endif
291
292#ifdef CONFIG_PCI
293 /* Next, try to locate PCI ports */
294 for (np = NULL; (np = of_find_all_nodes(np));) {
295 struct device_node *pci, *parent = of_get_parent(np);
296 if (parent && !strcmp(parent->name, "isa")) {
297 of_node_put(parent);
298 continue;
299 }
300 if (strcmp(np->name, "serial") && strcmp(np->type, "serial")) {
301 of_node_put(parent);
302 continue;
303 }
304 /* Check for known pciclass, and also check wether we have
305 * a device with child nodes for ports or not
306 */
307 if (device_is_compatible(np, "pciclass,0700") ||
308 device_is_compatible(np, "pciclass,070002"))
309 pci = np;
310 else if (device_is_compatible(parent, "pciclass,0700") ||
311 device_is_compatible(parent, "pciclass,070002"))
312 pci = parent;
313 else {
314 of_node_put(parent);
315 continue;
316 }
317 index = add_legacy_pci_port(np, pci);
318 if (index >= 0 && np == stdout)
319 legacy_serial_console = index;
320 of_node_put(parent);
321 }
322#endif
323
324 DBG("legacy_serial_console = %d\n", legacy_serial_console);
325
326 /* udbg is 64 bits only for now, that will change soon though ... */
327 while (legacy_serial_console >= 0) {
328 struct legacy_serial_info *info =
329 &legacy_serial_infos[legacy_serial_console];
330 void __iomem *addr;
331
332 if (info->taddr == 0)
333 break;
334 addr = ioremap(info->taddr, 0x1000);
335 if (addr == NULL)
336 break;
337 if (info->speed == 0)
338 info->speed = udbg_probe_uart_speed(addr, info->clock);
339 DBG("default console speed = %d\n", info->speed);
340 udbg_init_uart(addr, info->speed, info->clock);
341 break;
342 }
343
344 DBG(" <- find_legacy_serial_port()\n");
345}
346
347static struct platform_device serial_device = {
348 .name = "serial8250",
349 .id = PLAT8250_DEV_PLATFORM,
350 .dev = {
351 .platform_data = legacy_serial_ports,
352 },
353};
354
355static void __init fixup_port_irq(int index,
356 struct device_node *np,
357 struct plat_serial8250_port *port)
358{
359 DBG("fixup_port_irq(%d)\n", index);
360
361 /* Check for interrupts in that node */
362 if (np->n_intrs > 0) {
363 port->irq = np->intrs[0].line;
364 DBG(" port %d (%s), irq=%d\n",
365 index, np->full_name, port->irq);
366 return;
367 }
368
369 /* Check for interrupts in the parent */
370 np = of_get_parent(np);
371 if (np == NULL)
372 return;
373
374 if (np->n_intrs > 0) {
375 port->irq = np->intrs[0].line;
376 DBG(" port %d (%s), irq=%d\n",
377 index, np->full_name, port->irq);
378 }
379 of_node_put(np);
380}
381
382static void __init fixup_port_pio(int index,
383 struct device_node *np,
384 struct plat_serial8250_port *port)
385{
386#ifdef CONFIG_PCI
387 struct pci_controller *hose;
388
389 DBG("fixup_port_pio(%d)\n", index);
390
391 hose = pci_find_hose_for_OF_device(np);
392 if (hose) {
393 unsigned long offset = (unsigned long)hose->io_base_virt -
394#ifdef CONFIG_PPC64
395 pci_io_base;
396#else
397 isa_io_base;
398#endif
399 DBG("port %d, IO %lx -> %lx\n",
400 index, port->iobase, port->iobase + offset);
401 port->iobase += offset;
402 }
403#endif
404}
405
406static void __init fixup_port_mmio(int index,
407 struct device_node *np,
408 struct plat_serial8250_port *port)
409{
410 DBG("fixup_port_mmio(%d)\n", index);
411
412 port->membase = ioremap(port->mapbase, 0x100);
413}
414
415/*
416 * This is called as an arch initcall, hopefully before the PCI bus is
417 * probed and/or the 8250 driver loaded since we need to register our
418 * platform devices before 8250 PCI ones are detected as some of them
419 * must properly "override" the platform ones.
420 *
421 * This function fixes up the interrupt value for platform ports as it
422 * couldn't be done earlier before interrupt maps have been parsed. It
423 * also "corrects" the IO address for PIO ports for the same reason,
424 * since earlier, the PHBs virtual IO space wasn't assigned yet. It then
425 * registers all those platform ports for use by the 8250 driver when it
426 * finally loads.
427 */
428static int __init serial_dev_init(void)
429{
430 int i;
431
432 if (legacy_serial_count == 0)
433 return -ENODEV;
434
435 /*
436 * Before we register the platfrom serial devices, we need
437 * to fixup their interrutps and their IO ports.
438 */
439 DBG("Fixing serial ports interrupts and IO ports ...\n");
440
441 for (i = 0; i < legacy_serial_count; i++) {
442 struct plat_serial8250_port *port = &legacy_serial_ports[i];
443 struct device_node *np = legacy_serial_infos[i].np;
444
445 if (port->irq == NO_IRQ)
446 fixup_port_irq(i, np, port);
447 if (port->iotype == UPIO_PORT)
448 fixup_port_pio(i, np, port);
449 if (port->iotype == UPIO_MEM)
450 fixup_port_mmio(i, np, port);
451 }
452
453 DBG("Registering platform serial ports\n");
454
455 return platform_device_register(&serial_device);
456}
457arch_initcall(serial_dev_init);
458
459
460/*
461 * This is called very early, as part of console_init() (typically just after
462 * time_init()). This function is respondible for trying to find a good
463 * default console on serial ports. It tries to match the open firmware
464 * default output with one of the available serial console drivers, either
465 * one of the platform serial ports that have been probed earlier by
466 * find_legacy_serial_ports() or some more platform specific ones.
467 */
468static int __init check_legacy_serial_console(void)
469{
470 struct device_node *prom_stdout = NULL;
471 int speed = 0, offset = 0;
472 char *name;
473 u32 *spd;
474
475 DBG(" -> check_legacy_serial_console()\n");
476
477 /* The user has requested a console so this is already set up. */
478 if (strstr(saved_command_line, "console=")) {
479 DBG(" console was specified !\n");
480 return -EBUSY;
481 }
482
483 if (!of_chosen) {
484 DBG(" of_chosen is NULL !\n");
485 return -ENODEV;
486 }
487
488 if (legacy_serial_console < 0) {
489 DBG(" legacy_serial_console not found !\n");
490 return -ENODEV;
491 }
492 /* We are getting a weird phandle from OF ... */
493 /* ... So use the full path instead */
494 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
495 if (name == NULL) {
496 DBG(" no linux,stdout-path !\n");
497 return -ENODEV;
498 }
499 prom_stdout = of_find_node_by_path(name);
500 if (!prom_stdout) {
501 DBG(" can't find stdout package %s !\n", name);
502 return -ENODEV;
503 }
504 DBG("stdout is %s\n", prom_stdout->full_name);
505
506 name = (char *)get_property(prom_stdout, "name", NULL);
507 if (!name) {
508 DBG(" stdout package has no name !\n");
509 goto not_found;
510 }
511 spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
512 if (spd)
513 speed = *spd;
514
515 if (0)
516 ;
517#ifdef CONFIG_SERIAL_8250_CONSOLE
518 else if (strcmp(name, "serial") == 0) {
519 int i;
520 /* Look for it in probed array */
521 for (i = 0; i < legacy_serial_count; i++) {
522 if (prom_stdout != legacy_serial_infos[i].np)
523 continue;
524 offset = i;
525 speed = legacy_serial_infos[i].speed;
526 break;
527 }
528 if (i >= legacy_serial_count)
529 goto not_found;
530 }
531#endif /* CONFIG_SERIAL_8250_CONSOLE */
532#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
533 else if (strcmp(name, "ch-a") == 0)
534 offset = 0;
535 else if (strcmp(name, "ch-b") == 0)
536 offset = 1;
537#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
538 else
539 goto not_found;
540 of_node_put(prom_stdout);
541
542 DBG("Found serial console at ttyS%d\n", offset);
543
544 if (speed) {
545 static char __initdata opt[16];
546 sprintf(opt, "%d", speed);
547 return add_preferred_console("ttyS", offset, opt);
548 } else
549 return add_preferred_console("ttyS", offset, NULL);
550
551 not_found:
552 DBG("No preferred console found !\n");
553 of_node_put(prom_stdout);
554 return -ENODEV;
555}
556console_initcall(check_legacy_serial_console);
557
diff --git a/arch/powerpc/kernel/lparmap.c b/arch/powerpc/kernel/lparmap.c
index 5a05a797485f..584d1e3c013d 100644
--- a/arch/powerpc/kernel/lparmap.c
+++ b/arch/powerpc/kernel/lparmap.c
@@ -7,7 +7,7 @@
7 * 2 of the License, or (at your option) any later version. 7 * 2 of the License, or (at your option) any later version.
8 */ 8 */
9#include <asm/mmu.h> 9#include <asm/mmu.h>
10#include <asm/page.h> 10#include <asm/pgtable.h>
11#include <asm/iseries/lpar_map.h> 11#include <asm/iseries/lpar_map.h>
12 12
13const struct LparMap __attribute__((__section__(".text"))) xLparMap = { 13const struct LparMap __attribute__((__section__(".text"))) xLparMap = {
@@ -16,16 +16,16 @@ const struct LparMap __attribute__((__section__(".text"))) xLparMap = {
16 .xSegmentTableOffs = STAB0_PAGE, 16 .xSegmentTableOffs = STAB0_PAGE,
17 17
18 .xEsids = { 18 .xEsids = {
19 { .xKernelEsid = GET_ESID(KERNELBASE), 19 { .xKernelEsid = GET_ESID(PAGE_OFFSET),
20 .xKernelVsid = KERNEL_VSID(KERNELBASE), }, 20 .xKernelVsid = KERNEL_VSID(PAGE_OFFSET), },
21 { .xKernelEsid = GET_ESID(VMALLOCBASE), 21 { .xKernelEsid = GET_ESID(VMALLOC_START),
22 .xKernelVsid = KERNEL_VSID(VMALLOCBASE), }, 22 .xKernelVsid = KERNEL_VSID(VMALLOC_START), },
23 }, 23 },
24 24
25 .xRanges = { 25 .xRanges = {
26 { .xPages = HvPagesToMap, 26 { .xPages = HvPagesToMap,
27 .xOffset = 0, 27 .xOffset = 0,
28 .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - HW_PAGE_SHIFT), 28 .xVPN = KERNEL_VSID(PAGE_OFFSET) << (SID_SHIFT - HW_PAGE_SHIFT),
29 }, 29 },
30 }, 30 },
31}; 31};
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c
new file mode 100644
index 000000000000..a91e40c9ae45
--- /dev/null
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -0,0 +1,67 @@
1/*
2 * Code to handle transition of Linux booting another kernel.
3 *
4 * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com>
5 * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
6 * Copyright (C) 2005 IBM Corporation.
7 *
8 * This source code is licensed under the GNU General Public License,
9 * Version 2. See the file COPYING for more details.
10 */
11
12#include <linux/kexec.h>
13#include <linux/reboot.h>
14#include <linux/threads.h>
15#include <asm/machdep.h>
16
17/*
18 * Provide a dummy crash_notes definition until crash dump is implemented.
19 * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
20 */
21note_buf_t crash_notes[NR_CPUS];
22
23void machine_crash_shutdown(struct pt_regs *regs)
24{
25 if (ppc_md.machine_crash_shutdown)
26 ppc_md.machine_crash_shutdown(regs);
27}
28
29/*
30 * Do what every setup is needed on image and the
31 * reboot code buffer to allow us to avoid allocations
32 * later.
33 */
34int machine_kexec_prepare(struct kimage *image)
35{
36 if (ppc_md.machine_kexec_prepare)
37 return ppc_md.machine_kexec_prepare(image);
38 /*
39 * Fail if platform doesn't provide its own machine_kexec_prepare
40 * implementation.
41 */
42 return -ENOSYS;
43}
44
45void machine_kexec_cleanup(struct kimage *image)
46{
47 if (ppc_md.machine_kexec_cleanup)
48 ppc_md.machine_kexec_cleanup(image);
49}
50
51/*
52 * Do not allocate memory (or fail in any way) in machine_kexec().
53 * We are past the point of no return, committed to rebooting now.
54 */
55NORET_TYPE void machine_kexec(struct kimage *image)
56{
57 if (ppc_md.machine_kexec)
58 ppc_md.machine_kexec(image);
59 else {
60 /*
61 * Fall back to normal restart if platform doesn't provide
62 * its own kexec function, and user insist to kexec...
63 */
64 machine_restart(NULL);
65 }
66 for(;;);
67}
diff --git a/arch/powerpc/kernel/machine_kexec_32.c b/arch/powerpc/kernel/machine_kexec_32.c
new file mode 100644
index 000000000000..443606134dff
--- /dev/null
+++ b/arch/powerpc/kernel/machine_kexec_32.c
@@ -0,0 +1,65 @@
1/*
2 * PPC32 code to handle Linux booting another kernel.
3 *
4 * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com>
5 * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
6 * Copyright (C) 2005 IBM Corporation.
7 *
8 * This source code is licensed under the GNU General Public License,
9 * Version 2. See the file COPYING for more details.
10 */
11
12#include <linux/kexec.h>
13#include <linux/mm.h>
14#include <linux/string.h>
15#include <asm/cacheflush.h>
16#include <asm/hw_irq.h>
17#include <asm/io.h>
18
19typedef NORET_TYPE void (*relocate_new_kernel_t)(
20 unsigned long indirection_page,
21 unsigned long reboot_code_buffer,
22 unsigned long start_address) ATTRIB_NORET;
23
24/*
25 * This is a generic machine_kexec function suitable at least for
26 * non-OpenFirmware embedded platforms.
27 * It merely copies the image relocation code to the control page and
28 * jumps to it.
29 * A platform specific function may just call this one.
30 */
31void default_machine_kexec(struct kimage *image)
32{
33 const extern unsigned char relocate_new_kernel[];
34 const extern unsigned int relocate_new_kernel_size;
35 unsigned long page_list;
36 unsigned long reboot_code_buffer, reboot_code_buffer_phys;
37 relocate_new_kernel_t rnk;
38
39 /* Interrupts aren't acceptable while we reboot */
40 local_irq_disable();
41
42 page_list = image->head;
43
44 /* we need both effective and real address here */
45 reboot_code_buffer =
46 (unsigned long)page_address(image->control_code_page);
47 reboot_code_buffer_phys = virt_to_phys((void *)reboot_code_buffer);
48
49 /* copy our kernel relocation code to the control code page */
50 memcpy((void *)reboot_code_buffer, relocate_new_kernel,
51 relocate_new_kernel_size);
52
53 flush_icache_range(reboot_code_buffer,
54 reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE);
55 printk(KERN_INFO "Bye!\n");
56
57 /* now call it */
58 rnk = (relocate_new_kernel_t) reboot_code_buffer;
59 (*rnk)(page_list, reboot_code_buffer_phys, image->start);
60}
61
62int default_machine_kexec_prepare(struct kimage *image)
63{
64 return 0;
65}
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 97c51e452be7..d6431440c54f 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * machine_kexec.c - handle transition of Linux booting another kernel 2 * PPC64 code to handle Linux booting another kernel.
3 * 3 *
4 * Copyright (C) 2004-2005, IBM Corp. 4 * Copyright (C) 2004-2005, IBM Corp.
5 * 5 *
@@ -28,21 +28,7 @@
28 28
29#define HASH_GROUP_SIZE 0x80 /* size of each hash group, asm/mmu.h */ 29#define HASH_GROUP_SIZE 0x80 /* size of each hash group, asm/mmu.h */
30 30
31/* Have this around till we move it into crash specific file */ 31int default_machine_kexec_prepare(struct kimage *image)
32note_buf_t crash_notes[NR_CPUS];
33
34/* Dummy for now. Not sure if we need to have a crash shutdown in here
35 * and if what it will achieve. Letting it be now to compile the code
36 * in generic kexec environment
37 */
38void machine_crash_shutdown(struct pt_regs *regs)
39{
40 /* do nothing right now */
41 /* smp_relase_cpus() if we want smp on panic kernel */
42 /* cpu_irq_down to isolate us until we are ready */
43}
44
45int machine_kexec_prepare(struct kimage *image)
46{ 32{
47 int i; 33 int i;
48 unsigned long begin, end; /* limits of segment */ 34 unsigned long begin, end; /* limits of segment */
@@ -111,11 +97,6 @@ int machine_kexec_prepare(struct kimage *image)
111 return 0; 97 return 0;
112} 98}
113 99
114void machine_kexec_cleanup(struct kimage *image)
115{
116 /* we do nothing in prepare that needs to be undone */
117}
118
119#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE) 100#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
120 101
121static void copy_segments(unsigned long ind) 102static void copy_segments(unsigned long ind)
@@ -172,9 +153,8 @@ void kexec_copy_flush(struct kimage *image)
172 * including ones that were in place on the original copy 153 * including ones that were in place on the original copy
173 */ 154 */
174 for (i = 0; i < nr_segments; i++) 155 for (i = 0; i < nr_segments; i++)
175 flush_icache_range(ranges[i].mem + KERNELBASE, 156 flush_icache_range((unsigned long)__va(ranges[i].mem),
176 ranges[i].mem + KERNELBASE + 157 (unsigned long)__va(ranges[i].mem + ranges[i].memsz));
177 ranges[i].memsz);
178} 158}
179 159
180#ifdef CONFIG_SMP 160#ifdef CONFIG_SMP
@@ -283,13 +263,20 @@ extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start,
283 void (*clear_all)(void)) ATTRIB_NORET; 263 void (*clear_all)(void)) ATTRIB_NORET;
284 264
285/* too late to fail here */ 265/* too late to fail here */
286void machine_kexec(struct kimage *image) 266void default_machine_kexec(struct kimage *image)
287{ 267{
288
289 /* prepare control code if any */ 268 /* prepare control code if any */
290 269
291 /* shutdown other cpus into our wait loop and quiesce interrupts */ 270 /*
292 kexec_prepare_cpus(); 271 * If the kexec boot is the normal one, need to shutdown other cpus
272 * into our wait loop and quiesce interrupts.
273 * Otherwise, in the case of crashed mode (crashing_cpu >= 0),
274 * stopping other CPUs and collecting their pt_regs is done before
275 * using debugger IPI.
276 */
277
278 if (crashing_cpu == -1)
279 kexec_prepare_cpus();
293 280
294 /* switch to a staticly allocated stack. Based on irq stack code. 281 /* switch to a staticly allocated stack. Based on irq stack code.
295 * XXX: the task struct will likely be invalid once we do the copy! 282 * XXX: the task struct will likely be invalid once we do the copy!
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 624a983a9676..01d0d97a16e1 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -5,6 +5,10 @@
5 * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) 5 * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
6 * and Paul Mackerras. 6 * and Paul Mackerras.
7 * 7 *
8 * kexec bits:
9 * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com>
10 * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
11 *
8 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 13 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 14 * as published by the Free Software Foundation; either version
@@ -24,6 +28,8 @@
24#include <asm/ppc_asm.h> 28#include <asm/ppc_asm.h>
25#include <asm/thread_info.h> 29#include <asm/thread_info.h>
26#include <asm/asm-offsets.h> 30#include <asm/asm-offsets.h>
31#include <asm/processor.h>
32#include <asm/kexec.h>
27 33
28 .text 34 .text
29 35
@@ -1006,3 +1012,110 @@ _GLOBAL(execve)
1006 */ 1012 */
1007_GLOBAL(__main) 1013_GLOBAL(__main)
1008 blr 1014 blr
1015
1016#ifdef CONFIG_KEXEC
1017 /*
1018 * Must be relocatable PIC code callable as a C function.
1019 */
1020 .globl relocate_new_kernel
1021relocate_new_kernel:
1022 /* r3 = page_list */
1023 /* r4 = reboot_code_buffer */
1024 /* r5 = start_address */
1025
1026 li r0, 0
1027
1028 /*
1029 * Set Machine Status Register to a known status,
1030 * switch the MMU off and jump to 1: in a single step.
1031 */
1032
1033 mr r8, r0
1034 ori r8, r8, MSR_RI|MSR_ME
1035 mtspr SPRN_SRR1, r8
1036 addi r8, r4, 1f - relocate_new_kernel
1037 mtspr SPRN_SRR0, r8
1038 sync
1039 rfi
1040
10411:
1042 /* from this point address translation is turned off */
1043 /* and interrupts are disabled */
1044
1045 /* set a new stack at the bottom of our page... */
1046 /* (not really needed now) */
1047 addi r1, r4, KEXEC_CONTROL_CODE_SIZE - 8 /* for LR Save+Back Chain */
1048 stw r0, 0(r1)
1049
1050 /* Do the copies */
1051 li r6, 0 /* checksum */
1052 mr r0, r3
1053 b 1f
1054
10550: /* top, read another word for the indirection page */
1056 lwzu r0, 4(r3)
1057
10581:
1059 /* is it a destination page? (r8) */
1060 rlwinm. r7, r0, 0, 31, 31 /* IND_DESTINATION (1<<0) */
1061 beq 2f
1062
1063 rlwinm r8, r0, 0, 0, 19 /* clear kexec flags, page align */
1064 b 0b
1065
10662: /* is it an indirection page? (r3) */
1067 rlwinm. r7, r0, 0, 30, 30 /* IND_INDIRECTION (1<<1) */
1068 beq 2f
1069
1070 rlwinm r3, r0, 0, 0, 19 /* clear kexec flags, page align */
1071 subi r3, r3, 4
1072 b 0b
1073
10742: /* are we done? */
1075 rlwinm. r7, r0, 0, 29, 29 /* IND_DONE (1<<2) */
1076 beq 2f
1077 b 3f
1078
10792: /* is it a source page? (r9) */
1080 rlwinm. r7, r0, 0, 28, 28 /* IND_SOURCE (1<<3) */
1081 beq 0b
1082
1083 rlwinm r9, r0, 0, 0, 19 /* clear kexec flags, page align */
1084
1085 li r7, PAGE_SIZE / 4
1086 mtctr r7
1087 subi r9, r9, 4
1088 subi r8, r8, 4
10899:
1090 lwzu r0, 4(r9) /* do the copy */
1091 xor r6, r6, r0
1092 stwu r0, 4(r8)
1093 dcbst 0, r8
1094 sync
1095 icbi 0, r8
1096 bdnz 9b
1097
1098 addi r9, r9, 4
1099 addi r8, r8, 4
1100 b 0b
1101
11023:
1103
1104 /* To be certain of avoiding problems with self-modifying code
1105 * execute a serializing instruction here.
1106 */
1107 isync
1108 sync
1109
1110 /* jump to the entry point, usually the setup routine */
1111 mtlr r5
1112 blrl
1113
11141: b 1b
1115
1116relocate_new_kernel_end:
1117
1118 .globl relocate_new_kernel_size
1119relocate_new_kernel_size:
1120 .long relocate_new_kernel_end - relocate_new_kernel
1121#endif
diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index c0fcd29918ce..fd7db8d542db 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -80,80 +80,74 @@ static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin)
80static ssize_t dev_nvram_read(struct file *file, char __user *buf, 80static ssize_t dev_nvram_read(struct file *file, char __user *buf,
81 size_t count, loff_t *ppos) 81 size_t count, loff_t *ppos)
82{ 82{
83 ssize_t len; 83 ssize_t ret;
84 char *tmp_buffer; 84 char *tmp = NULL;
85 int size; 85 ssize_t size;
86 86
87 if (ppc_md.nvram_size == NULL) 87 ret = -ENODEV;
88 return -ENODEV; 88 if (!ppc_md.nvram_size)
89 goto out;
90
91 ret = 0;
89 size = ppc_md.nvram_size(); 92 size = ppc_md.nvram_size();
93 if (*ppos >= size || size < 0)
94 goto out;
90 95
91 if (!access_ok(VERIFY_WRITE, buf, count)) 96 count = min_t(size_t, count, size - *ppos);
92 return -EFAULT; 97 count = min(count, PAGE_SIZE);
93 if (*ppos >= size)
94 return 0;
95 if (count > size)
96 count = size;
97 98
98 tmp_buffer = (char *) kmalloc(count, GFP_KERNEL); 99 ret = -ENOMEM;
99 if (!tmp_buffer) { 100 tmp = kmalloc(count, GFP_KERNEL);
100 printk(KERN_ERR "dev_read_nvram: kmalloc failed\n"); 101 if (!tmp)
101 return -ENOMEM; 102 goto out;
102 }
103 103
104 len = ppc_md.nvram_read(tmp_buffer, count, ppos); 104 ret = ppc_md.nvram_read(tmp, count, ppos);
105 if ((long)len <= 0) { 105 if (ret <= 0)
106 kfree(tmp_buffer); 106 goto out;
107 return len;
108 }
109 107
110 if (copy_to_user(buf, tmp_buffer, len)) { 108 if (copy_to_user(buf, tmp, ret))
111 kfree(tmp_buffer); 109 ret = -EFAULT;
112 return -EFAULT;
113 }
114 110
115 kfree(tmp_buffer); 111out:
116 return len; 112 kfree(tmp);
113 return ret;
117 114
118} 115}
119 116
120static ssize_t dev_nvram_write(struct file *file, const char __user *buf, 117static ssize_t dev_nvram_write(struct file *file, const char __user *buf,
121 size_t count, loff_t *ppos) 118 size_t count, loff_t *ppos)
122{ 119{
123 ssize_t len; 120 ssize_t ret;
124 char * tmp_buffer; 121 char *tmp = NULL;
125 int size; 122 ssize_t size;
126 123
127 if (ppc_md.nvram_size == NULL) 124 ret = -ENODEV;
128 return -ENODEV; 125 if (!ppc_md.nvram_size)
126 goto out;
127
128 ret = 0;
129 size = ppc_md.nvram_size(); 129 size = ppc_md.nvram_size();
130 if (*ppos >= size || size < 0)
131 goto out;
130 132
131 if (!access_ok(VERIFY_READ, buf, count)) 133 count = min_t(size_t, count, size - *ppos);
132 return -EFAULT; 134 count = min(count, PAGE_SIZE);
133 if (*ppos >= size)
134 return 0;
135 if (count > size)
136 count = size;
137 135
138 tmp_buffer = (char *) kmalloc(count, GFP_KERNEL); 136 ret = -ENOMEM;
139 if (!tmp_buffer) { 137 tmp = kmalloc(count, GFP_KERNEL);
140 printk(KERN_ERR "dev_nvram_write: kmalloc failed\n"); 138 if (!tmp)
141 return -ENOMEM; 139 goto out;
142 }
143
144 if (copy_from_user(tmp_buffer, buf, count)) {
145 kfree(tmp_buffer);
146 return -EFAULT;
147 }
148 140
149 len = ppc_md.nvram_write(tmp_buffer, count, ppos); 141 ret = -EFAULT;
150 if ((long)len <= 0) { 142 if (copy_from_user(tmp, buf, count))
151 kfree(tmp_buffer); 143 goto out;
152 return len; 144
153 } 145 ret = ppc_md.nvram_write(tmp, count, ppos);
146
147out:
148 kfree(tmp);
149 return ret;
154 150
155 kfree(tmp_buffer);
156 return len;
157} 151}
158 152
159static int dev_nvram_ioctl(struct inode *inode, struct file *file, 153static int dev_nvram_ioctl(struct inode *inode, struct file *file,
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index a7b68f911eb1..999bdd816769 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -17,6 +17,7 @@
17#include <asm/page.h> 17#include <asm/page.h>
18#include <asm/lppaca.h> 18#include <asm/lppaca.h>
19#include <asm/iseries/it_lp_queue.h> 19#include <asm/iseries/it_lp_queue.h>
20#include <asm/iseries/it_lp_reg_save.h>
20#include <asm/paca.h> 21#include <asm/paca.h>
21 22
22 23
@@ -26,8 +27,7 @@ extern unsigned long __toc_start;
26 27
27/* The Paca is an array with one entry per processor. Each contains an 28/* The Paca is an array with one entry per processor. Each contains an
28 * lppaca, which contains the information shared between the 29 * lppaca, which contains the information shared between the
29 * hypervisor and Linux. Each also contains an ItLpRegSave area which 30 * hypervisor and Linux.
30 * is used by the hypervisor to save registers.
31 * On systems with hardware multi-threading, there are two threads 31 * On systems with hardware multi-threading, there are two threads
32 * per processor. The Paca array must contain an entry for each thread. 32 * per processor. The Paca array must contain an entry for each thread.
33 * The VPD Areas will give a max logical processors = 2 * max physical 33 * The VPD Areas will give a max logical processors = 2 * max physical
@@ -37,7 +37,6 @@ extern unsigned long __toc_start;
37#define PACA_INIT_COMMON(number, start, asrr, asrv) \ 37#define PACA_INIT_COMMON(number, start, asrr, asrv) \
38 .lock_token = 0x8000, \ 38 .lock_token = 0x8000, \
39 .paca_index = (number), /* Paca Index */ \ 39 .paca_index = (number), /* Paca Index */ \
40 .default_decr = 0x00ff0000, /* Initial Decr */ \
41 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ 40 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
42 .stab_real = (asrr), /* Real pointer to segment table */ \ 41 .stab_real = (asrr), /* Real pointer to segment table */ \
43 .stab_addr = (asrv), /* Virt pointer to segment table */ \ 42 .stab_addr = (asrv), /* Virt pointer to segment table */ \
@@ -57,11 +56,7 @@ extern unsigned long __toc_start;
57#ifdef CONFIG_PPC_ISERIES 56#ifdef CONFIG_PPC_ISERIES
58#define PACA_INIT_ISERIES(number) \ 57#define PACA_INIT_ISERIES(number) \
59 .lppaca_ptr = &paca[number].lppaca, \ 58 .lppaca_ptr = &paca[number].lppaca, \
60 .reg_save_ptr = &paca[number].reg_save, \ 59 .reg_save_ptr = &iseries_reg_save[number],
61 .reg_save = { \
62 .xDesc = 0xd397d9e2, /* "LpRS" */ \
63 .xSize = sizeof(struct ItLpRegSave) \
64 }
65 60
66#define PACA_INIT(number) \ 61#define PACA_INIT(number) \
67{ \ 62{ \
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 8b6008ab217d..fc60a773af7d 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -34,7 +34,7 @@
34 34
35#ifdef DEBUG 35#ifdef DEBUG
36#include <asm/udbg.h> 36#include <asm/udbg.h>
37#define DBG(fmt...) udbg_printf(fmt) 37#define DBG(fmt...) printk(fmt)
38#else 38#else
39#define DBG(fmt...) 39#define DBG(fmt...)
40#endif 40#endif
@@ -251,7 +251,7 @@ void pcibios_free_controller(struct pci_controller *phb)
251 kfree(phb); 251 kfree(phb);
252} 252}
253 253
254static void __init pcibios_claim_one_bus(struct pci_bus *b) 254void __devinit pcibios_claim_one_bus(struct pci_bus *b)
255{ 255{
256 struct pci_dev *dev; 256 struct pci_dev *dev;
257 struct pci_bus *child_bus; 257 struct pci_bus *child_bus;
@@ -323,6 +323,7 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
323 addrs = (u32 *) get_property(node, "assigned-addresses", &proplen); 323 addrs = (u32 *) get_property(node, "assigned-addresses", &proplen);
324 if (!addrs) 324 if (!addrs)
325 return; 325 return;
326 DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs);
326 for (; proplen >= 20; proplen -= 20, addrs += 5) { 327 for (; proplen >= 20; proplen -= 20, addrs += 5) {
327 flags = pci_parse_of_flags(addrs[0]); 328 flags = pci_parse_of_flags(addrs[0]);
328 if (!flags) 329 if (!flags)
@@ -332,6 +333,9 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
332 if (!size) 333 if (!size)
333 continue; 334 continue;
334 i = addrs[0] & 0xff; 335 i = addrs[0] & 0xff;
336 DBG(" base: %llx, size: %llx, i: %x\n",
337 (unsigned long long)base, (unsigned long long)size, i);
338
335 if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { 339 if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
336 res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; 340 res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
337 } else if (i == dev->rom_base_reg) { 341 } else if (i == dev->rom_base_reg) {
@@ -362,6 +366,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
362 if (type == NULL) 366 if (type == NULL)
363 type = ""; 367 type = "";
364 368
369 DBG(" create device, devfn: %x, type: %s\n", devfn, type);
370
365 memset(dev, 0, sizeof(struct pci_dev)); 371 memset(dev, 0, sizeof(struct pci_dev));
366 dev->bus = bus; 372 dev->bus = bus;
367 dev->sysdata = node; 373 dev->sysdata = node;
@@ -381,6 +387,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
381 dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); 387 dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
382 dev->class = get_int_prop(node, "class-code", 0); 388 dev->class = get_int_prop(node, "class-code", 0);
383 389
390 DBG(" class: 0x%x\n", dev->class);
391
384 dev->current_state = 4; /* unknown power state */ 392 dev->current_state = 4; /* unknown power state */
385 393
386 if (!strcmp(type, "pci")) { 394 if (!strcmp(type, "pci")) {
@@ -402,6 +410,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
402 410
403 pci_parse_of_addrs(node, dev); 411 pci_parse_of_addrs(node, dev);
404 412
413 DBG(" adding to system ...\n");
414
405 pci_device_add(dev, bus); 415 pci_device_add(dev, bus);
406 416
407 /* XXX pci_scan_msi_device(dev); */ 417 /* XXX pci_scan_msi_device(dev); */
@@ -418,15 +428,21 @@ void __devinit of_scan_bus(struct device_node *node,
418 int reglen, devfn; 428 int reglen, devfn;
419 struct pci_dev *dev; 429 struct pci_dev *dev;
420 430
431 DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number);
432
421 while ((child = of_get_next_child(node, child)) != NULL) { 433 while ((child = of_get_next_child(node, child)) != NULL) {
434 DBG(" * %s\n", child->full_name);
422 reg = (u32 *) get_property(child, "reg", &reglen); 435 reg = (u32 *) get_property(child, "reg", &reglen);
423 if (reg == NULL || reglen < 20) 436 if (reg == NULL || reglen < 20)
424 continue; 437 continue;
425 devfn = (reg[0] >> 8) & 0xff; 438 devfn = (reg[0] >> 8) & 0xff;
439
426 /* create a new pci_dev for this device */ 440 /* create a new pci_dev for this device */
427 dev = of_create_pci_dev(child, bus, devfn); 441 dev = of_create_pci_dev(child, bus, devfn);
428 if (!dev) 442 if (!dev)
429 continue; 443 continue;
444 DBG("dev header type: %x\n", dev->hdr_type);
445
430 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 446 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
431 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) 447 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
432 of_scan_pci_bridge(child, dev); 448 of_scan_pci_bridge(child, dev);
@@ -446,16 +462,18 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
446 unsigned int flags; 462 unsigned int flags;
447 u64 size; 463 u64 size;
448 464
465 DBG("of_scan_pci_bridge(%s)\n", node->full_name);
466
449 /* parse bus-range property */ 467 /* parse bus-range property */
450 busrange = (u32 *) get_property(node, "bus-range", &len); 468 busrange = (u32 *) get_property(node, "bus-range", &len);
451 if (busrange == NULL || len != 8) { 469 if (busrange == NULL || len != 8) {
452 printk(KERN_ERR "Can't get bus-range for PCI-PCI bridge %s\n", 470 printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
453 node->full_name); 471 node->full_name);
454 return; 472 return;
455 } 473 }
456 ranges = (u32 *) get_property(node, "ranges", &len); 474 ranges = (u32 *) get_property(node, "ranges", &len);
457 if (ranges == NULL) { 475 if (ranges == NULL) {
458 printk(KERN_ERR "Can't get ranges for PCI-PCI bridge %s\n", 476 printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
459 node->full_name); 477 node->full_name);
460 return; 478 return;
461 } 479 }
@@ -509,10 +527,13 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
509 } 527 }
510 sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), 528 sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
511 bus->number); 529 bus->number);
530 DBG(" bus name: %s\n", bus->name);
512 531
513 mode = PCI_PROBE_NORMAL; 532 mode = PCI_PROBE_NORMAL;
514 if (ppc_md.pci_probe_mode) 533 if (ppc_md.pci_probe_mode)
515 mode = ppc_md.pci_probe_mode(bus); 534 mode = ppc_md.pci_probe_mode(bus);
535 DBG(" probe mode: %d\n", mode);
536
516 if (mode == PCI_PROBE_DEVTREE) 537 if (mode == PCI_PROBE_DEVTREE)
517 of_scan_bus(node, bus); 538 of_scan_bus(node, bus);
518 else if (mode == PCI_PROBE_NORMAL) 539 else if (mode == PCI_PROBE_NORMAL)
@@ -528,6 +549,8 @@ void __devinit scan_phb(struct pci_controller *hose)
528 int i, mode; 549 int i, mode;
529 struct resource *res; 550 struct resource *res;
530 551
552 DBG("Scanning PHB %s\n", node ? node->full_name : "<NO NAME>");
553
531 bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node); 554 bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node);
532 if (bus == NULL) { 555 if (bus == NULL) {
533 printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", 556 printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
@@ -552,8 +575,9 @@ void __devinit scan_phb(struct pci_controller *hose)
552 575
553 mode = PCI_PROBE_NORMAL; 576 mode = PCI_PROBE_NORMAL;
554#ifdef CONFIG_PPC_MULTIPLATFORM 577#ifdef CONFIG_PPC_MULTIPLATFORM
555 if (ppc_md.pci_probe_mode) 578 if (node && ppc_md.pci_probe_mode)
556 mode = ppc_md.pci_probe_mode(bus); 579 mode = ppc_md.pci_probe_mode(bus);
580 DBG(" probe mode: %d\n", mode);
557 if (mode == PCI_PROBE_DEVTREE) { 581 if (mode == PCI_PROBE_DEVTREE) {
558 bus->subordinate = hose->last_busno; 582 bus->subordinate = hose->last_busno;
559 of_scan_bus(node, bus); 583 of_scan_bus(node, bus);
@@ -842,8 +866,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file,
842 * Returns a negative error code on failure, zero on success. 866 * Returns a negative error code on failure, zero on success.
843 */ 867 */
844int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, 868int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
845 enum pci_mmap_state mmap_state, 869 enum pci_mmap_state mmap_state, int write_combine)
846 int write_combine)
847{ 870{
848 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 871 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
849 struct resource *rp; 872 struct resource *rp;
@@ -896,6 +919,25 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
896 unsigned long phb_io_base_phys, 919 unsigned long phb_io_base_phys,
897 void __iomem * phb_io_base_virt) 920 void __iomem * phb_io_base_virt)
898{ 921{
922 /* Remove these asap */
923
924 struct pci_address {
925 u32 a_hi;
926 u32 a_mid;
927 u32 a_lo;
928 };
929
930 struct isa_address {
931 u32 a_hi;
932 u32 a_lo;
933 };
934
935 struct isa_range {
936 struct isa_address isa_addr;
937 struct pci_address pci_addr;
938 unsigned int size;
939 };
940
899 struct isa_range *range; 941 struct isa_range *range;
900 unsigned long pci_addr; 942 unsigned long pci_addr;
901 unsigned int isa_addr; 943 unsigned int isa_addr;
@@ -1223,6 +1265,7 @@ void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
1223} 1265}
1224EXPORT_SYMBOL(pcibios_fixup_device_resources); 1266EXPORT_SYMBOL(pcibios_fixup_device_resources);
1225 1267
1268
1226static void __devinit do_bus_setup(struct pci_bus *bus) 1269static void __devinit do_bus_setup(struct pci_bus *bus)
1227{ 1270{
1228 struct pci_dev *dev; 1271 struct pci_dev *dev;
@@ -1306,8 +1349,38 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
1306 *end = rsrc->end + offset; 1349 *end = rsrc->end + offset;
1307} 1350}
1308 1351
1352struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
1353{
1354 if (!have_of)
1355 return NULL;
1356 while(node) {
1357 struct pci_controller *hose, *tmp;
1358 list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
1359 if (hose->arch_data == node)
1360 return hose;
1361 node = node->parent;
1362 }
1363 return NULL;
1364}
1365
1309#endif /* CONFIG_PPC_MULTIPLATFORM */ 1366#endif /* CONFIG_PPC_MULTIPLATFORM */
1310 1367
1368unsigned long pci_address_to_pio(phys_addr_t address)
1369{
1370 struct pci_controller *hose, *tmp;
1371
1372 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
1373 if (address >= hose->io_base_phys &&
1374 address < (hose->io_base_phys + hose->pci_io_size)) {
1375 unsigned long base =
1376 (unsigned long)hose->io_base_virt - pci_io_base;
1377 return base + (address - hose->io_base_phys);
1378 }
1379 }
1380 return (unsigned int)-1;
1381}
1382EXPORT_SYMBOL_GPL(pci_address_to_pio);
1383
1311 1384
1312#define IOBASE_BRIDGE_NUMBER 0 1385#define IOBASE_BRIDGE_NUMBER 0
1313#define IOBASE_MEMORY 1 1386#define IOBASE_MEMORY 1
diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c
index 2d333cc84082..e6fb194fe537 100644
--- a/arch/powerpc/kernel/pmc.c
+++ b/arch/powerpc/kernel/pmc.c
@@ -43,8 +43,13 @@ static void dummy_perf(struct pt_regs *regs)
43 mtspr(SPRN_MMCR0, mmcr0); 43 mtspr(SPRN_MMCR0, mmcr0);
44} 44}
45#else 45#else
46/* Ensure exceptions are disabled */
46static void dummy_perf(struct pt_regs *regs) 47static void dummy_perf(struct pt_regs *regs)
47{ 48{
49 unsigned int mmcr0 = mfspr(SPRN_MMCR0);
50
51 mmcr0 &= ~(MMCR0_PMXE);
52 mtspr(SPRN_MMCR0, mmcr0);
48} 53}
49#endif 54#endif
50 55
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 94db25708456..b2758148a0de 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -76,11 +76,6 @@ EXPORT_SYMBOL(single_step_exception);
76EXPORT_SYMBOL(sys_sigreturn); 76EXPORT_SYMBOL(sys_sigreturn);
77#endif 77#endif
78 78
79#if defined(CONFIG_PPC_PREP)
80EXPORT_SYMBOL(_prep_type);
81EXPORT_SYMBOL(ucSystemType);
82#endif
83
84EXPORT_SYMBOL(strcpy); 79EXPORT_SYMBOL(strcpy);
85EXPORT_SYMBOL(strncpy); 80EXPORT_SYMBOL(strncpy);
86EXPORT_SYMBOL(strcat); 81EXPORT_SYMBOL(strcat);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 3bf968e74095..977ee3adaf2d 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -29,6 +29,7 @@
29#include <linux/initrd.h> 29#include <linux/initrd.h>
30#include <linux/bitops.h> 30#include <linux/bitops.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/kexec.h>
32 33
33#include <asm/prom.h> 34#include <asm/prom.h>
34#include <asm/rtas.h> 35#include <asm/rtas.h>
@@ -37,6 +38,7 @@
37#include <asm/processor.h> 38#include <asm/processor.h>
38#include <asm/irq.h> 39#include <asm/irq.h>
39#include <asm/io.h> 40#include <asm/io.h>
41#include <asm/kdump.h>
40#include <asm/smp.h> 42#include <asm/smp.h>
41#include <asm/system.h> 43#include <asm/system.h>
42#include <asm/mmu.h> 44#include <asm/mmu.h>
@@ -55,21 +57,6 @@
55#define DBG(fmt...) 57#define DBG(fmt...)
56#endif 58#endif
57 59
58struct pci_reg_property {
59 struct pci_address addr;
60 u32 size_hi;
61 u32 size_lo;
62};
63
64struct isa_reg_property {
65 u32 space;
66 u32 address;
67 u32 size;
68};
69
70
71typedef int interpret_func(struct device_node *, unsigned long *,
72 int, int, int);
73 60
74static int __initdata dt_root_addr_cells; 61static int __initdata dt_root_addr_cells;
75static int __initdata dt_root_size_cells; 62static int __initdata dt_root_size_cells;
@@ -311,6 +298,16 @@ static int __devinit finish_node_interrupts(struct device_node *np,
311 int i, j, n, sense; 298 int i, j, n, sense;
312 unsigned int *irq, virq; 299 unsigned int *irq, virq;
313 struct device_node *ic; 300 struct device_node *ic;
301 int trace = 0;
302
303 //#define TRACE(fmt...) do { if (trace) { printk(fmt); mdelay(1000); } } while(0)
304#define TRACE(fmt...)
305
306 if (!strcmp(np->name, "smu-doorbell"))
307 trace = 1;
308
309 TRACE("Finishing SMU doorbell ! num_interrupt_controllers = %d\n",
310 num_interrupt_controllers);
314 311
315 if (num_interrupt_controllers == 0) { 312 if (num_interrupt_controllers == 0) {
316 /* 313 /*
@@ -345,11 +342,12 @@ static int __devinit finish_node_interrupts(struct device_node *np,
345 } 342 }
346 343
347 ints = (unsigned int *) get_property(np, "interrupts", &intlen); 344 ints = (unsigned int *) get_property(np, "interrupts", &intlen);
345 TRACE("ints=%p, intlen=%d\n", ints, intlen);
348 if (ints == NULL) 346 if (ints == NULL)
349 return 0; 347 return 0;
350 intrcells = prom_n_intr_cells(np); 348 intrcells = prom_n_intr_cells(np);
351 intlen /= intrcells * sizeof(unsigned int); 349 intlen /= intrcells * sizeof(unsigned int);
352 350 TRACE("intrcells=%d, new intlen=%d\n", intrcells, intlen);
353 np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start); 351 np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start);
354 if (!np->intrs) 352 if (!np->intrs)
355 return -ENOMEM; 353 return -ENOMEM;
@@ -360,6 +358,7 @@ static int __devinit finish_node_interrupts(struct device_node *np,
360 intrcount = 0; 358 intrcount = 0;
361 for (i = 0; i < intlen; ++i, ints += intrcells) { 359 for (i = 0; i < intlen; ++i, ints += intrcells) {
362 n = map_interrupt(&irq, &ic, np, ints, intrcells); 360 n = map_interrupt(&irq, &ic, np, ints, intrcells);
361 TRACE("map, irq=%d, ic=%p, n=%d\n", irq, ic, n);
363 if (n <= 0) 362 if (n <= 0)
364 continue; 363 continue;
365 364
@@ -370,6 +369,7 @@ static int __devinit finish_node_interrupts(struct device_node *np,
370 np->intrs[intrcount].sense = map_isa_senses[sense]; 369 np->intrs[intrcount].sense = map_isa_senses[sense];
371 } else { 370 } else {
372 virq = virt_irq_create_mapping(irq[0]); 371 virq = virt_irq_create_mapping(irq[0]);
372 TRACE("virq=%d\n", virq);
373#ifdef CONFIG_PPC64 373#ifdef CONFIG_PPC64
374 if (virq == NO_IRQ) { 374 if (virq == NO_IRQ) {
375 printk(KERN_CRIT "Could not allocate interrupt" 375 printk(KERN_CRIT "Could not allocate interrupt"
@@ -379,6 +379,12 @@ static int __devinit finish_node_interrupts(struct device_node *np,
379#endif 379#endif
380 np->intrs[intrcount].line = irq_offset_up(virq); 380 np->intrs[intrcount].line = irq_offset_up(virq);
381 sense = (n > 1)? (irq[1] & 3): 1; 381 sense = (n > 1)? (irq[1] & 3): 1;
382
383 /* Apple uses bits in there in a different way, let's
384 * only keep the real sense bit on macs
385 */
386 if (_machine == PLATFORM_POWERMAC)
387 sense &= 0x1;
382 np->intrs[intrcount].sense = map_mpic_senses[sense]; 388 np->intrs[intrcount].sense = map_mpic_senses[sense];
383 } 389 }
384 390
@@ -388,12 +394,13 @@ static int __devinit finish_node_interrupts(struct device_node *np,
388 char *name = get_property(ic->parent, "name", NULL); 394 char *name = get_property(ic->parent, "name", NULL);
389 if (name && !strcmp(name, "u3")) 395 if (name && !strcmp(name, "u3"))
390 np->intrs[intrcount].line += 128; 396 np->intrs[intrcount].line += 128;
391 else if (!(name && !strcmp(name, "mac-io"))) 397 else if (!(name && (!strcmp(name, "mac-io") ||
398 !strcmp(name, "u4"))))
392 /* ignore other cascaded controllers, such as 399 /* ignore other cascaded controllers, such as
393 the k2-sata-root */ 400 the k2-sata-root */
394 break; 401 break;
395 } 402 }
396#endif 403#endif /* CONFIG_PPC64 */
397 if (n > 2) { 404 if (n > 2) {
398 printk("hmmm, got %d intr cells for %s:", n, 405 printk("hmmm, got %d intr cells for %s:", n,
399 np->full_name); 406 np->full_name);
@@ -408,234 +415,19 @@ static int __devinit finish_node_interrupts(struct device_node *np,
408 return 0; 415 return 0;
409} 416}
410 417
411static int __devinit interpret_pci_props(struct device_node *np,
412 unsigned long *mem_start,
413 int naddrc, int nsizec,
414 int measure_only)
415{
416 struct address_range *adr;
417 struct pci_reg_property *pci_addrs;
418 int i, l, n_addrs;
419
420 pci_addrs = (struct pci_reg_property *)
421 get_property(np, "assigned-addresses", &l);
422 if (!pci_addrs)
423 return 0;
424
425 n_addrs = l / sizeof(*pci_addrs);
426
427 adr = prom_alloc(n_addrs * sizeof(*adr), mem_start);
428 if (!adr)
429 return -ENOMEM;
430
431 if (measure_only)
432 return 0;
433
434 np->addrs = adr;
435 np->n_addrs = n_addrs;
436
437 for (i = 0; i < n_addrs; i++) {
438 adr[i].space = pci_addrs[i].addr.a_hi;
439 adr[i].address = pci_addrs[i].addr.a_lo |
440 ((u64)pci_addrs[i].addr.a_mid << 32);
441 adr[i].size = pci_addrs[i].size_lo;
442 }
443
444 return 0;
445}
446
447static int __init interpret_dbdma_props(struct device_node *np,
448 unsigned long *mem_start,
449 int naddrc, int nsizec,
450 int measure_only)
451{
452 struct reg_property32 *rp;
453 struct address_range *adr;
454 unsigned long base_address;
455 int i, l;
456 struct device_node *db;
457
458 base_address = 0;
459 if (!measure_only) {
460 for (db = np->parent; db != NULL; db = db->parent) {
461 if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
462 base_address = db->addrs[0].address;
463 break;
464 }
465 }
466 }
467
468 rp = (struct reg_property32 *) get_property(np, "reg", &l);
469 if (rp != 0 && l >= sizeof(struct reg_property32)) {
470 i = 0;
471 adr = (struct address_range *) (*mem_start);
472 while ((l -= sizeof(struct reg_property32)) >= 0) {
473 if (!measure_only) {
474 adr[i].space = 2;
475 adr[i].address = rp[i].address + base_address;
476 adr[i].size = rp[i].size;
477 }
478 ++i;
479 }
480 np->addrs = adr;
481 np->n_addrs = i;
482 (*mem_start) += i * sizeof(struct address_range);
483 }
484
485 return 0;
486}
487
488static int __init interpret_macio_props(struct device_node *np,
489 unsigned long *mem_start,
490 int naddrc, int nsizec,
491 int measure_only)
492{
493 struct reg_property32 *rp;
494 struct address_range *adr;
495 unsigned long base_address;
496 int i, l;
497 struct device_node *db;
498
499 base_address = 0;
500 if (!measure_only) {
501 for (db = np->parent; db != NULL; db = db->parent) {
502 if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
503 base_address = db->addrs[0].address;
504 break;
505 }
506 }
507 }
508
509 rp = (struct reg_property32 *) get_property(np, "reg", &l);
510 if (rp != 0 && l >= sizeof(struct reg_property32)) {
511 i = 0;
512 adr = (struct address_range *) (*mem_start);
513 while ((l -= sizeof(struct reg_property32)) >= 0) {
514 if (!measure_only) {
515 adr[i].space = 2;
516 adr[i].address = rp[i].address + base_address;
517 adr[i].size = rp[i].size;
518 }
519 ++i;
520 }
521 np->addrs = adr;
522 np->n_addrs = i;
523 (*mem_start) += i * sizeof(struct address_range);
524 }
525
526 return 0;
527}
528
529static int __init interpret_isa_props(struct device_node *np,
530 unsigned long *mem_start,
531 int naddrc, int nsizec,
532 int measure_only)
533{
534 struct isa_reg_property *rp;
535 struct address_range *adr;
536 int i, l;
537
538 rp = (struct isa_reg_property *) get_property(np, "reg", &l);
539 if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
540 i = 0;
541 adr = (struct address_range *) (*mem_start);
542 while ((l -= sizeof(struct isa_reg_property)) >= 0) {
543 if (!measure_only) {
544 adr[i].space = rp[i].space;
545 adr[i].address = rp[i].address;
546 adr[i].size = rp[i].size;
547 }
548 ++i;
549 }
550 np->addrs = adr;
551 np->n_addrs = i;
552 (*mem_start) += i * sizeof(struct address_range);
553 }
554
555 return 0;
556}
557
558static int __init interpret_root_props(struct device_node *np,
559 unsigned long *mem_start,
560 int naddrc, int nsizec,
561 int measure_only)
562{
563 struct address_range *adr;
564 int i, l;
565 unsigned int *rp;
566 int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
567
568 rp = (unsigned int *) get_property(np, "reg", &l);
569 if (rp != 0 && l >= rpsize) {
570 i = 0;
571 adr = (struct address_range *) (*mem_start);
572 while ((l -= rpsize) >= 0) {
573 if (!measure_only) {
574 adr[i].space = 0;
575 adr[i].address = rp[naddrc - 1];
576 adr[i].size = rp[naddrc + nsizec - 1];
577 }
578 ++i;
579 rp += naddrc + nsizec;
580 }
581 np->addrs = adr;
582 np->n_addrs = i;
583 (*mem_start) += i * sizeof(struct address_range);
584 }
585
586 return 0;
587}
588
589static int __devinit finish_node(struct device_node *np, 418static int __devinit finish_node(struct device_node *np,
590 unsigned long *mem_start, 419 unsigned long *mem_start,
591 interpret_func *ifunc,
592 int naddrc, int nsizec,
593 int measure_only) 420 int measure_only)
594{ 421{
595 struct device_node *child; 422 struct device_node *child;
596 int *ip, rc = 0; 423 int rc = 0;
597
598 /* get the device addresses and interrupts */
599 if (ifunc != NULL)
600 rc = ifunc(np, mem_start, naddrc, nsizec, measure_only);
601 if (rc)
602 goto out;
603 424
604 rc = finish_node_interrupts(np, mem_start, measure_only); 425 rc = finish_node_interrupts(np, mem_start, measure_only);
605 if (rc) 426 if (rc)
606 goto out; 427 goto out;
607 428
608 /* Look for #address-cells and #size-cells properties. */
609 ip = (int *) get_property(np, "#address-cells", NULL);
610 if (ip != NULL)
611 naddrc = *ip;
612 ip = (int *) get_property(np, "#size-cells", NULL);
613 if (ip != NULL)
614 nsizec = *ip;
615
616 if (!strcmp(np->name, "device-tree") || np->parent == NULL)
617 ifunc = interpret_root_props;
618 else if (np->type == 0)
619 ifunc = NULL;
620 else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
621 ifunc = interpret_pci_props;
622 else if (!strcmp(np->type, "dbdma"))
623 ifunc = interpret_dbdma_props;
624 else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
625 ifunc = interpret_macio_props;
626 else if (!strcmp(np->type, "isa"))
627 ifunc = interpret_isa_props;
628 else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
629 ifunc = interpret_root_props;
630 else if (!((ifunc == interpret_dbdma_props
631 || ifunc == interpret_macio_props)
632 && (!strcmp(np->type, "escc")
633 || !strcmp(np->type, "media-bay"))))
634 ifunc = NULL;
635
636 for (child = np->child; child != NULL; child = child->sibling) { 429 for (child = np->child; child != NULL; child = child->sibling) {
637 rc = finish_node(child, mem_start, ifunc, 430 rc = finish_node(child, mem_start, measure_only);
638 naddrc, nsizec, measure_only);
639 if (rc) 431 if (rc)
640 goto out; 432 goto out;
641 } 433 }
@@ -697,10 +489,10 @@ void __init finish_device_tree(void)
697 * reason and then remove those additional 16 bytes 489 * reason and then remove those additional 16 bytes
698 */ 490 */
699 size = 16; 491 size = 16;
700 finish_node(allnodes, &size, NULL, 0, 0, 1); 492 finish_node(allnodes, &size, 1);
701 size -= 16; 493 size -= 16;
702 end = start = (unsigned long) __va(lmb_alloc(size, 128)); 494 end = start = (unsigned long) __va(lmb_alloc(size, 128));
703 finish_node(allnodes, &end, NULL, 0, 0, 0); 495 finish_node(allnodes, &end, 0);
704 BUG_ON(end != start + size); 496 BUG_ON(end != start + size);
705 497
706 DBG(" <- finish_device_tree\n"); 498 DBG(" <- finish_device_tree\n");
@@ -1197,6 +989,16 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
1197 } 989 }
1198#endif /* CONFIG_PPC_RTAS */ 990#endif /* CONFIG_PPC_RTAS */
1199 991
992#ifdef CONFIG_KEXEC
993 lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL);
994 if (lprop)
995 crashk_res.start = *lprop;
996
997 lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-size", NULL);
998 if (lprop)
999 crashk_res.end = crashk_res.start + *lprop - 1;
1000#endif
1001
1200 /* break now */ 1002 /* break now */
1201 return 1; 1003 return 1;
1202} 1004}
@@ -1263,7 +1065,9 @@ static int __init early_init_dt_scan_memory(unsigned long node,
1263 } else if (strcmp(type, "memory") != 0) 1065 } else if (strcmp(type, "memory") != 0)
1264 return 0; 1066 return 0;
1265 1067
1266 reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l); 1068 reg = (cell_t *)of_get_flat_dt_prop(node, "linux,usable-memory", &l);
1069 if (reg == NULL)
1070 reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
1267 if (reg == NULL) 1071 if (reg == NULL)
1268 return 0; 1072 return 0;
1269 1073
@@ -1335,11 +1139,14 @@ void __init early_init_devtree(void *params)
1335 of_scan_flat_dt(early_init_dt_scan_memory, NULL); 1139 of_scan_flat_dt(early_init_dt_scan_memory, NULL);
1336 lmb_enforce_memory_limit(memory_limit); 1140 lmb_enforce_memory_limit(memory_limit);
1337 lmb_analyze(); 1141 lmb_analyze();
1338 lmb_reserve(0, __pa(klimit));
1339 1142
1340 DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); 1143 DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
1341 1144
1342 /* Reserve LMB regions used by kernel, initrd, dt, etc... */ 1145 /* Reserve LMB regions used by kernel, initrd, dt, etc... */
1146 lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
1147#ifdef CONFIG_CRASH_DUMP
1148 lmb_reserve(0, KDUMP_RESERVE_LIMIT);
1149#endif
1343 early_reserve_mem(); 1150 early_reserve_mem();
1344 1151
1345 DBG("Scanning CPUs ...\n"); 1152 DBG("Scanning CPUs ...\n");
@@ -1802,7 +1609,6 @@ static void of_node_release(struct kref *kref)
1802 prop = next; 1609 prop = next;
1803 } 1610 }
1804 kfree(node->intrs); 1611 kfree(node->intrs);
1805 kfree(node->addrs);
1806 kfree(node->full_name); 1612 kfree(node->full_name);
1807 kfree(node->data); 1613 kfree(node->data);
1808 kfree(node); 1614 kfree(node);
@@ -1884,9 +1690,7 @@ void of_detach_node(const struct device_node *np)
1884 * This should probably be split up into smaller chunks. 1690 * This should probably be split up into smaller chunks.
1885 */ 1691 */
1886 1692
1887static int of_finish_dynamic_node(struct device_node *node, 1693static int of_finish_dynamic_node(struct device_node *node)
1888 unsigned long *unused1, int unused2,
1889 int unused3, int unused4)
1890{ 1694{
1891 struct device_node *parent = of_get_parent(node); 1695 struct device_node *parent = of_get_parent(node);
1892 int err = 0; 1696 int err = 0;
@@ -1907,7 +1711,8 @@ static int of_finish_dynamic_node(struct device_node *node,
1907 return -ENODEV; 1711 return -ENODEV;
1908 1712
1909 /* fix up new node's linux_phandle field */ 1713 /* fix up new node's linux_phandle field */
1910 if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL))) 1714 if ((ibm_phandle = (unsigned int *)get_property(node,
1715 "ibm,phandle", NULL)))
1911 node->linux_phandle = *ibm_phandle; 1716 node->linux_phandle = *ibm_phandle;
1912 1717
1913out: 1718out:
@@ -1922,7 +1727,9 @@ static int prom_reconfig_notifier(struct notifier_block *nb,
1922 1727
1923 switch (action) { 1728 switch (action) {
1924 case PSERIES_RECONFIG_ADD: 1729 case PSERIES_RECONFIG_ADD:
1925 err = finish_node(node, NULL, of_finish_dynamic_node, 0, 0, 0); 1730 err = of_finish_dynamic_node(node);
1731 if (!err)
1732 finish_node(node, NULL, 0);
1926 if (err < 0) { 1733 if (err < 0) {
1927 printk(KERN_ERR "finish_node returned %d\n", err); 1734 printk(KERN_ERR "finish_node returned %d\n", err);
1928 err = NOTIFY_BAD; 1735 err = NOTIFY_BAD;
@@ -1996,175 +1803,4 @@ int prom_add_property(struct device_node* np, struct property* prop)
1996 return 0; 1803 return 0;
1997} 1804}
1998 1805
1999/* I quickly hacked that one, check against spec ! */
2000static inline unsigned long
2001bus_space_to_resource_flags(unsigned int bus_space)
2002{
2003 u8 space = (bus_space >> 24) & 0xf;
2004 if (space == 0)
2005 space = 0x02;
2006 if (space == 0x02)
2007 return IORESOURCE_MEM;
2008 else if (space == 0x01)
2009 return IORESOURCE_IO;
2010 else {
2011 printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n",
2012 bus_space);
2013 return 0;
2014 }
2015}
2016
2017#ifdef CONFIG_PCI
2018static struct resource *find_parent_pci_resource(struct pci_dev* pdev,
2019 struct address_range *range)
2020{
2021 unsigned long mask;
2022 int i;
2023
2024 /* Check this one */
2025 mask = bus_space_to_resource_flags(range->space);
2026 for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
2027 if ((pdev->resource[i].flags & mask) == mask &&
2028 pdev->resource[i].start <= range->address &&
2029 pdev->resource[i].end > range->address) {
2030 if ((range->address + range->size - 1) > pdev->resource[i].end) {
2031 /* Add better message */
2032 printk(KERN_WARNING "PCI/OF resource overlap !\n");
2033 return NULL;
2034 }
2035 break;
2036 }
2037 }
2038 if (i == DEVICE_COUNT_RESOURCE)
2039 return NULL;
2040 return &pdev->resource[i];
2041}
2042
2043/*
2044 * Request an OF device resource. Currently handles child of PCI devices,
2045 * or other nodes attached to the root node. Ultimately, put some
2046 * link to resources in the OF node.
2047 */
2048struct resource *request_OF_resource(struct device_node* node, int index,
2049 const char* name_postfix)
2050{
2051 struct pci_dev* pcidev;
2052 u8 pci_bus, pci_devfn;
2053 unsigned long iomask;
2054 struct device_node* nd;
2055 struct resource* parent;
2056 struct resource *res = NULL;
2057 int nlen, plen;
2058
2059 if (index >= node->n_addrs)
2060 goto fail;
2061
2062 /* Sanity check on bus space */
2063 iomask = bus_space_to_resource_flags(node->addrs[index].space);
2064 if (iomask & IORESOURCE_MEM)
2065 parent = &iomem_resource;
2066 else if (iomask & IORESOURCE_IO)
2067 parent = &ioport_resource;
2068 else
2069 goto fail;
2070
2071 /* Find a PCI parent if any */
2072 nd = node;
2073 pcidev = NULL;
2074 while (nd) {
2075 if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
2076 pcidev = pci_find_slot(pci_bus, pci_devfn);
2077 if (pcidev) break;
2078 nd = nd->parent;
2079 }
2080 if (pcidev)
2081 parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
2082 if (!parent) {
2083 printk(KERN_WARNING "request_OF_resource(%s), parent not found\n",
2084 node->name);
2085 goto fail;
2086 }
2087 1806
2088 res = __request_region(parent, node->addrs[index].address,
2089 node->addrs[index].size, NULL);
2090 if (!res)
2091 goto fail;
2092 nlen = strlen(node->name);
2093 plen = name_postfix ? strlen(name_postfix) : 0;
2094 res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL);
2095 if (res->name) {
2096 strcpy((char *)res->name, node->name);
2097 if (plen)
2098 strcpy((char *)res->name+nlen, name_postfix);
2099 }
2100 return res;
2101fail:
2102 return NULL;
2103}
2104EXPORT_SYMBOL(request_OF_resource);
2105
2106int release_OF_resource(struct device_node *node, int index)
2107{
2108 struct pci_dev* pcidev;
2109 u8 pci_bus, pci_devfn;
2110 unsigned long iomask, start, end;
2111 struct device_node* nd;
2112 struct resource* parent;
2113 struct resource *res = NULL;
2114
2115 if (index >= node->n_addrs)
2116 return -EINVAL;
2117
2118 /* Sanity check on bus space */
2119 iomask = bus_space_to_resource_flags(node->addrs[index].space);
2120 if (iomask & IORESOURCE_MEM)
2121 parent = &iomem_resource;
2122 else if (iomask & IORESOURCE_IO)
2123 parent = &ioport_resource;
2124 else
2125 return -EINVAL;
2126
2127 /* Find a PCI parent if any */
2128 nd = node;
2129 pcidev = NULL;
2130 while(nd) {
2131 if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
2132 pcidev = pci_find_slot(pci_bus, pci_devfn);
2133 if (pcidev) break;
2134 nd = nd->parent;
2135 }
2136 if (pcidev)
2137 parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
2138 if (!parent) {
2139 printk(KERN_WARNING "release_OF_resource(%s), parent not found\n",
2140 node->name);
2141 return -ENODEV;
2142 }
2143
2144 /* Find us in the parent and its childs */
2145 res = parent->child;
2146 start = node->addrs[index].address;
2147 end = start + node->addrs[index].size - 1;
2148 while (res) {
2149 if (res->start == start && res->end == end &&
2150 (res->flags & IORESOURCE_BUSY))
2151 break;
2152 if (res->start <= start && res->end >= end)
2153 res = res->child;
2154 else
2155 res = res->sibling;
2156 }
2157 if (!res)
2158 return -ENODEV;
2159
2160 if (res->name) {
2161 kfree(res->name);
2162 res->name = NULL;
2163 }
2164 release_resource(res);
2165 kfree(res);
2166
2167 return 0;
2168}
2169EXPORT_SYMBOL(release_OF_resource);
2170#endif /* CONFIG_PCI */
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index bcdc209dca85..e381f2fc121c 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -192,6 +192,11 @@ static unsigned long __initdata alloc_bottom;
192static unsigned long __initdata rmo_top; 192static unsigned long __initdata rmo_top;
193static unsigned long __initdata ram_top; 193static unsigned long __initdata ram_top;
194 194
195#ifdef CONFIG_KEXEC
196static unsigned long __initdata prom_crashk_base;
197static unsigned long __initdata prom_crashk_size;
198#endif
199
195static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE]; 200static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
196static int __initdata mem_reserve_cnt; 201static int __initdata mem_reserve_cnt;
197 202
@@ -553,7 +558,8 @@ unsigned long prom_memparse(const char *ptr, const char **retptr)
553static void __init early_cmdline_parse(void) 558static void __init early_cmdline_parse(void)
554{ 559{
555 struct prom_t *_prom = &RELOC(prom); 560 struct prom_t *_prom = &RELOC(prom);
556 char *opt, *p; 561 const char *opt;
562 char *p;
557 int l = 0; 563 int l = 0;
558 564
559 RELOC(prom_cmd_line[0]) = 0; 565 RELOC(prom_cmd_line[0]) = 0;
@@ -590,6 +596,34 @@ static void __init early_cmdline_parse(void)
590 RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000); 596 RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
591#endif 597#endif
592 } 598 }
599
600#ifdef CONFIG_KEXEC
601 /*
602 * crashkernel=size@addr specifies the location to reserve for
603 * crash kernel.
604 */
605 opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel="));
606 if (opt) {
607 opt += 12;
608 RELOC(prom_crashk_size) = prom_memparse(opt, &opt);
609
610 if (ALIGN(RELOC(prom_crashk_size), 0x1000000) !=
611 RELOC(prom_crashk_size)) {
612 prom_printf("Warning: crashkernel size is not "
613 "aligned to 16MB\n");
614 }
615
616 /*
617 * At present, the crash kernel always run at 32MB.
618 * Just ignore whatever user passed.
619 */
620 RELOC(prom_crashk_base) = 0x2000000;
621 if (*opt == '@') {
622 prom_printf("Warning: PPC64 kdump kernel always runs "
623 "at 32 MB\n");
624 }
625 }
626#endif
593} 627}
594 628
595#ifdef CONFIG_PPC_PSERIES 629#ifdef CONFIG_PPC_PSERIES
@@ -1011,6 +1045,12 @@ static void __init prom_init_mem(void)
1011 prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); 1045 prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
1012 prom_printf(" rmo_top : %x\n", RELOC(rmo_top)); 1046 prom_printf(" rmo_top : %x\n", RELOC(rmo_top));
1013 prom_printf(" ram_top : %x\n", RELOC(ram_top)); 1047 prom_printf(" ram_top : %x\n", RELOC(ram_top));
1048#ifdef CONFIG_KEXEC
1049 if (RELOC(prom_crashk_base)) {
1050 prom_printf(" crashk_base : %x\n", RELOC(prom_crashk_base));
1051 prom_printf(" crashk_size : %x\n", RELOC(prom_crashk_size));
1052 }
1053#endif
1014} 1054}
1015 1055
1016 1056
@@ -1500,6 +1540,8 @@ static int __init prom_find_machine_type(void)
1500#ifdef CONFIG_PPC64 1540#ifdef CONFIG_PPC64
1501 if (strstr(p, RELOC("Momentum,Maple"))) 1541 if (strstr(p, RELOC("Momentum,Maple")))
1502 return PLATFORM_MAPLE; 1542 return PLATFORM_MAPLE;
1543 if (strstr(p, RELOC("IBM,CPB")))
1544 return PLATFORM_CELL;
1503#endif 1545#endif
1504 i += sl + 1; 1546 i += sl + 1;
1505 } 1547 }
@@ -1994,7 +2036,7 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
1994 if (r3 && r4 && r4 != 0xdeadbeef) { 2036 if (r3 && r4 && r4 != 0xdeadbeef) {
1995 unsigned long val; 2037 unsigned long val;
1996 2038
1997 RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3; 2039 RELOC(prom_initrd_start) = is_kernel_addr(r3) ? __pa(r3) : r3;
1998 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4; 2040 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
1999 2041
2000 val = RELOC(prom_initrd_start); 2042 val = RELOC(prom_initrd_start);
@@ -2094,6 +2136,10 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2094 */ 2136 */
2095 prom_init_mem(); 2137 prom_init_mem();
2096 2138
2139#ifdef CONFIG_KEXEC
2140 if (RELOC(prom_crashk_base))
2141 reserve_mem(RELOC(prom_crashk_base), RELOC(prom_crashk_size));
2142#endif
2097 /* 2143 /*
2098 * Determine which cpu is actually running right _now_ 2144 * Determine which cpu is actually running right _now_
2099 */ 2145 */
@@ -2150,6 +2196,16 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2150 } 2196 }
2151#endif 2197#endif
2152 2198
2199#ifdef CONFIG_KEXEC
2200 if (RELOC(prom_crashk_base)) {
2201 prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-base",
2202 PTRRELOC(&prom_crashk_base),
2203 sizeof(RELOC(prom_crashk_base)));
2204 prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-size",
2205 PTRRELOC(&prom_crashk_size),
2206 sizeof(RELOC(prom_crashk_size)));
2207 }
2208#endif
2153 /* 2209 /*
2154 * Fixup any known bugs in the device-tree 2210 * Fixup any known bugs in the device-tree
2155 */ 2211 */
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
new file mode 100644
index 000000000000..309ae1d5fa77
--- /dev/null
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -0,0 +1,547 @@
1#undef DEBUG
2
3#include <linux/kernel.h>
4#include <linux/string.h>
5#include <linux/pci_regs.h>
6#include <linux/module.h>
7#include <linux/ioport.h>
8#include <asm/prom.h>
9#include <asm/pci-bridge.h>
10
11#ifdef DEBUG
12#define DBG(fmt...) do { printk(fmt); } while(0)
13#else
14#define DBG(fmt...) do { } while(0)
15#endif
16
17#ifdef CONFIG_PPC64
18#define PRu64 "%lx"
19#else
20#define PRu64 "%llx"
21#endif
22
23/* Max address size we deal with */
24#define OF_MAX_ADDR_CELLS 4
25#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
26 (ns) > 0)
27
28/* Debug utility */
29#ifdef DEBUG
30static void of_dump_addr(const char *s, u32 *addr, int na)
31{
32 printk("%s", s);
33 while(na--)
34 printk(" %08x", *(addr++));
35 printk("\n");
36}
37#else
38static void of_dump_addr(const char *s, u32 *addr, int na) { }
39#endif
40
41/* Read a big address */
42static inline u64 of_read_addr(u32 *cell, int size)
43{
44 u64 r = 0;
45 while (size--)
46 r = (r << 32) | *(cell++);
47 return r;
48}
49
50/* Callbacks for bus specific translators */
51struct of_bus {
52 const char *name;
53 const char *addresses;
54 int (*match)(struct device_node *parent);
55 void (*count_cells)(struct device_node *child,
56 int *addrc, int *sizec);
57 u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna);
58 int (*translate)(u32 *addr, u64 offset, int na);
59 unsigned int (*get_flags)(u32 *addr);
60};
61
62
63/*
64 * Default translator (generic bus)
65 */
66
67static void of_bus_default_count_cells(struct device_node *dev,
68 int *addrc, int *sizec)
69{
70 if (addrc)
71 *addrc = prom_n_addr_cells(dev);
72 if (sizec)
73 *sizec = prom_n_size_cells(dev);
74}
75
76static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna)
77{
78 u64 cp, s, da;
79
80 cp = of_read_addr(range, na);
81 s = of_read_addr(range + na + pna, ns);
82 da = of_read_addr(addr, na);
83
84 DBG("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
85 cp, s, da);
86
87 if (da < cp || da >= (cp + s))
88 return OF_BAD_ADDR;
89 return da - cp;
90}
91
92static int of_bus_default_translate(u32 *addr, u64 offset, int na)
93{
94 u64 a = of_read_addr(addr, na);
95 memset(addr, 0, na * 4);
96 a += offset;
97 if (na > 1)
98 addr[na - 2] = a >> 32;
99 addr[na - 1] = a & 0xffffffffu;
100
101 return 0;
102}
103
104static unsigned int of_bus_default_get_flags(u32 *addr)
105{
106 return IORESOURCE_MEM;
107}
108
109
110/*
111 * PCI bus specific translator
112 */
113
114static int of_bus_pci_match(struct device_node *np)
115{
116 return !strcmp(np->type, "pci");
117}
118
119static void of_bus_pci_count_cells(struct device_node *np,
120 int *addrc, int *sizec)
121{
122 if (addrc)
123 *addrc = 3;
124 if (sizec)
125 *sizec = 2;
126}
127
128static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna)
129{
130 u64 cp, s, da;
131
132 /* Check address type match */
133 if ((addr[0] ^ range[0]) & 0x03000000)
134 return OF_BAD_ADDR;
135
136 /* Read address values, skipping high cell */
137 cp = of_read_addr(range + 1, na - 1);
138 s = of_read_addr(range + na + pna, ns);
139 da = of_read_addr(addr + 1, na - 1);
140
141 DBG("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
142
143 if (da < cp || da >= (cp + s))
144 return OF_BAD_ADDR;
145 return da - cp;
146}
147
148static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
149{
150 return of_bus_default_translate(addr + 1, offset, na - 1);
151}
152
153static unsigned int of_bus_pci_get_flags(u32 *addr)
154{
155 unsigned int flags = 0;
156 u32 w = addr[0];
157
158 switch((w >> 24) & 0x03) {
159 case 0x01:
160 flags |= IORESOURCE_IO;
161 case 0x02: /* 32 bits */
162 case 0x03: /* 64 bits */
163 flags |= IORESOURCE_MEM;
164 }
165 if (w & 0x40000000)
166 flags |= IORESOURCE_PREFETCH;
167 return flags;
168}
169
170/*
171 * ISA bus specific translator
172 */
173
174static int of_bus_isa_match(struct device_node *np)
175{
176 return !strcmp(np->name, "isa");
177}
178
179static void of_bus_isa_count_cells(struct device_node *child,
180 int *addrc, int *sizec)
181{
182 if (addrc)
183 *addrc = 2;
184 if (sizec)
185 *sizec = 1;
186}
187
188static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna)
189{
190 u64 cp, s, da;
191
192 /* Check address type match */
193 if ((addr[0] ^ range[0]) & 0x00000001)
194 return OF_BAD_ADDR;
195
196 /* Read address values, skipping high cell */
197 cp = of_read_addr(range + 1, na - 1);
198 s = of_read_addr(range + na + pna, ns);
199 da = of_read_addr(addr + 1, na - 1);
200
201 DBG("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
202
203 if (da < cp || da >= (cp + s))
204 return OF_BAD_ADDR;
205 return da - cp;
206}
207
208static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
209{
210 return of_bus_default_translate(addr + 1, offset, na - 1);
211}
212
213static unsigned int of_bus_isa_get_flags(u32 *addr)
214{
215 unsigned int flags = 0;
216 u32 w = addr[0];
217
218 if (w & 1)
219 flags |= IORESOURCE_IO;
220 else
221 flags |= IORESOURCE_MEM;
222 return flags;
223}
224
225
226/*
227 * Array of bus specific translators
228 */
229
230static struct of_bus of_busses[] = {
231 /* PCI */
232 {
233 .name = "pci",
234 .addresses = "assigned-addresses",
235 .match = of_bus_pci_match,
236 .count_cells = of_bus_pci_count_cells,
237 .map = of_bus_pci_map,
238 .translate = of_bus_pci_translate,
239 .get_flags = of_bus_pci_get_flags,
240 },
241 /* ISA */
242 {
243 .name = "isa",
244 .addresses = "reg",
245 .match = of_bus_isa_match,
246 .count_cells = of_bus_isa_count_cells,
247 .map = of_bus_isa_map,
248 .translate = of_bus_isa_translate,
249 .get_flags = of_bus_isa_get_flags,
250 },
251 /* Default */
252 {
253 .name = "default",
254 .addresses = "reg",
255 .match = NULL,
256 .count_cells = of_bus_default_count_cells,
257 .map = of_bus_default_map,
258 .translate = of_bus_default_translate,
259 .get_flags = of_bus_default_get_flags,
260 },
261};
262
263static struct of_bus *of_match_bus(struct device_node *np)
264{
265 int i;
266
267 for (i = 0; i < ARRAY_SIZE(of_busses); i ++)
268 if (!of_busses[i].match || of_busses[i].match(np))
269 return &of_busses[i];
270 BUG();
271 return NULL;
272}
273
274static int of_translate_one(struct device_node *parent, struct of_bus *bus,
275 struct of_bus *pbus, u32 *addr,
276 int na, int ns, int pna)
277{
278 u32 *ranges;
279 unsigned int rlen;
280 int rone;
281 u64 offset = OF_BAD_ADDR;
282
283 /* Normally, an absence of a "ranges" property means we are
284 * crossing a non-translatable boundary, and thus the addresses
285 * below the current not cannot be converted to CPU physical ones.
286 * Unfortunately, while this is very clear in the spec, it's not
287 * what Apple understood, and they do have things like /uni-n or
288 * /ht nodes with no "ranges" property and a lot of perfectly
289 * useable mapped devices below them. Thus we treat the absence of
290 * "ranges" as equivalent to an empty "ranges" property which means
291 * a 1:1 translation at that level. It's up to the caller not to try
292 * to translate addresses that aren't supposed to be translated in
293 * the first place. --BenH.
294 */
295 ranges = (u32 *)get_property(parent, "ranges", &rlen);
296 if (ranges == NULL || rlen == 0) {
297 offset = of_read_addr(addr, na);
298 memset(addr, 0, pna * 4);
299 DBG("OF: no ranges, 1:1 translation\n");
300 goto finish;
301 }
302
303 DBG("OF: walking ranges...\n");
304
305 /* Now walk through the ranges */
306 rlen /= 4;
307 rone = na + pna + ns;
308 for (; rlen >= rone; rlen -= rone, ranges += rone) {
309 offset = bus->map(addr, ranges, na, ns, pna);
310 if (offset != OF_BAD_ADDR)
311 break;
312 }
313 if (offset == OF_BAD_ADDR) {
314 DBG("OF: not found !\n");
315 return 1;
316 }
317 memcpy(addr, ranges + na, 4 * pna);
318
319 finish:
320 of_dump_addr("OF: parent translation for:", addr, pna);
321 DBG("OF: with offset: "PRu64"\n", offset);
322
323 /* Translate it into parent bus space */
324 return pbus->translate(addr, offset, pna);
325}
326
327
328/*
329 * Translate an address from the device-tree into a CPU physical address,
330 * this walks up the tree and applies the various bus mappings on the
331 * way.
332 *
333 * Note: We consider that crossing any level with #size-cells == 0 to mean
334 * that translation is impossible (that is we are not dealing with a value
335 * that can be mapped to a cpu physical address). This is not really specified
336 * that way, but this is traditionally the way IBM at least do things
337 */
338u64 of_translate_address(struct device_node *dev, u32 *in_addr)
339{
340 struct device_node *parent = NULL;
341 struct of_bus *bus, *pbus;
342 u32 addr[OF_MAX_ADDR_CELLS];
343 int na, ns, pna, pns;
344 u64 result = OF_BAD_ADDR;
345
346 DBG("OF: ** translation for device %s **\n", dev->full_name);
347
348 /* Increase refcount at current level */
349 of_node_get(dev);
350
351 /* Get parent & match bus type */
352 parent = of_get_parent(dev);
353 if (parent == NULL)
354 goto bail;
355 bus = of_match_bus(parent);
356
357 /* Cound address cells & copy address locally */
358 bus->count_cells(dev, &na, &ns);
359 if (!OF_CHECK_COUNTS(na, ns)) {
360 printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
361 dev->full_name);
362 goto bail;
363 }
364 memcpy(addr, in_addr, na * 4);
365
366 DBG("OF: bus is %s (na=%d, ns=%d) on %s\n",
367 bus->name, na, ns, parent->full_name);
368 of_dump_addr("OF: translating address:", addr, na);
369
370 /* Translate */
371 for (;;) {
372 /* Switch to parent bus */
373 of_node_put(dev);
374 dev = parent;
375 parent = of_get_parent(dev);
376
377 /* If root, we have finished */
378 if (parent == NULL) {
379 DBG("OF: reached root node\n");
380 result = of_read_addr(addr, na);
381 break;
382 }
383
384 /* Get new parent bus and counts */
385 pbus = of_match_bus(parent);
386 pbus->count_cells(dev, &pna, &pns);
387 if (!OF_CHECK_COUNTS(pna, pns)) {
388 printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
389 dev->full_name);
390 break;
391 }
392
393 DBG("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
394 pbus->name, pna, pns, parent->full_name);
395
396 /* Apply bus translation */
397 if (of_translate_one(dev, bus, pbus, addr, na, ns, pna))
398 break;
399
400 /* Complete the move up one level */
401 na = pna;
402 ns = pns;
403 bus = pbus;
404
405 of_dump_addr("OF: one level translation:", addr, na);
406 }
407 bail:
408 of_node_put(parent);
409 of_node_put(dev);
410
411 return result;
412}
413EXPORT_SYMBOL(of_translate_address);
414
415u32 *of_get_address(struct device_node *dev, int index, u64 *size,
416 unsigned int *flags)
417{
418 u32 *prop;
419 unsigned int psize;
420 struct device_node *parent;
421 struct of_bus *bus;
422 int onesize, i, na, ns;
423
424 /* Get parent & match bus type */
425 parent = of_get_parent(dev);
426 if (parent == NULL)
427 return NULL;
428 bus = of_match_bus(parent);
429 bus->count_cells(dev, &na, &ns);
430 of_node_put(parent);
431 if (!OF_CHECK_COUNTS(na, ns))
432 return NULL;
433
434 /* Get "reg" or "assigned-addresses" property */
435 prop = (u32 *)get_property(dev, bus->addresses, &psize);
436 if (prop == NULL)
437 return NULL;
438 psize /= 4;
439
440 onesize = na + ns;
441 for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
442 if (i == index) {
443 if (size)
444 *size = of_read_addr(prop + na, ns);
445 if (flags)
446 *flags = bus->get_flags(prop);
447 return prop;
448 }
449 return NULL;
450}
451EXPORT_SYMBOL(of_get_address);
452
453u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
454 unsigned int *flags)
455{
456 u32 *prop;
457 unsigned int psize;
458 struct device_node *parent;
459 struct of_bus *bus;
460 int onesize, i, na, ns;
461
462 /* Get parent & match bus type */
463 parent = of_get_parent(dev);
464 if (parent == NULL)
465 return NULL;
466 bus = of_match_bus(parent);
467 if (strcmp(bus->name, "pci"))
468 return NULL;
469 bus->count_cells(dev, &na, &ns);
470 of_node_put(parent);
471 if (!OF_CHECK_COUNTS(na, ns))
472 return NULL;
473
474 /* Get "reg" or "assigned-addresses" property */
475 prop = (u32 *)get_property(dev, bus->addresses, &psize);
476 if (prop == NULL)
477 return NULL;
478 psize /= 4;
479
480 onesize = na + ns;
481 for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
482 if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
483 if (size)
484 *size = of_read_addr(prop + na, ns);
485 if (flags)
486 *flags = bus->get_flags(prop);
487 return prop;
488 }
489 return NULL;
490}
491EXPORT_SYMBOL(of_get_pci_address);
492
493static int __of_address_to_resource(struct device_node *dev, u32 *addrp,
494 u64 size, unsigned int flags,
495 struct resource *r)
496{
497 u64 taddr;
498
499 if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
500 return -EINVAL;
501 taddr = of_translate_address(dev, addrp);
502 if (taddr == OF_BAD_ADDR)
503 return -EINVAL;
504 memset(r, 0, sizeof(struct resource));
505 if (flags & IORESOURCE_IO) {
506 unsigned long port;
507 port = pci_address_to_pio(taddr);
508 if (port == (unsigned long)-1)
509 return -EINVAL;
510 r->start = port;
511 r->end = port + size - 1;
512 } else {
513 r->start = taddr;
514 r->end = taddr + size - 1;
515 }
516 r->flags = flags;
517 r->name = dev->name;
518 return 0;
519}
520
521int of_address_to_resource(struct device_node *dev, int index,
522 struct resource *r)
523{
524 u32 *addrp;
525 u64 size;
526 unsigned int flags;
527
528 addrp = of_get_address(dev, index, &size, &flags);
529 if (addrp == NULL)
530 return -EINVAL;
531 return __of_address_to_resource(dev, addrp, size, flags, r);
532}
533EXPORT_SYMBOL_GPL(of_address_to_resource);
534
535int of_pci_address_to_resource(struct device_node *dev, int bar,
536 struct resource *r)
537{
538 u32 *addrp;
539 u64 size;
540 unsigned int flags;
541
542 addrp = of_get_pci_address(dev, bar, &size, &flags);
543 if (addrp == NULL)
544 return -EINVAL;
545 return __of_address_to_resource(dev, addrp, size, flags, r);
546}
547EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index 61762640b877..826ee3d056de 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -45,33 +45,19 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
45 unsigned long data) 45 unsigned long data)
46{ 46{
47 struct task_struct *child; 47 struct task_struct *child;
48 int ret = -EPERM; 48 int ret;
49 49
50 lock_kernel(); 50 lock_kernel();
51 if (request == PTRACE_TRACEME) { 51 if (request == PTRACE_TRACEME) {
52 /* are we already being traced? */ 52 ret = ptrace_traceme();
53 if (current->ptrace & PT_PTRACED)
54 goto out;
55 ret = security_ptrace(current->parent, current);
56 if (ret)
57 goto out;
58 /* set the ptrace bit in the process flags. */
59 current->ptrace |= PT_PTRACED;
60 ret = 0;
61 goto out; 53 goto out;
62 } 54 }
63 ret = -ESRCH;
64 read_lock(&tasklist_lock);
65 child = find_task_by_pid(pid);
66 if (child)
67 get_task_struct(child);
68 read_unlock(&tasklist_lock);
69 if (!child)
70 goto out;
71 55
72 ret = -EPERM; 56 child = ptrace_get_task_struct(pid);
73 if (pid == 1) /* you may not mess with init */ 57 if (IS_ERR(child)) {
74 goto out_tsk; 58 ret = PTR_ERR(child);
59 goto out;
60 }
75 61
76 if (request == PTRACE_ATTACH) { 62 if (request == PTRACE_ATTACH) {
77 ret = ptrace_attach(child); 63 ret = ptrace_attach(child);
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 60dec2401c26..45b8109951fe 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -188,39 +188,19 @@ int is_python(struct device_node *dev)
188 return 0; 188 return 0;
189} 189}
190 190
191static int get_phb_reg_prop(struct device_node *dev, 191static void python_countermeasures(struct device_node *dev)
192 unsigned int addr_size_words,
193 struct reg_property64 *reg)
194{ 192{
195 unsigned int *ui_ptr = NULL, len; 193 struct resource registers;
196
197 /* Found a PHB, now figure out where his registers are mapped. */
198 ui_ptr = (unsigned int *)get_property(dev, "reg", &len);
199 if (ui_ptr == NULL)
200 return 1;
201
202 if (addr_size_words == 1) {
203 reg->address = ((struct reg_property32 *)ui_ptr)->address;
204 reg->size = ((struct reg_property32 *)ui_ptr)->size;
205 } else {
206 *reg = *((struct reg_property64 *)ui_ptr);
207 }
208
209 return 0;
210}
211
212static void python_countermeasures(struct device_node *dev,
213 unsigned int addr_size_words)
214{
215 struct reg_property64 reg_struct;
216 void __iomem *chip_regs; 194 void __iomem *chip_regs;
217 volatile u32 val; 195 volatile u32 val;
218 196
219 if (get_phb_reg_prop(dev, addr_size_words, &reg_struct)) 197 if (of_address_to_resource(dev, 0, &registers)) {
198 printk(KERN_ERR "Can't get address for Python workarounds !\n");
220 return; 199 return;
200 }
221 201
222 /* Python's register file is 1 MB in size. */ 202 /* Python's register file is 1 MB in size. */
223 chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000); 203 chip_regs = ioremap(registers.start & ~(0xfffffUL), 0x100000);
224 204
225 /* 205 /*
226 * Firmware doesn't always clear this bit which is critical 206 * Firmware doesn't always clear this bit which is critical
@@ -301,11 +281,10 @@ static int phb_set_bus_ranges(struct device_node *dev,
301} 281}
302 282
303static int __devinit setup_phb(struct device_node *dev, 283static int __devinit setup_phb(struct device_node *dev,
304 struct pci_controller *phb, 284 struct pci_controller *phb)
305 unsigned int addr_size_words)
306{ 285{
307 if (is_python(dev)) 286 if (is_python(dev))
308 python_countermeasures(dev, addr_size_words); 287 python_countermeasures(dev);
309 288
310 if (phb_set_bus_ranges(dev, phb)) 289 if (phb_set_bus_ranges(dev, phb))
311 return 1; 290 return 1;
@@ -320,8 +299,8 @@ unsigned long __init find_and_init_phbs(void)
320{ 299{
321 struct device_node *node; 300 struct device_node *node;
322 struct pci_controller *phb; 301 struct pci_controller *phb;
323 unsigned int root_size_cells = 0;
324 unsigned int index; 302 unsigned int index;
303 unsigned int root_size_cells = 0;
325 unsigned int *opprop = NULL; 304 unsigned int *opprop = NULL;
326 struct device_node *root = of_find_node_by_path("/"); 305 struct device_node *root = of_find_node_by_path("/");
327 306
@@ -343,10 +322,11 @@ unsigned long __init find_and_init_phbs(void)
343 phb = pcibios_alloc_controller(node); 322 phb = pcibios_alloc_controller(node);
344 if (!phb) 323 if (!phb)
345 continue; 324 continue;
346 setup_phb(node, phb, root_size_cells); 325 setup_phb(node, phb);
347 pci_process_bridge_OF_ranges(phb, node, 0); 326 pci_process_bridge_OF_ranges(phb, node, 0);
348 pci_setup_phb_io(phb, index == 0); 327 pci_setup_phb_io(phb, index == 0);
349#ifdef CONFIG_PPC_PSERIES 328#ifdef CONFIG_PPC_PSERIES
329 /* XXX This code need serious fixing ... --BenH */
350 if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) { 330 if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
351 int addr = root_size_cells * (index + 2) - 1; 331 int addr = root_size_cells * (index + 2) - 1;
352 mpic_assign_isu(pSeries_mpic, index, opprop[addr]); 332 mpic_assign_isu(pSeries_mpic, index, opprop[addr]);
@@ -381,22 +361,17 @@ unsigned long __init find_and_init_phbs(void)
381 361
382struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) 362struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
383{ 363{
384 struct device_node *root = of_find_node_by_path("/");
385 unsigned int root_size_cells = 0;
386 struct pci_controller *phb; 364 struct pci_controller *phb;
387 int primary; 365 int primary;
388 366
389 root_size_cells = prom_n_size_cells(root);
390
391 primary = list_empty(&hose_list); 367 primary = list_empty(&hose_list);
392 phb = pcibios_alloc_controller(dn); 368 phb = pcibios_alloc_controller(dn);
393 if (!phb) 369 if (!phb)
394 return NULL; 370 return NULL;
395 setup_phb(dn, phb, root_size_cells); 371 setup_phb(dn, phb);
396 pci_process_bridge_OF_ranges(phb, dn, primary); 372 pci_process_bridge_OF_ranges(phb, dn, primary);
397 373
398 pci_setup_phb_io_dynamic(phb, primary); 374 pci_setup_phb_io_dynamic(phb, primary);
399 of_node_put(root);
400 375
401 pci_devs_phb_init_dynamic(phb); 376 pci_devs_phb_init_dynamic(phb);
402 scan_phb(phb); 377 scan_phb(phb);
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index bd3eb4292b53..d5c52fae023a 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -93,8 +93,8 @@ EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
93/* also used by kexec */ 93/* also used by kexec */
94void machine_shutdown(void) 94void machine_shutdown(void)
95{ 95{
96 if (ppc_md.nvram_sync) 96 if (ppc_md.machine_shutdown)
97 ppc_md.nvram_sync(); 97 ppc_md.machine_shutdown();
98} 98}
99 99
100void machine_restart(char *cmd) 100void machine_restart(char *cmd)
@@ -294,129 +294,6 @@ struct seq_operations cpuinfo_op = {
294 .show = show_cpuinfo, 294 .show = show_cpuinfo,
295}; 295};
296 296
297#ifdef CONFIG_PPC_MULTIPLATFORM
298static int __init set_preferred_console(void)
299{
300 struct device_node *prom_stdout = NULL;
301 char *name;
302 u32 *spd;
303 int offset = 0;
304
305 DBG(" -> set_preferred_console()\n");
306
307 /* The user has requested a console so this is already set up. */
308 if (strstr(saved_command_line, "console=")) {
309 DBG(" console was specified !\n");
310 return -EBUSY;
311 }
312
313 if (!of_chosen) {
314 DBG(" of_chosen is NULL !\n");
315 return -ENODEV;
316 }
317 /* We are getting a weird phandle from OF ... */
318 /* ... So use the full path instead */
319 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
320 if (name == NULL) {
321 DBG(" no linux,stdout-path !\n");
322 return -ENODEV;
323 }
324 prom_stdout = of_find_node_by_path(name);
325 if (!prom_stdout) {
326 DBG(" can't find stdout package %s !\n", name);
327 return -ENODEV;
328 }
329 DBG("stdout is %s\n", prom_stdout->full_name);
330
331 name = (char *)get_property(prom_stdout, "name", NULL);
332 if (!name) {
333 DBG(" stdout package has no name !\n");
334 goto not_found;
335 }
336 spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
337
338 if (0)
339 ;
340#ifdef CONFIG_SERIAL_8250_CONSOLE
341 else if (strcmp(name, "serial") == 0) {
342 int i;
343 u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
344 if (i > 8) {
345 switch (reg[1]) {
346 case 0x3f8:
347 offset = 0;
348 break;
349 case 0x2f8:
350 offset = 1;
351 break;
352 case 0x898:
353 offset = 2;
354 break;
355 case 0x890:
356 offset = 3;
357 break;
358 default:
359 /* We dont recognise the serial port */
360 goto not_found;
361 }
362 }
363 }
364#endif /* CONFIG_SERIAL_8250_CONSOLE */
365#ifdef CONFIG_PPC_PSERIES
366 else if (strcmp(name, "vty") == 0) {
367 u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL);
368 char *compat = (char *)get_property(prom_stdout, "compatible", NULL);
369
370 if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) {
371 /* Host Virtual Serial Interface */
372 switch (reg[0]) {
373 case 0x30000000:
374 offset = 0;
375 break;
376 case 0x30000001:
377 offset = 1;
378 break;
379 default:
380 goto not_found;
381 }
382 of_node_put(prom_stdout);
383 DBG("Found hvsi console at offset %d\n", offset);
384 return add_preferred_console("hvsi", offset, NULL);
385 } else {
386 /* pSeries LPAR virtual console */
387 of_node_put(prom_stdout);
388 DBG("Found hvc console\n");
389 return add_preferred_console("hvc", 0, NULL);
390 }
391 }
392#endif /* CONFIG_PPC_PSERIES */
393#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
394 else if (strcmp(name, "ch-a") == 0)
395 offset = 0;
396 else if (strcmp(name, "ch-b") == 0)
397 offset = 1;
398#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
399 else
400 goto not_found;
401 of_node_put(prom_stdout);
402
403 DBG("Found serial console at ttyS%d\n", offset);
404
405 if (spd) {
406 static char __initdata opt[16];
407 sprintf(opt, "%d", *spd);
408 return add_preferred_console("ttyS", offset, opt);
409 } else
410 return add_preferred_console("ttyS", offset, NULL);
411
412 not_found:
413 DBG("No preferred console found !\n");
414 of_node_put(prom_stdout);
415 return -ENODEV;
416}
417console_initcall(set_preferred_console);
418#endif /* CONFIG_PPC_MULTIPLATFORM */
419
420void __init check_for_initrd(void) 297void __init check_for_initrd(void)
421{ 298{
422#ifdef CONFIG_BLK_DEV_INITRD 299#ifdef CONFIG_BLK_DEV_INITRD
@@ -442,7 +319,7 @@ void __init check_for_initrd(void)
442 /* If we were passed an initrd, set the ROOT_DEV properly if the values 319 /* If we were passed an initrd, set the ROOT_DEV properly if the values
443 * look sensible. If not, clear initrd reference. 320 * look sensible. If not, clear initrd reference.
444 */ 321 */
445 if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE && 322 if (is_kernel_addr(initrd_start) && is_kernel_addr(initrd_end) &&
446 initrd_end > initrd_start) 323 initrd_end > initrd_start)
447 ROOT_DEV = Root_RAM0; 324 ROOT_DEV = Root_RAM0;
448 else 325 else
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index e5694335bf10..e5d285adb496 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -39,6 +39,8 @@
39#include <asm/nvram.h> 39#include <asm/nvram.h>
40#include <asm/xmon.h> 40#include <asm/xmon.h>
41#include <asm/time.h> 41#include <asm/time.h>
42#include <asm/serial.h>
43#include <asm/udbg.h>
42 44
43#include "setup.h" 45#include "setup.h"
44 46
@@ -172,12 +174,23 @@ void __init platform_init(void)
172 */ 174 */
173void __init machine_init(unsigned long dt_ptr, unsigned long phys) 175void __init machine_init(unsigned long dt_ptr, unsigned long phys)
174{ 176{
177 /* If btext is enabled, we might have a BAT setup for early display,
178 * thus we do enable some very basic udbg output
179 */
180#ifdef CONFIG_BOOTX_TEXT
181 udbg_putc = btext_drawchar;
182#endif
183
184 /* Do some early initialization based on the flat device tree */
175 early_init_devtree(__va(dt_ptr)); 185 early_init_devtree(__va(dt_ptr));
176 186
187 /* Check default command line */
177#ifdef CONFIG_CMDLINE 188#ifdef CONFIG_CMDLINE
178 strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); 189 if (cmd_line[0] == 0)
190 strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
179#endif /* CONFIG_CMDLINE */ 191#endif /* CONFIG_CMDLINE */
180 192
193 /* Base init based on machine type */
181 platform_init(); 194 platform_init();
182 195
183#ifdef CONFIG_6xx 196#ifdef CONFIG_6xx
@@ -282,25 +295,22 @@ void __init setup_arch(char **cmdline_p)
282 295
283 unflatten_device_tree(); 296 unflatten_device_tree();
284 check_for_initrd(); 297 check_for_initrd();
285 finish_device_tree();
286 298
287 smp_setup_cpu_maps(); 299 if (ppc_md.init_early)
300 ppc_md.init_early();
288 301
289#ifdef CONFIG_BOOTX_TEXT 302#ifdef CONFIG_SERIAL_8250
290 init_boot_display(); 303 find_legacy_serial_ports();
291#endif 304#endif
305 finish_device_tree();
292 306
293#ifdef CONFIG_PPC_PMAC 307 smp_setup_cpu_maps();
294 /* This could be called "early setup arch", it must be done
295 * now because xmon need it
296 */
297 if (_machine == _MACH_Pmac)
298 pmac_feature_init(); /* New cool way */
299#endif
300 308
301#ifdef CONFIG_XMON_DEFAULT 309#ifdef CONFIG_XMON_DEFAULT
302 xmon_init(1); 310 xmon_init(1);
303#endif 311#endif
312 /* Register early console */
313 register_early_udbg_console();
304 314
305#if defined(CONFIG_KGDB) 315#if defined(CONFIG_KGDB)
306 if (ppc_md.kgdb_map_scc) 316 if (ppc_md.kgdb_map_scc)
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index e3fb78397dc6..98e9f0595dd8 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -34,6 +34,7 @@
34#include <linux/serial.h> 34#include <linux/serial.h>
35#include <linux/serial_8250.h> 35#include <linux/serial_8250.h>
36#include <asm/io.h> 36#include <asm/io.h>
37#include <asm/kdump.h>
37#include <asm/prom.h> 38#include <asm/prom.h>
38#include <asm/processor.h> 39#include <asm/processor.h>
39#include <asm/pgtable.h> 40#include <asm/pgtable.h>
@@ -268,6 +269,10 @@ void __init early_setup(unsigned long dt_ptr)
268 } 269 }
269 ppc_md = **mach; 270 ppc_md = **mach;
270 271
272#ifdef CONFIG_CRASH_DUMP
273 kdump_setup();
274#endif
275
271 DBG("Found, Initializing memory management...\n"); 276 DBG("Found, Initializing memory management...\n");
272 277
273 /* 278 /*
@@ -317,6 +322,7 @@ void early_setup_secondary(void)
317void smp_release_cpus(void) 322void smp_release_cpus(void)
318{ 323{
319 extern unsigned long __secondary_hold_spinloop; 324 extern unsigned long __secondary_hold_spinloop;
325 unsigned long *ptr;
320 326
321 DBG(" -> smp_release_cpus()\n"); 327 DBG(" -> smp_release_cpus()\n");
322 328
@@ -327,7 +333,9 @@ void smp_release_cpus(void)
327 * This is useless but harmless on iSeries, secondaries are already 333 * This is useless but harmless on iSeries, secondaries are already
328 * waiting on their paca spinloops. */ 334 * waiting on their paca spinloops. */
329 335
330 __secondary_hold_spinloop = 1; 336 ptr = (unsigned long *)((unsigned long)&__secondary_hold_spinloop
337 - PHYSICAL_START);
338 *ptr = 1;
331 mb(); 339 mb();
332 340
333 DBG(" <- smp_release_cpus()\n"); 341 DBG(" <- smp_release_cpus()\n");
@@ -459,16 +467,21 @@ void __init setup_system(void)
459 */ 467 */
460 ppc_md.init_early(); 468 ppc_md.init_early();
461 469
470 /*
471 * We can discover serial ports now since the above did setup the
472 * hash table management for us, thus ioremap works. We do that early
473 * so that further code can be debugged
474 */
475#ifdef CONFIG_SERIAL_8250
476 find_legacy_serial_ports();
477#endif
478
462 /* 479 /*
463 * "Finish" the device-tree, that is do the actual parsing of 480 * "Finish" the device-tree, that is do the actual parsing of
464 * some of the properties like the interrupt map 481 * some of the properties like the interrupt map
465 */ 482 */
466 finish_device_tree(); 483 finish_device_tree();
467 484
468#ifdef CONFIG_BOOTX_TEXT
469 init_boot_display();
470#endif
471
472 /* 485 /*
473 * Initialize xmon 486 * Initialize xmon
474 */ 487 */
@@ -507,6 +520,9 @@ void __init setup_system(void)
507 ppc64_caches.iline_size); 520 ppc64_caches.iline_size);
508 printk("htab_address = 0x%p\n", htab_address); 521 printk("htab_address = 0x%p\n", htab_address);
509 printk("htab_hash_mask = 0x%lx\n", htab_hash_mask); 522 printk("htab_hash_mask = 0x%lx\n", htab_hash_mask);
523#if PHYSICAL_START > 0
524 printk("physical_start = 0x%x\n", PHYSICAL_START);
525#endif
510 printk("-----------------------------------------------------\n"); 526 printk("-----------------------------------------------------\n");
511 527
512 mm_init_ppc64(); 528 mm_init_ppc64();
@@ -657,187 +673,6 @@ void ppc64_terminate_msg(unsigned int src, const char *msg)
657 printk("[terminate]%04x %s\n", src, msg); 673 printk("[terminate]%04x %s\n", src, msg);
658} 674}
659 675
660#ifndef CONFIG_PPC_ISERIES
661/*
662 * This function can be used by platforms to "find" legacy serial ports.
663 * It works for "serial" nodes under an "isa" node, and will try to
664 * respect the "ibm,aix-loc" property if any. It works with up to 8
665 * ports.
666 */
667
668#define MAX_LEGACY_SERIAL_PORTS 8
669static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
670static unsigned int old_serial_count;
671
672void __init generic_find_legacy_serial_ports(u64 *physport,
673 unsigned int *default_speed)
674{
675 struct device_node *np;
676 u32 *sizeprop;
677
678 struct isa_reg_property {
679 u32 space;
680 u32 address;
681 u32 size;
682 };
683 struct pci_reg_property {
684 struct pci_address addr;
685 u32 size_hi;
686 u32 size_lo;
687 };
688
689 DBG(" -> generic_find_legacy_serial_port()\n");
690
691 *physport = 0;
692 if (default_speed)
693 *default_speed = 0;
694
695 np = of_find_node_by_path("/");
696 if (!np)
697 return;
698
699 /* First fill our array */
700 for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
701 struct device_node *isa, *pci;
702 struct isa_reg_property *reg;
703 unsigned long phys_size, addr_size, io_base;
704 u32 *rangesp;
705 u32 *interrupts, *clk, *spd;
706 char *typep;
707 int index, rlen, rentsize;
708
709 /* Ok, first check if it's under an "isa" parent */
710 isa = of_get_parent(np);
711 if (!isa || strcmp(isa->name, "isa")) {
712 DBG("%s: no isa parent found\n", np->full_name);
713 continue;
714 }
715
716 /* Now look for an "ibm,aix-loc" property that gives us ordering
717 * if any...
718 */
719 typep = (char *)get_property(np, "ibm,aix-loc", NULL);
720
721 /* Get the ISA port number */
722 reg = (struct isa_reg_property *)get_property(np, "reg", NULL);
723 if (reg == NULL)
724 goto next_port;
725 /* We assume the interrupt number isn't translated ... */
726 interrupts = (u32 *)get_property(np, "interrupts", NULL);
727 /* get clock freq. if present */
728 clk = (u32 *)get_property(np, "clock-frequency", NULL);
729 /* get default speed if present */
730 spd = (u32 *)get_property(np, "current-speed", NULL);
731 /* Default to locate at end of array */
732 index = old_serial_count; /* end of the array by default */
733
734 /* If we have a location index, then use it */
735 if (typep && *typep == 'S') {
736 index = simple_strtol(typep+1, NULL, 0) - 1;
737 /* if index is out of range, use end of array instead */
738 if (index >= MAX_LEGACY_SERIAL_PORTS)
739 index = old_serial_count;
740 /* if our index is still out of range, that mean that
741 * array is full, we could scan for a free slot but that
742 * make little sense to bother, just skip the port
743 */
744 if (index >= MAX_LEGACY_SERIAL_PORTS)
745 goto next_port;
746 if (index >= old_serial_count)
747 old_serial_count = index + 1;
748 /* Check if there is a port who already claimed our slot */
749 if (serial_ports[index].iobase != 0) {
750 /* if we still have some room, move it, else override */
751 if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) {
752 DBG("Moved legacy port %d -> %d\n", index,
753 old_serial_count);
754 serial_ports[old_serial_count++] =
755 serial_ports[index];
756 } else {
757 DBG("Replacing legacy port %d\n", index);
758 }
759 }
760 }
761 if (index >= MAX_LEGACY_SERIAL_PORTS)
762 goto next_port;
763 if (index >= old_serial_count)
764 old_serial_count = index + 1;
765
766 /* Now fill the entry */
767 memset(&serial_ports[index], 0, sizeof(struct plat_serial8250_port));
768 serial_ports[index].uartclk = clk ? *clk : BASE_BAUD * 16;
769 serial_ports[index].iobase = reg->address;
770 serial_ports[index].irq = interrupts ? interrupts[0] : 0;
771 serial_ports[index].flags = ASYNC_BOOT_AUTOCONF;
772
773 DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n",
774 index,
775 serial_ports[index].iobase,
776 serial_ports[index].irq,
777 serial_ports[index].uartclk);
778
779 /* Get phys address of IO reg for port 1 */
780 if (index != 0)
781 goto next_port;
782
783 pci = of_get_parent(isa);
784 if (!pci) {
785 DBG("%s: no pci parent found\n", np->full_name);
786 goto next_port;
787 }
788
789 rangesp = (u32 *)get_property(pci, "ranges", &rlen);
790 if (rangesp == NULL) {
791 of_node_put(pci);
792 goto next_port;
793 }
794 rlen /= 4;
795
796 /* we need the #size-cells of the PCI bridge node itself */
797 phys_size = 1;
798 sizeprop = (u32 *)get_property(pci, "#size-cells", NULL);
799 if (sizeprop != NULL)
800 phys_size = *sizeprop;
801 /* we need the parent #addr-cells */
802 addr_size = prom_n_addr_cells(pci);
803 rentsize = 3 + addr_size + phys_size;
804 io_base = 0;
805 for (;rlen >= rentsize; rlen -= rentsize,rangesp += rentsize) {
806 if (((rangesp[0] >> 24) & 0x3) != 1)
807 continue; /* not IO space */
808 io_base = rangesp[3];
809 if (addr_size == 2)
810 io_base = (io_base << 32) | rangesp[4];
811 }
812 if (io_base != 0) {
813 *physport = io_base + reg->address;
814 if (default_speed && spd)
815 *default_speed = *spd;
816 }
817 of_node_put(pci);
818 next_port:
819 of_node_put(isa);
820 }
821
822 DBG(" <- generic_find_legacy_serial_port()\n");
823}
824
825static struct platform_device serial_device = {
826 .name = "serial8250",
827 .id = PLAT8250_DEV_PLATFORM,
828 .dev = {
829 .platform_data = serial_ports,
830 },
831};
832
833static int __init serial_dev_init(void)
834{
835 return platform_device_register(&serial_device);
836}
837arch_initcall(serial_dev_init);
838
839#endif /* CONFIG_PPC_ISERIES */
840
841int check_legacy_ioport(unsigned long base_port) 676int check_legacy_ioport(unsigned long base_port)
842{ 677{
843 if (ppc_md.check_legacy_ioport == NULL) 678 if (ppc_md.check_legacy_ioport == NULL)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 5a2eba60dd39..d3f0b6d452fb 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -76,7 +76,6 @@
76 * registers from *regs. This is what we need 76 * registers from *regs. This is what we need
77 * to do when a signal has been delivered. 77 * to do when a signal has been delivered.
78 */ 78 */
79#define sigreturn_exit(regs) return 0
80 79
81#define GP_REGS_SIZE min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32)) 80#define GP_REGS_SIZE min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32))
82#undef __SIGNAL_FRAMESIZE 81#undef __SIGNAL_FRAMESIZE
@@ -156,9 +155,17 @@ static inline int save_general_regs(struct pt_regs *regs,
156 elf_greg_t64 *gregs = (elf_greg_t64 *)regs; 155 elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
157 int i; 156 int i;
158 157
159 for (i = 0; i <= PT_RESULT; i ++) 158 if (!FULL_REGS(regs)) {
159 set_thread_flag(TIF_SAVE_NVGPRS);
160 current_thread_info()->nvgprs_frame = frame->mc_gregs;
161 }
162
163 for (i = 0; i <= PT_RESULT; i ++) {
164 if (i == 14 && !FULL_REGS(regs))
165 i = 32;
160 if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i])) 166 if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i]))
161 return -EFAULT; 167 return -EFAULT;
168 }
162 return 0; 169 return 0;
163} 170}
164 171
@@ -179,8 +186,6 @@ static inline int restore_general_regs(struct pt_regs *regs,
179 186
180#else /* CONFIG_PPC64 */ 187#else /* CONFIG_PPC64 */
181 188
182extern void sigreturn_exit(struct pt_regs *);
183
184#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) 189#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
185 190
186static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set) 191static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set)
@@ -214,6 +219,15 @@ static inline int get_old_sigaction(struct k_sigaction *new_ka,
214static inline int save_general_regs(struct pt_regs *regs, 219static inline int save_general_regs(struct pt_regs *regs,
215 struct mcontext __user *frame) 220 struct mcontext __user *frame)
216{ 221{
222 if (!FULL_REGS(regs)) {
223 /* Zero out the unsaved GPRs to avoid information
224 leak, and set TIF_SAVE_NVGPRS to ensure that the
225 registers do actually get saved later. */
226 memset(&regs->gpr[14], 0, 18 * sizeof(unsigned long));
227 current_thread_info()->nvgprs_frame = &frame->mc_gregs;
228 set_thread_flag(TIF_SAVE_NVGPRS);
229 }
230
217 return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE); 231 return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE);
218} 232}
219 233
@@ -256,8 +270,10 @@ long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
256 while (1) { 270 while (1) {
257 current->state = TASK_INTERRUPTIBLE; 271 current->state = TASK_INTERRUPTIBLE;
258 schedule(); 272 schedule();
259 if (do_signal(&saveset, regs)) 273 if (do_signal(&saveset, regs)) {
260 sigreturn_exit(regs); 274 set_thread_flag(TIF_RESTOREALL);
275 return 0;
276 }
261 } 277 }
262} 278}
263 279
@@ -292,8 +308,10 @@ long sys_rt_sigsuspend(
292 while (1) { 308 while (1) {
293 current->state = TASK_INTERRUPTIBLE; 309 current->state = TASK_INTERRUPTIBLE;
294 schedule(); 310 schedule();
295 if (do_signal(&saveset, regs)) 311 if (do_signal(&saveset, regs)) {
296 sigreturn_exit(regs); 312 set_thread_flag(TIF_RESTOREALL);
313 return 0;
314 }
297 } 315 }
298} 316}
299 317
@@ -391,9 +409,6 @@ struct rt_sigframe {
391static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, 409static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
392 int sigret) 410 int sigret)
393{ 411{
394#ifdef CONFIG_PPC32
395 CHECK_FULL_REGS(regs);
396#endif
397 /* Make sure floating point registers are stored in regs */ 412 /* Make sure floating point registers are stored in regs */
398 flush_fp_to_thread(current); 413 flush_fp_to_thread(current);
399 414
@@ -828,12 +843,6 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
828 regs->gpr[6] = (unsigned long) rt_sf; 843 regs->gpr[6] = (unsigned long) rt_sf;
829 regs->nip = (unsigned long) ka->sa.sa_handler; 844 regs->nip = (unsigned long) ka->sa.sa_handler;
830 regs->trap = 0; 845 regs->trap = 0;
831#ifdef CONFIG_PPC64
832 regs->result = 0;
833
834 if (test_thread_flag(TIF_SINGLESTEP))
835 ptrace_notify(SIGTRAP);
836#endif
837 return 1; 846 return 1;
838 847
839badframe: 848badframe:
@@ -911,8 +920,8 @@ long sys_swapcontext(struct ucontext __user *old_ctx,
911 */ 920 */
912 if (do_setcontext(new_ctx, regs, 0)) 921 if (do_setcontext(new_ctx, regs, 0))
913 do_exit(SIGSEGV); 922 do_exit(SIGSEGV);
914 sigreturn_exit(regs); 923
915 /* doesn't actually return back to here */ 924 set_thread_flag(TIF_RESTOREALL);
916 return 0; 925 return 0;
917} 926}
918 927
@@ -945,12 +954,11 @@ long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
945 * nobody does any... 954 * nobody does any...
946 */ 955 */
947 compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs); 956 compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs);
948 return (int)regs->result;
949#else 957#else
950 do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]); 958 do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
951 sigreturn_exit(regs); /* doesn't return here */
952 return 0;
953#endif 959#endif
960 set_thread_flag(TIF_RESTOREALL);
961 return 0;
954 962
955 bad: 963 bad:
956 force_sig(SIGSEGV, current); 964 force_sig(SIGSEGV, current);
@@ -1041,9 +1049,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
1041 */ 1049 */
1042 do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]); 1050 do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]);
1043 1051
1044 sigreturn_exit(regs); 1052 set_thread_flag(TIF_RESTOREALL);
1045 /* doesn't actually return back to here */
1046
1047 out: 1053 out:
1048 return 0; 1054 return 0;
1049} 1055}
@@ -1107,12 +1113,6 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
1107 regs->gpr[4] = (unsigned long) sc; 1113 regs->gpr[4] = (unsigned long) sc;
1108 regs->nip = (unsigned long) ka->sa.sa_handler; 1114 regs->nip = (unsigned long) ka->sa.sa_handler;
1109 regs->trap = 0; 1115 regs->trap = 0;
1110#ifdef CONFIG_PPC64
1111 regs->result = 0;
1112
1113 if (test_thread_flag(TIF_SINGLESTEP))
1114 ptrace_notify(SIGTRAP);
1115#endif
1116 1116
1117 return 1; 1117 return 1;
1118 1118
@@ -1160,12 +1160,8 @@ long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
1160 || restore_user_regs(regs, sr, 1)) 1160 || restore_user_regs(regs, sr, 1))
1161 goto badframe; 1161 goto badframe;
1162 1162
1163#ifdef CONFIG_PPC64 1163 set_thread_flag(TIF_RESTOREALL);
1164 return (int)regs->result;
1165#else
1166 sigreturn_exit(regs); /* doesn't return */
1167 return 0; 1164 return 0;
1168#endif
1169 1165
1170badframe: 1166badframe:
1171 force_sig(SIGSEGV, current); 1167 force_sig(SIGSEGV, current);
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 1decf2785530..5462bef898f6 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -96,8 +96,10 @@ long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int
96 while (1) { 96 while (1) {
97 current->state = TASK_INTERRUPTIBLE; 97 current->state = TASK_INTERRUPTIBLE;
98 schedule(); 98 schedule();
99 if (do_signal(&saveset, regs)) 99 if (do_signal(&saveset, regs)) {
100 set_thread_flag(TIF_RESTOREALL);
100 return 0; 101 return 0;
102 }
101 } 103 }
102} 104}
103 105
@@ -152,6 +154,14 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
152 err |= __put_user(0, &sc->v_regs); 154 err |= __put_user(0, &sc->v_regs);
153#endif /* CONFIG_ALTIVEC */ 155#endif /* CONFIG_ALTIVEC */
154 err |= __put_user(&sc->gp_regs, &sc->regs); 156 err |= __put_user(&sc->gp_regs, &sc->regs);
157 if (!FULL_REGS(regs)) {
158 /* Zero out the unsaved GPRs to avoid information
159 leak, and set TIF_SAVE_NVGPRS to ensure that the
160 registers do actually get saved later. */
161 memset(&regs->gpr[14], 0, 18 * sizeof(unsigned long));
162 set_thread_flag(TIF_SAVE_NVGPRS);
163 current_thread_info()->nvgprs_frame = &sc->gp_regs;
164 }
155 err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE); 165 err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
156 err |= __copy_to_user(&sc->fp_regs, &current->thread.fpr, FP_REGS_SIZE); 166 err |= __copy_to_user(&sc->fp_regs, &current->thread.fpr, FP_REGS_SIZE);
157 err |= __put_user(signr, &sc->signal); 167 err |= __put_user(signr, &sc->signal);
@@ -340,6 +350,7 @@ int sys_swapcontext(struct ucontext __user *old_ctx,
340 do_exit(SIGSEGV); 350 do_exit(SIGSEGV);
341 351
342 /* This returns like rt_sigreturn */ 352 /* This returns like rt_sigreturn */
353 set_thread_flag(TIF_RESTOREALL);
343 return 0; 354 return 0;
344} 355}
345 356
@@ -372,7 +383,8 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
372 */ 383 */
373 do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]); 384 do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]);
374 385
375 return regs->result; 386 set_thread_flag(TIF_RESTOREALL);
387 return 0;
376 388
377badframe: 389badframe:
378#if DEBUG_SIG 390#if DEBUG_SIG
@@ -454,9 +466,6 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
454 if (err) 466 if (err)
455 goto badframe; 467 goto badframe;
456 468
457 if (test_thread_flag(TIF_SINGLESTEP))
458 ptrace_notify(SIGTRAP);
459
460 return 1; 469 return 1;
461 470
462badframe: 471badframe:
@@ -502,6 +511,8 @@ static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
502 * we only get here if there is a handler, we dont restart. 511 * we only get here if there is a handler, we dont restart.
503 */ 512 */
504 regs->result = -EINTR; 513 regs->result = -EINTR;
514 regs->gpr[3] = EINTR;
515 regs->ccr |= 0x10000000;
505 break; 516 break;
506 case -ERESTARTSYS: 517 case -ERESTARTSYS:
507 /* ERESTARTSYS means to restart the syscall if there is no 518 /* ERESTARTSYS means to restart the syscall if there is no
@@ -509,6 +520,8 @@ static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
509 */ 520 */
510 if (!(ka->sa.sa_flags & SA_RESTART)) { 521 if (!(ka->sa.sa_flags & SA_RESTART)) {
511 regs->result = -EINTR; 522 regs->result = -EINTR;
523 regs->gpr[3] = EINTR;
524 regs->ccr |= 0x10000000;
512 break; 525 break;
513 } 526 }
514 /* fallthrough */ 527 /* fallthrough */
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 30374d2f88e5..d381ec90b759 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -31,6 +31,7 @@
31#include <linux/sysdev.h> 31#include <linux/sysdev.h>
32#include <linux/cpu.h> 32#include <linux/cpu.h>
33#include <linux/notifier.h> 33#include <linux/notifier.h>
34#include <linux/topology.h>
34 35
35#include <asm/ptrace.h> 36#include <asm/ptrace.h>
36#include <asm/atomic.h> 37#include <asm/atomic.h>
@@ -75,6 +76,8 @@ void smp_call_function_interrupt(void);
75 76
76int smt_enabled_at_boot = 1; 77int smt_enabled_at_boot = 1;
77 78
79static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL;
80
78#ifdef CONFIG_MPIC 81#ifdef CONFIG_MPIC
79int __init smp_mpic_probe(void) 82int __init smp_mpic_probe(void)
80{ 83{
@@ -123,11 +126,16 @@ void smp_message_recv(int msg, struct pt_regs *regs)
123 /* XXX Do we have to do this? */ 126 /* XXX Do we have to do this? */
124 set_need_resched(); 127 set_need_resched();
125 break; 128 break;
126#ifdef CONFIG_DEBUGGER
127 case PPC_MSG_DEBUGGER_BREAK: 129 case PPC_MSG_DEBUGGER_BREAK:
130 if (crash_ipi_function_ptr) {
131 crash_ipi_function_ptr(regs);
132 break;
133 }
134#ifdef CONFIG_DEBUGGER
128 debugger_ipi(regs); 135 debugger_ipi(regs);
129 break; 136 break;
130#endif 137#endif /* CONFIG_DEBUGGER */
138 /* FALLTHROUGH */
131 default: 139 default:
132 printk("SMP %d: smp_message_recv(): unknown msg %d\n", 140 printk("SMP %d: smp_message_recv(): unknown msg %d\n",
133 smp_processor_id(), msg); 141 smp_processor_id(), msg);
@@ -147,6 +155,17 @@ void smp_send_debugger_break(int cpu)
147} 155}
148#endif 156#endif
149 157
158#ifdef CONFIG_KEXEC
159void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
160{
161 crash_ipi_function_ptr = crash_ipi_callback;
162 if (crash_ipi_callback) {
163 mb();
164 smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK);
165 }
166}
167#endif
168
150static void stop_this_cpu(void *dummy) 169static void stop_this_cpu(void *dummy)
151{ 170{
152 local_irq_disable(); 171 local_irq_disable();
@@ -452,10 +471,6 @@ int __devinit __cpu_up(unsigned int cpu)
452 if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)) 471 if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))
453 return -EINVAL; 472 return -EINVAL;
454 473
455#ifdef CONFIG_PPC64
456 paca[cpu].default_decr = tb_ticks_per_jiffy;
457#endif
458
459 /* Make sure callin-map entry is 0 (can be leftover a CPU 474 /* Make sure callin-map entry is 0 (can be leftover a CPU
460 * hotplug 475 * hotplug
461 */ 476 */
@@ -554,6 +569,8 @@ void __init smp_cpus_done(unsigned int max_cpus)
554 smp_ops->setup_cpu(boot_cpuid); 569 smp_ops->setup_cpu(boot_cpuid);
555 570
556 set_cpus_allowed(current, old_mask); 571 set_cpus_allowed(current, old_mask);
572
573 dump_numa_cpu_topology();
557} 574}
558 575
559#ifdef CONFIG_HOTPLUG_CPU 576#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index 91b93d917b64..ad895c99813b 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -43,9 +43,6 @@
43#include <asm/time.h> 43#include <asm/time.h>
44#include <asm/unistd.h> 44#include <asm/unistd.h>
45 45
46extern unsigned long wall_jiffies;
47
48
49/* 46/*
50 * sys_ipc() is the de-multiplexer for the SysV IPC calls.. 47 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
51 * 48 *
@@ -311,31 +308,6 @@ int sys_olduname(struct oldold_utsname __user *name)
311 return error? -EFAULT: 0; 308 return error? -EFAULT: 0;
312} 309}
313 310
314#ifdef CONFIG_PPC64
315time_t sys64_time(time_t __user * tloc)
316{
317 time_t secs;
318 time_t usecs;
319
320 long tb_delta = tb_ticks_since(tb_last_stamp);
321 tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
322
323 secs = xtime.tv_sec;
324 usecs = (xtime.tv_nsec/1000) + tb_delta / tb_ticks_per_usec;
325 while (usecs >= USEC_PER_SEC) {
326 ++secs;
327 usecs -= USEC_PER_SEC;
328 }
329
330 if (tloc) {
331 if (put_user(secs,tloc))
332 secs = -EFAULT;
333 }
334
335 return secs;
336}
337#endif
338
339long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low, 311long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
340 u32 len_high, u32 len_low) 312 u32 len_high, u32 len_low)
341{ 313{
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index 65eaea91b499..65463a1076e8 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -54,7 +54,7 @@ SYSCALL(link)
54SYSCALL(unlink) 54SYSCALL(unlink)
55COMPAT_SYS(execve) 55COMPAT_SYS(execve)
56SYSCALL(chdir) 56SYSCALL(chdir)
57SYSX(sys64_time,compat_sys_time,sys_time) 57COMPAT_SYS(time)
58SYSCALL(mknod) 58SYSCALL(mknod)
59SYSCALL(chmod) 59SYSCALL(chmod)
60SYSCALL(lchown) 60SYSCALL(lchown)
@@ -113,7 +113,7 @@ SYSCALL(sgetmask)
113COMPAT_SYS(ssetmask) 113COMPAT_SYS(ssetmask)
114SYSCALL(setreuid) 114SYSCALL(setreuid)
115SYSCALL(setregid) 115SYSCALL(setregid)
116SYSX(sys_ni_syscall,ppc32_sigsuspend,ppc_sigsuspend) 116SYS32ONLY(sigsuspend)
117COMPAT_SYS(sigpending) 117COMPAT_SYS(sigpending)
118COMPAT_SYS(sethostname) 118COMPAT_SYS(sethostname)
119COMPAT_SYS(setrlimit) 119COMPAT_SYS(setrlimit)
@@ -160,7 +160,7 @@ SYSCALL(swapoff)
160COMPAT_SYS(sysinfo) 160COMPAT_SYS(sysinfo)
161COMPAT_SYS(ipc) 161COMPAT_SYS(ipc)
162SYSCALL(fsync) 162SYSCALL(fsync)
163SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn) 163SYS32ONLY(sigreturn)
164PPC_SYS(clone) 164PPC_SYS(clone)
165COMPAT_SYS(setdomainname) 165COMPAT_SYS(setdomainname)
166PPC_SYS(newuname) 166PPC_SYS(newuname)
@@ -213,13 +213,13 @@ COMPAT_SYS(nfsservctl)
213SYSCALL(setresgid) 213SYSCALL(setresgid)
214SYSCALL(getresgid) 214SYSCALL(getresgid)
215COMPAT_SYS(prctl) 215COMPAT_SYS(prctl)
216SYSX(ppc64_rt_sigreturn,ppc32_rt_sigreturn,sys_rt_sigreturn) 216COMPAT_SYS(rt_sigreturn)
217COMPAT_SYS(rt_sigaction) 217COMPAT_SYS(rt_sigaction)
218COMPAT_SYS(rt_sigprocmask) 218COMPAT_SYS(rt_sigprocmask)
219COMPAT_SYS(rt_sigpending) 219COMPAT_SYS(rt_sigpending)
220COMPAT_SYS(rt_sigtimedwait) 220COMPAT_SYS(rt_sigtimedwait)
221COMPAT_SYS(rt_sigqueueinfo) 221COMPAT_SYS(rt_sigqueueinfo)
222SYSX(ppc64_rt_sigsuspend,ppc32_rt_sigsuspend,ppc_rt_sigsuspend) 222COMPAT_SYS(rt_sigsuspend)
223COMPAT_SYS(pread64) 223COMPAT_SYS(pread64)
224COMPAT_SYS(pwrite64) 224COMPAT_SYS(pwrite64)
225SYSCALL(chown) 225SYSCALL(chown)
@@ -290,7 +290,7 @@ COMPAT_SYS(clock_settime)
290COMPAT_SYS(clock_gettime) 290COMPAT_SYS(clock_gettime)
291COMPAT_SYS(clock_getres) 291COMPAT_SYS(clock_getres)
292COMPAT_SYS(clock_nanosleep) 292COMPAT_SYS(clock_nanosleep)
293SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext) 293COMPAT_SYS(swapcontext)
294COMPAT_SYS(tgkill) 294COMPAT_SYS(tgkill)
295COMPAT_SYS(utimes) 295COMPAT_SYS(utimes)
296COMPAT_SYS(statfs64) 296COMPAT_SYS(statfs64)
@@ -319,3 +319,5 @@ COMPAT_SYS(ioprio_get)
319SYSCALL(inotify_init) 319SYSCALL(inotify_init)
320SYSCALL(inotify_add_watch) 320SYSCALL(inotify_add_watch)
321SYSCALL(inotify_rm_watch) 321SYSCALL(inotify_rm_watch)
322SYSCALL(spu_run)
323SYSCALL(spu_create)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index de8479769bb7..56f50e91bddb 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -699,10 +699,6 @@ void __init time_init(void)
699 div128_by_32(1024*1024, 0, tb_ticks_per_sec, &res); 699 div128_by_32(1024*1024, 0, tb_ticks_per_sec, &res);
700 tb_to_xs = res.result_low; 700 tb_to_xs = res.result_low;
701 701
702#ifdef CONFIG_PPC64
703 get_paca()->default_decr = tb_ticks_per_jiffy;
704#endif
705
706 /* 702 /*
707 * Compute scale factor for sched_clock. 703 * Compute scale factor for sched_clock.
708 * The calibrate_decr() function has set tb_ticks_per_sec, 704 * The calibrate_decr() function has set tb_ticks_per_sec,
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 1511454c4690..7509aa6474f2 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -31,6 +31,7 @@
31#include <linux/prctl.h> 31#include <linux/prctl.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/kprobes.h> 33#include <linux/kprobes.h>
34#include <linux/kexec.h>
34 35
35#include <asm/kdebug.h> 36#include <asm/kdebug.h>
36#include <asm/pgtable.h> 37#include <asm/pgtable.h>
@@ -95,7 +96,7 @@ static DEFINE_SPINLOCK(die_lock);
95 96
96int die(const char *str, struct pt_regs *regs, long err) 97int die(const char *str, struct pt_regs *regs, long err)
97{ 98{
98 static int die_counter; 99 static int die_counter, crash_dump_start = 0;
99 int nl = 0; 100 int nl = 0;
100 101
101 if (debugger(regs)) 102 if (debugger(regs))
@@ -156,7 +157,21 @@ int die(const char *str, struct pt_regs *regs, long err)
156 print_modules(); 157 print_modules();
157 show_regs(regs); 158 show_regs(regs);
158 bust_spinlocks(0); 159 bust_spinlocks(0);
160
161 if (!crash_dump_start && kexec_should_crash(current)) {
162 crash_dump_start = 1;
163 spin_unlock_irq(&die_lock);
164 crash_kexec(regs);
165 /* NOTREACHED */
166 }
159 spin_unlock_irq(&die_lock); 167 spin_unlock_irq(&die_lock);
168 if (crash_dump_start)
169 /*
170 * Only for soft-reset: Other CPUs will be responded to an IPI
171 * sent by first kexec CPU.
172 */
173 for(;;)
174 ;
160 175
161 if (in_interrupt()) 176 if (in_interrupt())
162 panic("Fatal exception in interrupt"); 177 panic("Fatal exception in interrupt");
@@ -215,8 +230,10 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
215void system_reset_exception(struct pt_regs *regs) 230void system_reset_exception(struct pt_regs *regs)
216{ 231{
217 /* See if any machine dependent calls */ 232 /* See if any machine dependent calls */
218 if (ppc_md.system_reset_exception) 233 if (ppc_md.system_reset_exception) {
219 ppc_md.system_reset_exception(regs); 234 if (ppc_md.system_reset_exception(regs))
235 return;
236 }
220 237
221 die("System Reset", regs, SIGABRT); 238 die("System Reset", regs, SIGABRT);
222 239
@@ -886,12 +903,10 @@ void altivec_unavailable_exception(struct pt_regs *regs)
886 die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); 903 die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
887} 904}
888 905
889#if defined(CONFIG_PPC64) || defined(CONFIG_E500)
890void performance_monitor_exception(struct pt_regs *regs) 906void performance_monitor_exception(struct pt_regs *regs)
891{ 907{
892 perf_irq(regs); 908 perf_irq(regs);
893} 909}
894#endif
895 910
896#ifdef CONFIG_8xx 911#ifdef CONFIG_8xx
897void SoftwareEmulation(struct pt_regs *regs) 912void SoftwareEmulation(struct pt_regs *regs)
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 0d878e72fc44..558c1ceb2b93 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -16,8 +16,8 @@
16#include <linux/console.h> 16#include <linux/console.h>
17#include <asm/processor.h> 17#include <asm/processor.h>
18 18
19void (*udbg_putc)(unsigned char c); 19void (*udbg_putc)(char c);
20unsigned char (*udbg_getc)(void); 20int (*udbg_getc)(void);
21int (*udbg_getc_poll)(void); 21int (*udbg_getc_poll)(void);
22 22
23/* udbg library, used by xmon et al */ 23/* udbg library, used by xmon et al */
@@ -57,8 +57,8 @@ int udbg_write(const char *s, int n)
57 57
58int udbg_read(char *buf, int buflen) 58int udbg_read(char *buf, int buflen)
59{ 59{
60 char c, *p = buf; 60 char *p = buf;
61 int i; 61 int i, c;
62 62
63 if (!udbg_getc) 63 if (!udbg_getc)
64 return 0; 64 return 0;
@@ -66,8 +66,11 @@ int udbg_read(char *buf, int buflen)
66 for (i = 0; i < buflen; ++i) { 66 for (i = 0; i < buflen; ++i) {
67 do { 67 do {
68 c = udbg_getc(); 68 c = udbg_getc();
69 if (c == -1 && i == 0)
70 return -1;
71
69 } while (c == 0x11 || c == 0x13); 72 } while (c == 0x11 || c == 0x13);
70 if (c == 0) 73 if (c == 0 || c == -1)
71 break; 74 break;
72 *p++ = c; 75 *p++ = c;
73 } 76 }
@@ -78,7 +81,7 @@ int udbg_read(char *buf, int buflen)
78#define UDBG_BUFSIZE 256 81#define UDBG_BUFSIZE 256
79void udbg_printf(const char *fmt, ...) 82void udbg_printf(const char *fmt, ...)
80{ 83{
81 unsigned char buf[UDBG_BUFSIZE]; 84 char buf[UDBG_BUFSIZE];
82 va_list args; 85 va_list args;
83 86
84 va_start(args, fmt); 87 va_start(args, fmt);
@@ -87,6 +90,12 @@ void udbg_printf(const char *fmt, ...)
87 va_end(args); 90 va_end(args);
88} 91}
89 92
93void __init udbg_progress(char *s, unsigned short hex)
94{
95 udbg_puts(s);
96 udbg_puts("\n");
97}
98
90/* 99/*
91 * Early boot console based on udbg 100 * Early boot console based on udbg
92 */ 101 */
@@ -99,7 +108,7 @@ static void udbg_console_write(struct console *con, const char *s,
99static struct console udbg_console = { 108static struct console udbg_console = {
100 .name = "udbg", 109 .name = "udbg",
101 .write = udbg_console_write, 110 .write = udbg_console_write,
102 .flags = CON_PRINTBUFFER, 111 .flags = CON_PRINTBUFFER | CON_ENABLED,
103 .index = -1, 112 .index = -1,
104}; 113};
105 114
@@ -107,15 +116,19 @@ static int early_console_initialized;
107 116
108void __init disable_early_printk(void) 117void __init disable_early_printk(void)
109{ 118{
119#if 1
110 if (!early_console_initialized) 120 if (!early_console_initialized)
111 return; 121 return;
112 unregister_console(&udbg_console); 122 unregister_console(&udbg_console);
113 early_console_initialized = 0; 123 early_console_initialized = 0;
124#endif
114} 125}
115 126
116/* called by setup_system */ 127/* called by setup_system */
117void register_early_udbg_console(void) 128void register_early_udbg_console(void)
118{ 129{
130 if (early_console_initialized)
131 return;
119 early_console_initialized = 1; 132 early_console_initialized = 1;
120 register_console(&udbg_console); 133 register_console(&udbg_console);
121} 134}
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index 9313574ab935..7541bf44d2da 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -43,9 +43,11 @@ struct NS16550 {
43#define LSR_TEMT 0x40 /* Xmitter empty */ 43#define LSR_TEMT 0x40 /* Xmitter empty */
44#define LSR_ERR 0x80 /* Error */ 44#define LSR_ERR 0x80 /* Error */
45 45
46#define LCR_DLAB 0x80
47
46static volatile struct NS16550 __iomem *udbg_comport; 48static volatile struct NS16550 __iomem *udbg_comport;
47 49
48static void udbg_550_putc(unsigned char c) 50static void udbg_550_putc(char c)
49{ 51{
50 if (udbg_comport) { 52 if (udbg_comport) {
51 while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0) 53 while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0)
@@ -67,39 +69,80 @@ static int udbg_550_getc_poll(void)
67 return -1; 69 return -1;
68} 70}
69 71
70static unsigned char udbg_550_getc(void) 72static int udbg_550_getc(void)
71{ 73{
72 if (udbg_comport) { 74 if (udbg_comport) {
73 while ((in_8(&udbg_comport->lsr) & LSR_DR) == 0) 75 while ((in_8(&udbg_comport->lsr) & LSR_DR) == 0)
74 /* wait for char */; 76 /* wait for char */;
75 return in_8(&udbg_comport->rbr); 77 return in_8(&udbg_comport->rbr);
76 } 78 }
77 return 0; 79 return -1;
78} 80}
79 81
80void udbg_init_uart(void __iomem *comport, unsigned int speed) 82void udbg_init_uart(void __iomem *comport, unsigned int speed,
83 unsigned int clock)
81{ 84{
82 u16 dll = speed ? (115200 / speed) : 12; 85 unsigned int dll, base_bauds = clock / 16;
86
87 if (speed == 0)
88 speed = 9600;
89 dll = base_bauds / speed;
83 90
84 if (comport) { 91 if (comport) {
85 udbg_comport = (struct NS16550 __iomem *)comport; 92 udbg_comport = (struct NS16550 __iomem *)comport;
86 out_8(&udbg_comport->lcr, 0x00); 93 out_8(&udbg_comport->lcr, 0x00);
87 out_8(&udbg_comport->ier, 0xff); 94 out_8(&udbg_comport->ier, 0xff);
88 out_8(&udbg_comport->ier, 0x00); 95 out_8(&udbg_comport->ier, 0x00);
89 out_8(&udbg_comport->lcr, 0x80); /* Access baud rate */ 96 out_8(&udbg_comport->lcr, LCR_DLAB);
90 out_8(&udbg_comport->dll, dll & 0xff); /* 1 = 115200, 2 = 57600, 97 out_8(&udbg_comport->dll, dll & 0xff);
91 3 = 38400, 12 = 9600 baud */ 98 out_8(&udbg_comport->dlm, dll >> 8);
92 out_8(&udbg_comport->dlm, dll >> 8); /* dll >> 8 which should be zero 99 /* 8 data, 1 stop, no parity */
93 for fast rates; */ 100 out_8(&udbg_comport->lcr, 0x03);
94 out_8(&udbg_comport->lcr, 0x03); /* 8 data, 1 stop, no parity */ 101 /* RTS/DTR */
95 out_8(&udbg_comport->mcr, 0x03); /* RTS/DTR */ 102 out_8(&udbg_comport->mcr, 0x03);
96 out_8(&udbg_comport->fcr ,0x07); /* Clear & enable FIFOs */ 103 /* Clear & enable FIFOs */
104 out_8(&udbg_comport->fcr ,0x07);
97 udbg_putc = udbg_550_putc; 105 udbg_putc = udbg_550_putc;
98 udbg_getc = udbg_550_getc; 106 udbg_getc = udbg_550_getc;
99 udbg_getc_poll = udbg_550_getc_poll; 107 udbg_getc_poll = udbg_550_getc_poll;
100 } 108 }
101} 109}
102 110
111unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock)
112{
113 unsigned int dll, dlm, divisor, prescaler, speed;
114 u8 old_lcr;
115 volatile struct NS16550 __iomem *port = comport;
116
117 old_lcr = in_8(&port->lcr);
118
119 /* select divisor latch registers. */
120 out_8(&port->lcr, LCR_DLAB);
121
122 /* now, read the divisor */
123 dll = in_8(&port->dll);
124 dlm = in_8(&port->dlm);
125 divisor = dlm << 8 | dll;
126
127 /* check prescaling */
128 if (in_8(&port->mcr) & 0x80)
129 prescaler = 4;
130 else
131 prescaler = 1;
132
133 /* restore the LCR */
134 out_8(&port->lcr, old_lcr);
135
136 /* calculate speed */
137 speed = (clock / prescaler) / (divisor * 16);
138
139 /* sanity check */
140 if (speed < 0 || speed > (clock / 16))
141 speed = 9600;
142
143 return speed;
144}
145
103#ifdef CONFIG_PPC_MAPLE 146#ifdef CONFIG_PPC_MAPLE
104void udbg_maple_real_putc(unsigned char c) 147void udbg_maple_real_putc(unsigned char c)
105{ 148{
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 93d4fbfdb724..a4815d316722 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -81,7 +81,8 @@ static int store_updates_sp(struct pt_regs *regs)
81} 81}
82 82
83#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) 83#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
84static void do_dabr(struct pt_regs *regs, unsigned long error_code) 84static void do_dabr(struct pt_regs *regs, unsigned long address,
85 unsigned long error_code)
85{ 86{
86 siginfo_t info; 87 siginfo_t info;
87 88
@@ -99,7 +100,7 @@ static void do_dabr(struct pt_regs *regs, unsigned long error_code)
99 info.si_signo = SIGTRAP; 100 info.si_signo = SIGTRAP;
100 info.si_errno = 0; 101 info.si_errno = 0;
101 info.si_code = TRAP_HWBKPT; 102 info.si_code = TRAP_HWBKPT;
102 info.si_addr = (void __user *)regs->nip; 103 info.si_addr = (void __user *)address;
103 force_sig_info(SIGTRAP, &info, current); 104 force_sig_info(SIGTRAP, &info, current);
104} 105}
105#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/ 106#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
@@ -159,7 +160,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
159#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) 160#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
160 if (error_code & DSISR_DABRMATCH) { 161 if (error_code & DSISR_DABRMATCH) {
161 /* DABR match */ 162 /* DABR match */
162 do_dabr(regs, error_code); 163 do_dabr(regs, address, error_code);
163 return 0; 164 return 0;
164 } 165 }
165#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/ 166#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index a606504678bd..5bb433cbe41b 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -456,7 +456,7 @@ void __init htab_initialize(void)
456 456
457 /* create bolted the linear mapping in the hash table */ 457 /* create bolted the linear mapping in the hash table */
458 for (i=0; i < lmb.memory.cnt; i++) { 458 for (i=0; i < lmb.memory.cnt; i++) {
459 base = lmb.memory.region[i].base + KERNELBASE; 459 base = (unsigned long)__va(lmb.memory.region[i].base);
460 size = lmb.memory.region[i].size; 460 size = lmb.memory.region[i].size;
461 461
462 DBG("creating mapping for region: %lx : %lx\n", base, size); 462 DBG("creating mapping for region: %lx : %lx\n", base, size);
@@ -498,8 +498,8 @@ void __init htab_initialize(void)
498 * for either 4K or 16MB pages. 498 * for either 4K or 16MB pages.
499 */ 499 */
500 if (tce_alloc_start) { 500 if (tce_alloc_start) {
501 tce_alloc_start += KERNELBASE; 501 tce_alloc_start = (unsigned long)__va(tce_alloc_start);
502 tce_alloc_end += KERNELBASE; 502 tce_alloc_end = (unsigned long)__va(tce_alloc_end);
503 503
504 if (base + size >= tce_alloc_start) 504 if (base + size >= tce_alloc_start)
505 tce_alloc_start = base + size + 1; 505 tce_alloc_start = base + size + 1;
@@ -644,6 +644,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
644 DBG_LOW(" -> rc=%d\n", rc); 644 DBG_LOW(" -> rc=%d\n", rc);
645 return rc; 645 return rc;
646} 646}
647EXPORT_SYMBOL_GPL(hash_page);
647 648
648void hash_preload(struct mm_struct *mm, unsigned long ea, 649void hash_preload(struct mm_struct *mm, unsigned long ea,
649 unsigned long access, unsigned long trap) 650 unsigned long access, unsigned long trap)
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 54131b877da3..b51bb28c054b 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -549,6 +549,17 @@ fail:
549 return addr; 549 return addr;
550} 550}
551 551
552static int htlb_check_hinted_area(unsigned long addr, unsigned long len)
553{
554 struct vm_area_struct *vma;
555
556 vma = find_vma(current->mm, addr);
557 if (!vma || ((addr + len) <= vma->vm_start))
558 return 0;
559
560 return -ENOMEM;
561}
562
552static unsigned long htlb_get_low_area(unsigned long len, u16 segmask) 563static unsigned long htlb_get_low_area(unsigned long len, u16 segmask)
553{ 564{
554 unsigned long addr = 0; 565 unsigned long addr = 0;
@@ -618,15 +629,28 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
618 if (!cpu_has_feature(CPU_FTR_16M_PAGE)) 629 if (!cpu_has_feature(CPU_FTR_16M_PAGE))
619 return -EINVAL; 630 return -EINVAL;
620 631
632 /* Paranoia, caller should have dealt with this */
633 BUG_ON((addr + len) < addr);
634
621 if (test_thread_flag(TIF_32BIT)) { 635 if (test_thread_flag(TIF_32BIT)) {
636 /* Paranoia, caller should have dealt with this */
637 BUG_ON((addr + len) > 0x100000000UL);
638
622 curareas = current->mm->context.low_htlb_areas; 639 curareas = current->mm->context.low_htlb_areas;
623 640
624 /* First see if we can do the mapping in the existing 641 /* First see if we can use the hint address */
625 * low areas */ 642 if (addr && (htlb_check_hinted_area(addr, len) == 0)) {
643 areamask = LOW_ESID_MASK(addr, len);
644 if (open_low_hpage_areas(current->mm, areamask) == 0)
645 return addr;
646 }
647
648 /* Next see if we can map in the existing low areas */
626 addr = htlb_get_low_area(len, curareas); 649 addr = htlb_get_low_area(len, curareas);
627 if (addr != -ENOMEM) 650 if (addr != -ENOMEM)
628 return addr; 651 return addr;
629 652
653 /* Finally go looking for areas to open */
630 lastshift = 0; 654 lastshift = 0;
631 for (areamask = LOW_ESID_MASK(0x100000000UL-len, len); 655 for (areamask = LOW_ESID_MASK(0x100000000UL-len, len);
632 ! lastshift; areamask >>=1) { 656 ! lastshift; areamask >>=1) {
@@ -641,12 +665,22 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
641 } else { 665 } else {
642 curareas = current->mm->context.high_htlb_areas; 666 curareas = current->mm->context.high_htlb_areas;
643 667
644 /* First see if we can do the mapping in the existing 668 /* First see if we can use the hint address */
645 * high areas */ 669 /* We discourage 64-bit processes from doing hugepage
670 * mappings below 4GB (must use MAP_FIXED) */
671 if ((addr >= 0x100000000UL)
672 && (htlb_check_hinted_area(addr, len) == 0)) {
673 areamask = HTLB_AREA_MASK(addr, len);
674 if (open_high_hpage_areas(current->mm, areamask) == 0)
675 return addr;
676 }
677
678 /* Next see if we can map in the existing high areas */
646 addr = htlb_get_high_area(len, curareas); 679 addr = htlb_get_high_area(len, curareas);
647 if (addr != -ENOMEM) 680 if (addr != -ENOMEM)
648 return addr; 681 return addr;
649 682
683 /* Finally go looking for areas to open */
650 lastshift = 0; 684 lastshift = 0;
651 for (areamask = HTLB_AREA_MASK(TASK_SIZE_USER64-len, len); 685 for (areamask = HTLB_AREA_MASK(TASK_SIZE_USER64-len, len);
652 ! lastshift; areamask >>=1) { 686 ! lastshift; areamask >>=1) {
diff --git a/arch/powerpc/mm/imalloc.c b/arch/powerpc/mm/imalloc.c
index f9587bcc6a48..8b0c132bc163 100644
--- a/arch/powerpc/mm/imalloc.c
+++ b/arch/powerpc/mm/imalloc.c
@@ -107,6 +107,7 @@ static int im_region_status(unsigned long v_addr, unsigned long size,
107 if (v_addr < (unsigned long) tmp->addr + tmp->size) 107 if (v_addr < (unsigned long) tmp->addr + tmp->size)
108 break; 108 break;
109 109
110 *vm = NULL;
110 if (tmp) { 111 if (tmp) {
111 if (im_region_overlaps(v_addr, size, tmp)) 112 if (im_region_overlaps(v_addr, size, tmp))
112 return IM_REGION_OVERLAP; 113 return IM_REGION_OVERLAP;
@@ -127,7 +128,6 @@ static int im_region_status(unsigned long v_addr, unsigned long size,
127 } 128 }
128 } 129 }
129 130
130 *vm = NULL;
131 return IM_REGION_UNUSED; 131 return IM_REGION_UNUSED;
132} 132}
133 133
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 7d4b8b5f0606..7d0d75c11848 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -188,6 +188,11 @@ void __init MMU_init(void)
188 188
189 if (ppc_md.progress) 189 if (ppc_md.progress)
190 ppc_md.progress("MMU:exit", 0x211); 190 ppc_md.progress("MMU:exit", 0x211);
191
192 /* From now on, btext is no longer BAT mapped if it was at all */
193#ifdef CONFIG_BOOTX_TEXT
194 btext_unmap();
195#endif
191} 196}
192 197
193/* This is only called until mem_init is done. */ 198/* This is only called until mem_init is done. */
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index ed6ed2e30dac..15aac0d78dfa 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -114,19 +114,18 @@ void online_page(struct page *page)
114 num_physpages++; 114 num_physpages++;
115} 115}
116 116
117/*
118 * This works only for the non-NUMA case. Later, we'll need a lookup
119 * to convert from real physical addresses to nid, that doesn't use
120 * pfn_to_nid().
121 */
122int __devinit add_memory(u64 start, u64 size) 117int __devinit add_memory(u64 start, u64 size)
123{ 118{
124 struct pglist_data *pgdata = NODE_DATA(0); 119 struct pglist_data *pgdata;
125 struct zone *zone; 120 struct zone *zone;
121 int nid;
126 unsigned long start_pfn = start >> PAGE_SHIFT; 122 unsigned long start_pfn = start >> PAGE_SHIFT;
127 unsigned long nr_pages = size >> PAGE_SHIFT; 123 unsigned long nr_pages = size >> PAGE_SHIFT;
128 124
129 start += KERNELBASE; 125 nid = hot_add_scn_to_nid(start);
126 pgdata = NODE_DATA(nid);
127
128 start = __va(start);
130 create_section_mapping(start, start + size); 129 create_section_mapping(start, start + size);
131 130
132 /* this should work for most non-highmem platforms */ 131 /* this should work for most non-highmem platforms */
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index ba7a3055a9fc..2863a912bcd0 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -37,6 +37,7 @@ EXPORT_SYMBOL(node_data);
37 37
38static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES]; 38static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES];
39static int min_common_depth; 39static int min_common_depth;
40static int n_mem_addr_cells, n_mem_size_cells;
40 41
41/* 42/*
42 * We need somewhere to store start/end/node for each region until we have 43 * We need somewhere to store start/end/node for each region until we have
@@ -254,32 +255,20 @@ static int __init find_min_common_depth(void)
254 return depth; 255 return depth;
255} 256}
256 257
257static int __init get_mem_addr_cells(void) 258static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells)
258{ 259{
259 struct device_node *memory = NULL; 260 struct device_node *memory = NULL;
260 int rc;
261 261
262 memory = of_find_node_by_type(memory, "memory"); 262 memory = of_find_node_by_type(memory, "memory");
263 if (!memory) 263 if (!memory)
264 return 0; /* it won't matter */ 264 panic("numa.c: No memory nodes found!");
265 265
266 rc = prom_n_addr_cells(memory); 266 *n_addr_cells = prom_n_addr_cells(memory);
267 return rc; 267 *n_size_cells = prom_n_size_cells(memory);
268 of_node_put(memory);
268} 269}
269 270
270static int __init get_mem_size_cells(void) 271static unsigned long __devinit read_n_cells(int n, unsigned int **buf)
271{
272 struct device_node *memory = NULL;
273 int rc;
274
275 memory = of_find_node_by_type(memory, "memory");
276 if (!memory)
277 return 0; /* it won't matter */
278 rc = prom_n_size_cells(memory);
279 return rc;
280}
281
282static unsigned long __init read_n_cells(int n, unsigned int **buf)
283{ 272{
284 unsigned long result = 0; 273 unsigned long result = 0;
285 274
@@ -386,7 +375,6 @@ static int __init parse_numa_properties(void)
386{ 375{
387 struct device_node *cpu = NULL; 376 struct device_node *cpu = NULL;
388 struct device_node *memory = NULL; 377 struct device_node *memory = NULL;
389 int addr_cells, size_cells;
390 int max_domain; 378 int max_domain;
391 unsigned long i; 379 unsigned long i;
392 380
@@ -425,8 +413,7 @@ static int __init parse_numa_properties(void)
425 } 413 }
426 } 414 }
427 415
428 addr_cells = get_mem_addr_cells(); 416 get_n_mem_cells(&n_mem_addr_cells, &n_mem_size_cells);
429 size_cells = get_mem_size_cells();
430 memory = NULL; 417 memory = NULL;
431 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { 418 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
432 unsigned long start; 419 unsigned long start;
@@ -436,15 +423,21 @@ static int __init parse_numa_properties(void)
436 unsigned int *memcell_buf; 423 unsigned int *memcell_buf;
437 unsigned int len; 424 unsigned int len;
438 425
439 memcell_buf = (unsigned int *)get_property(memory, "reg", &len); 426 memcell_buf = (unsigned int *)get_property(memory,
427 "linux,usable-memory", &len);
428 if (!memcell_buf || len <= 0)
429 memcell_buf =
430 (unsigned int *)get_property(memory, "reg",
431 &len);
440 if (!memcell_buf || len <= 0) 432 if (!memcell_buf || len <= 0)
441 continue; 433 continue;
442 434
443 ranges = memory->n_addrs; 435 /* ranges in cell */
436 ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells);
444new_range: 437new_range:
445 /* these are order-sensitive, and modify the buffer pointer */ 438 /* these are order-sensitive, and modify the buffer pointer */
446 start = read_n_cells(addr_cells, &memcell_buf); 439 start = read_n_cells(n_mem_addr_cells, &memcell_buf);
447 size = read_n_cells(size_cells, &memcell_buf); 440 size = read_n_cells(n_mem_size_cells, &memcell_buf);
448 441
449 numa_domain = of_node_numa_domain(memory); 442 numa_domain = of_node_numa_domain(memory);
450 443
@@ -497,7 +490,41 @@ static void __init setup_nonnuma(void)
497 node_set_online(0); 490 node_set_online(0);
498} 491}
499 492
500static void __init dump_numa_topology(void) 493void __init dump_numa_cpu_topology(void)
494{
495 unsigned int node;
496 unsigned int cpu, count;
497
498 if (min_common_depth == -1 || !numa_enabled)
499 return;
500
501 for_each_online_node(node) {
502 printk(KERN_INFO "Node %d CPUs:", node);
503
504 count = 0;
505 /*
506 * If we used a CPU iterator here we would miss printing
507 * the holes in the cpumap.
508 */
509 for (cpu = 0; cpu < NR_CPUS; cpu++) {
510 if (cpu_isset(cpu, numa_cpumask_lookup_table[node])) {
511 if (count == 0)
512 printk(" %u", cpu);
513 ++count;
514 } else {
515 if (count > 1)
516 printk("-%u", cpu - 1);
517 count = 0;
518 }
519 }
520
521 if (count > 1)
522 printk("-%u", NR_CPUS - 1);
523 printk("\n");
524 }
525}
526
527static void __init dump_numa_memory_topology(void)
501{ 528{
502 unsigned int node; 529 unsigned int node;
503 unsigned int count; 530 unsigned int count;
@@ -529,7 +556,6 @@ static void __init dump_numa_topology(void)
529 printk("-0x%lx", i); 556 printk("-0x%lx", i);
530 printk("\n"); 557 printk("\n");
531 } 558 }
532 return;
533} 559}
534 560
535/* 561/*
@@ -591,7 +617,7 @@ void __init do_init_bootmem(void)
591 if (parse_numa_properties()) 617 if (parse_numa_properties())
592 setup_nonnuma(); 618 setup_nonnuma();
593 else 619 else
594 dump_numa_topology(); 620 dump_numa_memory_topology();
595 621
596 register_cpu_notifier(&ppc64_numa_nb); 622 register_cpu_notifier(&ppc64_numa_nb);
597 623
@@ -730,3 +756,60 @@ static int __init early_numa(char *p)
730 return 0; 756 return 0;
731} 757}
732early_param("numa", early_numa); 758early_param("numa", early_numa);
759
760#ifdef CONFIG_MEMORY_HOTPLUG
761/*
762 * Find the node associated with a hot added memory section. Section
763 * corresponds to a SPARSEMEM section, not an LMB. It is assumed that
764 * sections are fully contained within a single LMB.
765 */
766int hot_add_scn_to_nid(unsigned long scn_addr)
767{
768 struct device_node *memory = NULL;
769 nodemask_t nodes;
770 int numa_domain = 0;
771
772 if (!numa_enabled || (min_common_depth < 0))
773 return numa_domain;
774
775 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
776 unsigned long start, size;
777 int ranges;
778 unsigned int *memcell_buf;
779 unsigned int len;
780
781 memcell_buf = (unsigned int *)get_property(memory, "reg", &len);
782 if (!memcell_buf || len <= 0)
783 continue;
784
785 /* ranges in cell */
786 ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells);
787ha_new_range:
788 start = read_n_cells(n_mem_addr_cells, &memcell_buf);
789 size = read_n_cells(n_mem_size_cells, &memcell_buf);
790 numa_domain = of_node_numa_domain(memory);
791
792 /* Domains not present at boot default to 0 */
793 if (!node_online(numa_domain))
794 numa_domain = any_online_node(NODE_MASK_ALL);
795
796 if ((scn_addr >= start) && (scn_addr < (start + size))) {
797 of_node_put(memory);
798 goto got_numa_domain;
799 }
800
801 if (--ranges) /* process all ranges in cell */
802 goto ha_new_range;
803 }
804 BUG(); /* section address should be found above */
805
806 /* Temporary code to ensure that returned node is not empty */
807got_numa_domain:
808 nodes_setall(nodes);
809 while (NODE_DATA(numa_domain)->node_spanned_pages == 0) {
810 node_clear(numa_domain, nodes);
811 numa_domain = any_online_node(nodes);
812 }
813 return numa_domain;
814}
815#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index 60e852f2f8e5..ffc8ed4de62d 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -75,7 +75,7 @@ static void slb_flush_and_rebolt(void)
75 vflags = SLB_VSID_KERNEL | virtual_llp; 75 vflags = SLB_VSID_KERNEL | virtual_llp;
76 76
77 ksp_esid_data = mk_esid_data(get_paca()->kstack, 2); 77 ksp_esid_data = mk_esid_data(get_paca()->kstack, 2);
78 if ((ksp_esid_data & ESID_MASK) == KERNELBASE) 78 if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET)
79 ksp_esid_data &= ~SLB_ESID_V; 79 ksp_esid_data &= ~SLB_ESID_V;
80 80
81 /* We need to do this all in asm, so we're sure we don't touch 81 /* We need to do this all in asm, so we're sure we don't touch
@@ -87,8 +87,8 @@ static void slb_flush_and_rebolt(void)
87 /* Slot 2 - kernel stack */ 87 /* Slot 2 - kernel stack */
88 "slbmte %2,%3\n" 88 "slbmte %2,%3\n"
89 "isync" 89 "isync"
90 :: "r"(mk_vsid_data(VMALLOCBASE, vflags)), 90 :: "r"(mk_vsid_data(VMALLOC_START, vflags)),
91 "r"(mk_esid_data(VMALLOCBASE, 1)), 91 "r"(mk_esid_data(VMALLOC_START, 1)),
92 "r"(mk_vsid_data(ksp_esid_data, lflags)), 92 "r"(mk_vsid_data(ksp_esid_data, lflags)),
93 "r"(ksp_esid_data) 93 "r"(ksp_esid_data)
94 : "memory"); 94 : "memory");
@@ -134,14 +134,14 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
134 else 134 else
135 unmapped_base = TASK_UNMAPPED_BASE_USER64; 135 unmapped_base = TASK_UNMAPPED_BASE_USER64;
136 136
137 if (pc >= KERNELBASE) 137 if (is_kernel_addr(pc))
138 return; 138 return;
139 slb_allocate(pc); 139 slb_allocate(pc);
140 140
141 if (GET_ESID(pc) == GET_ESID(stack)) 141 if (GET_ESID(pc) == GET_ESID(stack))
142 return; 142 return;
143 143
144 if (stack >= KERNELBASE) 144 if (is_kernel_addr(stack))
145 return; 145 return;
146 slb_allocate(stack); 146 slb_allocate(stack);
147 147
@@ -149,7 +149,7 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
149 || (GET_ESID(stack) == GET_ESID(unmapped_base))) 149 || (GET_ESID(stack) == GET_ESID(unmapped_base)))
150 return; 150 return;
151 151
152 if (unmapped_base >= KERNELBASE) 152 if (is_kernel_addr(unmapped_base))
153 return; 153 return;
154 slb_allocate(unmapped_base); 154 slb_allocate(unmapped_base);
155} 155}
@@ -213,10 +213,10 @@ void slb_initialize(void)
213 asm volatile("isync":::"memory"); 213 asm volatile("isync":::"memory");
214 asm volatile("slbmte %0,%0"::"r" (0) : "memory"); 214 asm volatile("slbmte %0,%0"::"r" (0) : "memory");
215 asm volatile("isync; slbia; isync":::"memory"); 215 asm volatile("isync; slbia; isync":::"memory");
216 create_slbe(KERNELBASE, lflags, 0); 216 create_slbe(PAGE_OFFSET, lflags, 0);
217 217
218 /* VMALLOC space has 4K pages always for now */ 218 /* VMALLOC space has 4K pages always for now */
219 create_slbe(VMALLOCBASE, vflags, 1); 219 create_slbe(VMALLOC_START, vflags, 1);
220 220
221 /* We don't bolt the stack for the time being - we're in boot, 221 /* We don't bolt the stack for the time being - we're in boot,
222 * so the stack is in the bolted segment. By the time it goes 222 * so the stack is in the bolted segment. By the time it goes
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index 950ffc5848c7..d1acee38f163 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -37,9 +37,9 @@ _GLOBAL(slb_allocate_realmode)
37 37
38 srdi r9,r3,60 /* get region */ 38 srdi r9,r3,60 /* get region */
39 srdi r10,r3,28 /* get esid */ 39 srdi r10,r3,28 /* get esid */
40 cmpldi cr7,r9,0xc /* cmp KERNELBASE for later use */ 40 cmpldi cr7,r9,0xc /* cmp PAGE_OFFSET for later use */
41 41
42 /* r3 = address, r10 = esid, cr7 = <>KERNELBASE */ 42 /* r3 = address, r10 = esid, cr7 = <> PAGE_OFFSET */
43 blt cr7,0f /* user or kernel? */ 43 blt cr7,0f /* user or kernel? */
44 44
45 /* kernel address: proto-VSID = ESID */ 45 /* kernel address: proto-VSID = ESID */
@@ -166,7 +166,7 @@ _GLOBAL(slb_allocate_user)
166/* 166/*
167 * Finish loading of an SLB entry and return 167 * Finish loading of an SLB entry and return
168 * 168 *
169 * r3 = EA, r10 = proto-VSID, r11 = flags, clobbers r9, cr7 = <>KERNELBASE 169 * r3 = EA, r10 = proto-VSID, r11 = flags, clobbers r9, cr7 = <> PAGE_OFFSET
170 */ 170 */
171slb_finish_load: 171slb_finish_load:
172 ASM_VSID_SCRAMBLE(r10,r9) 172 ASM_VSID_SCRAMBLE(r10,r9)
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
index 51e7951414e5..82e4951826bc 100644
--- a/arch/powerpc/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -40,7 +40,7 @@ static int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid)
40 unsigned long entry, group, old_esid, castout_entry, i; 40 unsigned long entry, group, old_esid, castout_entry, i;
41 unsigned int global_entry; 41 unsigned int global_entry;
42 struct stab_entry *ste, *castout_ste; 42 struct stab_entry *ste, *castout_ste;
43 unsigned long kernel_segment = (esid << SID_SHIFT) >= KERNELBASE; 43 unsigned long kernel_segment = (esid << SID_SHIFT) >= PAGE_OFFSET;
44 44
45 vsid_data = vsid << STE_VSID_SHIFT; 45 vsid_data = vsid << STE_VSID_SHIFT;
46 esid_data = esid << SID_SHIFT | STE_ESID_KP | STE_ESID_V; 46 esid_data = esid << SID_SHIFT | STE_ESID_KP | STE_ESID_V;
@@ -83,7 +83,7 @@ static int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid)
83 } 83 }
84 84
85 /* Dont cast out the first kernel segment */ 85 /* Dont cast out the first kernel segment */
86 if ((castout_ste->esid_data & ESID_MASK) != KERNELBASE) 86 if ((castout_ste->esid_data & ESID_MASK) != PAGE_OFFSET)
87 break; 87 break;
88 88
89 castout_entry = (castout_entry + 1) & 0xf; 89 castout_entry = (castout_entry + 1) & 0xf;
@@ -122,7 +122,7 @@ static int __ste_allocate(unsigned long ea, struct mm_struct *mm)
122 unsigned long offset; 122 unsigned long offset;
123 123
124 /* Kernel or user address? */ 124 /* Kernel or user address? */
125 if (ea >= KERNELBASE) { 125 if (is_kernel_addr(ea)) {
126 vsid = get_kernel_vsid(ea); 126 vsid = get_kernel_vsid(ea);
127 } else { 127 } else {
128 if ((ea >= TASK_SIZE_USER64) || (! mm)) 128 if ((ea >= TASK_SIZE_USER64) || (! mm))
@@ -133,7 +133,7 @@ static int __ste_allocate(unsigned long ea, struct mm_struct *mm)
133 133
134 stab_entry = make_ste(get_paca()->stab_addr, GET_ESID(ea), vsid); 134 stab_entry = make_ste(get_paca()->stab_addr, GET_ESID(ea), vsid);
135 135
136 if (ea < KERNELBASE) { 136 if (!is_kernel_addr(ea)) {
137 offset = __get_cpu_var(stab_cache_ptr); 137 offset = __get_cpu_var(stab_cache_ptr);
138 if (offset < NR_STAB_CACHE_ENTRIES) 138 if (offset < NR_STAB_CACHE_ENTRIES)
139 __get_cpu_var(stab_cache[offset++]) = stab_entry; 139 __get_cpu_var(stab_cache[offset++]) = stab_entry;
@@ -190,7 +190,7 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
190 entry++, ste++) { 190 entry++, ste++) {
191 unsigned long ea; 191 unsigned long ea;
192 ea = ste->esid_data & ESID_MASK; 192 ea = ste->esid_data & ESID_MASK;
193 if (ea < KERNELBASE) { 193 if (!is_kernel_addr(ea)) {
194 ste->esid_data = 0; 194 ste->esid_data = 0;
195 } 195 }
196 } 196 }
@@ -251,7 +251,7 @@ void stabs_alloc(void)
251 panic("Unable to allocate segment table for CPU %d.\n", 251 panic("Unable to allocate segment table for CPU %d.\n",
252 cpu); 252 cpu);
253 253
254 newstab += KERNELBASE; 254 newstab = (unsigned long)__va(newstab);
255 255
256 memset((void *)newstab, 0, HW_PAGE_SIZE); 256 memset((void *)newstab, 0, HW_PAGE_SIZE);
257 257
@@ -270,11 +270,11 @@ void stabs_alloc(void)
270 */ 270 */
271void stab_initialize(unsigned long stab) 271void stab_initialize(unsigned long stab)
272{ 272{
273 unsigned long vsid = get_kernel_vsid(KERNELBASE); 273 unsigned long vsid = get_kernel_vsid(PAGE_OFFSET);
274 unsigned long stabreal; 274 unsigned long stabreal;
275 275
276 asm volatile("isync; slbia; isync":::"memory"); 276 asm volatile("isync; slbia; isync":::"memory");
277 make_ste(stab, GET_ESID(KERNELBASE), vsid); 277 make_ste(stab, GET_ESID(PAGE_OFFSET), vsid);
278 278
279 /* Order update */ 279 /* Order update */
280 asm volatile("sync":::"memory"); 280 asm volatile("sync":::"memory");
diff --git a/arch/powerpc/mm/tlb_64.c b/arch/powerpc/mm/tlb_64.c
index 859d29a0cac5..bb3afb6e6317 100644
--- a/arch/powerpc/mm/tlb_64.c
+++ b/arch/powerpc/mm/tlb_64.c
@@ -168,7 +168,7 @@ void hpte_update(struct mm_struct *mm, unsigned long addr,
168 batch->mm = mm; 168 batch->mm = mm;
169 batch->psize = psize; 169 batch->psize = psize;
170 } 170 }
171 if (addr < KERNELBASE) { 171 if (!is_kernel_addr(addr)) {
172 vsid = get_vsid(mm->context.id, addr); 172 vsid = get_vsid(mm->context.id, addr);
173 WARN_ON(vsid == 0); 173 WARN_ON(vsid == 0);
174 } else 174 } else
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index 0782d0cca89c..554cd7c75321 100644
--- a/arch/powerpc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -9,3 +9,4 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
9oprofile-y := $(DRIVER_OBJS) common.o 9oprofile-y := $(DRIVER_OBJS) common.o
10oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o 10oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
11oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o 11oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
12oprofile-$(CONFIG_PPC32) += op_model_7450.o
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c
index af2c05d20ba5..71615eb70b2b 100644
--- a/arch/powerpc/oprofile/common.c
+++ b/arch/powerpc/oprofile/common.c
@@ -14,9 +14,6 @@
14 */ 14 */
15 15
16#include <linux/oprofile.h> 16#include <linux/oprofile.h>
17#ifndef __powerpc64__
18#include <linux/slab.h>
19#endif /* ! __powerpc64__ */
20#include <linux/init.h> 17#include <linux/init.h>
21#include <linux/smp.h> 18#include <linux/smp.h>
22#include <linux/errno.h> 19#include <linux/errno.h>
@@ -31,10 +28,6 @@ static struct op_powerpc_model *model;
31static struct op_counter_config ctr[OP_MAX_COUNTER]; 28static struct op_counter_config ctr[OP_MAX_COUNTER];
32static struct op_system_config sys; 29static struct op_system_config sys;
33 30
34#ifndef __powerpc64__
35static char *cpu_type;
36#endif /* ! __powerpc64__ */
37
38static void op_handle_interrupt(struct pt_regs *regs) 31static void op_handle_interrupt(struct pt_regs *regs)
39{ 32{
40 model->handle_interrupt(regs, ctr); 33 model->handle_interrupt(regs, ctr);
@@ -53,14 +46,7 @@ static int op_powerpc_setup(void)
53 model->reg_setup(ctr, &sys, model->num_counters); 46 model->reg_setup(ctr, &sys, model->num_counters);
54 47
55 /* Configure the registers on all cpus. */ 48 /* Configure the registers on all cpus. */
56#ifdef __powerpc64__
57 on_each_cpu(model->cpu_setup, NULL, 0, 1); 49 on_each_cpu(model->cpu_setup, NULL, 0, 1);
58#else /* __powerpc64__ */
59#if 0
60 /* FIXME: Make multi-cpu work */
61 on_each_cpu(model->reg_setup, NULL, 0, 1);
62#endif
63#endif /* __powerpc64__ */
64 50
65 return 0; 51 return 0;
66} 52}
@@ -95,7 +81,7 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
95{ 81{
96 int i; 82 int i;
97 83
98#ifdef __powerpc64__ 84#ifdef CONFIG_PPC64
99 /* 85 /*
100 * There is one mmcr0, mmcr1 and mmcra for setting the events for 86 * There is one mmcr0, mmcr1 and mmcra for setting the events for
101 * all of the counters. 87 * all of the counters.
@@ -103,7 +89,7 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
103 oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0); 89 oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0);
104 oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1); 90 oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1);
105 oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra); 91 oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra);
106#endif /* __powerpc64__ */ 92#endif
107 93
108 for (i = 0; i < model->num_counters; ++i) { 94 for (i = 0; i < model->num_counters; ++i) {
109 struct dentry *dir; 95 struct dentry *dir;
@@ -115,65 +101,68 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
115 oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); 101 oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
116 oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); 102 oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
117 oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); 103 oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
118#ifdef __powerpc64__ 104
119 /* 105 /*
120 * We dont support per counter user/kernel selection, but 106 * Classic PowerPC doesn't support per-counter
121 * we leave the entries because userspace expects them 107 * control like this, but the options are
108 * expected, so they remain. For Freescale
109 * Book-E style performance monitors, we do
110 * support them.
122 */ 111 */
123#endif /* __powerpc64__ */
124 oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); 112 oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
125 oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); 113 oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
126 114
127#ifndef __powerpc64__
128 /* FIXME: Not sure if this is used */
129#endif /* ! __powerpc64__ */
130 oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask); 115 oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
131 } 116 }
132 117
133 oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel); 118 oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
134 oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user); 119 oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
135#ifdef __powerpc64__ 120#ifdef CONFIG_PPC64
136 oprofilefs_create_ulong(sb, root, "backtrace_spinlocks", 121 oprofilefs_create_ulong(sb, root, "backtrace_spinlocks",
137 &sys.backtrace_spinlocks); 122 &sys.backtrace_spinlocks);
138#endif /* __powerpc64__ */ 123#endif
139 124
140 /* Default to tracing both kernel and user */ 125 /* Default to tracing both kernel and user */
141 sys.enable_kernel = 1; 126 sys.enable_kernel = 1;
142 sys.enable_user = 1; 127 sys.enable_user = 1;
143#ifdef __powerpc64__ 128#ifdef CONFIG_PPC64
144 /* Turn on backtracing through spinlocks by default */ 129 /* Turn on backtracing through spinlocks by default */
145 sys.backtrace_spinlocks = 1; 130 sys.backtrace_spinlocks = 1;
146#endif /* __powerpc64__ */ 131#endif
147 132
148 return 0; 133 return 0;
149} 134}
150 135
151int __init oprofile_arch_init(struct oprofile_operations *ops) 136int __init oprofile_arch_init(struct oprofile_operations *ops)
152{ 137{
153#ifndef __powerpc64__ 138 if (!cur_cpu_spec->oprofile_cpu_type)
154#ifdef CONFIG_FSL_BOOKE 139 return -ENODEV;
155 model = &op_model_fsl_booke; 140
141 switch (cur_cpu_spec->oprofile_type) {
142#ifdef CONFIG_PPC64
143 case RS64:
144 model = &op_model_rs64;
145 break;
146 case POWER4:
147 model = &op_model_power4;
148 break;
156#else 149#else
157 return -ENODEV; 150 case G4:
151 model = &op_model_7450;
152 break;
158#endif 153#endif
154#ifdef CONFIG_FSL_BOOKE
155 case BOOKE:
156 model = &op_model_fsl_booke;
157 break;
158#endif
159 default:
160 return -ENODEV;
161 }
159 162
160 cpu_type = kmalloc(32, GFP_KERNEL);
161 if (NULL == cpu_type)
162 return -ENOMEM;
163
164 sprintf(cpu_type, "ppc/%s", cur_cpu_spec->cpu_name);
165
166 model->num_counters = cur_cpu_spec->num_pmcs;
167
168 ops->cpu_type = cpu_type;
169#else /* __powerpc64__ */
170 if (!cur_cpu_spec->oprofile_model || !cur_cpu_spec->oprofile_cpu_type)
171 return -ENODEV;
172 model = cur_cpu_spec->oprofile_model;
173 model->num_counters = cur_cpu_spec->num_pmcs; 163 model->num_counters = cur_cpu_spec->num_pmcs;
174 164
175 ops->cpu_type = cur_cpu_spec->oprofile_cpu_type; 165 ops->cpu_type = cur_cpu_spec->oprofile_cpu_type;
176#endif /* __powerpc64__ */
177 ops->create_files = op_powerpc_create_files; 166 ops->create_files = op_powerpc_create_files;
178 ops->setup = op_powerpc_setup; 167 ops->setup = op_powerpc_setup;
179 ops->shutdown = op_powerpc_shutdown; 168 ops->shutdown = op_powerpc_shutdown;
@@ -188,8 +177,4 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
188 177
189void oprofile_arch_exit(void) 178void oprofile_arch_exit(void)
190{ 179{
191#ifndef __powerpc64__
192 kfree(cpu_type);
193 cpu_type = NULL;
194#endif /* ! __powerpc64__ */
195} 180}
diff --git a/arch/powerpc/oprofile/op_model_7450.c b/arch/powerpc/oprofile/op_model_7450.c
new file mode 100644
index 000000000000..32abfdbb0eb1
--- /dev/null
+++ b/arch/powerpc/oprofile/op_model_7450.c
@@ -0,0 +1,206 @@
1/*
2 * oprofile/op_model_7450.c
3 *
4 * Freescale 745x/744x oprofile support, based on fsl_booke support
5 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
6 *
7 * Copyright (c) 2004 Freescale Semiconductor, Inc
8 *
9 * Author: Andy Fleming
10 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
16 */
17
18#include <linux/oprofile.h>
19#include <linux/init.h>
20#include <linux/smp.h>
21#include <asm/ptrace.h>
22#include <asm/system.h>
23#include <asm/processor.h>
24#include <asm/cputable.h>
25#include <asm/page.h>
26#include <asm/pmc.h>
27#include <asm/oprofile_impl.h>
28
29static unsigned long reset_value[OP_MAX_COUNTER];
30
31static int oprofile_running;
32static u32 mmcr0_val, mmcr1_val, mmcr2_val;
33
34#define MMCR0_PMC1_SHIFT 6
35#define MMCR0_PMC2_SHIFT 0
36#define MMCR1_PMC3_SHIFT 27
37#define MMCR1_PMC4_SHIFT 22
38#define MMCR1_PMC5_SHIFT 17
39#define MMCR1_PMC6_SHIFT 11
40
41#define mmcr0_event1(event) \
42 ((event << MMCR0_PMC1_SHIFT) & MMCR0_PMC1SEL)
43#define mmcr0_event2(event) \
44 ((event << MMCR0_PMC2_SHIFT) & MMCR0_PMC2SEL)
45
46#define mmcr1_event3(event) \
47 ((event << MMCR1_PMC3_SHIFT) & MMCR1_PMC3SEL)
48#define mmcr1_event4(event) \
49 ((event << MMCR1_PMC4_SHIFT) & MMCR1_PMC4SEL)
50#define mmcr1_event5(event) \
51 ((event << MMCR1_PMC5_SHIFT) & MMCR1_PMC5SEL)
52#define mmcr1_event6(event) \
53 ((event << MMCR1_PMC6_SHIFT) & MMCR1_PMC6SEL)
54
55#define MMCR0_INIT (MMCR0_FC | MMCR0_FCS | MMCR0_FCP | MMCR0_FCM1 | MMCR0_FCM0)
56
57/* Unfreezes the counters on this CPU, enables the interrupt,
58 * enables the counters to trigger the interrupt, and sets the
59 * counters to only count when the mark bit is not set.
60 */
61static void pmc_start_ctrs(void)
62{
63 u32 mmcr0 = mfspr(SPRN_MMCR0);
64
65 mmcr0 &= ~(MMCR0_FC | MMCR0_FCM0);
66 mmcr0 |= (MMCR0_FCECE | MMCR0_PMC1CE | MMCR0_PMCnCE | MMCR0_PMXE);
67
68 mtspr(SPRN_MMCR0, mmcr0);
69}
70
71/* Disables the counters on this CPU, and freezes them */
72static void pmc_stop_ctrs(void)
73{
74 u32 mmcr0 = mfspr(SPRN_MMCR0);
75
76 mmcr0 |= MMCR0_FC;
77 mmcr0 &= ~(MMCR0_FCECE | MMCR0_PMC1CE | MMCR0_PMCnCE | MMCR0_PMXE);
78
79 mtspr(SPRN_MMCR0, mmcr0);
80}
81
82/* Configures the counters on this CPU based on the global
83 * settings */
84static void fsl7450_cpu_setup(void *unused)
85{
86 /* freeze all counters */
87 pmc_stop_ctrs();
88
89 mtspr(SPRN_MMCR0, mmcr0_val);
90 mtspr(SPRN_MMCR1, mmcr1_val);
91 mtspr(SPRN_MMCR2, mmcr2_val);
92}
93
94#define NUM_CTRS 6
95
96/* Configures the global settings for the countes on all CPUs. */
97static void fsl7450_reg_setup(struct op_counter_config *ctr,
98 struct op_system_config *sys,
99 int num_ctrs)
100{
101 int i;
102
103 /* Our counters count up, and "count" refers to
104 * how much before the next interrupt, and we interrupt
105 * on overflow. So we calculate the starting value
106 * which will give us "count" until overflow.
107 * Then we set the events on the enabled counters */
108 for (i = 0; i < NUM_CTRS; ++i)
109 reset_value[i] = 0x80000000UL - ctr[i].count;
110
111 /* Set events for Counters 1 & 2 */
112 mmcr0_val = MMCR0_INIT | mmcr0_event1(ctr[0].event)
113 | mmcr0_event2(ctr[1].event);
114
115 /* Setup user/kernel bits */
116 if (sys->enable_kernel)
117 mmcr0_val &= ~(MMCR0_FCS);
118
119 if (sys->enable_user)
120 mmcr0_val &= ~(MMCR0_FCP);
121
122 /* Set events for Counters 3-6 */
123 mmcr1_val = mmcr1_event3(ctr[2].event)
124 | mmcr1_event4(ctr[3].event)
125 | mmcr1_event5(ctr[4].event)
126 | mmcr1_event6(ctr[5].event);
127
128 mmcr2_val = 0;
129}
130
131/* Sets the counters on this CPU to the chosen values, and starts them */
132static void fsl7450_start(struct op_counter_config *ctr)
133{
134 int i;
135
136 mtmsr(mfmsr() | MSR_PMM);
137
138 for (i = 0; i < NUM_CTRS; ++i) {
139 if (ctr[i].enabled)
140 ctr_write(i, reset_value[i]);
141 else
142 ctr_write(i, 0);
143 }
144
145 /* Clear the freeze bit, and enable the interrupt.
146 * The counters won't actually start until the rfi clears
147 * the PMM bit */
148 pmc_start_ctrs();
149
150 oprofile_running = 1;
151}
152
153/* Stop the counters on this CPU */
154static void fsl7450_stop(void)
155{
156 /* freeze counters */
157 pmc_stop_ctrs();
158
159 oprofile_running = 0;
160
161 mb();
162}
163
164
165/* Handle the interrupt on this CPU, and log a sample for each
166 * event that triggered the interrupt */
167static void fsl7450_handle_interrupt(struct pt_regs *regs,
168 struct op_counter_config *ctr)
169{
170 unsigned long pc;
171 int is_kernel;
172 int val;
173 int i;
174
175 /* set the PMM bit (see comment below) */
176 mtmsr(mfmsr() | MSR_PMM);
177
178 pc = mfspr(SPRN_SIAR);
179 is_kernel = (pc >= KERNELBASE);
180
181 for (i = 0; i < NUM_CTRS; ++i) {
182 val = ctr_read(i);
183 if (val < 0) {
184 if (oprofile_running && ctr[i].enabled) {
185 oprofile_add_pc(pc, is_kernel, i);
186 ctr_write(i, reset_value[i]);
187 } else {
188 ctr_write(i, 0);
189 }
190 }
191 }
192
193 /* The freeze bit was set by the interrupt. */
194 /* Clear the freeze bit, and reenable the interrupt.
195 * The counters won't actually start until the rfi clears
196 * the PMM bit */
197 pmc_start_ctrs();
198}
199
200struct op_powerpc_model op_model_7450= {
201 .reg_setup = fsl7450_reg_setup,
202 .cpu_setup = fsl7450_cpu_setup,
203 .start = fsl7450_start,
204 .stop = fsl7450_stop,
205 .handle_interrupt = fsl7450_handle_interrupt,
206};
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
index a3401b46f3ba..659a021da0c7 100644
--- a/arch/powerpc/oprofile/op_model_power4.c
+++ b/arch/powerpc/oprofile/op_model_power4.c
@@ -252,7 +252,7 @@ static unsigned long get_pc(struct pt_regs *regs)
252 return (unsigned long)__va(pc); 252 return (unsigned long)__va(pc);
253 253
254 /* Not sure where we were */ 254 /* Not sure where we were */
255 if (pc < KERNELBASE) 255 if (!is_kernel_addr(pc))
256 /* function descriptor madness */ 256 /* function descriptor madness */
257 return *((unsigned long *)kernel_unknown_bucket); 257 return *((unsigned long *)kernel_unknown_bucket);
258 258
@@ -264,7 +264,7 @@ static int get_kernel(unsigned long pc)
264 int is_kernel; 264 int is_kernel;
265 265
266 if (!mmcra_has_sihv) { 266 if (!mmcra_has_sihv) {
267 is_kernel = (pc >= KERNELBASE); 267 is_kernel = is_kernel_addr(pc);
268 } else { 268 } else {
269 unsigned long mmcra = mfspr(SPRN_MMCRA); 269 unsigned long mmcra = mfspr(SPRN_MMCRA);
270 is_kernel = ((mmcra & MMCRA_SIPR) == 0); 270 is_kernel = ((mmcra & MMCRA_SIPR) == 0);
diff --git a/arch/powerpc/oprofile/op_model_rs64.c b/arch/powerpc/oprofile/op_model_rs64.c
index e010b85996e8..5c909ee609fe 100644
--- a/arch/powerpc/oprofile/op_model_rs64.c
+++ b/arch/powerpc/oprofile/op_model_rs64.c
@@ -178,7 +178,6 @@ static void rs64_handle_interrupt(struct pt_regs *regs,
178 int val; 178 int val;
179 int i; 179 int i;
180 unsigned long pc = mfspr(SPRN_SIAR); 180 unsigned long pc = mfspr(SPRN_SIAR);
181 int is_kernel = (pc >= KERNELBASE);
182 181
183 /* set the PMM bit (see comment below) */ 182 /* set the PMM bit (see comment below) */
184 mtmsrd(mfmsr() | MSR_PMM); 183 mtmsrd(mfmsr() | MSR_PMM);
@@ -187,7 +186,7 @@ static void rs64_handle_interrupt(struct pt_regs *regs,
187 val = ctr_read(i); 186 val = ctr_read(i);
188 if (val < 0) { 187 if (val < 0) {
189 if (ctr[i].enabled) { 188 if (ctr[i].enabled) {
190 oprofile_add_pc(pc, is_kernel, i); 189 oprofile_add_pc(pc, is_kernel_addr(pc), i);
191 ctr_write(i, reset_value[i]); 190 ctr_write(i, reset_value[i]);
192 } else { 191 } else {
193 ctr_write(i, 0); 192 ctr_write(i, 0);
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
new file mode 100644
index 000000000000..3157071e241c
--- /dev/null
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -0,0 +1,13 @@
1menu "Cell Broadband Engine options"
2 depends on PPC_CELL
3
4config SPU_FS
5 tristate "SPU file system"
6 default m
7 depends on PPC_CELL
8 help
9 The SPU file system is used to access Synergistic Processing
10 Units on machines implementing the Broadband Processor
11 Architecture.
12
13endmenu
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index 55e094b96bc0..16031b565be4 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -1,2 +1,10 @@
1obj-y += interrupt.o iommu.o setup.o spider-pic.o 1obj-y += interrupt.o iommu.o setup.o spider-pic.o
2obj-y += pervasive.o
3
2obj-$(CONFIG_SMP) += smp.o 4obj-$(CONFIG_SMP) += smp.o
5obj-$(CONFIG_SPU_FS) += spufs/ spu-base.o
6
7spu-base-y += spu_base.o spu_priv1.o
8
9builtin-spufs-$(CONFIG_SPU_FS) += spu_syscalls.o
10obj-y += $(builtin-spufs-m)
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 7fbe78a9327d..63aa52acf441 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -23,6 +23,7 @@
23#include <linux/config.h> 23#include <linux/config.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/irq.h> 25#include <linux/irq.h>
26#include <linux/module.h>
26#include <linux/percpu.h> 27#include <linux/percpu.h>
27#include <linux/types.h> 28#include <linux/types.h>
28 29
@@ -55,6 +56,7 @@ struct iic_regs {
55 56
56struct iic { 57struct iic {
57 struct iic_regs __iomem *regs; 58 struct iic_regs __iomem *regs;
59 u8 target_id;
58}; 60};
59 61
60static DEFINE_PER_CPU(struct iic, iic); 62static DEFINE_PER_CPU(struct iic, iic);
@@ -172,12 +174,11 @@ int iic_get_irq(struct pt_regs *regs)
172 return irq; 174 return irq;
173} 175}
174 176
175static struct iic_regs __iomem *find_iic(int cpu) 177static int setup_iic(int cpu, struct iic *iic)
176{ 178{
177 struct device_node *np; 179 struct device_node *np;
178 int nodeid = cpu / 2; 180 int nodeid = cpu / 2;
179 unsigned long regs; 181 unsigned long regs;
180 struct iic_regs __iomem *iic_regs;
181 182
182 for (np = of_find_node_by_type(NULL, "cpu"); 183 for (np = of_find_node_by_type(NULL, "cpu");
183 np; 184 np;
@@ -188,20 +189,23 @@ static struct iic_regs __iomem *find_iic(int cpu)
188 189
189 if (!np) { 190 if (!np) {
190 printk(KERN_WARNING "IIC: CPU %d not found\n", cpu); 191 printk(KERN_WARNING "IIC: CPU %d not found\n", cpu);
191 iic_regs = NULL; 192 iic->regs = NULL;
192 } else { 193 iic->target_id = 0xff;
193 regs = *(long *)get_property(np, "iic", NULL); 194 return -ENODEV;
194
195 /* hack until we have decided on the devtree info */
196 regs += 0x400;
197 if (cpu & 1)
198 regs += 0x20;
199
200 printk(KERN_DEBUG "IIC for CPU %d at %lx\n", cpu, regs);
201 iic_regs = __ioremap(regs, sizeof(struct iic_regs),
202 _PAGE_NO_CACHE);
203 } 195 }
204 return iic_regs; 196
197 regs = *(long *)get_property(np, "iic", NULL);
198
199 /* hack until we have decided on the devtree info */
200 regs += 0x400;
201 if (cpu & 1)
202 regs += 0x20;
203
204 printk(KERN_DEBUG "IIC for CPU %d at %lx\n", cpu, regs);
205 iic->regs = __ioremap(regs, sizeof(struct iic_regs),
206 _PAGE_NO_CACHE);
207 iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe);
208 return 0;
205} 209}
206 210
207#ifdef CONFIG_SMP 211#ifdef CONFIG_SMP
@@ -227,6 +231,12 @@ void iic_cause_IPI(int cpu, int mesg)
227 out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) << 4); 231 out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) << 4);
228} 232}
229 233
234u8 iic_get_target_id(int cpu)
235{
236 return per_cpu(iic, cpu).target_id;
237}
238EXPORT_SYMBOL_GPL(iic_get_target_id);
239
230static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs) 240static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
231{ 241{
232 smp_message_recv(iic_irq_to_ipi(irq), regs); 242 smp_message_recv(iic_irq_to_ipi(irq), regs);
@@ -276,7 +286,7 @@ void iic_init_IRQ(void)
276 irq_offset = 0; 286 irq_offset = 0;
277 for_each_cpu(cpu) { 287 for_each_cpu(cpu) {
278 iic = &per_cpu(iic, cpu); 288 iic = &per_cpu(iic, cpu);
279 iic->regs = find_iic(cpu); 289 setup_iic(cpu, iic);
280 if (iic->regs) 290 if (iic->regs)
281 out_be64(&iic->regs->prio, 0xff); 291 out_be64(&iic->regs->prio, 0xff);
282 } 292 }
diff --git a/arch/powerpc/platforms/cell/interrupt.h b/arch/powerpc/platforms/cell/interrupt.h
index 37d58e6fd0c6..a14bd38791c0 100644
--- a/arch/powerpc/platforms/cell/interrupt.h
+++ b/arch/powerpc/platforms/cell/interrupt.h
@@ -54,6 +54,7 @@ extern void iic_setup_cpu(void);
54extern void iic_local_enable(void); 54extern void iic_local_enable(void);
55extern void iic_local_disable(void); 55extern void iic_local_disable(void);
56 56
57extern u8 iic_get_target_id(int cpu);
57 58
58extern void spider_init_IRQ(void); 59extern void spider_init_IRQ(void);
59extern int spider_get_irq(unsigned long int_pending); 60extern int spider_get_irq(unsigned long int_pending);
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 74f999b4ac9e..46e7cb9c3e64 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -29,6 +29,8 @@
29#include <linux/bootmem.h> 29#include <linux/bootmem.h>
30#include <linux/mm.h> 30#include <linux/mm.h>
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/kernel.h>
33#include <linux/compiler.h>
32 34
33#include <asm/sections.h> 35#include <asm/sections.h>
34#include <asm/iommu.h> 36#include <asm/iommu.h>
@@ -40,6 +42,7 @@
40#include <asm/abs_addr.h> 42#include <asm/abs_addr.h>
41#include <asm/system.h> 43#include <asm/system.h>
42#include <asm/ppc-pci.h> 44#include <asm/ppc-pci.h>
45#include <asm/udbg.h>
43 46
44#include "iommu.h" 47#include "iommu.h"
45 48
@@ -220,8 +223,6 @@ set_iopt_cache(void __iomem *base, unsigned long index,
220{ 223{
221 unsigned long __iomem *tags = base + IOC_PT_CACHE_DIR; 224 unsigned long __iomem *tags = base + IOC_PT_CACHE_DIR;
222 unsigned long __iomem *p = base + IOC_PT_CACHE_REG; 225 unsigned long __iomem *p = base + IOC_PT_CACHE_REG;
223 pr_debug("iopt %02lx was v%016lx/t%016lx, store v%016lx/t%016lx\n",
224 index, get_iopt_cache(base, index, &oldtag), oldtag, val, tag);
225 226
226 out_be64(p, val); 227 out_be64(p, val);
227 out_be64(&tags[index], tag); 228 out_be64(&tags[index], tag);
@@ -248,67 +249,176 @@ set_iocmd_config(void __iomem *base)
248 out_be64(p, conf | IOCMD_CONF_TE); 249 out_be64(p, conf | IOCMD_CONF_TE);
249} 250}
250 251
251/* FIXME: get these from the device tree */ 252static void enable_mapping(void __iomem *base, void __iomem *mmio_base)
252#define ioc_base 0x20000511000ull
253#define ioc_mmio_base 0x20000510000ull
254#define ioid 0x48a
255#define iopt_phys_offset (- 0x20000000) /* We have a 512MB offset from the SB */
256#define io_page_size 0x1000000
257
258static unsigned long map_iopt_entry(unsigned long address)
259{ 253{
260 switch (address >> 20) { 254 set_iocmd_config(base);
261 case 0x600: 255 set_iost_origin(mmio_base);
262 address = 0x24020000000ull; /* spider i/o */
263 break;
264 default:
265 address += iopt_phys_offset;
266 break;
267 }
268
269 return get_iopt_entry(address, ioid, IOPT_PROT_RW);
270} 256}
271 257
272static void iommu_bus_setup_null(struct pci_bus *b) { }
273static void iommu_dev_setup_null(struct pci_dev *d) { } 258static void iommu_dev_setup_null(struct pci_dev *d) { }
259static void iommu_bus_setup_null(struct pci_bus *b) { }
260
261struct cell_iommu {
262 unsigned long base;
263 unsigned long mmio_base;
264 void __iomem *mapped_base;
265 void __iomem *mapped_mmio_base;
266};
267
268static struct cell_iommu cell_iommus[NR_CPUS];
274 269
275/* initialize the iommu to support a simple linear mapping 270/* initialize the iommu to support a simple linear mapping
276 * for each DMA window used by any device. For now, we 271 * for each DMA window used by any device. For now, we
277 * happen to know that there is only one DMA window in use, 272 * happen to know that there is only one DMA window in use,
278 * starting at iopt_phys_offset. */ 273 * starting at iopt_phys_offset. */
279static void cell_map_iommu(void) 274static void cell_do_map_iommu(struct cell_iommu *iommu,
275 unsigned int ioid,
276 unsigned long map_start,
277 unsigned long map_size)
280{ 278{
281 unsigned long address; 279 unsigned long io_address, real_address;
282 void __iomem *base; 280 void __iomem *ioc_base, *ioc_mmio_base;
283 ioste ioste; 281 ioste ioste;
284 unsigned long index; 282 unsigned long index;
285 283
286 base = __ioremap(ioc_base, 0x1000, _PAGE_NO_CACHE); 284 /* we pretend the io page table was at a very high address */
287 pr_debug("%lx mapped to %p\n", ioc_base, base); 285 const unsigned long fake_iopt = 0x10000000000ul;
288 set_iocmd_config(base); 286 const unsigned long io_page_size = 0x1000000; /* use 16M pages */
289 iounmap(base); 287 const unsigned long io_segment_size = 0x10000000; /* 256M */
288
289 ioc_base = iommu->mapped_base;
290 ioc_mmio_base = iommu->mapped_mmio_base;
291
292 for (real_address = 0, io_address = 0;
293 io_address <= map_start + map_size;
294 real_address += io_page_size, io_address += io_page_size) {
295 ioste = get_iost_entry(fake_iopt, io_address, io_page_size);
296 if ((real_address % io_segment_size) == 0) /* segment start */
297 set_iost_cache(ioc_mmio_base,
298 io_address >> 28, ioste);
299 index = get_ioc_hash_1way(ioste, io_address);
300 pr_debug("addr %08lx, index %02lx, ioste %016lx\n",
301 io_address, index, ioste.val);
302 set_iopt_cache(ioc_mmio_base,
303 get_ioc_hash_1way(ioste, io_address),
304 get_ioc_tag(ioste, io_address),
305 get_iopt_entry(real_address-map_start, ioid, IOPT_PROT_RW));
306 }
307}
290 308
291 base = __ioremap(ioc_mmio_base, 0x1000, _PAGE_NO_CACHE); 309static void iommu_devnode_setup(struct device_node *d)
292 pr_debug("%lx mapped to %p\n", ioc_mmio_base, base); 310{
311 unsigned int *ioid;
312 unsigned long *dma_window, map_start, map_size, token;
313 struct cell_iommu *iommu;
293 314
294 set_iost_origin(base); 315 ioid = (unsigned int *)get_property(d, "ioid", NULL);
316 if (!ioid)
317 pr_debug("No ioid entry found !\n");
295 318
296 for (address = 0; address < 0x100000000ul; address += io_page_size) { 319 dma_window = (unsigned long *)get_property(d, "ibm,dma-window", NULL);
297 ioste = get_iost_entry(0x10000000000ul, address, io_page_size); 320 if (!dma_window)
298 if ((address & 0xfffffff) == 0) /* segment start */ 321 pr_debug("No ibm,dma-window entry found !\n");
299 set_iost_cache(base, address >> 28, ioste); 322
300 index = get_ioc_hash_1way(ioste, address); 323 map_start = dma_window[1];
301 pr_debug("addr %08lx, index %02lx, ioste %016lx\n", 324 map_size = dma_window[2];
302 address, index, ioste.val); 325 token = dma_window[0] >> 32;
303 set_iopt_cache(base, 326
304 get_ioc_hash_1way(ioste, address), 327 iommu = &cell_iommus[token];
305 get_ioc_tag(ioste, address), 328
306 map_iopt_entry(address)); 329 cell_do_map_iommu(iommu, *ioid, map_start, map_size);
307 } 330}
308 iounmap(base); 331
332static void iommu_bus_setup(struct pci_bus *b)
333{
334 struct device_node *d = (struct device_node *)b->sysdata;
335 iommu_devnode_setup(d);
336}
337
338
339static int cell_map_iommu_hardcoded(int num_nodes)
340{
341 struct cell_iommu *iommu = NULL;
342
343 pr_debug("%s(%d): Using hardcoded defaults\n", __FUNCTION__, __LINE__);
344
345 /* node 0 */
346 iommu = &cell_iommus[0];
347 iommu->mapped_base = __ioremap(0x20000511000, 0x1000, _PAGE_NO_CACHE);
348 iommu->mapped_mmio_base = __ioremap(0x20000510000, 0x1000, _PAGE_NO_CACHE);
349
350 enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base);
351
352 cell_do_map_iommu(iommu, 0x048a,
353 0x20000000ul,0x20000000ul);
354
355 if (num_nodes < 2)
356 return 0;
357
358 /* node 1 */
359 iommu = &cell_iommus[1];
360 iommu->mapped_base = __ioremap(0x30000511000, 0x1000, _PAGE_NO_CACHE);
361 iommu->mapped_mmio_base = __ioremap(0x30000510000, 0x1000, _PAGE_NO_CACHE);
362
363 enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base);
364
365 cell_do_map_iommu(iommu, 0x048a,
366 0x20000000,0x20000000ul);
367
368 return 0;
309} 369}
310 370
311 371
372static int cell_map_iommu(void)
373{
374 unsigned int num_nodes = 0, *node_id;
375 unsigned long *base, *mmio_base;
376 struct device_node *dn;
377 struct cell_iommu *iommu = NULL;
378
379 /* determine number of nodes (=iommus) */
380 pr_debug("%s(%d): determining number of nodes...", __FUNCTION__, __LINE__);
381 for(dn = of_find_node_by_type(NULL, "cpu");
382 dn;
383 dn = of_find_node_by_type(dn, "cpu")) {
384 node_id = (unsigned int *)get_property(dn, "node-id", NULL);
385
386 if (num_nodes < *node_id)
387 num_nodes = *node_id;
388 }
389
390 num_nodes++;
391 pr_debug("%i found.\n", num_nodes);
392
393 /* map the iommu registers for each node */
394 pr_debug("%s(%d): Looping through nodes\n", __FUNCTION__, __LINE__);
395 for(dn = of_find_node_by_type(NULL, "cpu");
396 dn;
397 dn = of_find_node_by_type(dn, "cpu")) {
398
399 node_id = (unsigned int *)get_property(dn, "node-id", NULL);
400 base = (unsigned long *)get_property(dn, "ioc-cache", NULL);
401 mmio_base = (unsigned long *)get_property(dn, "ioc-translation", NULL);
402
403 if (!base || !mmio_base || !node_id)
404 return cell_map_iommu_hardcoded(num_nodes);
405
406 iommu = &cell_iommus[*node_id];
407 iommu->base = *base;
408 iommu->mmio_base = *mmio_base;
409
410 iommu->mapped_base = __ioremap(*base, 0x1000, _PAGE_NO_CACHE);
411 iommu->mapped_mmio_base = __ioremap(*mmio_base, 0x1000, _PAGE_NO_CACHE);
412
413 enable_mapping(iommu->mapped_base,
414 iommu->mapped_mmio_base);
415
416 /* everything else will be done in iommu_bus_setup */
417 }
418
419 return 1;
420}
421
312static void *cell_alloc_coherent(struct device *hwdev, size_t size, 422static void *cell_alloc_coherent(struct device *hwdev, size_t size,
313 dma_addr_t *dma_handle, gfp_t flag) 423 dma_addr_t *dma_handle, gfp_t flag)
314{ 424{
@@ -365,11 +475,28 @@ static int cell_dma_supported(struct device *dev, u64 mask)
365 475
366void cell_init_iommu(void) 476void cell_init_iommu(void)
367{ 477{
368 cell_map_iommu(); 478 int setup_bus = 0;
369 479
370 /* Direct I/O, IOMMU off */ 480 if (of_find_node_by_path("/mambo")) {
371 ppc_md.iommu_dev_setup = iommu_dev_setup_null; 481 pr_info("Not using iommu on systemsim\n");
372 ppc_md.iommu_bus_setup = iommu_bus_setup_null; 482 } else {
483
484 if (!(of_chosen &&
485 get_property(of_chosen, "linux,iommu-off", NULL)))
486 setup_bus = cell_map_iommu();
487
488 if (setup_bus) {
489 pr_debug("%s: IOMMU mapping activated\n", __FUNCTION__);
490 ppc_md.iommu_dev_setup = iommu_dev_setup_null;
491 ppc_md.iommu_bus_setup = iommu_bus_setup;
492 } else {
493 pr_debug("%s: IOMMU mapping activated, "
494 "no device action necessary\n", __FUNCTION__);
495 /* Direct I/O, IOMMU off */
496 ppc_md.iommu_dev_setup = iommu_dev_setup_null;
497 ppc_md.iommu_bus_setup = iommu_bus_setup_null;
498 }
499 }
373 500
374 pci_dma_ops.alloc_coherent = cell_alloc_coherent; 501 pci_dma_ops.alloc_coherent = cell_alloc_coherent;
375 pci_dma_ops.free_coherent = cell_free_coherent; 502 pci_dma_ops.free_coherent = cell_free_coherent;
diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c
new file mode 100644
index 000000000000..85152544c153
--- /dev/null
+++ b/arch/powerpc/platforms/cell/pervasive.c
@@ -0,0 +1,229 @@
1/*
2 * CBE Pervasive Monitor and Debug
3 *
4 * (C) Copyright IBM Corporation 2005
5 *
6 * Authors: Maximino Aguilar (maguilar@us.ibm.com)
7 * Michael N. Day (mnday@us.ibm.com)
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 as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#undef DEBUG
25
26#include <linux/config.h>
27#include <linux/interrupt.h>
28#include <linux/irq.h>
29#include <linux/percpu.h>
30#include <linux/types.h>
31#include <linux/kallsyms.h>
32
33#include <asm/io.h>
34#include <asm/machdep.h>
35#include <asm/prom.h>
36#include <asm/pgtable.h>
37#include <asm/reg.h>
38
39#include "pervasive.h"
40
41static DEFINE_SPINLOCK(cbe_pervasive_lock);
42struct cbe_pervasive {
43 struct pmd_regs __iomem *regs;
44 unsigned int thread;
45};
46
47/* can't use per_cpu from setup_arch */
48static struct cbe_pervasive cbe_pervasive[NR_CPUS];
49
50static void __init cbe_enable_pause_zero(void)
51{
52 unsigned long thread_switch_control;
53 unsigned long temp_register;
54 struct cbe_pervasive *p;
55 int thread;
56
57 spin_lock_irq(&cbe_pervasive_lock);
58 p = &cbe_pervasive[smp_processor_id()];
59
60 if (!cbe_pervasive->regs)
61 goto out;
62
63 pr_debug("Power Management: CPU %d\n", smp_processor_id());
64
65 /* Enable Pause(0) control bit */
66 temp_register = in_be64(&p->regs->pm_control);
67
68 out_be64(&p->regs->pm_control,
69 temp_register|PMD_PAUSE_ZERO_CONTROL);
70
71 /* Enable DEC and EE interrupt request */
72 thread_switch_control = mfspr(SPRN_TSC_CELL);
73 thread_switch_control |= TSC_CELL_EE_ENABLE | TSC_CELL_EE_BOOST;
74
75 switch ((mfspr(SPRN_CTRLF) & CTRL_CT)) {
76 case CTRL_CT0:
77 thread_switch_control |= TSC_CELL_DEC_ENABLE_0;
78 thread = 0;
79 break;
80 case CTRL_CT1:
81 thread_switch_control |= TSC_CELL_DEC_ENABLE_1;
82 thread = 1;
83 break;
84 default:
85 printk(KERN_WARNING "%s: unknown configuration\n",
86 __FUNCTION__);
87 thread = -1;
88 break;
89 }
90
91 if (p->thread != thread)
92 printk(KERN_WARNING "%s: device tree inconsistant, "
93 "cpu %i: %d/%d\n", __FUNCTION__,
94 smp_processor_id(),
95 p->thread, thread);
96
97 mtspr(SPRN_TSC_CELL, thread_switch_control);
98
99out:
100 spin_unlock_irq(&cbe_pervasive_lock);
101}
102
103static void cbe_idle(void)
104{
105 unsigned long ctrl;
106
107 cbe_enable_pause_zero();
108
109 while (1) {
110 if (!need_resched()) {
111 local_irq_disable();
112 while (!need_resched()) {
113 /* go into low thread priority */
114 HMT_low();
115
116 /*
117 * atomically disable thread execution
118 * and runlatch.
119 * External and Decrementer exceptions
120 * are still handled when the thread
121 * is disabled but now enter in
122 * cbe_system_reset_exception()
123 */
124 ctrl = mfspr(SPRN_CTRLF);
125 ctrl &= ~(CTRL_RUNLATCH | CTRL_TE);
126 mtspr(SPRN_CTRLT, ctrl);
127 }
128 /* restore thread prio */
129 HMT_medium();
130 local_irq_enable();
131 }
132
133 /*
134 * turn runlatch on again before scheduling the
135 * process we just woke up
136 */
137 ppc64_runlatch_on();
138
139 preempt_enable_no_resched();
140 schedule();
141 preempt_disable();
142 }
143}
144
145int cbe_system_reset_exception(struct pt_regs *regs)
146{
147 switch (regs->msr & SRR1_WAKEMASK) {
148 case SRR1_WAKEEE:
149 do_IRQ(regs);
150 break;
151 case SRR1_WAKEDEC:
152 timer_interrupt(regs);
153 break;
154 case SRR1_WAKEMT:
155 /* no action required */
156 break;
157 default:
158 /* do system reset */
159 return 0;
160 }
161 /* everything handled */
162 return 1;
163}
164
165static int __init cbe_find_pmd_mmio(int cpu, struct cbe_pervasive *p)
166{
167 struct device_node *node;
168 unsigned int *int_servers;
169 char *addr;
170 unsigned long real_address;
171 unsigned int size;
172
173 struct pmd_regs __iomem *pmd_mmio_area;
174 int hardid, thread;
175 int proplen;
176
177 pmd_mmio_area = NULL;
178 hardid = get_hard_smp_processor_id(cpu);
179 for (node = NULL; (node = of_find_node_by_type(node, "cpu"));) {
180 int_servers = (void *) get_property(node,
181 "ibm,ppc-interrupt-server#s", &proplen);
182 if (!int_servers) {
183 printk(KERN_WARNING "%s misses "
184 "ibm,ppc-interrupt-server#s property",
185 node->full_name);
186 continue;
187 }
188 for (thread = 0; thread < proplen / sizeof (int); thread++) {
189 if (hardid == int_servers[thread]) {
190 addr = get_property(node, "pervasive", NULL);
191 goto found;
192 }
193 }
194 }
195
196 printk(KERN_WARNING "%s: CPU %d not found\n", __FUNCTION__, cpu);
197 return -EINVAL;
198
199found:
200 real_address = *(unsigned long*) addr;
201 addr += sizeof (unsigned long);
202 size = *(unsigned int*) addr;
203
204 pr_debug("pervasive area for CPU %d at %lx, size %x\n",
205 cpu, real_address, size);
206 p->regs = __ioremap(real_address, size, _PAGE_NO_CACHE);
207 p->thread = thread;
208 return 0;
209}
210
211void __init cell_pervasive_init(void)
212{
213 struct cbe_pervasive *p;
214 int cpu;
215 int ret;
216
217 if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO))
218 return;
219
220 for_each_cpu(cpu) {
221 p = &cbe_pervasive[cpu];
222 ret = cbe_find_pmd_mmio(cpu, p);
223 if (ret)
224 return;
225 }
226
227 ppc_md.idle_loop = cbe_idle;
228 ppc_md.system_reset_exception = cbe_system_reset_exception;
229}
diff --git a/arch/powerpc/platforms/cell/pervasive.h b/arch/powerpc/platforms/cell/pervasive.h
new file mode 100644
index 000000000000..da1fb85ca3e8
--- /dev/null
+++ b/arch/powerpc/platforms/cell/pervasive.h
@@ -0,0 +1,62 @@
1/*
2 * Cell Pervasive Monitor and Debug interface and HW structures
3 *
4 * (C) Copyright IBM Corporation 2005
5 *
6 * Authors: Maximino Aguilar (maguilar@us.ibm.com)
7 * David J. Erb (djerb@us.ibm.com)
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 as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24
25#ifndef PERVASIVE_H
26#define PERVASIVE_H
27
28struct pmd_regs {
29 u8 pad_0x0000_0x0800[0x0800 - 0x0000]; /* 0x0000 */
30
31 /* Thermal Sensor Registers */
32 u64 ts_ctsr1; /* 0x0800 */
33 u64 ts_ctsr2; /* 0x0808 */
34 u64 ts_mtsr1; /* 0x0810 */
35 u64 ts_mtsr2; /* 0x0818 */
36 u64 ts_itr1; /* 0x0820 */
37 u64 ts_itr2; /* 0x0828 */
38 u64 ts_gitr; /* 0x0830 */
39 u64 ts_isr; /* 0x0838 */
40 u64 ts_imr; /* 0x0840 */
41 u64 tm_cr1; /* 0x0848 */
42 u64 tm_cr2; /* 0x0850 */
43 u64 tm_simr; /* 0x0858 */
44 u64 tm_tpr; /* 0x0860 */
45 u64 tm_str1; /* 0x0868 */
46 u64 tm_str2; /* 0x0870 */
47 u64 tm_tsr; /* 0x0878 */
48
49 /* Power Management */
50 u64 pm_control; /* 0x0880 */
51#define PMD_PAUSE_ZERO_CONTROL 0x10000
52 u64 pm_status; /* 0x0888 */
53
54 /* Time Base Register */
55 u64 tbr; /* 0x0890 */
56
57 u8 pad_0x0898_0x1000 [0x1000 - 0x0898]; /* 0x0898 */
58};
59
60void __init cell_pervasive_init(void);
61
62#endif
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 9a495634d0c2..18e25e65c04b 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -33,6 +33,7 @@
33#include <asm/mmu.h> 33#include <asm/mmu.h>
34#include <asm/processor.h> 34#include <asm/processor.h>
35#include <asm/io.h> 35#include <asm/io.h>
36#include <asm/kexec.h>
36#include <asm/pgtable.h> 37#include <asm/pgtable.h>
37#include <asm/prom.h> 38#include <asm/prom.h>
38#include <asm/rtas.h> 39#include <asm/rtas.h>
@@ -48,6 +49,7 @@
48 49
49#include "interrupt.h" 50#include "interrupt.h"
50#include "iommu.h" 51#include "iommu.h"
52#include "pervasive.h"
51 53
52#ifdef DEBUG 54#ifdef DEBUG
53#define DBG(fmt...) udbg_printf(fmt) 55#define DBG(fmt...) udbg_printf(fmt)
@@ -67,6 +69,77 @@ void cell_show_cpuinfo(struct seq_file *m)
67 of_node_put(root); 69 of_node_put(root);
68} 70}
69 71
72#ifdef CONFIG_SPARSEMEM
73static int __init find_spu_node_id(struct device_node *spe)
74{
75 unsigned int *id;
76#ifdef CONFIG_NUMA
77 struct device_node *cpu;
78 cpu = spe->parent->parent;
79 id = (unsigned int *)get_property(cpu, "node-id", NULL);
80#else
81 id = NULL;
82#endif
83 return id ? *id : 0;
84}
85
86static void __init cell_spuprop_present(struct device_node *spe,
87 const char *prop, int early)
88{
89 struct address_prop {
90 unsigned long address;
91 unsigned int len;
92 } __attribute__((packed)) *p;
93 int proplen;
94
95 unsigned long start_pfn, end_pfn, pfn;
96 int node_id;
97
98 p = (void*)get_property(spe, prop, &proplen);
99 WARN_ON(proplen != sizeof (*p));
100
101 node_id = find_spu_node_id(spe);
102
103 start_pfn = p->address >> PAGE_SHIFT;
104 end_pfn = (p->address + p->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
105
106 /* We need to call memory_present *before* the call to sparse_init,
107 but we can initialize the page structs only *after* that call.
108 Thus, we're being called twice. */
109 if (early)
110 memory_present(node_id, start_pfn, end_pfn);
111 else {
112 /* As the pages backing SPU LS and I/O are outside the range
113 of regular memory, their page structs were not initialized
114 by free_area_init. Do it here instead. */
115 for (pfn = start_pfn; pfn < end_pfn; pfn++) {
116 struct page *page = pfn_to_page(pfn);
117 set_page_links(page, ZONE_DMA, node_id, pfn);
118 set_page_count(page, 1);
119 reset_page_mapcount(page);
120 SetPageReserved(page);
121 INIT_LIST_HEAD(&page->lru);
122 }
123 }
124}
125
126static void __init cell_spumem_init(int early)
127{
128 struct device_node *node;
129 for (node = of_find_node_by_type(NULL, "spe");
130 node; node = of_find_node_by_type(node, "spe")) {
131 cell_spuprop_present(node, "local-store", early);
132 cell_spuprop_present(node, "problem", early);
133 cell_spuprop_present(node, "priv1", early);
134 cell_spuprop_present(node, "priv2", early);
135 }
136}
137#else
138static void __init cell_spumem_init(int early)
139{
140}
141#endif
142
70static void cell_progress(char *s, unsigned short hex) 143static void cell_progress(char *s, unsigned short hex)
71{ 144{
72 printk("*** %04x : %s\n", hex, s ? s : ""); 145 printk("*** %04x : %s\n", hex, s ? s : "");
@@ -93,11 +166,14 @@ static void __init cell_setup_arch(void)
93 init_pci_config_tokens(); 166 init_pci_config_tokens();
94 find_and_init_phbs(); 167 find_and_init_phbs();
95 spider_init_IRQ(); 168 spider_init_IRQ();
169 cell_pervasive_init();
96#ifdef CONFIG_DUMMY_CONSOLE 170#ifdef CONFIG_DUMMY_CONSOLE
97 conswitchp = &dummy_con; 171 conswitchp = &dummy_con;
98#endif 172#endif
99 173
100 mmio_nvram_init(); 174 mmio_nvram_init();
175
176 cell_spumem_init(0);
101} 177}
102 178
103/* 179/*
@@ -113,6 +189,8 @@ static void __init cell_init_early(void)
113 189
114 ppc64_interrupt_controller = IC_CELL_PIC; 190 ppc64_interrupt_controller = IC_CELL_PIC;
115 191
192 cell_spumem_init(1);
193
116 DBG(" <- cell_init_early()\n"); 194 DBG(" <- cell_init_early()\n");
117} 195}
118 196
@@ -125,6 +203,15 @@ static int __init cell_probe(int platform)
125 return 1; 203 return 1;
126} 204}
127 205
206/*
207 * Cell has no legacy IO; anything calling this function has to
208 * fail or bad things will happen
209 */
210static int cell_check_legacy_ioport(unsigned int baseport)
211{
212 return -ENODEV;
213}
214
128struct machdep_calls __initdata cell_md = { 215struct machdep_calls __initdata cell_md = {
129 .probe = cell_probe, 216 .probe = cell_probe,
130 .setup_arch = cell_setup_arch, 217 .setup_arch = cell_setup_arch,
@@ -137,5 +224,11 @@ struct machdep_calls __initdata cell_md = {
137 .get_rtc_time = rtas_get_rtc_time, 224 .get_rtc_time = rtas_get_rtc_time,
138 .set_rtc_time = rtas_set_rtc_time, 225 .set_rtc_time = rtas_set_rtc_time,
139 .calibrate_decr = generic_calibrate_decr, 226 .calibrate_decr = generic_calibrate_decr,
227 .check_legacy_ioport = cell_check_legacy_ioport,
140 .progress = cell_progress, 228 .progress = cell_progress,
229#ifdef CONFIG_KEXEC
230 .machine_kexec = default_machine_kexec,
231 .machine_kexec_prepare = default_machine_kexec_prepare,
232 .machine_crash_shutdown = default_machine_crash_shutdown,
233#endif
141}; 234};
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
new file mode 100644
index 000000000000..d75ae03df686
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -0,0 +1,711 @@
1/*
2 * Low-level SPU handling
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 *
6 * Author: Arnd Bergmann <arndb@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#undef DEBUG
24
25#include <linux/interrupt.h>
26#include <linux/list.h>
27#include <linux/module.h>
28#include <linux/poll.h>
29#include <linux/ptrace.h>
30#include <linux/slab.h>
31#include <linux/wait.h>
32
33#include <asm/io.h>
34#include <asm/prom.h>
35#include <asm/semaphore.h>
36#include <asm/spu.h>
37#include <asm/mmu_context.h>
38
39#include "interrupt.h"
40
41static int __spu_trap_invalid_dma(struct spu *spu)
42{
43 pr_debug("%s\n", __FUNCTION__);
44 force_sig(SIGBUS, /* info, */ current);
45 return 0;
46}
47
48static int __spu_trap_dma_align(struct spu *spu)
49{
50 pr_debug("%s\n", __FUNCTION__);
51 force_sig(SIGBUS, /* info, */ current);
52 return 0;
53}
54
55static int __spu_trap_error(struct spu *spu)
56{
57 pr_debug("%s\n", __FUNCTION__);
58 force_sig(SIGILL, /* info, */ current);
59 return 0;
60}
61
62static void spu_restart_dma(struct spu *spu)
63{
64 struct spu_priv2 __iomem *priv2 = spu->priv2;
65
66 if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags))
67 out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND);
68}
69
70static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
71{
72 struct spu_priv2 __iomem *priv2 = spu->priv2;
73 struct mm_struct *mm = spu->mm;
74 u64 esid, vsid;
75
76 pr_debug("%s\n", __FUNCTION__);
77
78 if (test_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags)) {
79 /* SLBs are pre-loaded for context switch, so
80 * we should never get here!
81 */
82 printk("%s: invalid access during switch!\n", __func__);
83 return 1;
84 }
85 if (!mm || (REGION_ID(ea) != USER_REGION_ID)) {
86 /* Future: support kernel segments so that drivers
87 * can use SPUs.
88 */
89 pr_debug("invalid region access at %016lx\n", ea);
90 return 1;
91 }
92
93 esid = (ea & ESID_MASK) | SLB_ESID_V;
94 vsid = (get_vsid(mm->context.id, ea) << SLB_VSID_SHIFT) | SLB_VSID_USER;
95 if (in_hugepage_area(mm->context, ea))
96 vsid |= SLB_VSID_L;
97
98 out_be64(&priv2->slb_index_W, spu->slb_replace);
99 out_be64(&priv2->slb_vsid_RW, vsid);
100 out_be64(&priv2->slb_esid_RW, esid);
101
102 spu->slb_replace++;
103 if (spu->slb_replace >= 8)
104 spu->slb_replace = 0;
105
106 spu_restart_dma(spu);
107
108 return 0;
109}
110
111extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX
112static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
113{
114 pr_debug("%s\n", __FUNCTION__);
115
116 /* Handle kernel space hash faults immediately.
117 User hash faults need to be deferred to process context. */
118 if ((dsisr & MFC_DSISR_PTE_NOT_FOUND)
119 && REGION_ID(ea) != USER_REGION_ID
120 && hash_page(ea, _PAGE_PRESENT, 0x300) == 0) {
121 spu_restart_dma(spu);
122 return 0;
123 }
124
125 if (test_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags)) {
126 printk("%s: invalid access during switch!\n", __func__);
127 return 1;
128 }
129
130 spu->dar = ea;
131 spu->dsisr = dsisr;
132 mb();
133 if (spu->stop_callback)
134 spu->stop_callback(spu);
135 return 0;
136}
137
138static int __spu_trap_mailbox(struct spu *spu)
139{
140 if (spu->ibox_callback)
141 spu->ibox_callback(spu);
142
143 /* atomically disable SPU mailbox interrupts */
144 spin_lock(&spu->register_lock);
145 spu_int_mask_and(spu, 2, ~0x1);
146 spin_unlock(&spu->register_lock);
147 return 0;
148}
149
150static int __spu_trap_stop(struct spu *spu)
151{
152 pr_debug("%s\n", __FUNCTION__);
153 spu->stop_code = in_be32(&spu->problem->spu_status_R);
154 if (spu->stop_callback)
155 spu->stop_callback(spu);
156 return 0;
157}
158
159static int __spu_trap_halt(struct spu *spu)
160{
161 pr_debug("%s\n", __FUNCTION__);
162 spu->stop_code = in_be32(&spu->problem->spu_status_R);
163 if (spu->stop_callback)
164 spu->stop_callback(spu);
165 return 0;
166}
167
168static int __spu_trap_tag_group(struct spu *spu)
169{
170 pr_debug("%s\n", __FUNCTION__);
171 /* wake_up(&spu->dma_wq); */
172 return 0;
173}
174
175static int __spu_trap_spubox(struct spu *spu)
176{
177 if (spu->wbox_callback)
178 spu->wbox_callback(spu);
179
180 /* atomically disable SPU mailbox interrupts */
181 spin_lock(&spu->register_lock);
182 spu_int_mask_and(spu, 2, ~0x10);
183 spin_unlock(&spu->register_lock);
184 return 0;
185}
186
187static irqreturn_t
188spu_irq_class_0(int irq, void *data, struct pt_regs *regs)
189{
190 struct spu *spu;
191
192 spu = data;
193 spu->class_0_pending = 1;
194 if (spu->stop_callback)
195 spu->stop_callback(spu);
196
197 return IRQ_HANDLED;
198}
199
200int
201spu_irq_class_0_bottom(struct spu *spu)
202{
203 unsigned long stat, mask;
204
205 spu->class_0_pending = 0;
206
207 mask = spu_int_mask_get(spu, 0);
208 stat = spu_int_stat_get(spu, 0);
209
210 stat &= mask;
211
212 if (stat & 1) /* invalid MFC DMA */
213 __spu_trap_invalid_dma(spu);
214
215 if (stat & 2) /* invalid DMA alignment */
216 __spu_trap_dma_align(spu);
217
218 if (stat & 4) /* error on SPU */
219 __spu_trap_error(spu);
220
221 spu_int_stat_clear(spu, 0, stat);
222
223 return (stat & 0x7) ? -EIO : 0;
224}
225EXPORT_SYMBOL_GPL(spu_irq_class_0_bottom);
226
227static irqreturn_t
228spu_irq_class_1(int irq, void *data, struct pt_regs *regs)
229{
230 struct spu *spu;
231 unsigned long stat, mask, dar, dsisr;
232
233 spu = data;
234
235 /* atomically read & clear class1 status. */
236 spin_lock(&spu->register_lock);
237 mask = spu_int_mask_get(spu, 1);
238 stat = spu_int_stat_get(spu, 1) & mask;
239 dar = spu_mfc_dar_get(spu);
240 dsisr = spu_mfc_dsisr_get(spu);
241 if (stat & 2) /* mapping fault */
242 spu_mfc_dsisr_set(spu, 0ul);
243 spu_int_stat_clear(spu, 1, stat);
244 spin_unlock(&spu->register_lock);
245
246 if (stat & 1) /* segment fault */
247 __spu_trap_data_seg(spu, dar);
248
249 if (stat & 2) { /* mapping fault */
250 __spu_trap_data_map(spu, dar, dsisr);
251 }
252
253 if (stat & 4) /* ls compare & suspend on get */
254 ;
255
256 if (stat & 8) /* ls compare & suspend on put */
257 ;
258
259 return stat ? IRQ_HANDLED : IRQ_NONE;
260}
261EXPORT_SYMBOL_GPL(spu_irq_class_1_bottom);
262
263static irqreturn_t
264spu_irq_class_2(int irq, void *data, struct pt_regs *regs)
265{
266 struct spu *spu;
267 unsigned long stat;
268 unsigned long mask;
269
270 spu = data;
271 stat = spu_int_stat_get(spu, 2);
272 mask = spu_int_mask_get(spu, 2);
273
274 pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask);
275
276 stat &= mask;
277
278 if (stat & 1) /* PPC core mailbox */
279 __spu_trap_mailbox(spu);
280
281 if (stat & 2) /* SPU stop-and-signal */
282 __spu_trap_stop(spu);
283
284 if (stat & 4) /* SPU halted */
285 __spu_trap_halt(spu);
286
287 if (stat & 8) /* DMA tag group complete */
288 __spu_trap_tag_group(spu);
289
290 if (stat & 0x10) /* SPU mailbox threshold */
291 __spu_trap_spubox(spu);
292
293 spu_int_stat_clear(spu, 2, stat);
294 return stat ? IRQ_HANDLED : IRQ_NONE;
295}
296
297static int
298spu_request_irqs(struct spu *spu)
299{
300 int ret;
301 int irq_base;
302
303 irq_base = IIC_NODE_STRIDE * spu->node + IIC_SPE_OFFSET;
304
305 snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", spu->number);
306 ret = request_irq(irq_base + spu->isrc,
307 spu_irq_class_0, 0, spu->irq_c0, spu);
308 if (ret)
309 goto out;
310
311 snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", spu->number);
312 ret = request_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc,
313 spu_irq_class_1, 0, spu->irq_c1, spu);
314 if (ret)
315 goto out1;
316
317 snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", spu->number);
318 ret = request_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc,
319 spu_irq_class_2, 0, spu->irq_c2, spu);
320 if (ret)
321 goto out2;
322 goto out;
323
324out2:
325 free_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, spu);
326out1:
327 free_irq(irq_base + spu->isrc, spu);
328out:
329 return ret;
330}
331
332static void
333spu_free_irqs(struct spu *spu)
334{
335 int irq_base;
336
337 irq_base = IIC_NODE_STRIDE * spu->node + IIC_SPE_OFFSET;
338
339 free_irq(irq_base + spu->isrc, spu);
340 free_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, spu);
341 free_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc, spu);
342}
343
344static LIST_HEAD(spu_list);
345static DECLARE_MUTEX(spu_mutex);
346
347static void spu_init_channels(struct spu *spu)
348{
349 static const struct {
350 unsigned channel;
351 unsigned count;
352 } zero_list[] = {
353 { 0x00, 1, }, { 0x01, 1, }, { 0x03, 1, }, { 0x04, 1, },
354 { 0x18, 1, }, { 0x19, 1, }, { 0x1b, 1, }, { 0x1d, 1, },
355 }, count_list[] = {
356 { 0x00, 0, }, { 0x03, 0, }, { 0x04, 0, }, { 0x15, 16, },
357 { 0x17, 1, }, { 0x18, 0, }, { 0x19, 0, }, { 0x1b, 0, },
358 { 0x1c, 1, }, { 0x1d, 0, }, { 0x1e, 1, },
359 };
360 struct spu_priv2 __iomem *priv2;
361 int i;
362
363 priv2 = spu->priv2;
364
365 /* initialize all channel data to zero */
366 for (i = 0; i < ARRAY_SIZE(zero_list); i++) {
367 int count;
368
369 out_be64(&priv2->spu_chnlcntptr_RW, zero_list[i].channel);
370 for (count = 0; count < zero_list[i].count; count++)
371 out_be64(&priv2->spu_chnldata_RW, 0);
372 }
373
374 /* initialize channel counts to meaningful values */
375 for (i = 0; i < ARRAY_SIZE(count_list); i++) {
376 out_be64(&priv2->spu_chnlcntptr_RW, count_list[i].channel);
377 out_be64(&priv2->spu_chnlcnt_RW, count_list[i].count);
378 }
379}
380
381struct spu *spu_alloc(void)
382{
383 struct spu *spu;
384
385 down(&spu_mutex);
386 if (!list_empty(&spu_list)) {
387 spu = list_entry(spu_list.next, struct spu, list);
388 list_del_init(&spu->list);
389 pr_debug("Got SPU %x %d\n", spu->isrc, spu->number);
390 } else {
391 pr_debug("No SPU left\n");
392 spu = NULL;
393 }
394 up(&spu_mutex);
395
396 if (spu)
397 spu_init_channels(spu);
398
399 return spu;
400}
401EXPORT_SYMBOL_GPL(spu_alloc);
402
403void spu_free(struct spu *spu)
404{
405 down(&spu_mutex);
406 list_add_tail(&spu->list, &spu_list);
407 up(&spu_mutex);
408}
409EXPORT_SYMBOL_GPL(spu_free);
410
411static int spu_handle_mm_fault(struct spu *spu)
412{
413 struct mm_struct *mm = spu->mm;
414 struct vm_area_struct *vma;
415 u64 ea, dsisr, is_write;
416 int ret;
417
418 ea = spu->dar;
419 dsisr = spu->dsisr;
420#if 0
421 if (!IS_VALID_EA(ea)) {
422 return -EFAULT;
423 }
424#endif /* XXX */
425 if (mm == NULL) {
426 return -EFAULT;
427 }
428 if (mm->pgd == NULL) {
429 return -EFAULT;
430 }
431
432 down_read(&mm->mmap_sem);
433 vma = find_vma(mm, ea);
434 if (!vma)
435 goto bad_area;
436 if (vma->vm_start <= ea)
437 goto good_area;
438 if (!(vma->vm_flags & VM_GROWSDOWN))
439 goto bad_area;
440#if 0
441 if (expand_stack(vma, ea))
442 goto bad_area;
443#endif /* XXX */
444good_area:
445 is_write = dsisr & MFC_DSISR_ACCESS_PUT;
446 if (is_write) {
447 if (!(vma->vm_flags & VM_WRITE))
448 goto bad_area;
449 } else {
450 if (dsisr & MFC_DSISR_ACCESS_DENIED)
451 goto bad_area;
452 if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
453 goto bad_area;
454 }
455 ret = 0;
456 switch (handle_mm_fault(mm, vma, ea, is_write)) {
457 case VM_FAULT_MINOR:
458 current->min_flt++;
459 break;
460 case VM_FAULT_MAJOR:
461 current->maj_flt++;
462 break;
463 case VM_FAULT_SIGBUS:
464 ret = -EFAULT;
465 goto bad_area;
466 case VM_FAULT_OOM:
467 ret = -ENOMEM;
468 goto bad_area;
469 default:
470 BUG();
471 }
472 up_read(&mm->mmap_sem);
473 return ret;
474
475bad_area:
476 up_read(&mm->mmap_sem);
477 return -EFAULT;
478}
479
480int spu_irq_class_1_bottom(struct spu *spu)
481{
482 u64 ea, dsisr, access, error = 0UL;
483 int ret = 0;
484
485 ea = spu->dar;
486 dsisr = spu->dsisr;
487 if (dsisr & MFC_DSISR_PTE_NOT_FOUND) {
488 access = (_PAGE_PRESENT | _PAGE_USER);
489 access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL;
490 if (hash_page(ea, access, 0x300) != 0)
491 error |= CLASS1_ENABLE_STORAGE_FAULT_INTR;
492 }
493 if ((error & CLASS1_ENABLE_STORAGE_FAULT_INTR) ||
494 (dsisr & MFC_DSISR_ACCESS_DENIED)) {
495 if ((ret = spu_handle_mm_fault(spu)) != 0)
496 error |= CLASS1_ENABLE_STORAGE_FAULT_INTR;
497 else
498 error &= ~CLASS1_ENABLE_STORAGE_FAULT_INTR;
499 }
500 spu->dar = 0UL;
501 spu->dsisr = 0UL;
502 if (!error) {
503 spu_restart_dma(spu);
504 } else {
505 __spu_trap_invalid_dma(spu);
506 }
507 return ret;
508}
509
510void spu_irq_setaffinity(struct spu *spu, int cpu)
511{
512 u64 target = iic_get_target_id(cpu);
513 u64 route = target << 48 | target << 32 | target << 16;
514 spu_int_route_set(spu, route);
515}
516EXPORT_SYMBOL_GPL(spu_irq_setaffinity);
517
518static void __iomem * __init map_spe_prop(struct device_node *n,
519 const char *name)
520{
521 struct address_prop {
522 unsigned long address;
523 unsigned int len;
524 } __attribute__((packed)) *prop;
525
526 void *p;
527 int proplen;
528
529 p = get_property(n, name, &proplen);
530 if (proplen != sizeof (struct address_prop))
531 return NULL;
532
533 prop = p;
534
535 return ioremap(prop->address, prop->len);
536}
537
538static void spu_unmap(struct spu *spu)
539{
540 iounmap(spu->priv2);
541 iounmap(spu->priv1);
542 iounmap(spu->problem);
543 iounmap((u8 __iomem *)spu->local_store);
544}
545
546static int __init spu_map_device(struct spu *spu, struct device_node *spe)
547{
548 char *prop;
549 int ret;
550
551 ret = -ENODEV;
552 prop = get_property(spe, "isrc", NULL);
553 if (!prop)
554 goto out;
555 spu->isrc = *(unsigned int *)prop;
556
557 spu->name = get_property(spe, "name", NULL);
558 if (!spu->name)
559 goto out;
560
561 prop = get_property(spe, "local-store", NULL);
562 if (!prop)
563 goto out;
564 spu->local_store_phys = *(unsigned long *)prop;
565
566 /* we use local store as ram, not io memory */
567 spu->local_store = (void __force *)map_spe_prop(spe, "local-store");
568 if (!spu->local_store)
569 goto out;
570
571 spu->problem= map_spe_prop(spe, "problem");
572 if (!spu->problem)
573 goto out_unmap;
574
575 spu->priv1= map_spe_prop(spe, "priv1");
576 /* priv1 is not available on a hypervisor */
577
578 spu->priv2= map_spe_prop(spe, "priv2");
579 if (!spu->priv2)
580 goto out_unmap;
581 ret = 0;
582 goto out;
583
584out_unmap:
585 spu_unmap(spu);
586out:
587 return ret;
588}
589
590static int __init find_spu_node_id(struct device_node *spe)
591{
592 unsigned int *id;
593 struct device_node *cpu;
594
595 cpu = spe->parent->parent;
596 id = (unsigned int *)get_property(cpu, "node-id", NULL);
597
598 return id ? *id : 0;
599}
600
601static int __init create_spu(struct device_node *spe)
602{
603 struct spu *spu;
604 int ret;
605 static int number;
606
607 ret = -ENOMEM;
608 spu = kmalloc(sizeof (*spu), GFP_KERNEL);
609 if (!spu)
610 goto out;
611
612 ret = spu_map_device(spu, spe);
613 if (ret)
614 goto out_free;
615
616 spu->node = find_spu_node_id(spe);
617 spu->stop_code = 0;
618 spu->slb_replace = 0;
619 spu->mm = NULL;
620 spu->ctx = NULL;
621 spu->rq = NULL;
622 spu->pid = 0;
623 spu->class_0_pending = 0;
624 spu->flags = 0UL;
625 spu->dar = 0UL;
626 spu->dsisr = 0UL;
627 spin_lock_init(&spu->register_lock);
628
629 spu_mfc_sdr_set(spu, mfspr(SPRN_SDR1));
630 spu_mfc_sr1_set(spu, 0x33);
631
632 spu->ibox_callback = NULL;
633 spu->wbox_callback = NULL;
634 spu->stop_callback = NULL;
635
636 down(&spu_mutex);
637 spu->number = number++;
638 ret = spu_request_irqs(spu);
639 if (ret)
640 goto out_unmap;
641
642 list_add(&spu->list, &spu_list);
643 up(&spu_mutex);
644
645 pr_debug(KERN_DEBUG "Using SPE %s %02x %p %p %p %p %d\n",
646 spu->name, spu->isrc, spu->local_store,
647 spu->problem, spu->priv1, spu->priv2, spu->number);
648 goto out;
649
650out_unmap:
651 up(&spu_mutex);
652 spu_unmap(spu);
653out_free:
654 kfree(spu);
655out:
656 return ret;
657}
658
659static void destroy_spu(struct spu *spu)
660{
661 list_del_init(&spu->list);
662
663 spu_free_irqs(spu);
664 spu_unmap(spu);
665 kfree(spu);
666}
667
668static void cleanup_spu_base(void)
669{
670 struct spu *spu, *tmp;
671 down(&spu_mutex);
672 list_for_each_entry_safe(spu, tmp, &spu_list, list)
673 destroy_spu(spu);
674 up(&spu_mutex);
675}
676module_exit(cleanup_spu_base);
677
678static int __init init_spu_base(void)
679{
680 struct device_node *node;
681 int ret;
682
683 ret = -ENODEV;
684 for (node = of_find_node_by_type(NULL, "spe");
685 node; node = of_find_node_by_type(node, "spe")) {
686 ret = create_spu(node);
687 if (ret) {
688 printk(KERN_WARNING "%s: Error initializing %s\n",
689 __FUNCTION__, node->name);
690 cleanup_spu_base();
691 break;
692 }
693 }
694 /* in some old firmware versions, the spe is called 'spc', so we
695 look for that as well */
696 for (node = of_find_node_by_type(NULL, "spc");
697 node; node = of_find_node_by_type(node, "spc")) {
698 ret = create_spu(node);
699 if (ret) {
700 printk(KERN_WARNING "%s: Error initializing %s\n",
701 __FUNCTION__, node->name);
702 cleanup_spu_base();
703 break;
704 }
705 }
706 return ret;
707}
708module_init(init_spu_base);
709
710MODULE_LICENSE("GPL");
711MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
diff --git a/arch/powerpc/platforms/cell/spu_priv1.c b/arch/powerpc/platforms/cell/spu_priv1.c
new file mode 100644
index 000000000000..b2656421c7b5
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spu_priv1.c
@@ -0,0 +1,133 @@
1/*
2 * access to SPU privileged registers
3 */
4#include <linux/module.h>
5
6#include <asm/io.h>
7#include <asm/spu.h>
8
9void spu_int_mask_and(struct spu *spu, int class, u64 mask)
10{
11 u64 old_mask;
12
13 old_mask = in_be64(&spu->priv1->int_mask_RW[class]);
14 out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask);
15}
16EXPORT_SYMBOL_GPL(spu_int_mask_and);
17
18void spu_int_mask_or(struct spu *spu, int class, u64 mask)
19{
20 u64 old_mask;
21
22 old_mask = in_be64(&spu->priv1->int_mask_RW[class]);
23 out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask);
24}
25EXPORT_SYMBOL_GPL(spu_int_mask_or);
26
27void spu_int_mask_set(struct spu *spu, int class, u64 mask)
28{
29 out_be64(&spu->priv1->int_mask_RW[class], mask);
30}
31EXPORT_SYMBOL_GPL(spu_int_mask_set);
32
33u64 spu_int_mask_get(struct spu *spu, int class)
34{
35 return in_be64(&spu->priv1->int_mask_RW[class]);
36}
37EXPORT_SYMBOL_GPL(spu_int_mask_get);
38
39void spu_int_stat_clear(struct spu *spu, int class, u64 stat)
40{
41 out_be64(&spu->priv1->int_stat_RW[class], stat);
42}
43EXPORT_SYMBOL_GPL(spu_int_stat_clear);
44
45u64 spu_int_stat_get(struct spu *spu, int class)
46{
47 return in_be64(&spu->priv1->int_stat_RW[class]);
48}
49EXPORT_SYMBOL_GPL(spu_int_stat_get);
50
51void spu_int_route_set(struct spu *spu, u64 route)
52{
53 out_be64(&spu->priv1->int_route_RW, route);
54}
55EXPORT_SYMBOL_GPL(spu_int_route_set);
56
57u64 spu_mfc_dar_get(struct spu *spu)
58{
59 return in_be64(&spu->priv1->mfc_dar_RW);
60}
61EXPORT_SYMBOL_GPL(spu_mfc_dar_get);
62
63u64 spu_mfc_dsisr_get(struct spu *spu)
64{
65 return in_be64(&spu->priv1->mfc_dsisr_RW);
66}
67EXPORT_SYMBOL_GPL(spu_mfc_dsisr_get);
68
69void spu_mfc_dsisr_set(struct spu *spu, u64 dsisr)
70{
71 out_be64(&spu->priv1->mfc_dsisr_RW, dsisr);
72}
73EXPORT_SYMBOL_GPL(spu_mfc_dsisr_set);
74
75void spu_mfc_sdr_set(struct spu *spu, u64 sdr)
76{
77 out_be64(&spu->priv1->mfc_sdr_RW, sdr);
78}
79EXPORT_SYMBOL_GPL(spu_mfc_sdr_set);
80
81void spu_mfc_sr1_set(struct spu *spu, u64 sr1)
82{
83 out_be64(&spu->priv1->mfc_sr1_RW, sr1);
84}
85EXPORT_SYMBOL_GPL(spu_mfc_sr1_set);
86
87u64 spu_mfc_sr1_get(struct spu *spu)
88{
89 return in_be64(&spu->priv1->mfc_sr1_RW);
90}
91EXPORT_SYMBOL_GPL(spu_mfc_sr1_get);
92
93void spu_mfc_tclass_id_set(struct spu *spu, u64 tclass_id)
94{
95 out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id);
96}
97EXPORT_SYMBOL_GPL(spu_mfc_tclass_id_set);
98
99u64 spu_mfc_tclass_id_get(struct spu *spu)
100{
101 return in_be64(&spu->priv1->mfc_tclass_id_RW);
102}
103EXPORT_SYMBOL_GPL(spu_mfc_tclass_id_get);
104
105void spu_tlb_invalidate(struct spu *spu)
106{
107 out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul);
108}
109EXPORT_SYMBOL_GPL(spu_tlb_invalidate);
110
111void spu_resource_allocation_groupID_set(struct spu *spu, u64 id)
112{
113 out_be64(&spu->priv1->resource_allocation_groupID_RW, id);
114}
115EXPORT_SYMBOL_GPL(spu_resource_allocation_groupID_set);
116
117u64 spu_resource_allocation_groupID_get(struct spu *spu)
118{
119 return in_be64(&spu->priv1->resource_allocation_groupID_RW);
120}
121EXPORT_SYMBOL_GPL(spu_resource_allocation_groupID_get);
122
123void spu_resource_allocation_enable_set(struct spu *spu, u64 enable)
124{
125 out_be64(&spu->priv1->resource_allocation_enable_RW, enable);
126}
127EXPORT_SYMBOL_GPL(spu_resource_allocation_enable_set);
128
129u64 spu_resource_allocation_enable_get(struct spu *spu)
130{
131 return in_be64(&spu->priv1->resource_allocation_enable_RW);
132}
133EXPORT_SYMBOL_GPL(spu_resource_allocation_enable_get);
diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c
new file mode 100644
index 000000000000..261b507a901a
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spu_syscalls.c
@@ -0,0 +1,88 @@
1/*
2 * SPU file system -- system call stubs
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 *
6 * Author: Arnd Bergmann <arndb@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22#include <linux/file.h>
23#include <linux/module.h>
24#include <linux/syscalls.h>
25
26#include <asm/spu.h>
27
28struct spufs_calls spufs_calls = {
29 .owner = NULL,
30};
31
32/* These stub syscalls are needed to have the actual implementation
33 * within a loadable module. When spufs is built into the kernel,
34 * this file is not used and the syscalls directly enter the fs code */
35
36asmlinkage long sys_spu_create(const char __user *name,
37 unsigned int flags, mode_t mode)
38{
39 long ret;
40 struct module *owner = spufs_calls.owner;
41
42 ret = -ENOSYS;
43 if (owner && try_module_get(owner)) {
44 ret = spufs_calls.create_thread(name, flags, mode);
45 module_put(owner);
46 }
47 return ret;
48}
49
50asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
51{
52 long ret;
53 struct file *filp;
54 int fput_needed;
55 struct module *owner = spufs_calls.owner;
56
57 ret = -ENOSYS;
58 if (owner && try_module_get(owner)) {
59 ret = -EBADF;
60 filp = fget_light(fd, &fput_needed);
61 if (filp) {
62 ret = spufs_calls.spu_run(filp, unpc, ustatus);
63 fput_light(filp, fput_needed);
64 }
65 module_put(owner);
66 }
67 return ret;
68}
69
70int register_spu_syscalls(struct spufs_calls *calls)
71{
72 if (spufs_calls.owner)
73 return -EBUSY;
74
75 spufs_calls.create_thread = calls->create_thread;
76 spufs_calls.spu_run = calls->spu_run;
77 smp_mb();
78 spufs_calls.owner = calls->owner;
79 return 0;
80}
81EXPORT_SYMBOL_GPL(register_spu_syscalls);
82
83void unregister_spu_syscalls(struct spufs_calls *calls)
84{
85 BUG_ON(spufs_calls.owner != calls->owner);
86 spufs_calls.owner = NULL;
87}
88EXPORT_SYMBOL_GPL(unregister_spu_syscalls);
diff --git a/arch/powerpc/platforms/cell/spufs/Makefile b/arch/powerpc/platforms/cell/spufs/Makefile
new file mode 100644
index 000000000000..a7cddf40e3d9
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/Makefile
@@ -0,0 +1,54 @@
1obj-$(CONFIG_SPU_FS) += spufs.o
2spufs-y += inode.o file.o context.o switch.o syscalls.o
3spufs-y += sched.o backing_ops.o hw_ops.o run.o
4
5# Rules to build switch.o with the help of SPU tool chain
6SPU_CROSS := spu-
7SPU_CC := $(SPU_CROSS)gcc
8SPU_AS := $(SPU_CROSS)gcc
9SPU_LD := $(SPU_CROSS)ld
10SPU_OBJCOPY := $(SPU_CROSS)objcopy
11SPU_CFLAGS := -O2 -Wall -I$(srctree)/include -I$(objtree)/include2
12SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include -I$(objtree)/include2
13SPU_LDFLAGS := -N -Ttext=0x0
14
15$(obj)/switch.o: $(obj)/spu_save_dump.h $(obj)/spu_restore_dump.h
16
17# Compile SPU files
18 cmd_spu_cc = $(SPU_CC) $(SPU_CFLAGS) -c -o $@ $<
19quiet_cmd_spu_cc = SPU_CC $@
20$(obj)/spu_%.o: $(src)/spu_%.c
21 $(call if_changed,spu_cc)
22
23# Assemble SPU files
24 cmd_spu_as = $(SPU_AS) $(SPU_AFLAGS) -o $@ $<
25quiet_cmd_spu_as = SPU_AS $@
26$(obj)/spu_%.o: $(src)/spu_%.S
27 $(call if_changed,spu_as)
28
29# Link SPU Executables
30 cmd_spu_ld = $(SPU_LD) $(SPU_LDFLAGS) -o $@ $^
31quiet_cmd_spu_ld = SPU_LD $@
32$(obj)/spu_%: $(obj)/spu_%_crt0.o $(obj)/spu_%.o
33 $(call if_changed,spu_ld)
34
35# Copy into binary format
36 cmd_spu_objcopy = $(SPU_OBJCOPY) -O binary $< $@
37quiet_cmd_spu_objcopy = OBJCOPY $@
38$(obj)/spu_%.bin: $(src)/spu_%
39 $(call if_changed,spu_objcopy)
40
41# create C code from ELF executable
42cmd_hexdump = ( \
43 echo "/*" ; \
44 echo " * $*_dump.h: Copyright (C) 2005 IBM." ; \
45 echo " * Hex-dump auto generated from $*.c." ; \
46 echo " * Do not edit!" ; \
47 echo " */" ; \
48 echo "static unsigned int $*_code[] __page_aligned = {" ; \
49 hexdump -v -e '"0x" 4/1 "%02x" "," "\n"' $< ; \
50 echo "};" ; \
51 ) > $@
52quiet_cmd_hexdump = HEXDUMP $@
53$(obj)/%_dump.h: $(obj)/%.bin
54 $(call if_changed,hexdump)
diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c
new file mode 100644
index 000000000000..a5c489a53c61
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c
@@ -0,0 +1,308 @@
1/* backing_ops.c - query/set operations on saved SPU context.
2 *
3 * Copyright (C) IBM 2005
4 * Author: Mark Nutter <mnutter@us.ibm.com>
5 *
6 * These register operations allow SPUFS to operate on saved
7 * SPU contexts rather than hardware.
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 as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/config.h>
25#include <linux/module.h>
26#include <linux/errno.h>
27#include <linux/sched.h>
28#include <linux/kernel.h>
29#include <linux/mm.h>
30#include <linux/vmalloc.h>
31#include <linux/smp.h>
32#include <linux/smp_lock.h>
33#include <linux/stddef.h>
34#include <linux/unistd.h>
35#include <linux/poll.h>
36
37#include <asm/io.h>
38#include <asm/spu.h>
39#include <asm/spu_csa.h>
40#include <asm/mmu_context.h>
41#include "spufs.h"
42
43/*
44 * Reads/writes to various problem and priv2 registers require
45 * state changes, i.e. generate SPU events, modify channel
46 * counts, etc.
47 */
48
49static void gen_spu_event(struct spu_context *ctx, u32 event)
50{
51 u64 ch0_cnt;
52 u64 ch0_data;
53 u64 ch1_data;
54
55 ch0_cnt = ctx->csa.spu_chnlcnt_RW[0];
56 ch0_data = ctx->csa.spu_chnldata_RW[0];
57 ch1_data = ctx->csa.spu_chnldata_RW[1];
58 ctx->csa.spu_chnldata_RW[0] |= event;
59 if ((ch0_cnt == 0) && !(ch0_data & event) && (ch1_data & event)) {
60 ctx->csa.spu_chnlcnt_RW[0] = 1;
61 }
62}
63
64static int spu_backing_mbox_read(struct spu_context *ctx, u32 * data)
65{
66 u32 mbox_stat;
67 int ret = 0;
68
69 spin_lock(&ctx->csa.register_lock);
70 mbox_stat = ctx->csa.prob.mb_stat_R;
71 if (mbox_stat & 0x0000ff) {
72 /* Read the first available word.
73 * Implementation note: the depth
74 * of pu_mb_R is currently 1.
75 */
76 *data = ctx->csa.prob.pu_mb_R;
77 ctx->csa.prob.mb_stat_R &= ~(0x0000ff);
78 ctx->csa.spu_chnlcnt_RW[28] = 1;
79 gen_spu_event(ctx, MFC_PU_MAILBOX_AVAILABLE_EVENT);
80 ret = 4;
81 }
82 spin_unlock(&ctx->csa.register_lock);
83 return ret;
84}
85
86static u32 spu_backing_mbox_stat_read(struct spu_context *ctx)
87{
88 return ctx->csa.prob.mb_stat_R;
89}
90
91static unsigned int spu_backing_mbox_stat_poll(struct spu_context *ctx,
92 unsigned int events)
93{
94 int ret;
95 u32 stat;
96
97 ret = 0;
98 spin_lock_irq(&ctx->csa.register_lock);
99 stat = ctx->csa.prob.mb_stat_R;
100
101 /* if the requested event is there, return the poll
102 mask, otherwise enable the interrupt to get notified,
103 but first mark any pending interrupts as done so
104 we don't get woken up unnecessarily */
105
106 if (events & (POLLIN | POLLRDNORM)) {
107 if (stat & 0xff0000)
108 ret |= POLLIN | POLLRDNORM;
109 else {
110 ctx->csa.priv1.int_stat_class0_RW &= ~0x1;
111 ctx->csa.priv1.int_mask_class2_RW |= 0x1;
112 }
113 }
114 if (events & (POLLOUT | POLLWRNORM)) {
115 if (stat & 0x00ff00)
116 ret = POLLOUT | POLLWRNORM;
117 else {
118 ctx->csa.priv1.int_stat_class0_RW &= ~0x10;
119 ctx->csa.priv1.int_mask_class2_RW |= 0x10;
120 }
121 }
122 spin_unlock_irq(&ctx->csa.register_lock);
123 return ret;
124}
125
126static int spu_backing_ibox_read(struct spu_context *ctx, u32 * data)
127{
128 int ret;
129
130 spin_lock(&ctx->csa.register_lock);
131 if (ctx->csa.prob.mb_stat_R & 0xff0000) {
132 /* Read the first available word.
133 * Implementation note: the depth
134 * of puint_mb_R is currently 1.
135 */
136 *data = ctx->csa.priv2.puint_mb_R;
137 ctx->csa.prob.mb_stat_R &= ~(0xff0000);
138 ctx->csa.spu_chnlcnt_RW[30] = 1;
139 gen_spu_event(ctx, MFC_PU_INT_MAILBOX_AVAILABLE_EVENT);
140 ret = 4;
141 } else {
142 /* make sure we get woken up by the interrupt */
143 ctx->csa.priv1.int_mask_class2_RW |= 0x1UL;
144 ret = 0;
145 }
146 spin_unlock(&ctx->csa.register_lock);
147 return ret;
148}
149
150static int spu_backing_wbox_write(struct spu_context *ctx, u32 data)
151{
152 int ret;
153
154 spin_lock(&ctx->csa.register_lock);
155 if ((ctx->csa.prob.mb_stat_R) & 0x00ff00) {
156 int slot = ctx->csa.spu_chnlcnt_RW[29];
157 int avail = (ctx->csa.prob.mb_stat_R & 0x00ff00) >> 8;
158
159 /* We have space to write wbox_data.
160 * Implementation note: the depth
161 * of spu_mb_W is currently 4.
162 */
163 BUG_ON(avail != (4 - slot));
164 ctx->csa.spu_mailbox_data[slot] = data;
165 ctx->csa.spu_chnlcnt_RW[29] = ++slot;
166 ctx->csa.prob.mb_stat_R = (((4 - slot) & 0xff) << 8);
167 gen_spu_event(ctx, MFC_SPU_MAILBOX_WRITTEN_EVENT);
168 ret = 4;
169 } else {
170 /* make sure we get woken up by the interrupt when space
171 becomes available */
172 ctx->csa.priv1.int_mask_class2_RW |= 0x10;
173 ret = 0;
174 }
175 spin_unlock(&ctx->csa.register_lock);
176 return ret;
177}
178
179static u32 spu_backing_signal1_read(struct spu_context *ctx)
180{
181 return ctx->csa.spu_chnldata_RW[3];
182}
183
184static void spu_backing_signal1_write(struct spu_context *ctx, u32 data)
185{
186 spin_lock(&ctx->csa.register_lock);
187 if (ctx->csa.priv2.spu_cfg_RW & 0x1)
188 ctx->csa.spu_chnldata_RW[3] |= data;
189 else
190 ctx->csa.spu_chnldata_RW[3] = data;
191 ctx->csa.spu_chnlcnt_RW[3] = 1;
192 gen_spu_event(ctx, MFC_SIGNAL_1_EVENT);
193 spin_unlock(&ctx->csa.register_lock);
194}
195
196static u32 spu_backing_signal2_read(struct spu_context *ctx)
197{
198 return ctx->csa.spu_chnldata_RW[4];
199}
200
201static void spu_backing_signal2_write(struct spu_context *ctx, u32 data)
202{
203 spin_lock(&ctx->csa.register_lock);
204 if (ctx->csa.priv2.spu_cfg_RW & 0x2)
205 ctx->csa.spu_chnldata_RW[4] |= data;
206 else
207 ctx->csa.spu_chnldata_RW[4] = data;
208 ctx->csa.spu_chnlcnt_RW[4] = 1;
209 gen_spu_event(ctx, MFC_SIGNAL_2_EVENT);
210 spin_unlock(&ctx->csa.register_lock);
211}
212
213static void spu_backing_signal1_type_set(struct spu_context *ctx, u64 val)
214{
215 u64 tmp;
216
217 spin_lock(&ctx->csa.register_lock);
218 tmp = ctx->csa.priv2.spu_cfg_RW;
219 if (val)
220 tmp |= 1;
221 else
222 tmp &= ~1;
223 ctx->csa.priv2.spu_cfg_RW = tmp;
224 spin_unlock(&ctx->csa.register_lock);
225}
226
227static u64 spu_backing_signal1_type_get(struct spu_context *ctx)
228{
229 return ((ctx->csa.priv2.spu_cfg_RW & 1) != 0);
230}
231
232static void spu_backing_signal2_type_set(struct spu_context *ctx, u64 val)
233{
234 u64 tmp;
235
236 spin_lock(&ctx->csa.register_lock);
237 tmp = ctx->csa.priv2.spu_cfg_RW;
238 if (val)
239 tmp |= 2;
240 else
241 tmp &= ~2;
242 ctx->csa.priv2.spu_cfg_RW = tmp;
243 spin_unlock(&ctx->csa.register_lock);
244}
245
246static u64 spu_backing_signal2_type_get(struct spu_context *ctx)
247{
248 return ((ctx->csa.priv2.spu_cfg_RW & 2) != 0);
249}
250
251static u32 spu_backing_npc_read(struct spu_context *ctx)
252{
253 return ctx->csa.prob.spu_npc_RW;
254}
255
256static void spu_backing_npc_write(struct spu_context *ctx, u32 val)
257{
258 ctx->csa.prob.spu_npc_RW = val;
259}
260
261static u32 spu_backing_status_read(struct spu_context *ctx)
262{
263 return ctx->csa.prob.spu_status_R;
264}
265
266static char *spu_backing_get_ls(struct spu_context *ctx)
267{
268 return ctx->csa.lscsa->ls;
269}
270
271static void spu_backing_runcntl_write(struct spu_context *ctx, u32 val)
272{
273 spin_lock(&ctx->csa.register_lock);
274 ctx->csa.prob.spu_runcntl_RW = val;
275 if (val & SPU_RUNCNTL_RUNNABLE) {
276 ctx->csa.prob.spu_status_R |= SPU_STATUS_RUNNING;
277 } else {
278 ctx->csa.prob.spu_status_R &= ~SPU_STATUS_RUNNING;
279 }
280 spin_unlock(&ctx->csa.register_lock);
281}
282
283static void spu_backing_runcntl_stop(struct spu_context *ctx)
284{
285 spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP);
286}
287
288struct spu_context_ops spu_backing_ops = {
289 .mbox_read = spu_backing_mbox_read,
290 .mbox_stat_read = spu_backing_mbox_stat_read,
291 .mbox_stat_poll = spu_backing_mbox_stat_poll,
292 .ibox_read = spu_backing_ibox_read,
293 .wbox_write = spu_backing_wbox_write,
294 .signal1_read = spu_backing_signal1_read,
295 .signal1_write = spu_backing_signal1_write,
296 .signal2_read = spu_backing_signal2_read,
297 .signal2_write = spu_backing_signal2_write,
298 .signal1_type_set = spu_backing_signal1_type_set,
299 .signal1_type_get = spu_backing_signal1_type_get,
300 .signal2_type_set = spu_backing_signal2_type_set,
301 .signal2_type_get = spu_backing_signal2_type_get,
302 .npc_read = spu_backing_npc_read,
303 .npc_write = spu_backing_npc_write,
304 .status_read = spu_backing_status_read,
305 .get_ls = spu_backing_get_ls,
306 .runcntl_write = spu_backing_runcntl_write,
307 .runcntl_stop = spu_backing_runcntl_stop,
308};
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
new file mode 100644
index 000000000000..336f238102fd
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -0,0 +1,167 @@
1/*
2 * SPU file system -- SPU context management
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 *
6 * Author: Arnd Bergmann <arndb@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/fs.h>
24#include <linux/mm.h>
25#include <linux/slab.h>
26#include <asm/spu.h>
27#include <asm/spu_csa.h>
28#include "spufs.h"
29
30struct spu_context *alloc_spu_context(struct address_space *local_store)
31{
32 struct spu_context *ctx;
33 ctx = kmalloc(sizeof *ctx, GFP_KERNEL);
34 if (!ctx)
35 goto out;
36 /* Binding to physical processor deferred
37 * until spu_activate().
38 */
39 spu_init_csa(&ctx->csa);
40 if (!ctx->csa.lscsa) {
41 goto out_free;
42 }
43 spin_lock_init(&ctx->mmio_lock);
44 kref_init(&ctx->kref);
45 init_rwsem(&ctx->state_sema);
46 init_MUTEX(&ctx->run_sema);
47 init_waitqueue_head(&ctx->ibox_wq);
48 init_waitqueue_head(&ctx->wbox_wq);
49 init_waitqueue_head(&ctx->stop_wq);
50 ctx->ibox_fasync = NULL;
51 ctx->wbox_fasync = NULL;
52 ctx->state = SPU_STATE_SAVED;
53 ctx->local_store = local_store;
54 ctx->spu = NULL;
55 ctx->ops = &spu_backing_ops;
56 ctx->owner = get_task_mm(current);
57 goto out;
58out_free:
59 kfree(ctx);
60 ctx = NULL;
61out:
62 return ctx;
63}
64
65void destroy_spu_context(struct kref *kref)
66{
67 struct spu_context *ctx;
68 ctx = container_of(kref, struct spu_context, kref);
69 down_write(&ctx->state_sema);
70 spu_deactivate(ctx);
71 ctx->ibox_fasync = NULL;
72 ctx->wbox_fasync = NULL;
73 up_write(&ctx->state_sema);
74 spu_fini_csa(&ctx->csa);
75 kfree(ctx);
76}
77
78struct spu_context * get_spu_context(struct spu_context *ctx)
79{
80 kref_get(&ctx->kref);
81 return ctx;
82}
83
84int put_spu_context(struct spu_context *ctx)
85{
86 return kref_put(&ctx->kref, &destroy_spu_context);
87}
88
89/* give up the mm reference when the context is about to be destroyed */
90void spu_forget(struct spu_context *ctx)
91{
92 struct mm_struct *mm;
93 spu_acquire_saved(ctx);
94 mm = ctx->owner;
95 ctx->owner = NULL;
96 mmput(mm);
97 spu_release(ctx);
98}
99
100void spu_acquire(struct spu_context *ctx)
101{
102 down_read(&ctx->state_sema);
103}
104
105void spu_release(struct spu_context *ctx)
106{
107 up_read(&ctx->state_sema);
108}
109
110void spu_unmap_mappings(struct spu_context *ctx)
111{
112 unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1);
113}
114
115int spu_acquire_runnable(struct spu_context *ctx)
116{
117 int ret = 0;
118
119 down_read(&ctx->state_sema);
120 if (ctx->state == SPU_STATE_RUNNABLE) {
121 ctx->spu->prio = current->prio;
122 return 0;
123 }
124 up_read(&ctx->state_sema);
125
126 down_write(&ctx->state_sema);
127 /* ctx is about to be freed, can't acquire any more */
128 if (!ctx->owner) {
129 ret = -EINVAL;
130 goto out;
131 }
132
133 if (ctx->state == SPU_STATE_SAVED) {
134 ret = spu_activate(ctx, 0);
135 if (ret)
136 goto out;
137 ctx->state = SPU_STATE_RUNNABLE;
138 }
139
140 downgrade_write(&ctx->state_sema);
141 /* On success, we return holding the lock */
142
143 return ret;
144out:
145 /* Release here, to simplify calling code. */
146 up_write(&ctx->state_sema);
147
148 return ret;
149}
150
151void spu_acquire_saved(struct spu_context *ctx)
152{
153 down_read(&ctx->state_sema);
154
155 if (ctx->state == SPU_STATE_SAVED)
156 return;
157
158 up_read(&ctx->state_sema);
159 down_write(&ctx->state_sema);
160
161 if (ctx->state == SPU_STATE_RUNNABLE) {
162 spu_deactivate(ctx);
163 ctx->state = SPU_STATE_SAVED;
164 }
165
166 downgrade_write(&ctx->state_sema);
167}
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
new file mode 100644
index 000000000000..dfa649c9b956
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -0,0 +1,794 @@
1/*
2 * SPU file system -- file contents
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 *
6 * Author: Arnd Bergmann <arndb@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/fs.h>
24#include <linux/ioctl.h>
25#include <linux/module.h>
26#include <linux/pagemap.h>
27#include <linux/poll.h>
28#include <linux/ptrace.h>
29
30#include <asm/io.h>
31#include <asm/semaphore.h>
32#include <asm/spu.h>
33#include <asm/uaccess.h>
34
35#include "spufs.h"
36
37
38static int
39spufs_mem_open(struct inode *inode, struct file *file)
40{
41 struct spufs_inode_info *i = SPUFS_I(inode);
42 file->private_data = i->i_ctx;
43 file->f_mapping = i->i_ctx->local_store;
44 return 0;
45}
46
47static ssize_t
48spufs_mem_read(struct file *file, char __user *buffer,
49 size_t size, loff_t *pos)
50{
51 struct spu_context *ctx = file->private_data;
52 char *local_store;
53 int ret;
54
55 spu_acquire(ctx);
56
57 local_store = ctx->ops->get_ls(ctx);
58 ret = simple_read_from_buffer(buffer, size, pos, local_store, LS_SIZE);
59
60 spu_release(ctx);
61 return ret;
62}
63
64static ssize_t
65spufs_mem_write(struct file *file, const char __user *buffer,
66 size_t size, loff_t *pos)
67{
68 struct spu_context *ctx = file->private_data;
69 char *local_store;
70 int ret;
71
72 size = min_t(ssize_t, LS_SIZE - *pos, size);
73 if (size <= 0)
74 return -EFBIG;
75 *pos += size;
76
77 spu_acquire(ctx);
78
79 local_store = ctx->ops->get_ls(ctx);
80 ret = copy_from_user(local_store + *pos - size,
81 buffer, size) ? -EFAULT : size;
82
83 spu_release(ctx);
84 return ret;
85}
86
87#ifdef CONFIG_SPARSEMEM
88static struct page *
89spufs_mem_mmap_nopage(struct vm_area_struct *vma,
90 unsigned long address, int *type)
91{
92 struct page *page = NOPAGE_SIGBUS;
93
94 struct spu_context *ctx = vma->vm_file->private_data;
95 unsigned long offset = address - vma->vm_start;
96 offset += vma->vm_pgoff << PAGE_SHIFT;
97
98 spu_acquire(ctx);
99
100 if (ctx->state == SPU_STATE_SAVED)
101 page = vmalloc_to_page(ctx->csa.lscsa->ls + offset);
102 else
103 page = pfn_to_page((ctx->spu->local_store_phys + offset)
104 >> PAGE_SHIFT);
105
106 spu_release(ctx);
107
108 if (type)
109 *type = VM_FAULT_MINOR;
110
111 page_cache_get(page);
112 return page;
113}
114
115static struct vm_operations_struct spufs_mem_mmap_vmops = {
116 .nopage = spufs_mem_mmap_nopage,
117};
118
119static int
120spufs_mem_mmap(struct file *file, struct vm_area_struct *vma)
121{
122 if (!(vma->vm_flags & VM_SHARED))
123 return -EINVAL;
124
125 /* FIXME: */
126 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
127 | _PAGE_NO_CACHE);
128
129 vma->vm_ops = &spufs_mem_mmap_vmops;
130 return 0;
131}
132#endif
133
134static struct file_operations spufs_mem_fops = {
135 .open = spufs_mem_open,
136 .read = spufs_mem_read,
137 .write = spufs_mem_write,
138 .llseek = generic_file_llseek,
139#ifdef CONFIG_SPARSEMEM
140 .mmap = spufs_mem_mmap,
141#endif
142};
143
144static int
145spufs_regs_open(struct inode *inode, struct file *file)
146{
147 struct spufs_inode_info *i = SPUFS_I(inode);
148 file->private_data = i->i_ctx;
149 return 0;
150}
151
152static ssize_t
153spufs_regs_read(struct file *file, char __user *buffer,
154 size_t size, loff_t *pos)
155{
156 struct spu_context *ctx = file->private_data;
157 struct spu_lscsa *lscsa = ctx->csa.lscsa;
158 int ret;
159
160 spu_acquire_saved(ctx);
161
162 ret = simple_read_from_buffer(buffer, size, pos,
163 lscsa->gprs, sizeof lscsa->gprs);
164
165 spu_release(ctx);
166 return ret;
167}
168
169static ssize_t
170spufs_regs_write(struct file *file, const char __user *buffer,
171 size_t size, loff_t *pos)
172{
173 struct spu_context *ctx = file->private_data;
174 struct spu_lscsa *lscsa = ctx->csa.lscsa;
175 int ret;
176
177 size = min_t(ssize_t, sizeof lscsa->gprs - *pos, size);
178 if (size <= 0)
179 return -EFBIG;
180 *pos += size;
181
182 spu_acquire_saved(ctx);
183
184 ret = copy_from_user(lscsa->gprs + *pos - size,
185 buffer, size) ? -EFAULT : size;
186
187 spu_release(ctx);
188 return ret;
189}
190
191static struct file_operations spufs_regs_fops = {
192 .open = spufs_regs_open,
193 .read = spufs_regs_read,
194 .write = spufs_regs_write,
195 .llseek = generic_file_llseek,
196};
197
198static ssize_t
199spufs_fpcr_read(struct file *file, char __user * buffer,
200 size_t size, loff_t * pos)
201{
202 struct spu_context *ctx = file->private_data;
203 struct spu_lscsa *lscsa = ctx->csa.lscsa;
204 int ret;
205
206 spu_acquire_saved(ctx);
207
208 ret = simple_read_from_buffer(buffer, size, pos,
209 &lscsa->fpcr, sizeof(lscsa->fpcr));
210
211 spu_release(ctx);
212 return ret;
213}
214
215static ssize_t
216spufs_fpcr_write(struct file *file, const char __user * buffer,
217 size_t size, loff_t * pos)
218{
219 struct spu_context *ctx = file->private_data;
220 struct spu_lscsa *lscsa = ctx->csa.lscsa;
221 int ret;
222
223 size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size);
224 if (size <= 0)
225 return -EFBIG;
226 *pos += size;
227
228 spu_acquire_saved(ctx);
229
230 ret = copy_from_user((char *)&lscsa->fpcr + *pos - size,
231 buffer, size) ? -EFAULT : size;
232
233 spu_release(ctx);
234 return ret;
235}
236
237static struct file_operations spufs_fpcr_fops = {
238 .open = spufs_regs_open,
239 .read = spufs_fpcr_read,
240 .write = spufs_fpcr_write,
241 .llseek = generic_file_llseek,
242};
243
244/* generic open function for all pipe-like files */
245static int spufs_pipe_open(struct inode *inode, struct file *file)
246{
247 struct spufs_inode_info *i = SPUFS_I(inode);
248 file->private_data = i->i_ctx;
249
250 return nonseekable_open(inode, file);
251}
252
253static ssize_t spufs_mbox_read(struct file *file, char __user *buf,
254 size_t len, loff_t *pos)
255{
256 struct spu_context *ctx = file->private_data;
257 u32 mbox_data;
258 int ret;
259
260 if (len < 4)
261 return -EINVAL;
262
263 spu_acquire(ctx);
264 ret = ctx->ops->mbox_read(ctx, &mbox_data);
265 spu_release(ctx);
266
267 if (!ret)
268 return -EAGAIN;
269
270 if (copy_to_user(buf, &mbox_data, sizeof mbox_data))
271 return -EFAULT;
272
273 return 4;
274}
275
276static struct file_operations spufs_mbox_fops = {
277 .open = spufs_pipe_open,
278 .read = spufs_mbox_read,
279};
280
281static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf,
282 size_t len, loff_t *pos)
283{
284 struct spu_context *ctx = file->private_data;
285 u32 mbox_stat;
286
287 if (len < 4)
288 return -EINVAL;
289
290 spu_acquire(ctx);
291
292 mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff;
293
294 spu_release(ctx);
295
296 if (copy_to_user(buf, &mbox_stat, sizeof mbox_stat))
297 return -EFAULT;
298
299 return 4;
300}
301
302static struct file_operations spufs_mbox_stat_fops = {
303 .open = spufs_pipe_open,
304 .read = spufs_mbox_stat_read,
305};
306
307/* low-level ibox access function */
308size_t spu_ibox_read(struct spu_context *ctx, u32 *data)
309{
310 return ctx->ops->ibox_read(ctx, data);
311}
312
313static int spufs_ibox_fasync(int fd, struct file *file, int on)
314{
315 struct spu_context *ctx = file->private_data;
316
317 return fasync_helper(fd, file, on, &ctx->ibox_fasync);
318}
319
320/* interrupt-level ibox callback function. */
321void spufs_ibox_callback(struct spu *spu)
322{
323 struct spu_context *ctx = spu->ctx;
324
325 wake_up_all(&ctx->ibox_wq);
326 kill_fasync(&ctx->ibox_fasync, SIGIO, POLLIN);
327}
328
329static ssize_t spufs_ibox_read(struct file *file, char __user *buf,
330 size_t len, loff_t *pos)
331{
332 struct spu_context *ctx = file->private_data;
333 u32 ibox_data;
334 ssize_t ret;
335
336 if (len < 4)
337 return -EINVAL;
338
339 spu_acquire(ctx);
340
341 ret = 0;
342 if (file->f_flags & O_NONBLOCK) {
343 if (!spu_ibox_read(ctx, &ibox_data))
344 ret = -EAGAIN;
345 } else {
346 ret = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data));
347 }
348
349 spu_release(ctx);
350
351 if (ret)
352 return ret;
353
354 ret = 4;
355 if (copy_to_user(buf, &ibox_data, sizeof ibox_data))
356 ret = -EFAULT;
357
358 return ret;
359}
360
361static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait)
362{
363 struct spu_context *ctx = file->private_data;
364 unsigned int mask;
365
366 poll_wait(file, &ctx->ibox_wq, wait);
367
368 spu_acquire(ctx);
369 mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM);
370 spu_release(ctx);
371
372 return mask;
373}
374
375static struct file_operations spufs_ibox_fops = {
376 .open = spufs_pipe_open,
377 .read = spufs_ibox_read,
378 .poll = spufs_ibox_poll,
379 .fasync = spufs_ibox_fasync,
380};
381
382static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf,
383 size_t len, loff_t *pos)
384{
385 struct spu_context *ctx = file->private_data;
386 u32 ibox_stat;
387
388 if (len < 4)
389 return -EINVAL;
390
391 spu_acquire(ctx);
392 ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff;
393 spu_release(ctx);
394
395 if (copy_to_user(buf, &ibox_stat, sizeof ibox_stat))
396 return -EFAULT;
397
398 return 4;
399}
400
401static struct file_operations spufs_ibox_stat_fops = {
402 .open = spufs_pipe_open,
403 .read = spufs_ibox_stat_read,
404};
405
406/* low-level mailbox write */
407size_t spu_wbox_write(struct spu_context *ctx, u32 data)
408{
409 return ctx->ops->wbox_write(ctx, data);
410}
411
412static int spufs_wbox_fasync(int fd, struct file *file, int on)
413{
414 struct spu_context *ctx = file->private_data;
415 int ret;
416
417 ret = fasync_helper(fd, file, on, &ctx->wbox_fasync);
418
419 return ret;
420}
421
422/* interrupt-level wbox callback function. */
423void spufs_wbox_callback(struct spu *spu)
424{
425 struct spu_context *ctx = spu->ctx;
426
427 wake_up_all(&ctx->wbox_wq);
428 kill_fasync(&ctx->wbox_fasync, SIGIO, POLLOUT);
429}
430
431static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
432 size_t len, loff_t *pos)
433{
434 struct spu_context *ctx = file->private_data;
435 u32 wbox_data;
436 int ret;
437
438 if (len < 4)
439 return -EINVAL;
440
441 if (copy_from_user(&wbox_data, buf, sizeof wbox_data))
442 return -EFAULT;
443
444 spu_acquire(ctx);
445
446 ret = 0;
447 if (file->f_flags & O_NONBLOCK) {
448 if (!spu_wbox_write(ctx, wbox_data))
449 ret = -EAGAIN;
450 } else {
451 ret = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data));
452 }
453
454 spu_release(ctx);
455
456 return ret ? ret : sizeof wbox_data;
457}
458
459static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait)
460{
461 struct spu_context *ctx = file->private_data;
462 unsigned int mask;
463
464 poll_wait(file, &ctx->wbox_wq, wait);
465
466 spu_acquire(ctx);
467 mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM);
468 spu_release(ctx);
469
470 return mask;
471}
472
473static struct file_operations spufs_wbox_fops = {
474 .open = spufs_pipe_open,
475 .write = spufs_wbox_write,
476 .poll = spufs_wbox_poll,
477 .fasync = spufs_wbox_fasync,
478};
479
480static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf,
481 size_t len, loff_t *pos)
482{
483 struct spu_context *ctx = file->private_data;
484 u32 wbox_stat;
485
486 if (len < 4)
487 return -EINVAL;
488
489 spu_acquire(ctx);
490 wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff;
491 spu_release(ctx);
492
493 if (copy_to_user(buf, &wbox_stat, sizeof wbox_stat))
494 return -EFAULT;
495
496 return 4;
497}
498
499static struct file_operations spufs_wbox_stat_fops = {
500 .open = spufs_pipe_open,
501 .read = spufs_wbox_stat_read,
502};
503
504static ssize_t spufs_signal1_read(struct file *file, char __user *buf,
505 size_t len, loff_t *pos)
506{
507 struct spu_context *ctx = file->private_data;
508 u32 data;
509
510 if (len < 4)
511 return -EINVAL;
512
513 spu_acquire(ctx);
514 data = ctx->ops->signal1_read(ctx);
515 spu_release(ctx);
516
517 if (copy_to_user(buf, &data, 4))
518 return -EFAULT;
519
520 return 4;
521}
522
523static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
524 size_t len, loff_t *pos)
525{
526 struct spu_context *ctx;
527 u32 data;
528
529 ctx = file->private_data;
530
531 if (len < 4)
532 return -EINVAL;
533
534 if (copy_from_user(&data, buf, 4))
535 return -EFAULT;
536
537 spu_acquire(ctx);
538 ctx->ops->signal1_write(ctx, data);
539 spu_release(ctx);
540
541 return 4;
542}
543
544static struct file_operations spufs_signal1_fops = {
545 .open = spufs_pipe_open,
546 .read = spufs_signal1_read,
547 .write = spufs_signal1_write,
548};
549
550static ssize_t spufs_signal2_read(struct file *file, char __user *buf,
551 size_t len, loff_t *pos)
552{
553 struct spu_context *ctx;
554 u32 data;
555
556 ctx = file->private_data;
557
558 if (len < 4)
559 return -EINVAL;
560
561 spu_acquire(ctx);
562 data = ctx->ops->signal2_read(ctx);
563 spu_release(ctx);
564
565 if (copy_to_user(buf, &data, 4))
566 return -EFAULT;
567
568 return 4;
569}
570
571static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
572 size_t len, loff_t *pos)
573{
574 struct spu_context *ctx;
575 u32 data;
576
577 ctx = file->private_data;
578
579 if (len < 4)
580 return -EINVAL;
581
582 if (copy_from_user(&data, buf, 4))
583 return -EFAULT;
584
585 spu_acquire(ctx);
586 ctx->ops->signal2_write(ctx, data);
587 spu_release(ctx);
588
589 return 4;
590}
591
592static struct file_operations spufs_signal2_fops = {
593 .open = spufs_pipe_open,
594 .read = spufs_signal2_read,
595 .write = spufs_signal2_write,
596};
597
598static void spufs_signal1_type_set(void *data, u64 val)
599{
600 struct spu_context *ctx = data;
601
602 spu_acquire(ctx);
603 ctx->ops->signal1_type_set(ctx, val);
604 spu_release(ctx);
605}
606
607static u64 spufs_signal1_type_get(void *data)
608{
609 struct spu_context *ctx = data;
610 u64 ret;
611
612 spu_acquire(ctx);
613 ret = ctx->ops->signal1_type_get(ctx);
614 spu_release(ctx);
615
616 return ret;
617}
618DEFINE_SIMPLE_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get,
619 spufs_signal1_type_set, "%llu");
620
621static void spufs_signal2_type_set(void *data, u64 val)
622{
623 struct spu_context *ctx = data;
624
625 spu_acquire(ctx);
626 ctx->ops->signal2_type_set(ctx, val);
627 spu_release(ctx);
628}
629
630static u64 spufs_signal2_type_get(void *data)
631{
632 struct spu_context *ctx = data;
633 u64 ret;
634
635 spu_acquire(ctx);
636 ret = ctx->ops->signal2_type_get(ctx);
637 spu_release(ctx);
638
639 return ret;
640}
641DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get,
642 spufs_signal2_type_set, "%llu");
643
644static void spufs_npc_set(void *data, u64 val)
645{
646 struct spu_context *ctx = data;
647 spu_acquire(ctx);
648 ctx->ops->npc_write(ctx, val);
649 spu_release(ctx);
650}
651
652static u64 spufs_npc_get(void *data)
653{
654 struct spu_context *ctx = data;
655 u64 ret;
656 spu_acquire(ctx);
657 ret = ctx->ops->npc_read(ctx);
658 spu_release(ctx);
659 return ret;
660}
661DEFINE_SIMPLE_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set, "%llx\n")
662
663static void spufs_decr_set(void *data, u64 val)
664{
665 struct spu_context *ctx = data;
666 struct spu_lscsa *lscsa = ctx->csa.lscsa;
667 spu_acquire_saved(ctx);
668 lscsa->decr.slot[0] = (u32) val;
669 spu_release(ctx);
670}
671
672static u64 spufs_decr_get(void *data)
673{
674 struct spu_context *ctx = data;
675 struct spu_lscsa *lscsa = ctx->csa.lscsa;
676 u64 ret;
677 spu_acquire_saved(ctx);
678 ret = lscsa->decr.slot[0];
679 spu_release(ctx);
680 return ret;
681}
682DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set,
683 "%llx\n")
684
685static void spufs_decr_status_set(void *data, u64 val)
686{
687 struct spu_context *ctx = data;
688 struct spu_lscsa *lscsa = ctx->csa.lscsa;
689 spu_acquire_saved(ctx);
690 lscsa->decr_status.slot[0] = (u32) val;
691 spu_release(ctx);
692}
693
694static u64 spufs_decr_status_get(void *data)
695{
696 struct spu_context *ctx = data;
697 struct spu_lscsa *lscsa = ctx->csa.lscsa;
698 u64 ret;
699 spu_acquire_saved(ctx);
700 ret = lscsa->decr_status.slot[0];
701 spu_release(ctx);
702 return ret;
703}
704DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get,
705 spufs_decr_status_set, "%llx\n")
706
707static void spufs_spu_tag_mask_set(void *data, u64 val)
708{
709 struct spu_context *ctx = data;
710 struct spu_lscsa *lscsa = ctx->csa.lscsa;
711 spu_acquire_saved(ctx);
712 lscsa->tag_mask.slot[0] = (u32) val;
713 spu_release(ctx);
714}
715
716static u64 spufs_spu_tag_mask_get(void *data)
717{
718 struct spu_context *ctx = data;
719 struct spu_lscsa *lscsa = ctx->csa.lscsa;
720 u64 ret;
721 spu_acquire_saved(ctx);
722 ret = lscsa->tag_mask.slot[0];
723 spu_release(ctx);
724 return ret;
725}
726DEFINE_SIMPLE_ATTRIBUTE(spufs_spu_tag_mask_ops, spufs_spu_tag_mask_get,
727 spufs_spu_tag_mask_set, "%llx\n")
728
729static void spufs_event_mask_set(void *data, u64 val)
730{
731 struct spu_context *ctx = data;
732 struct spu_lscsa *lscsa = ctx->csa.lscsa;
733 spu_acquire_saved(ctx);
734 lscsa->event_mask.slot[0] = (u32) val;
735 spu_release(ctx);
736}
737
738static u64 spufs_event_mask_get(void *data)
739{
740 struct spu_context *ctx = data;
741 struct spu_lscsa *lscsa = ctx->csa.lscsa;
742 u64 ret;
743 spu_acquire_saved(ctx);
744 ret = lscsa->event_mask.slot[0];
745 spu_release(ctx);
746 return ret;
747}
748DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get,
749 spufs_event_mask_set, "%llx\n")
750
751static void spufs_srr0_set(void *data, u64 val)
752{
753 struct spu_context *ctx = data;
754 struct spu_lscsa *lscsa = ctx->csa.lscsa;
755 spu_acquire_saved(ctx);
756 lscsa->srr0.slot[0] = (u32) val;
757 spu_release(ctx);
758}
759
760static u64 spufs_srr0_get(void *data)
761{
762 struct spu_context *ctx = data;
763 struct spu_lscsa *lscsa = ctx->csa.lscsa;
764 u64 ret;
765 spu_acquire_saved(ctx);
766 ret = lscsa->srr0.slot[0];
767 spu_release(ctx);
768 return ret;
769}
770DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set,
771 "%llx\n")
772
773struct tree_descr spufs_dir_contents[] = {
774 { "mem", &spufs_mem_fops, 0666, },
775 { "regs", &spufs_regs_fops, 0666, },
776 { "mbox", &spufs_mbox_fops, 0444, },
777 { "ibox", &spufs_ibox_fops, 0444, },
778 { "wbox", &spufs_wbox_fops, 0222, },
779 { "mbox_stat", &spufs_mbox_stat_fops, 0444, },
780 { "ibox_stat", &spufs_ibox_stat_fops, 0444, },
781 { "wbox_stat", &spufs_wbox_stat_fops, 0444, },
782 { "signal1", &spufs_signal1_fops, 0666, },
783 { "signal2", &spufs_signal2_fops, 0666, },
784 { "signal1_type", &spufs_signal1_type, 0666, },
785 { "signal2_type", &spufs_signal2_type, 0666, },
786 { "npc", &spufs_npc_ops, 0666, },
787 { "fpcr", &spufs_fpcr_fops, 0666, },
788 { "decr", &spufs_decr_ops, 0666, },
789 { "decr_status", &spufs_decr_status_ops, 0666, },
790 { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, },
791 { "event_mask", &spufs_event_mask_ops, 0666, },
792 { "srr0", &spufs_srr0_ops, 0666, },
793 {},
794};
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c
new file mode 100644
index 000000000000..5445719bff79
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -0,0 +1,255 @@
1/* hw_ops.c - query/set operations on active SPU context.
2 *
3 * Copyright (C) IBM 2005
4 * Author: Mark Nutter <mnutter@us.ibm.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/config.h>
22#include <linux/module.h>
23#include <linux/errno.h>
24#include <linux/sched.h>
25#include <linux/kernel.h>
26#include <linux/mm.h>
27#include <linux/poll.h>
28#include <linux/smp.h>
29#include <linux/smp_lock.h>
30#include <linux/stddef.h>
31#include <linux/unistd.h>
32
33#include <asm/io.h>
34#include <asm/spu.h>
35#include <asm/spu_csa.h>
36#include <asm/mmu_context.h>
37#include "spufs.h"
38
39static int spu_hw_mbox_read(struct spu_context *ctx, u32 * data)
40{
41 struct spu *spu = ctx->spu;
42 struct spu_problem __iomem *prob = spu->problem;
43 u32 mbox_stat;
44 int ret = 0;
45
46 spin_lock_irq(&spu->register_lock);
47 mbox_stat = in_be32(&prob->mb_stat_R);
48 if (mbox_stat & 0x0000ff) {
49 *data = in_be32(&prob->pu_mb_R);
50 ret = 4;
51 }
52 spin_unlock_irq(&spu->register_lock);
53 return ret;
54}
55
56static u32 spu_hw_mbox_stat_read(struct spu_context *ctx)
57{
58 return in_be32(&ctx->spu->problem->mb_stat_R);
59}
60
61static unsigned int spu_hw_mbox_stat_poll(struct spu_context *ctx,
62 unsigned int events)
63{
64 struct spu *spu = ctx->spu;
65 int ret = 0;
66 u32 stat;
67
68 spin_lock_irq(&spu->register_lock);
69 stat = in_be32(&spu->problem->mb_stat_R);
70
71 /* if the requested event is there, return the poll
72 mask, otherwise enable the interrupt to get notified,
73 but first mark any pending interrupts as done so
74 we don't get woken up unnecessarily */
75
76 if (events & (POLLIN | POLLRDNORM)) {
77 if (stat & 0xff0000)
78 ret |= POLLIN | POLLRDNORM;
79 else {
80 spu_int_stat_clear(spu, 2, 0x1);
81 spu_int_mask_or(spu, 2, 0x1);
82 }
83 }
84 if (events & (POLLOUT | POLLWRNORM)) {
85 if (stat & 0x00ff00)
86 ret = POLLOUT | POLLWRNORM;
87 else {
88 spu_int_stat_clear(spu, 2, 0x10);
89 spu_int_mask_or(spu, 2, 0x10);
90 }
91 }
92 spin_unlock_irq(&spu->register_lock);
93 return ret;
94}
95
96static int spu_hw_ibox_read(struct spu_context *ctx, u32 * data)
97{
98 struct spu *spu = ctx->spu;
99 struct spu_problem __iomem *prob = spu->problem;
100 struct spu_priv2 __iomem *priv2 = spu->priv2;
101 int ret;
102
103 spin_lock_irq(&spu->register_lock);
104 if (in_be32(&prob->mb_stat_R) & 0xff0000) {
105 /* read the first available word */
106 *data = in_be64(&priv2->puint_mb_R);
107 ret = 4;
108 } else {
109 /* make sure we get woken up by the interrupt */
110 spu_int_mask_or(spu, 2, 0x1);
111 ret = 0;
112 }
113 spin_unlock_irq(&spu->register_lock);
114 return ret;
115}
116
117static int spu_hw_wbox_write(struct spu_context *ctx, u32 data)
118{
119 struct spu *spu = ctx->spu;
120 struct spu_problem __iomem *prob = spu->problem;
121 int ret;
122
123 spin_lock_irq(&spu->register_lock);
124 if (in_be32(&prob->mb_stat_R) & 0x00ff00) {
125 /* we have space to write wbox_data to */
126 out_be32(&prob->spu_mb_W, data);
127 ret = 4;
128 } else {
129 /* make sure we get woken up by the interrupt when space
130 becomes available */
131 spu_int_mask_or(spu, 2, 0x10);
132 ret = 0;
133 }
134 spin_unlock_irq(&spu->register_lock);
135 return ret;
136}
137
138static u32 spu_hw_signal1_read(struct spu_context *ctx)
139{
140 return in_be32(&ctx->spu->problem->signal_notify1);
141}
142
143static void spu_hw_signal1_write(struct spu_context *ctx, u32 data)
144{
145 out_be32(&ctx->spu->problem->signal_notify1, data);
146}
147
148static u32 spu_hw_signal2_read(struct spu_context *ctx)
149{
150 return in_be32(&ctx->spu->problem->signal_notify1);
151}
152
153static void spu_hw_signal2_write(struct spu_context *ctx, u32 data)
154{
155 out_be32(&ctx->spu->problem->signal_notify2, data);
156}
157
158static void spu_hw_signal1_type_set(struct spu_context *ctx, u64 val)
159{
160 struct spu *spu = ctx->spu;
161 struct spu_priv2 __iomem *priv2 = spu->priv2;
162 u64 tmp;
163
164 spin_lock_irq(&spu->register_lock);
165 tmp = in_be64(&priv2->spu_cfg_RW);
166 if (val)
167 tmp |= 1;
168 else
169 tmp &= ~1;
170 out_be64(&priv2->spu_cfg_RW, tmp);
171 spin_unlock_irq(&spu->register_lock);
172}
173
174static u64 spu_hw_signal1_type_get(struct spu_context *ctx)
175{
176 return ((in_be64(&ctx->spu->priv2->spu_cfg_RW) & 1) != 0);
177}
178
179static void spu_hw_signal2_type_set(struct spu_context *ctx, u64 val)
180{
181 struct spu *spu = ctx->spu;
182 struct spu_priv2 __iomem *priv2 = spu->priv2;
183 u64 tmp;
184
185 spin_lock_irq(&spu->register_lock);
186 tmp = in_be64(&priv2->spu_cfg_RW);
187 if (val)
188 tmp |= 2;
189 else
190 tmp &= ~2;
191 out_be64(&priv2->spu_cfg_RW, tmp);
192 spin_unlock_irq(&spu->register_lock);
193}
194
195static u64 spu_hw_signal2_type_get(struct spu_context *ctx)
196{
197 return ((in_be64(&ctx->spu->priv2->spu_cfg_RW) & 2) != 0);
198}
199
200static u32 spu_hw_npc_read(struct spu_context *ctx)
201{
202 return in_be32(&ctx->spu->problem->spu_npc_RW);
203}
204
205static void spu_hw_npc_write(struct spu_context *ctx, u32 val)
206{
207 out_be32(&ctx->spu->problem->spu_npc_RW, val);
208}
209
210static u32 spu_hw_status_read(struct spu_context *ctx)
211{
212 return in_be32(&ctx->spu->problem->spu_status_R);
213}
214
215static char *spu_hw_get_ls(struct spu_context *ctx)
216{
217 return ctx->spu->local_store;
218}
219
220static void spu_hw_runcntl_write(struct spu_context *ctx, u32 val)
221{
222 eieio();
223 out_be32(&ctx->spu->problem->spu_runcntl_RW, val);
224}
225
226static void spu_hw_runcntl_stop(struct spu_context *ctx)
227{
228 spin_lock_irq(&ctx->spu->register_lock);
229 out_be32(&ctx->spu->problem->spu_runcntl_RW, SPU_RUNCNTL_STOP);
230 while (in_be32(&ctx->spu->problem->spu_status_R) & SPU_STATUS_RUNNING)
231 cpu_relax();
232 spin_unlock_irq(&ctx->spu->register_lock);
233}
234
235struct spu_context_ops spu_hw_ops = {
236 .mbox_read = spu_hw_mbox_read,
237 .mbox_stat_read = spu_hw_mbox_stat_read,
238 .mbox_stat_poll = spu_hw_mbox_stat_poll,
239 .ibox_read = spu_hw_ibox_read,
240 .wbox_write = spu_hw_wbox_write,
241 .signal1_read = spu_hw_signal1_read,
242 .signal1_write = spu_hw_signal1_write,
243 .signal2_read = spu_hw_signal2_read,
244 .signal2_write = spu_hw_signal2_write,
245 .signal1_type_set = spu_hw_signal1_type_set,
246 .signal1_type_get = spu_hw_signal1_type_get,
247 .signal2_type_set = spu_hw_signal2_type_set,
248 .signal2_type_get = spu_hw_signal2_type_get,
249 .npc_read = spu_hw_npc_read,
250 .npc_write = spu_hw_npc_write,
251 .status_read = spu_hw_status_read,
252 .get_ls = spu_hw_get_ls,
253 .runcntl_write = spu_hw_runcntl_write,
254 .runcntl_stop = spu_hw_runcntl_stop,
255};
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
new file mode 100644
index 000000000000..1f3507c75e90
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -0,0 +1,486 @@
1/*
2 * SPU file system
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 *
6 * Author: Arnd Bergmann <arndb@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/file.h>
24#include <linux/fs.h>
25#include <linux/backing-dev.h>
26#include <linux/init.h>
27#include <linux/ioctl.h>
28#include <linux/module.h>
29#include <linux/mount.h>
30#include <linux/namei.h>
31#include <linux/pagemap.h>
32#include <linux/poll.h>
33#include <linux/slab.h>
34#include <linux/parser.h>
35
36#include <asm/io.h>
37#include <asm/semaphore.h>
38#include <asm/spu.h>
39#include <asm/uaccess.h>
40
41#include "spufs.h"
42
43static kmem_cache_t *spufs_inode_cache;
44
45static struct inode *
46spufs_alloc_inode(struct super_block *sb)
47{
48 struct spufs_inode_info *ei;
49
50 ei = kmem_cache_alloc(spufs_inode_cache, SLAB_KERNEL);
51 if (!ei)
52 return NULL;
53 return &ei->vfs_inode;
54}
55
56static void
57spufs_destroy_inode(struct inode *inode)
58{
59 kmem_cache_free(spufs_inode_cache, SPUFS_I(inode));
60}
61
62static void
63spufs_init_once(void *p, kmem_cache_t * cachep, unsigned long flags)
64{
65 struct spufs_inode_info *ei = p;
66
67 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
68 SLAB_CTOR_CONSTRUCTOR) {
69 inode_init_once(&ei->vfs_inode);
70 }
71}
72
73static struct inode *
74spufs_new_inode(struct super_block *sb, int mode)
75{
76 struct inode *inode;
77
78 inode = new_inode(sb);
79 if (!inode)
80 goto out;
81
82 inode->i_mode = mode;
83 inode->i_uid = current->fsuid;
84 inode->i_gid = current->fsgid;
85 inode->i_blksize = PAGE_CACHE_SIZE;
86 inode->i_blocks = 0;
87 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
88out:
89 return inode;
90}
91
92static int
93spufs_setattr(struct dentry *dentry, struct iattr *attr)
94{
95 struct inode *inode = dentry->d_inode;
96
97 if ((attr->ia_valid & ATTR_SIZE) &&
98 (attr->ia_size != inode->i_size))
99 return -EINVAL;
100 return inode_setattr(inode, attr);
101}
102
103
104static int
105spufs_new_file(struct super_block *sb, struct dentry *dentry,
106 struct file_operations *fops, int mode,
107 struct spu_context *ctx)
108{
109 static struct inode_operations spufs_file_iops = {
110 .setattr = spufs_setattr,
111 };
112 struct inode *inode;
113 int ret;
114
115 ret = -ENOSPC;
116 inode = spufs_new_inode(sb, S_IFREG | mode);
117 if (!inode)
118 goto out;
119
120 ret = 0;
121 inode->i_op = &spufs_file_iops;
122 inode->i_fop = fops;
123 inode->u.generic_ip = SPUFS_I(inode)->i_ctx = get_spu_context(ctx);
124 d_add(dentry, inode);
125out:
126 return ret;
127}
128
129static void
130spufs_delete_inode(struct inode *inode)
131{
132 if (SPUFS_I(inode)->i_ctx)
133 put_spu_context(SPUFS_I(inode)->i_ctx);
134 clear_inode(inode);
135}
136
137static void spufs_prune_dir(struct dentry *dir)
138{
139 struct dentry *dentry, *tmp;
140 down(&dir->d_inode->i_sem);
141 list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
142 spin_lock(&dcache_lock);
143 spin_lock(&dentry->d_lock);
144 if (!(d_unhashed(dentry)) && dentry->d_inode) {
145 dget_locked(dentry);
146 __d_drop(dentry);
147 spin_unlock(&dentry->d_lock);
148 simple_unlink(dir->d_inode, dentry);
149 spin_unlock(&dcache_lock);
150 dput(dentry);
151 } else {
152 spin_unlock(&dentry->d_lock);
153 spin_unlock(&dcache_lock);
154 }
155 }
156 shrink_dcache_parent(dir);
157 up(&dir->d_inode->i_sem);
158}
159
160static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
161{
162 struct spu_context *ctx;
163
164 /* remove all entries */
165 down(&root->i_sem);
166 spufs_prune_dir(dir_dentry);
167 up(&root->i_sem);
168
169 /* We have to give up the mm_struct */
170 ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx;
171 spu_forget(ctx);
172
173 /* XXX Do we need to hold i_sem here ? */
174 return simple_rmdir(root, dir_dentry);
175}
176
177static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files,
178 int mode, struct spu_context *ctx)
179{
180 struct dentry *dentry;
181 int ret;
182
183 while (files->name && files->name[0]) {
184 ret = -ENOMEM;
185 dentry = d_alloc_name(dir, files->name);
186 if (!dentry)
187 goto out;
188 ret = spufs_new_file(dir->d_sb, dentry, files->ops,
189 files->mode & mode, ctx);
190 if (ret)
191 goto out;
192 files++;
193 }
194 return 0;
195out:
196 spufs_prune_dir(dir);
197 return ret;
198}
199
200static int spufs_dir_close(struct inode *inode, struct file *file)
201{
202 struct inode *dir;
203 struct dentry *dentry;
204 int ret;
205
206 dentry = file->f_dentry;
207 dir = dentry->d_parent->d_inode;
208
209 ret = spufs_rmdir(dir, dentry);
210 WARN_ON(ret);
211
212 return dcache_dir_close(inode, file);
213}
214
215struct inode_operations spufs_dir_inode_operations = {
216 .lookup = simple_lookup,
217};
218
219struct file_operations spufs_context_fops = {
220 .open = dcache_dir_open,
221 .release = spufs_dir_close,
222 .llseek = dcache_dir_lseek,
223 .read = generic_read_dir,
224 .readdir = dcache_readdir,
225 .fsync = simple_sync_file,
226};
227
228static int
229spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
230{
231 int ret;
232 struct inode *inode;
233 struct spu_context *ctx;
234
235 ret = -ENOSPC;
236 inode = spufs_new_inode(dir->i_sb, mode | S_IFDIR);
237 if (!inode)
238 goto out;
239
240 if (dir->i_mode & S_ISGID) {
241 inode->i_gid = dir->i_gid;
242 inode->i_mode &= S_ISGID;
243 }
244 ctx = alloc_spu_context(inode->i_mapping);
245 SPUFS_I(inode)->i_ctx = ctx;
246 if (!ctx)
247 goto out_iput;
248
249 inode->i_op = &spufs_dir_inode_operations;
250 inode->i_fop = &simple_dir_operations;
251 ret = spufs_fill_dir(dentry, spufs_dir_contents, mode, ctx);
252 if (ret)
253 goto out_free_ctx;
254
255 d_instantiate(dentry, inode);
256 dget(dentry);
257 dir->i_nlink++;
258 dentry->d_inode->i_nlink++;
259 goto out;
260
261out_free_ctx:
262 put_spu_context(ctx);
263out_iput:
264 iput(inode);
265out:
266 return ret;
267}
268
269static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt)
270{
271 int ret;
272 struct file *filp;
273
274 ret = get_unused_fd();
275 if (ret < 0) {
276 dput(dentry);
277 mntput(mnt);
278 goto out;
279 }
280
281 filp = dentry_open(dentry, mnt, O_RDONLY);
282 if (IS_ERR(filp)) {
283 put_unused_fd(ret);
284 ret = PTR_ERR(filp);
285 goto out;
286 }
287
288 filp->f_op = &spufs_context_fops;
289 fd_install(ret, filp);
290out:
291 return ret;
292}
293
294static struct file_system_type spufs_type;
295
296long spufs_create_thread(struct nameidata *nd,
297 unsigned int flags, mode_t mode)
298{
299 struct dentry *dentry;
300 int ret;
301
302 /* need to be at the root of spufs */
303 ret = -EINVAL;
304 if (nd->dentry->d_sb->s_type != &spufs_type ||
305 nd->dentry != nd->dentry->d_sb->s_root)
306 goto out;
307
308 dentry = lookup_create(nd, 1);
309 ret = PTR_ERR(dentry);
310 if (IS_ERR(dentry))
311 goto out_dir;
312
313 ret = -EEXIST;
314 if (dentry->d_inode)
315 goto out_dput;
316
317 mode &= ~current->fs->umask;
318 ret = spufs_mkdir(nd->dentry->d_inode, dentry, mode & S_IRWXUGO);
319 if (ret)
320 goto out_dput;
321
322 /*
323 * get references for dget and mntget, will be released
324 * in error path of *_open().
325 */
326 ret = spufs_context_open(dget(dentry), mntget(nd->mnt));
327 if (ret < 0)
328 spufs_rmdir(nd->dentry->d_inode, dentry);
329
330out_dput:
331 dput(dentry);
332out_dir:
333 up(&nd->dentry->d_inode->i_sem);
334out:
335 return ret;
336}
337
338/* File system initialization */
339enum {
340 Opt_uid, Opt_gid, Opt_err,
341};
342
343static match_table_t spufs_tokens = {
344 { Opt_uid, "uid=%d" },
345 { Opt_gid, "gid=%d" },
346 { Opt_err, NULL },
347};
348
349static int
350spufs_parse_options(char *options, struct inode *root)
351{
352 char *p;
353 substring_t args[MAX_OPT_ARGS];
354
355 while ((p = strsep(&options, ",")) != NULL) {
356 int token, option;
357
358 if (!*p)
359 continue;
360
361 token = match_token(p, spufs_tokens, args);
362 switch (token) {
363 case Opt_uid:
364 if (match_int(&args[0], &option))
365 return 0;
366 root->i_uid = option;
367 break;
368 case Opt_gid:
369 if (match_int(&args[0], &option))
370 return 0;
371 root->i_gid = option;
372 break;
373 default:
374 return 0;
375 }
376 }
377 return 1;
378}
379
380static int
381spufs_create_root(struct super_block *sb, void *data)
382{
383 struct inode *inode;
384 int ret;
385
386 ret = -ENOMEM;
387 inode = spufs_new_inode(sb, S_IFDIR | 0775);
388 if (!inode)
389 goto out;
390
391 inode->i_op = &spufs_dir_inode_operations;
392 inode->i_fop = &simple_dir_operations;
393 SPUFS_I(inode)->i_ctx = NULL;
394
395 ret = -EINVAL;
396 if (!spufs_parse_options(data, inode))
397 goto out_iput;
398
399 ret = -ENOMEM;
400 sb->s_root = d_alloc_root(inode);
401 if (!sb->s_root)
402 goto out_iput;
403
404 return 0;
405out_iput:
406 iput(inode);
407out:
408 return ret;
409}
410
411static int
412spufs_fill_super(struct super_block *sb, void *data, int silent)
413{
414 static struct super_operations s_ops = {
415 .alloc_inode = spufs_alloc_inode,
416 .destroy_inode = spufs_destroy_inode,
417 .statfs = simple_statfs,
418 .delete_inode = spufs_delete_inode,
419 .drop_inode = generic_delete_inode,
420 };
421
422 sb->s_maxbytes = MAX_LFS_FILESIZE;
423 sb->s_blocksize = PAGE_CACHE_SIZE;
424 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
425 sb->s_magic = SPUFS_MAGIC;
426 sb->s_op = &s_ops;
427
428 return spufs_create_root(sb, data);
429}
430
431static struct super_block *
432spufs_get_sb(struct file_system_type *fstype, int flags,
433 const char *name, void *data)
434{
435 return get_sb_single(fstype, flags, data, spufs_fill_super);
436}
437
438static struct file_system_type spufs_type = {
439 .owner = THIS_MODULE,
440 .name = "spufs",
441 .get_sb = spufs_get_sb,
442 .kill_sb = kill_litter_super,
443};
444
445static int spufs_init(void)
446{
447 int ret;
448 ret = -ENOMEM;
449 spufs_inode_cache = kmem_cache_create("spufs_inode_cache",
450 sizeof(struct spufs_inode_info), 0,
451 SLAB_HWCACHE_ALIGN, spufs_init_once, NULL);
452
453 if (!spufs_inode_cache)
454 goto out;
455 if (spu_sched_init() != 0) {
456 kmem_cache_destroy(spufs_inode_cache);
457 goto out;
458 }
459 ret = register_filesystem(&spufs_type);
460 if (ret)
461 goto out_cache;
462 ret = register_spu_syscalls(&spufs_calls);
463 if (ret)
464 goto out_fs;
465 return 0;
466out_fs:
467 unregister_filesystem(&spufs_type);
468out_cache:
469 kmem_cache_destroy(spufs_inode_cache);
470out:
471 return ret;
472}
473module_init(spufs_init);
474
475static void spufs_exit(void)
476{
477 spu_sched_exit();
478 unregister_spu_syscalls(&spufs_calls);
479 unregister_filesystem(&spufs_type);
480 kmem_cache_destroy(spufs_inode_cache);
481}
482module_exit(spufs_exit);
483
484MODULE_LICENSE("GPL");
485MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
486
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
new file mode 100644
index 000000000000..18ea8866c61a
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -0,0 +1,131 @@
1#include <linux/wait.h>
2#include <linux/ptrace.h>
3
4#include <asm/spu.h>
5
6#include "spufs.h"
7
8/* interrupt-level stop callback function. */
9void spufs_stop_callback(struct spu *spu)
10{
11 struct spu_context *ctx = spu->ctx;
12
13 wake_up_all(&ctx->stop_wq);
14}
15
16static inline int spu_stopped(struct spu_context *ctx, u32 * stat)
17{
18 struct spu *spu;
19 u64 pte_fault;
20
21 *stat = ctx->ops->status_read(ctx);
22 if (ctx->state != SPU_STATE_RUNNABLE)
23 return 1;
24 spu = ctx->spu;
25 pte_fault = spu->dsisr &
26 (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED);
27 return (!(*stat & 0x1) || pte_fault || spu->class_0_pending) ? 1 : 0;
28}
29
30static inline int spu_run_init(struct spu_context *ctx, u32 * npc,
31 u32 * status)
32{
33 int ret;
34
35 if ((ret = spu_acquire_runnable(ctx)) != 0)
36 return ret;
37 ctx->ops->npc_write(ctx, *npc);
38 ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE);
39 return 0;
40}
41
42static inline int spu_run_fini(struct spu_context *ctx, u32 * npc,
43 u32 * status)
44{
45 int ret = 0;
46
47 *status = ctx->ops->status_read(ctx);
48 *npc = ctx->ops->npc_read(ctx);
49 spu_release(ctx);
50
51 if (signal_pending(current))
52 ret = -ERESTARTSYS;
53 if (unlikely(current->ptrace & PT_PTRACED)) {
54 if ((*status & SPU_STATUS_STOPPED_BY_STOP)
55 && (*status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) {
56 force_sig(SIGTRAP, current);
57 ret = -ERESTARTSYS;
58 }
59 }
60 return ret;
61}
62
63static inline int spu_reacquire_runnable(struct spu_context *ctx, u32 *npc,
64 u32 *status)
65{
66 int ret;
67
68 if ((ret = spu_run_fini(ctx, npc, status)) != 0)
69 return ret;
70 if (*status & (SPU_STATUS_STOPPED_BY_STOP |
71 SPU_STATUS_STOPPED_BY_HALT)) {
72 return *status;
73 }
74 if ((ret = spu_run_init(ctx, npc, status)) != 0)
75 return ret;
76 return 0;
77}
78
79static inline int spu_process_events(struct spu_context *ctx)
80{
81 struct spu *spu = ctx->spu;
82 u64 pte_fault = MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED;
83 int ret = 0;
84
85 if (spu->dsisr & pte_fault)
86 ret = spu_irq_class_1_bottom(spu);
87 if (spu->class_0_pending)
88 ret = spu_irq_class_0_bottom(spu);
89 if (!ret && signal_pending(current))
90 ret = -ERESTARTSYS;
91 return ret;
92}
93
94long spufs_run_spu(struct file *file, struct spu_context *ctx,
95 u32 * npc, u32 * status)
96{
97 int ret;
98
99 if (down_interruptible(&ctx->run_sema))
100 return -ERESTARTSYS;
101
102 ret = spu_run_init(ctx, npc, status);
103 if (ret)
104 goto out;
105
106 do {
107 ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status));
108 if (unlikely(ret))
109 break;
110 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) {
111 ret = spu_reacquire_runnable(ctx, npc, status);
112 if (ret)
113 goto out;
114 continue;
115 }
116 ret = spu_process_events(ctx);
117
118 } while (!ret && !(*status & (SPU_STATUS_STOPPED_BY_STOP |
119 SPU_STATUS_STOPPED_BY_HALT)));
120
121 ctx->ops->runcntl_stop(ctx);
122 ret = spu_run_fini(ctx, npc, status);
123 if (!ret)
124 ret = *status;
125 spu_yield(ctx);
126
127out:
128 up(&ctx->run_sema);
129 return ret;
130}
131
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
new file mode 100644
index 000000000000..963182fbd1aa
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -0,0 +1,461 @@
1/* sched.c - SPU scheduler.
2 *
3 * Copyright (C) IBM 2005
4 * Author: Mark Nutter <mnutter@us.ibm.com>
5 *
6 * SPU scheduler, based on Linux thread priority. For now use
7 * a simple "cooperative" yield model with no preemption. SPU
8 * scheduling will eventually be preemptive: When a thread with
9 * a higher static priority gets ready to run, then an active SPU
10 * context will be preempted and returned to the waitq.
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 as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#undef DEBUG
28
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/errno.h>
32#include <linux/sched.h>
33#include <linux/kernel.h>
34#include <linux/mm.h>
35#include <linux/completion.h>
36#include <linux/vmalloc.h>
37#include <linux/smp.h>
38#include <linux/smp_lock.h>
39#include <linux/stddef.h>
40#include <linux/unistd.h>
41
42#include <asm/io.h>
43#include <asm/mmu_context.h>
44#include <asm/spu.h>
45#include <asm/spu_csa.h>
46#include "spufs.h"
47
48#define SPU_MIN_TIMESLICE (100 * HZ / 1000)
49
50#define SPU_BITMAP_SIZE (((MAX_PRIO+BITS_PER_LONG)/BITS_PER_LONG)+1)
51struct spu_prio_array {
52 atomic_t nr_blocked;
53 unsigned long bitmap[SPU_BITMAP_SIZE];
54 wait_queue_head_t waitq[MAX_PRIO];
55};
56
57/* spu_runqueue - This is the main runqueue data structure for SPUs. */
58struct spu_runqueue {
59 struct semaphore sem;
60 unsigned long nr_active;
61 unsigned long nr_idle;
62 unsigned long nr_switches;
63 struct list_head active_list;
64 struct list_head idle_list;
65 struct spu_prio_array prio;
66};
67
68static struct spu_runqueue *spu_runqueues = NULL;
69
70static inline struct spu_runqueue *spu_rq(void)
71{
72 /* Future: make this a per-NODE array,
73 * and use cpu_to_node(smp_processor_id())
74 */
75 return spu_runqueues;
76}
77
78static inline struct spu *del_idle(struct spu_runqueue *rq)
79{
80 struct spu *spu;
81
82 BUG_ON(rq->nr_idle <= 0);
83 BUG_ON(list_empty(&rq->idle_list));
84 /* Future: Move SPU out of low-power SRI state. */
85 spu = list_entry(rq->idle_list.next, struct spu, sched_list);
86 list_del_init(&spu->sched_list);
87 rq->nr_idle--;
88 return spu;
89}
90
91static inline void del_active(struct spu_runqueue *rq, struct spu *spu)
92{
93 BUG_ON(rq->nr_active <= 0);
94 BUG_ON(list_empty(&rq->active_list));
95 list_del_init(&spu->sched_list);
96 rq->nr_active--;
97}
98
99static inline void add_idle(struct spu_runqueue *rq, struct spu *spu)
100{
101 /* Future: Put SPU into low-power SRI state. */
102 list_add_tail(&spu->sched_list, &rq->idle_list);
103 rq->nr_idle++;
104}
105
106static inline void add_active(struct spu_runqueue *rq, struct spu *spu)
107{
108 rq->nr_active++;
109 rq->nr_switches++;
110 list_add_tail(&spu->sched_list, &rq->active_list);
111}
112
113static void prio_wakeup(struct spu_runqueue *rq)
114{
115 if (atomic_read(&rq->prio.nr_blocked) && rq->nr_idle) {
116 int best = sched_find_first_bit(rq->prio.bitmap);
117 if (best < MAX_PRIO) {
118 wait_queue_head_t *wq = &rq->prio.waitq[best];
119 wake_up_interruptible_nr(wq, 1);
120 }
121 }
122}
123
124static void prio_wait(struct spu_runqueue *rq, struct spu_context *ctx,
125 u64 flags)
126{
127 int prio = current->prio;
128 wait_queue_head_t *wq = &rq->prio.waitq[prio];
129 DEFINE_WAIT(wait);
130
131 __set_bit(prio, rq->prio.bitmap);
132 atomic_inc(&rq->prio.nr_blocked);
133 prepare_to_wait_exclusive(wq, &wait, TASK_INTERRUPTIBLE);
134 if (!signal_pending(current)) {
135 up(&rq->sem);
136 up_write(&ctx->state_sema);
137 pr_debug("%s: pid=%d prio=%d\n", __FUNCTION__,
138 current->pid, current->prio);
139 schedule();
140 down_write(&ctx->state_sema);
141 down(&rq->sem);
142 }
143 finish_wait(wq, &wait);
144 atomic_dec(&rq->prio.nr_blocked);
145 if (!waitqueue_active(wq))
146 __clear_bit(prio, rq->prio.bitmap);
147}
148
149static inline int is_best_prio(struct spu_runqueue *rq)
150{
151 int best_prio;
152
153 best_prio = sched_find_first_bit(rq->prio.bitmap);
154 return (current->prio < best_prio) ? 1 : 0;
155}
156
157static inline void mm_needs_global_tlbie(struct mm_struct *mm)
158{
159 /* Global TLBIE broadcast required with SPEs. */
160#if (NR_CPUS > 1)
161 __cpus_setall(&mm->cpu_vm_mask, NR_CPUS);
162#else
163 __cpus_setall(&mm->cpu_vm_mask, NR_CPUS+1); /* is this ok? */
164#endif
165}
166
167static inline void bind_context(struct spu *spu, struct spu_context *ctx)
168{
169 pr_debug("%s: pid=%d SPU=%d\n", __FUNCTION__, current->pid,
170 spu->number);
171 spu->ctx = ctx;
172 spu->flags = 0;
173 ctx->flags = 0;
174 ctx->spu = spu;
175 ctx->ops = &spu_hw_ops;
176 spu->pid = current->pid;
177 spu->prio = current->prio;
178 spu->mm = ctx->owner;
179 mm_needs_global_tlbie(spu->mm);
180 spu->ibox_callback = spufs_ibox_callback;
181 spu->wbox_callback = spufs_wbox_callback;
182 spu->stop_callback = spufs_stop_callback;
183 mb();
184 spu_unmap_mappings(ctx);
185 spu_restore(&ctx->csa, spu);
186 spu->timestamp = jiffies;
187}
188
189static inline void unbind_context(struct spu *spu, struct spu_context *ctx)
190{
191 pr_debug("%s: unbind pid=%d SPU=%d\n", __FUNCTION__,
192 spu->pid, spu->number);
193 spu_unmap_mappings(ctx);
194 spu_save(&ctx->csa, spu);
195 spu->timestamp = jiffies;
196 ctx->state = SPU_STATE_SAVED;
197 spu->ibox_callback = NULL;
198 spu->wbox_callback = NULL;
199 spu->stop_callback = NULL;
200 spu->mm = NULL;
201 spu->pid = 0;
202 spu->prio = MAX_PRIO;
203 ctx->ops = &spu_backing_ops;
204 ctx->spu = NULL;
205 ctx->flags = 0;
206 spu->flags = 0;
207 spu->ctx = NULL;
208}
209
210static void spu_reaper(void *data)
211{
212 struct spu_context *ctx = data;
213 struct spu *spu;
214
215 down_write(&ctx->state_sema);
216 spu = ctx->spu;
217 if (spu && test_bit(SPU_CONTEXT_PREEMPT, &ctx->flags)) {
218 if (atomic_read(&spu->rq->prio.nr_blocked)) {
219 pr_debug("%s: spu=%d\n", __func__, spu->number);
220 ctx->ops->runcntl_stop(ctx);
221 spu_deactivate(ctx);
222 wake_up_all(&ctx->stop_wq);
223 } else {
224 clear_bit(SPU_CONTEXT_PREEMPT, &ctx->flags);
225 }
226 }
227 up_write(&ctx->state_sema);
228 put_spu_context(ctx);
229}
230
231static void schedule_spu_reaper(struct spu_runqueue *rq, struct spu *spu)
232{
233 struct spu_context *ctx = get_spu_context(spu->ctx);
234 unsigned long now = jiffies;
235 unsigned long expire = spu->timestamp + SPU_MIN_TIMESLICE;
236
237 set_bit(SPU_CONTEXT_PREEMPT, &ctx->flags);
238 INIT_WORK(&ctx->reap_work, spu_reaper, ctx);
239 if (time_after(now, expire))
240 schedule_work(&ctx->reap_work);
241 else
242 schedule_delayed_work(&ctx->reap_work, expire - now);
243}
244
245static void check_preempt_active(struct spu_runqueue *rq)
246{
247 struct list_head *p;
248 struct spu *worst = NULL;
249
250 list_for_each(p, &rq->active_list) {
251 struct spu *spu = list_entry(p, struct spu, sched_list);
252 struct spu_context *ctx = spu->ctx;
253 if (!test_bit(SPU_CONTEXT_PREEMPT, &ctx->flags)) {
254 if (!worst || (spu->prio > worst->prio)) {
255 worst = spu;
256 }
257 }
258 }
259 if (worst && (current->prio < worst->prio))
260 schedule_spu_reaper(rq, worst);
261}
262
263static struct spu *get_idle_spu(struct spu_context *ctx, u64 flags)
264{
265 struct spu_runqueue *rq;
266 struct spu *spu = NULL;
267
268 rq = spu_rq();
269 down(&rq->sem);
270 for (;;) {
271 if (rq->nr_idle > 0) {
272 if (is_best_prio(rq)) {
273 /* Fall through. */
274 spu = del_idle(rq);
275 break;
276 } else {
277 prio_wakeup(rq);
278 up(&rq->sem);
279 yield();
280 if (signal_pending(current)) {
281 return NULL;
282 }
283 rq = spu_rq();
284 down(&rq->sem);
285 continue;
286 }
287 } else {
288 check_preempt_active(rq);
289 prio_wait(rq, ctx, flags);
290 if (signal_pending(current)) {
291 prio_wakeup(rq);
292 spu = NULL;
293 break;
294 }
295 continue;
296 }
297 }
298 up(&rq->sem);
299 return spu;
300}
301
302static void put_idle_spu(struct spu *spu)
303{
304 struct spu_runqueue *rq = spu->rq;
305
306 down(&rq->sem);
307 add_idle(rq, spu);
308 prio_wakeup(rq);
309 up(&rq->sem);
310}
311
312static int get_active_spu(struct spu *spu)
313{
314 struct spu_runqueue *rq = spu->rq;
315 struct list_head *p;
316 struct spu *tmp;
317 int rc = 0;
318
319 down(&rq->sem);
320 list_for_each(p, &rq->active_list) {
321 tmp = list_entry(p, struct spu, sched_list);
322 if (tmp == spu) {
323 del_active(rq, spu);
324 rc = 1;
325 break;
326 }
327 }
328 up(&rq->sem);
329 return rc;
330}
331
332static void put_active_spu(struct spu *spu)
333{
334 struct spu_runqueue *rq = spu->rq;
335
336 down(&rq->sem);
337 add_active(rq, spu);
338 up(&rq->sem);
339}
340
341/* Lock order:
342 * spu_activate() & spu_deactivate() require the
343 * caller to have down_write(&ctx->state_sema).
344 *
345 * The rq->sem is breifly held (inside or outside a
346 * given ctx lock) for list management, but is never
347 * held during save/restore.
348 */
349
350int spu_activate(struct spu_context *ctx, u64 flags)
351{
352 struct spu *spu;
353
354 if (ctx->spu)
355 return 0;
356 spu = get_idle_spu(ctx, flags);
357 if (!spu)
358 return (signal_pending(current)) ? -ERESTARTSYS : -EAGAIN;
359 bind_context(spu, ctx);
360 /*
361 * We're likely to wait for interrupts on the same
362 * CPU that we are now on, so send them here.
363 */
364 spu_irq_setaffinity(spu, raw_smp_processor_id());
365 put_active_spu(spu);
366 return 0;
367}
368
369void spu_deactivate(struct spu_context *ctx)
370{
371 struct spu *spu;
372 int needs_idle;
373
374 spu = ctx->spu;
375 if (!spu)
376 return;
377 needs_idle = get_active_spu(spu);
378 unbind_context(spu, ctx);
379 if (needs_idle)
380 put_idle_spu(spu);
381}
382
383void spu_yield(struct spu_context *ctx)
384{
385 struct spu *spu;
386 int need_yield = 0;
387
388 down_write(&ctx->state_sema);
389 spu = ctx->spu;
390 if (spu && (sched_find_first_bit(spu->rq->prio.bitmap) < MAX_PRIO)) {
391 pr_debug("%s: yielding SPU %d\n", __FUNCTION__, spu->number);
392 spu_deactivate(ctx);
393 ctx->state = SPU_STATE_SAVED;
394 need_yield = 1;
395 } else if (spu) {
396 spu->prio = MAX_PRIO;
397 }
398 up_write(&ctx->state_sema);
399 if (unlikely(need_yield))
400 yield();
401}
402
403int __init spu_sched_init(void)
404{
405 struct spu_runqueue *rq;
406 struct spu *spu;
407 int i;
408
409 rq = spu_runqueues = kmalloc(sizeof(struct spu_runqueue), GFP_KERNEL);
410 if (!rq) {
411 printk(KERN_WARNING "%s: Unable to allocate runqueues.\n",
412 __FUNCTION__);
413 return 1;
414 }
415 memset(rq, 0, sizeof(struct spu_runqueue));
416 init_MUTEX(&rq->sem);
417 INIT_LIST_HEAD(&rq->active_list);
418 INIT_LIST_HEAD(&rq->idle_list);
419 rq->nr_active = 0;
420 rq->nr_idle = 0;
421 rq->nr_switches = 0;
422 atomic_set(&rq->prio.nr_blocked, 0);
423 for (i = 0; i < MAX_PRIO; i++) {
424 init_waitqueue_head(&rq->prio.waitq[i]);
425 __clear_bit(i, rq->prio.bitmap);
426 }
427 __set_bit(MAX_PRIO, rq->prio.bitmap);
428 for (;;) {
429 spu = spu_alloc();
430 if (!spu)
431 break;
432 pr_debug("%s: adding SPU[%d]\n", __FUNCTION__, spu->number);
433 add_idle(rq, spu);
434 spu->rq = rq;
435 spu->timestamp = jiffies;
436 }
437 if (!rq->nr_idle) {
438 printk(KERN_WARNING "%s: No available SPUs.\n", __FUNCTION__);
439 kfree(rq);
440 return 1;
441 }
442 return 0;
443}
444
445void __exit spu_sched_exit(void)
446{
447 struct spu_runqueue *rq = spu_rq();
448 struct spu *spu;
449
450 if (!rq) {
451 printk(KERN_WARNING "%s: no runqueues!\n", __FUNCTION__);
452 return;
453 }
454 while (rq->nr_idle > 0) {
455 spu = del_idle(rq);
456 if (!spu)
457 break;
458 spu_free(spu);
459 }
460 kfree(rq);
461}
diff --git a/arch/powerpc/platforms/cell/spufs/spu_restore.c b/arch/powerpc/platforms/cell/spufs/spu_restore.c
new file mode 100644
index 000000000000..0bf723dcd677
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/spu_restore.c
@@ -0,0 +1,336 @@
1/*
2 * spu_restore.c
3 *
4 * (C) Copyright IBM Corp. 2005
5 *
6 * SPU-side context restore sequence outlined in
7 * Synergistic Processor Element Book IV
8 *
9 * Author: Mark Nutter <mnutter@us.ibm.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26
27
28#ifndef LS_SIZE
29#define LS_SIZE 0x40000 /* 256K (in bytes) */
30#endif
31
32typedef unsigned int u32;
33typedef unsigned long long u64;
34
35#include <spu_intrinsics.h>
36#include <asm/spu_csa.h>
37#include "spu_utils.h"
38
39#define BR_INSTR 0x327fff80 /* br -4 */
40#define NOP_INSTR 0x40200000 /* nop */
41#define HEQ_INSTR 0x7b000000 /* heq $0, $0 */
42#define STOP_INSTR 0x00000000 /* stop 0x0 */
43#define ILLEGAL_INSTR 0x00800000 /* illegal instr */
44#define RESTORE_COMPLETE 0x00003ffc /* stop 0x3ffc */
45
46static inline void fetch_regs_from_mem(addr64 lscsa_ea)
47{
48 unsigned int ls = (unsigned int)&regs_spill[0];
49 unsigned int size = sizeof(regs_spill);
50 unsigned int tag_id = 0;
51 unsigned int cmd = 0x40; /* GET */
52
53 spu_writech(MFC_LSA, ls);
54 spu_writech(MFC_EAH, lscsa_ea.ui[0]);
55 spu_writech(MFC_EAL, lscsa_ea.ui[1]);
56 spu_writech(MFC_Size, size);
57 spu_writech(MFC_TagID, tag_id);
58 spu_writech(MFC_Cmd, cmd);
59}
60
61static inline void restore_upper_240kb(addr64 lscsa_ea)
62{
63 unsigned int ls = 16384;
64 unsigned int list = (unsigned int)&dma_list[0];
65 unsigned int size = sizeof(dma_list);
66 unsigned int tag_id = 0;
67 unsigned int cmd = 0x44; /* GETL */
68
69 /* Restore, Step 4:
70 * Enqueue the GETL command (tag 0) to the MFC SPU command
71 * queue to transfer the upper 240 kb of LS from CSA.
72 */
73 spu_writech(MFC_LSA, ls);
74 spu_writech(MFC_EAH, lscsa_ea.ui[0]);
75 spu_writech(MFC_EAL, list);
76 spu_writech(MFC_Size, size);
77 spu_writech(MFC_TagID, tag_id);
78 spu_writech(MFC_Cmd, cmd);
79}
80
81static inline void restore_decr(void)
82{
83 unsigned int offset;
84 unsigned int decr_running;
85 unsigned int decr;
86
87 /* Restore, Step 6:
88 * If the LSCSA "decrementer running" flag is set
89 * then write the SPU_WrDec channel with the
90 * decrementer value from LSCSA.
91 */
92 offset = LSCSA_QW_OFFSET(decr_status);
93 decr_running = regs_spill[offset].slot[0];
94 if (decr_running) {
95 offset = LSCSA_QW_OFFSET(decr);
96 decr = regs_spill[offset].slot[0];
97 spu_writech(SPU_WrDec, decr);
98 }
99}
100
101static inline void write_ppu_mb(void)
102{
103 unsigned int offset;
104 unsigned int data;
105
106 /* Restore, Step 11:
107 * Write the MFC_WrOut_MB channel with the PPU_MB
108 * data from LSCSA.
109 */
110 offset = LSCSA_QW_OFFSET(ppu_mb);
111 data = regs_spill[offset].slot[0];
112 spu_writech(SPU_WrOutMbox, data);
113}
114
115static inline void write_ppuint_mb(void)
116{
117 unsigned int offset;
118 unsigned int data;
119
120 /* Restore, Step 12:
121 * Write the MFC_WrInt_MB channel with the PPUINT_MB
122 * data from LSCSA.
123 */
124 offset = LSCSA_QW_OFFSET(ppuint_mb);
125 data = regs_spill[offset].slot[0];
126 spu_writech(SPU_WrOutIntrMbox, data);
127}
128
129static inline void restore_fpcr(void)
130{
131 unsigned int offset;
132 vector unsigned int fpcr;
133
134 /* Restore, Step 13:
135 * Restore the floating-point status and control
136 * register from the LSCSA.
137 */
138 offset = LSCSA_QW_OFFSET(fpcr);
139 fpcr = regs_spill[offset].v;
140 spu_mtfpscr(fpcr);
141}
142
143static inline void restore_srr0(void)
144{
145 unsigned int offset;
146 unsigned int srr0;
147
148 /* Restore, Step 14:
149 * Restore the SPU SRR0 data from the LSCSA.
150 */
151 offset = LSCSA_QW_OFFSET(srr0);
152 srr0 = regs_spill[offset].slot[0];
153 spu_writech(SPU_WrSRR0, srr0);
154}
155
156static inline void restore_event_mask(void)
157{
158 unsigned int offset;
159 unsigned int event_mask;
160
161 /* Restore, Step 15:
162 * Restore the SPU_RdEventMsk data from the LSCSA.
163 */
164 offset = LSCSA_QW_OFFSET(event_mask);
165 event_mask = regs_spill[offset].slot[0];
166 spu_writech(SPU_WrEventMask, event_mask);
167}
168
169static inline void restore_tag_mask(void)
170{
171 unsigned int offset;
172 unsigned int tag_mask;
173
174 /* Restore, Step 16:
175 * Restore the SPU_RdTagMsk data from the LSCSA.
176 */
177 offset = LSCSA_QW_OFFSET(tag_mask);
178 tag_mask = regs_spill[offset].slot[0];
179 spu_writech(MFC_WrTagMask, tag_mask);
180}
181
182static inline void restore_complete(void)
183{
184 extern void exit_fini(void);
185 unsigned int *exit_instrs = (unsigned int *)exit_fini;
186 unsigned int offset;
187 unsigned int stopped_status;
188 unsigned int stopped_code;
189
190 /* Restore, Step 18:
191 * Issue a stop-and-signal instruction with
192 * "good context restore" signal value.
193 *
194 * Restore, Step 19:
195 * There may be additional instructions placed
196 * here by the PPE Sequence for SPU Context
197 * Restore in order to restore the correct
198 * "stopped state".
199 *
200 * This step is handled here by analyzing the
201 * LSCSA.stopped_status and then modifying the
202 * exit() function to behave appropriately.
203 */
204
205 offset = LSCSA_QW_OFFSET(stopped_status);
206 stopped_status = regs_spill[offset].slot[0];
207 stopped_code = regs_spill[offset].slot[1];
208
209 switch (stopped_status) {
210 case SPU_STOPPED_STATUS_P_I:
211 /* SPU_Status[P,I]=1. Add illegal instruction
212 * followed by stop-and-signal instruction after
213 * end of restore code.
214 */
215 exit_instrs[0] = RESTORE_COMPLETE;
216 exit_instrs[1] = ILLEGAL_INSTR;
217 exit_instrs[2] = STOP_INSTR | stopped_code;
218 break;
219 case SPU_STOPPED_STATUS_P_H:
220 /* SPU_Status[P,H]=1. Add 'heq $0, $0' followed
221 * by stop-and-signal instruction after end of
222 * restore code.
223 */
224 exit_instrs[0] = RESTORE_COMPLETE;
225 exit_instrs[1] = HEQ_INSTR;
226 exit_instrs[2] = STOP_INSTR | stopped_code;
227 break;
228 case SPU_STOPPED_STATUS_S_P:
229 /* SPU_Status[S,P]=1. Add nop instruction
230 * followed by 'br -4' after end of restore
231 * code.
232 */
233 exit_instrs[0] = RESTORE_COMPLETE;
234 exit_instrs[1] = STOP_INSTR | stopped_code;
235 exit_instrs[2] = NOP_INSTR;
236 exit_instrs[3] = BR_INSTR;
237 break;
238 case SPU_STOPPED_STATUS_S_I:
239 /* SPU_Status[S,I]=1. Add illegal instruction
240 * followed by 'br -4' after end of restore code.
241 */
242 exit_instrs[0] = RESTORE_COMPLETE;
243 exit_instrs[1] = ILLEGAL_INSTR;
244 exit_instrs[2] = NOP_INSTR;
245 exit_instrs[3] = BR_INSTR;
246 break;
247 case SPU_STOPPED_STATUS_I:
248 /* SPU_Status[I]=1. Add illegal instruction followed
249 * by infinite loop after end of restore sequence.
250 */
251 exit_instrs[0] = RESTORE_COMPLETE;
252 exit_instrs[1] = ILLEGAL_INSTR;
253 exit_instrs[2] = NOP_INSTR;
254 exit_instrs[3] = BR_INSTR;
255 break;
256 case SPU_STOPPED_STATUS_S:
257 /* SPU_Status[S]=1. Add two 'nop' instructions. */
258 exit_instrs[0] = RESTORE_COMPLETE;
259 exit_instrs[1] = NOP_INSTR;
260 exit_instrs[2] = NOP_INSTR;
261 exit_instrs[3] = BR_INSTR;
262 break;
263 case SPU_STOPPED_STATUS_H:
264 /* SPU_Status[H]=1. Add 'heq $0, $0' instruction
265 * after end of restore code.
266 */
267 exit_instrs[0] = RESTORE_COMPLETE;
268 exit_instrs[1] = HEQ_INSTR;
269 exit_instrs[2] = NOP_INSTR;
270 exit_instrs[3] = BR_INSTR;
271 break;
272 case SPU_STOPPED_STATUS_P:
273 /* SPU_Status[P]=1. Add stop-and-signal instruction
274 * after end of restore code.
275 */
276 exit_instrs[0] = RESTORE_COMPLETE;
277 exit_instrs[1] = STOP_INSTR | stopped_code;
278 break;
279 case SPU_STOPPED_STATUS_R:
280 /* SPU_Status[I,S,H,P,R]=0. Add infinite loop. */
281 exit_instrs[0] = RESTORE_COMPLETE;
282 exit_instrs[1] = NOP_INSTR;
283 exit_instrs[2] = NOP_INSTR;
284 exit_instrs[3] = BR_INSTR;
285 break;
286 default:
287 /* SPU_Status[R]=1. No additonal instructions. */
288 break;
289 }
290 spu_sync();
291}
292
293/**
294 * main - entry point for SPU-side context restore.
295 *
296 * This code deviates from the documented sequence in the
297 * following aspects:
298 *
299 * 1. The EA for LSCSA is passed from PPE in the
300 * signal notification channels.
301 * 2. The register spill area is pulled by SPU
302 * into LS, rather than pushed by PPE.
303 * 3. All 128 registers are restored by exit().
304 * 4. The exit() function is modified at run
305 * time in order to properly restore the
306 * SPU_Status register.
307 */
308int main()
309{
310 addr64 lscsa_ea;
311
312 lscsa_ea.ui[0] = spu_readch(SPU_RdSigNotify1);
313 lscsa_ea.ui[1] = spu_readch(SPU_RdSigNotify2);
314 fetch_regs_from_mem(lscsa_ea);
315
316 set_event_mask(); /* Step 1. */
317 set_tag_mask(); /* Step 2. */
318 build_dma_list(lscsa_ea); /* Step 3. */
319 restore_upper_240kb(lscsa_ea); /* Step 4. */
320 /* Step 5: done by 'exit'. */
321 restore_decr(); /* Step 6. */
322 enqueue_putllc(lscsa_ea); /* Step 7. */
323 set_tag_update(); /* Step 8. */
324 read_tag_status(); /* Step 9. */
325 read_llar_status(); /* Step 10. */
326 write_ppu_mb(); /* Step 11. */
327 write_ppuint_mb(); /* Step 12. */
328 restore_fpcr(); /* Step 13. */
329 restore_srr0(); /* Step 14. */
330 restore_event_mask(); /* Step 15. */
331 restore_tag_mask(); /* Step 16. */
332 /* Step 17. done by 'exit'. */
333 restore_complete(); /* Step 18. */
334
335 return 0;
336}
diff --git a/arch/powerpc/platforms/cell/spufs/spu_restore_crt0.S b/arch/powerpc/platforms/cell/spufs/spu_restore_crt0.S
new file mode 100644
index 000000000000..2905949debe1
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/spu_restore_crt0.S
@@ -0,0 +1,116 @@
1/*
2 * crt0_r.S: Entry function for SPU-side context restore.
3 *
4 * Copyright (C) 2005 IBM
5 *
6 * Entry and exit function for SPU-side of the context restore
7 * sequence. Sets up an initial stack frame, then branches to
8 * 'main'. On return, restores all 128 registers from the LSCSA
9 * and exits.
10 *
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 as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <asm/spu_csa.h>
28
29.data
30.align 7
31.globl regs_spill
32regs_spill:
33.space SIZEOF_SPU_SPILL_REGS, 0x0
34
35.text
36.global _start
37_start:
38 /* Initialize the stack pointer to point to 16368
39 * (16kb-16). The back chain pointer is initialized
40 * to NULL.
41 */
42 il $0, 0
43 il $SP, 16368
44 stqd $0, 0($SP)
45
46 /* Allocate a minimum stack frame for the called main.
47 * This is needed so that main has a place to save the
48 * link register when it calls another function.
49 */
50 stqd $SP, -160($SP)
51 ai $SP, $SP, -160
52
53 /* Call the program's main function. */
54 brsl $0, main
55
56.global exit
57.global _exit
58exit:
59_exit:
60 /* SPU Context Restore, Step 5: Restore the remaining 112 GPRs. */
61 ila $3, regs_spill + 256
62restore_regs:
63 lqr $4, restore_reg_insts
64restore_reg_loop:
65 ai $4, $4, 4
66 .balignl 16, 0x40200000
67restore_reg_insts: /* must be quad-word aligned. */
68 lqd $16, 0($3)
69 lqd $17, 16($3)
70 lqd $18, 32($3)
71 lqd $19, 48($3)
72 andi $5, $4, 0x7F
73 stqr $4, restore_reg_insts
74 ai $3, $3, 64
75 brnz $5, restore_reg_loop
76
77 /* SPU Context Restore Step 17: Restore the first 16 GPRs. */
78 lqa $0, regs_spill + 0
79 lqa $1, regs_spill + 16
80 lqa $2, regs_spill + 32
81 lqa $3, regs_spill + 48
82 lqa $4, regs_spill + 64
83 lqa $5, regs_spill + 80
84 lqa $6, regs_spill + 96
85 lqa $7, regs_spill + 112
86 lqa $8, regs_spill + 128
87 lqa $9, regs_spill + 144
88 lqa $10, regs_spill + 160
89 lqa $11, regs_spill + 176
90 lqa $12, regs_spill + 192
91 lqa $13, regs_spill + 208
92 lqa $14, regs_spill + 224
93 lqa $15, regs_spill + 240
94
95 /* Under normal circumstances, the 'exit' function
96 * terminates with 'stop SPU_RESTORE_COMPLETE',
97 * indicating that the SPU-side restore code has
98 * completed.
99 *
100 * However it is possible that instructions immediately
101 * following the 'stop 0x3ffc' have been modified at run
102 * time so as to recreate the exact SPU_Status settings
103 * from the application, e.g. illegal instruciton, halt,
104 * etc.
105 */
106.global exit_fini
107.global _exit_fini
108exit_fini:
109_exit_fini:
110 stop SPU_RESTORE_COMPLETE
111 stop 0
112 stop 0
113 stop 0
114
115 /* Pad the size of this crt0.o to be multiple of 16 bytes. */
116.balignl 16, 0x0
diff --git a/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped b/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped
new file mode 100644
index 000000000000..1b2355ff7036
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped
@@ -0,0 +1,231 @@
1/*
2 * spu_restore_dump.h: Copyright (C) 2005 IBM.
3 * Hex-dump auto generated from spu_restore.c.
4 * Do not edit!
5 */
6static unsigned int spu_restore_code[] __page_aligned = {
70x40800000, 0x409ff801, 0x24000080, 0x24fd8081,
80x1cd80081, 0x33001180, 0x42030003, 0x33800284,
90x1c010204, 0x40200000, 0x40200000, 0x40200000,
100x34000190, 0x34004191, 0x34008192, 0x3400c193,
110x141fc205, 0x23fffd84, 0x1c100183, 0x217ffa85,
120x3080a000, 0x3080a201, 0x3080a402, 0x3080a603,
130x3080a804, 0x3080aa05, 0x3080ac06, 0x3080ae07,
140x3080b008, 0x3080b209, 0x3080b40a, 0x3080b60b,
150x3080b80c, 0x3080ba0d, 0x3080bc0e, 0x3080be0f,
160x00003ffc, 0x00000000, 0x00000000, 0x00000000,
170x01a00182, 0x3ec00083, 0xb0a14103, 0x01a00204,
180x3ec10082, 0x4202800e, 0x04000703, 0xb0a14202,
190x21a00803, 0x3fbf028d, 0x3f20068d, 0x3fbe0682,
200x3fe30102, 0x21a00882, 0x3f82028f, 0x3fe3078f,
210x3fbf0784, 0x3f200204, 0x3fbe0204, 0x3fe30204,
220x04000203, 0x21a00903, 0x40848002, 0x21a00982,
230x40800003, 0x21a00a03, 0x40802002, 0x21a00a82,
240x21a00083, 0x40800082, 0x21a00b02, 0x10002818,
250x40a80002, 0x32800007, 0x4207000c, 0x18008208,
260x40a0000b, 0x4080020a, 0x40800709, 0x00200000,
270x42070002, 0x3ac30384, 0x1cffc489, 0x00200000,
280x18008383, 0x38830382, 0x4cffc486, 0x3ac28185,
290xb0408584, 0x28830382, 0x1c020387, 0x38828182,
300xb0408405, 0x1802c408, 0x28828182, 0x217ff886,
310x04000583, 0x21a00803, 0x3fbe0682, 0x3fe30102,
320x04000106, 0x21a00886, 0x04000603, 0x21a00903,
330x40803c02, 0x21a00982, 0x40800003, 0x04000184,
340x21a00a04, 0x40802202, 0x21a00a82, 0x42028005,
350x34208702, 0x21002282, 0x21a00804, 0x21a00886,
360x3fbf0782, 0x3f200102, 0x3fbe0102, 0x3fe30102,
370x21a00902, 0x40804003, 0x21a00983, 0x21a00a04,
380x40805a02, 0x21a00a82, 0x40800083, 0x21a00b83,
390x01a00c02, 0x01a00d83, 0x3420c282, 0x21a00e02,
400x34210283, 0x21a00f03, 0x34200284, 0x77400200,
410x3421c282, 0x21a00702, 0x34218283, 0x21a00083,
420x34214282, 0x21a00b02, 0x4200480c, 0x00200000,
430x1c010286, 0x34220284, 0x34220302, 0x0f608203,
440x5c024204, 0x3b81810b, 0x42013c02, 0x00200000,
450x18008185, 0x38808183, 0x3b814182, 0x21004e84,
460x4020007f, 0x35000100, 0x000004e0, 0x000002a0,
470x000002e8, 0x00000428, 0x00000360, 0x000002e8,
480x000004a0, 0x00000468, 0x000003c8, 0x00000360,
490x409ffe02, 0x30801203, 0x40800204, 0x3ec40085,
500x10009c09, 0x3ac10606, 0xb060c105, 0x4020007f,
510x4020007f, 0x20801203, 0x38810602, 0xb0408586,
520x28810602, 0x32004180, 0x34204702, 0x21a00382,
530x4020007f, 0x327fdc80, 0x409ffe02, 0x30801203,
540x40800204, 0x3ec40087, 0x40800405, 0x00200000,
550x40800606, 0x3ac10608, 0x3ac14609, 0x3ac1860a,
560xb060c107, 0x20801203, 0x41004003, 0x38810602,
570x4020007f, 0xb0408188, 0x4020007f, 0x28810602,
580x41201002, 0x38814603, 0x10009c09, 0xb060c109,
590x4020007f, 0x28814603, 0x41193f83, 0x38818602,
600x60ffc003, 0xb040818a, 0x28818602, 0x32003080,
610x409ffe02, 0x30801203, 0x40800204, 0x3ec40087,
620x41201008, 0x10009c14, 0x40800405, 0x3ac10609,
630x40800606, 0x3ac1460a, 0xb060c107, 0x3ac1860b,
640x20801203, 0x38810602, 0xb0408409, 0x28810602,
650x38814603, 0xb060c40a, 0x4020007f, 0x28814603,
660x41193f83, 0x38818602, 0x60ffc003, 0xb040818b,
670x28818602, 0x32002380, 0x409ffe02, 0x30801204,
680x40800205, 0x3ec40083, 0x40800406, 0x3ac14607,
690x3ac18608, 0xb0810103, 0x41004002, 0x20801204,
700x4020007f, 0x38814603, 0x10009c0b, 0xb060c107,
710x4020007f, 0x4020007f, 0x28814603, 0x38818602,
720x4020007f, 0x4020007f, 0xb0408588, 0x28818602,
730x4020007f, 0x32001780, 0x409ffe02, 0x1000640e,
740x40800204, 0x30801203, 0x40800405, 0x3ec40087,
750x40800606, 0x3ac10608, 0x3ac14609, 0x3ac1860a,
760xb060c107, 0x20801203, 0x413d8003, 0x38810602,
770x4020007f, 0x327fd780, 0x409ffe02, 0x10007f0c,
780x40800205, 0x30801204, 0x40800406, 0x3ec40083,
790x3ac14607, 0x3ac18608, 0xb0810103, 0x413d8002,
800x20801204, 0x38814603, 0x4020007f, 0x327feb80,
810x409ffe02, 0x30801203, 0x40800204, 0x3ec40087,
820x40800405, 0x1000650a, 0x40800606, 0x3ac10608,
830x3ac14609, 0x3ac1860a, 0xb060c107, 0x20801203,
840x38810602, 0xb0408588, 0x4020007f, 0x327fc980,
850x00400000, 0x40800003, 0x4020007f, 0x35000000,
860x00000000, 0x00000000, 0x00000000, 0x00000000,
870x00000000, 0x00000000, 0x00000000, 0x00000000,
880x00000000, 0x00000000, 0x00000000, 0x00000000,
890x00000000, 0x00000000, 0x00000000, 0x00000000,
900x00000000, 0x00000000, 0x00000000, 0x00000000,
910x00000000, 0x00000000, 0x00000000, 0x00000000,
920x00000000, 0x00000000, 0x00000000, 0x00000000,
930x00000000, 0x00000000, 0x00000000, 0x00000000,
940x00000000, 0x00000000, 0x00000000, 0x00000000,
950x00000000, 0x00000000, 0x00000000, 0x00000000,
960x00000000, 0x00000000, 0x00000000, 0x00000000,
970x00000000, 0x00000000, 0x00000000, 0x00000000,
980x00000000, 0x00000000, 0x00000000, 0x00000000,
990x00000000, 0x00000000, 0x00000000, 0x00000000,
1000x00000000, 0x00000000, 0x00000000, 0x00000000,
1010x00000000, 0x00000000, 0x00000000, 0x00000000,
1020x00000000, 0x00000000, 0x00000000, 0x00000000,
1030x00000000, 0x00000000, 0x00000000, 0x00000000,
1040x00000000, 0x00000000, 0x00000000, 0x00000000,
1050x00000000, 0x00000000, 0x00000000, 0x00000000,
1060x00000000, 0x00000000, 0x00000000, 0x00000000,
1070x00000000, 0x00000000, 0x00000000, 0x00000000,
1080x00000000, 0x00000000, 0x00000000, 0x00000000,
1090x00000000, 0x00000000, 0x00000000, 0x00000000,
1100x00000000, 0x00000000, 0x00000000, 0x00000000,
1110x00000000, 0x00000000, 0x00000000, 0x00000000,
1120x00000000, 0x00000000, 0x00000000, 0x00000000,
1130x00000000, 0x00000000, 0x00000000, 0x00000000,
1140x00000000, 0x00000000, 0x00000000, 0x00000000,
1150x00000000, 0x00000000, 0x00000000, 0x00000000,
1160x00000000, 0x00000000, 0x00000000, 0x00000000,
1170x00000000, 0x00000000, 0x00000000, 0x00000000,
1180x00000000, 0x00000000, 0x00000000, 0x00000000,
1190x00000000, 0x00000000, 0x00000000, 0x00000000,
1200x00000000, 0x00000000, 0x00000000, 0x00000000,
1210x00000000, 0x00000000, 0x00000000, 0x00000000,
1220x00000000, 0x00000000, 0x00000000, 0x00000000,
1230x00000000, 0x00000000, 0x00000000, 0x00000000,
1240x00000000, 0x00000000, 0x00000000, 0x00000000,
1250x00000000, 0x00000000, 0x00000000, 0x00000000,
1260x00000000, 0x00000000, 0x00000000, 0x00000000,
1270x00000000, 0x00000000, 0x00000000, 0x00000000,
1280x00000000, 0x00000000, 0x00000000, 0x00000000,
1290x00000000, 0x00000000, 0x00000000, 0x00000000,
1300x00000000, 0x00000000, 0x00000000, 0x00000000,
1310x00000000, 0x00000000, 0x00000000, 0x00000000,
1320x00000000, 0x00000000, 0x00000000, 0x00000000,
1330x00000000, 0x00000000, 0x00000000, 0x00000000,
1340x00000000, 0x00000000, 0x00000000, 0x00000000,
1350x00000000, 0x00000000, 0x00000000, 0x00000000,
1360x00000000, 0x00000000, 0x00000000, 0x00000000,
1370x00000000, 0x00000000, 0x00000000, 0x00000000,
1380x00000000, 0x00000000, 0x00000000, 0x00000000,
1390x00000000, 0x00000000, 0x00000000, 0x00000000,
1400x00000000, 0x00000000, 0x00000000, 0x00000000,
1410x00000000, 0x00000000, 0x00000000, 0x00000000,
1420x00000000, 0x00000000, 0x00000000, 0x00000000,
1430x00000000, 0x00000000, 0x00000000, 0x00000000,
1440x00000000, 0x00000000, 0x00000000, 0x00000000,
1450x00000000, 0x00000000, 0x00000000, 0x00000000,
1460x00000000, 0x00000000, 0x00000000, 0x00000000,
1470x00000000, 0x00000000, 0x00000000, 0x00000000,
1480x00000000, 0x00000000, 0x00000000, 0x00000000,
1490x00000000, 0x00000000, 0x00000000, 0x00000000,
1500x00000000, 0x00000000, 0x00000000, 0x00000000,
1510x00000000, 0x00000000, 0x00000000, 0x00000000,
1520x00000000, 0x00000000, 0x00000000, 0x00000000,
1530x00000000, 0x00000000, 0x00000000, 0x00000000,
1540x00000000, 0x00000000, 0x00000000, 0x00000000,
1550x00000000, 0x00000000, 0x00000000, 0x00000000,
1560x00000000, 0x00000000, 0x00000000, 0x00000000,
1570x00000000, 0x00000000, 0x00000000, 0x00000000,
1580x00000000, 0x00000000, 0x00000000, 0x00000000,
1590x00000000, 0x00000000, 0x00000000, 0x00000000,
1600x00000000, 0x00000000, 0x00000000, 0x00000000,
1610x00000000, 0x00000000, 0x00000000, 0x00000000,
1620x00000000, 0x00000000, 0x00000000, 0x00000000,
1630x00000000, 0x00000000, 0x00000000, 0x00000000,
1640x00000000, 0x00000000, 0x00000000, 0x00000000,
1650x00000000, 0x00000000, 0x00000000, 0x00000000,
1660x00000000, 0x00000000, 0x00000000, 0x00000000,
1670x00000000, 0x00000000, 0x00000000, 0x00000000,
1680x00000000, 0x00000000, 0x00000000, 0x00000000,
1690x00000000, 0x00000000, 0x00000000, 0x00000000,
1700x00000000, 0x00000000, 0x00000000, 0x00000000,
1710x00000000, 0x00000000, 0x00000000, 0x00000000,
1720x00000000, 0x00000000, 0x00000000, 0x00000000,
1730x00000000, 0x00000000, 0x00000000, 0x00000000,
1740x00000000, 0x00000000, 0x00000000, 0x00000000,
1750x00000000, 0x00000000, 0x00000000, 0x00000000,
1760x00000000, 0x00000000, 0x00000000, 0x00000000,
1770x00000000, 0x00000000, 0x00000000, 0x00000000,
1780x00000000, 0x00000000, 0x00000000, 0x00000000,
1790x00000000, 0x00000000, 0x00000000, 0x00000000,
1800x00000000, 0x00000000, 0x00000000, 0x00000000,
1810x00000000, 0x00000000, 0x00000000, 0x00000000,
1820x00000000, 0x00000000, 0x00000000, 0x00000000,
1830x00000000, 0x00000000, 0x00000000, 0x00000000,
1840x00000000, 0x00000000, 0x00000000, 0x00000000,
1850x00000000, 0x00000000, 0x00000000, 0x00000000,
1860x00000000, 0x00000000, 0x00000000, 0x00000000,
1870x00000000, 0x00000000, 0x00000000, 0x00000000,
1880x00000000, 0x00000000, 0x00000000, 0x00000000,
1890x00000000, 0x00000000, 0x00000000, 0x00000000,
1900x00000000, 0x00000000, 0x00000000, 0x00000000,
1910x00000000, 0x00000000, 0x00000000, 0x00000000,
1920x00000000, 0x00000000, 0x00000000, 0x00000000,
1930x00000000, 0x00000000, 0x00000000, 0x00000000,
1940x00000000, 0x00000000, 0x00000000, 0x00000000,
1950x00000000, 0x00000000, 0x00000000, 0x00000000,
1960x00000000, 0x00000000, 0x00000000, 0x00000000,
1970x00000000, 0x00000000, 0x00000000, 0x00000000,
1980x00000000, 0x00000000, 0x00000000, 0x00000000,
1990x00000000, 0x00000000, 0x00000000, 0x00000000,
2000x00000000, 0x00000000, 0x00000000, 0x00000000,
2010x00000000, 0x00000000, 0x00000000, 0x00000000,
2020x00000000, 0x00000000, 0x00000000, 0x00000000,
2030x00000000, 0x00000000, 0x00000000, 0x00000000,
2040x00000000, 0x00000000, 0x00000000, 0x00000000,
2050x00000000, 0x00000000, 0x00000000, 0x00000000,
2060x00000000, 0x00000000, 0x00000000, 0x00000000,
2070x00000000, 0x00000000, 0x00000000, 0x00000000,
2080x00000000, 0x00000000, 0x00000000, 0x00000000,
2090x00000000, 0x00000000, 0x00000000, 0x00000000,
2100x00000000, 0x00000000, 0x00000000, 0x00000000,
2110x00000000, 0x00000000, 0x00000000, 0x00000000,
2120x00000000, 0x00000000, 0x00000000, 0x00000000,
2130x00000000, 0x00000000, 0x00000000, 0x00000000,
2140x00000000, 0x00000000, 0x00000000, 0x00000000,
2150x00000000, 0x00000000, 0x00000000, 0x00000000,
2160x00000000, 0x00000000, 0x00000000, 0x00000000,
2170x00000000, 0x00000000, 0x00000000, 0x00000000,
2180x00000000, 0x00000000, 0x00000000, 0x00000000,
2190x00000000, 0x00000000, 0x00000000, 0x00000000,
2200x00000000, 0x00000000, 0x00000000, 0x00000000,
2210x00000000, 0x00000000, 0x00000000, 0x00000000,
2220x00000000, 0x00000000, 0x00000000, 0x00000000,
2230x00000000, 0x00000000, 0x00000000, 0x00000000,
2240x00000000, 0x00000000, 0x00000000, 0x00000000,
2250x00000000, 0x00000000, 0x00000000, 0x00000000,
2260x00000000, 0x00000000, 0x00000000, 0x00000000,
2270x00000000, 0x00000000, 0x00000000, 0x00000000,
2280x00000000, 0x00000000, 0x00000000, 0x00000000,
2290x00000000, 0x00000000, 0x00000000, 0x00000000,
2300x00000000, 0x00000000, 0x00000000, 0x00000000,
231};
diff --git a/arch/powerpc/platforms/cell/spufs/spu_save.c b/arch/powerpc/platforms/cell/spufs/spu_save.c
new file mode 100644
index 000000000000..196033b8a579
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/spu_save.c
@@ -0,0 +1,195 @@
1/*
2 * spu_save.c
3 *
4 * (C) Copyright IBM Corp. 2005
5 *
6 * SPU-side context save sequence outlined in
7 * Synergistic Processor Element Book IV
8 *
9 * Author: Mark Nutter <mnutter@us.ibm.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26
27
28#ifndef LS_SIZE
29#define LS_SIZE 0x40000 /* 256K (in bytes) */
30#endif
31
32typedef unsigned int u32;
33typedef unsigned long long u64;
34
35#include <spu_intrinsics.h>
36#include <asm/spu_csa.h>
37#include "spu_utils.h"
38
39static inline void save_event_mask(void)
40{
41 unsigned int offset;
42
43 /* Save, Step 2:
44 * Read the SPU_RdEventMsk channel and save to the LSCSA.
45 */
46 offset = LSCSA_QW_OFFSET(event_mask);
47 regs_spill[offset].slot[0] = spu_readch(SPU_RdEventStatMask);
48}
49
50static inline void save_tag_mask(void)
51{
52 unsigned int offset;
53
54 /* Save, Step 3:
55 * Read the SPU_RdTagMsk channel and save to the LSCSA.
56 */
57 offset = LSCSA_QW_OFFSET(tag_mask);
58 regs_spill[offset].slot[0] = spu_readch(MFC_RdTagMask);
59}
60
61static inline void save_upper_240kb(addr64 lscsa_ea)
62{
63 unsigned int ls = 16384;
64 unsigned int list = (unsigned int)&dma_list[0];
65 unsigned int size = sizeof(dma_list);
66 unsigned int tag_id = 0;
67 unsigned int cmd = 0x24; /* PUTL */
68
69 /* Save, Step 7:
70 * Enqueue the PUTL command (tag 0) to the MFC SPU command
71 * queue to transfer the remaining 240 kb of LS to CSA.
72 */
73 spu_writech(MFC_LSA, ls);
74 spu_writech(MFC_EAH, lscsa_ea.ui[0]);
75 spu_writech(MFC_EAL, list);
76 spu_writech(MFC_Size, size);
77 spu_writech(MFC_TagID, tag_id);
78 spu_writech(MFC_Cmd, cmd);
79}
80
81static inline void save_fpcr(void)
82{
83 // vector unsigned int fpcr;
84 unsigned int offset;
85
86 /* Save, Step 9:
87 * Issue the floating-point status and control register
88 * read instruction, and save to the LSCSA.
89 */
90 offset = LSCSA_QW_OFFSET(fpcr);
91 regs_spill[offset].v = spu_mffpscr();
92}
93
94static inline void save_decr(void)
95{
96 unsigned int offset;
97
98 /* Save, Step 10:
99 * Read and save the SPU_RdDec channel data to
100 * the LSCSA.
101 */
102 offset = LSCSA_QW_OFFSET(decr);
103 regs_spill[offset].slot[0] = spu_readch(SPU_RdDec);
104}
105
106static inline void save_srr0(void)
107{
108 unsigned int offset;
109
110 /* Save, Step 11:
111 * Read and save the SPU_WSRR0 channel data to
112 * the LSCSA.
113 */
114 offset = LSCSA_QW_OFFSET(srr0);
115 regs_spill[offset].slot[0] = spu_readch(SPU_RdSRR0);
116}
117
118static inline void spill_regs_to_mem(addr64 lscsa_ea)
119{
120 unsigned int ls = (unsigned int)&regs_spill[0];
121 unsigned int size = sizeof(regs_spill);
122 unsigned int tag_id = 0;
123 unsigned int cmd = 0x20; /* PUT */
124
125 /* Save, Step 13:
126 * Enqueue a PUT command (tag 0) to send the LSCSA
127 * to the CSA.
128 */
129 spu_writech(MFC_LSA, ls);
130 spu_writech(MFC_EAH, lscsa_ea.ui[0]);
131 spu_writech(MFC_EAL, lscsa_ea.ui[1]);
132 spu_writech(MFC_Size, size);
133 spu_writech(MFC_TagID, tag_id);
134 spu_writech(MFC_Cmd, cmd);
135}
136
137static inline void enqueue_sync(addr64 lscsa_ea)
138{
139 unsigned int tag_id = 0;
140 unsigned int cmd = 0xCC;
141
142 /* Save, Step 14:
143 * Enqueue an MFC_SYNC command (tag 0).
144 */
145 spu_writech(MFC_TagID, tag_id);
146 spu_writech(MFC_Cmd, cmd);
147}
148
149static inline void save_complete(void)
150{
151 /* Save, Step 18:
152 * Issue a stop-and-signal instruction indicating
153 * "save complete". Note: This function will not
154 * return!!
155 */
156 spu_stop(SPU_SAVE_COMPLETE);
157}
158
159/**
160 * main - entry point for SPU-side context save.
161 *
162 * This code deviates from the documented sequence as follows:
163 *
164 * 1. The EA for LSCSA is passed from PPE in the
165 * signal notification channels.
166 * 2. All 128 registers are saved by crt0.o.
167 */
168int main()
169{
170 addr64 lscsa_ea;
171
172 lscsa_ea.ui[0] = spu_readch(SPU_RdSigNotify1);
173 lscsa_ea.ui[1] = spu_readch(SPU_RdSigNotify2);
174
175 /* Step 1: done by exit(). */
176 save_event_mask(); /* Step 2. */
177 save_tag_mask(); /* Step 3. */
178 set_event_mask(); /* Step 4. */
179 set_tag_mask(); /* Step 5. */
180 build_dma_list(lscsa_ea); /* Step 6. */
181 save_upper_240kb(lscsa_ea); /* Step 7. */
182 /* Step 8: done by exit(). */
183 save_fpcr(); /* Step 9. */
184 save_decr(); /* Step 10. */
185 save_srr0(); /* Step 11. */
186 enqueue_putllc(lscsa_ea); /* Step 12. */
187 spill_regs_to_mem(lscsa_ea); /* Step 13. */
188 enqueue_sync(lscsa_ea); /* Step 14. */
189 set_tag_update(); /* Step 15. */
190 read_tag_status(); /* Step 16. */
191 read_llar_status(); /* Step 17. */
192 save_complete(); /* Step 18. */
193
194 return 0;
195}
diff --git a/arch/powerpc/platforms/cell/spufs/spu_save_crt0.S b/arch/powerpc/platforms/cell/spufs/spu_save_crt0.S
new file mode 100644
index 000000000000..6659d6a66faa
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/spu_save_crt0.S
@@ -0,0 +1,102 @@
1/*
2 * crt0_s.S: Entry function for SPU-side context save.
3 *
4 * Copyright (C) 2005 IBM
5 *
6 * Entry function for SPU-side of the context save sequence.
7 * Saves all 128 GPRs, sets up an initial stack frame, then
8 * branches to 'main'.
9 *
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <asm/spu_csa.h>
27
28.data
29.align 7
30.globl regs_spill
31regs_spill:
32.space SIZEOF_SPU_SPILL_REGS, 0x0
33
34.text
35.global _start
36_start:
37 /* SPU Context Save Step 1: Save the first 16 GPRs. */
38 stqa $0, regs_spill + 0
39 stqa $1, regs_spill + 16
40 stqa $2, regs_spill + 32
41 stqa $3, regs_spill + 48
42 stqa $4, regs_spill + 64
43 stqa $5, regs_spill + 80
44 stqa $6, regs_spill + 96
45 stqa $7, regs_spill + 112
46 stqa $8, regs_spill + 128
47 stqa $9, regs_spill + 144
48 stqa $10, regs_spill + 160
49 stqa $11, regs_spill + 176
50 stqa $12, regs_spill + 192
51 stqa $13, regs_spill + 208
52 stqa $14, regs_spill + 224
53 stqa $15, regs_spill + 240
54
55 /* SPU Context Save, Step 8: Save the remaining 112 GPRs. */
56 ila $3, regs_spill + 256
57save_regs:
58 lqr $4, save_reg_insts
59save_reg_loop:
60 ai $4, $4, 4
61 .balignl 16, 0x40200000
62save_reg_insts: /* must be quad-word aligned. */
63 stqd $16, 0($3)
64 stqd $17, 16($3)
65 stqd $18, 32($3)
66 stqd $19, 48($3)
67 andi $5, $4, 0x7F
68 stqr $4, save_reg_insts
69 ai $3, $3, 64
70 brnz $5, save_reg_loop
71
72 /* Initialize the stack pointer to point to 16368
73 * (16kb-16). The back chain pointer is initialized
74 * to NULL.
75 */
76 il $0, 0
77 il $SP, 16368
78 stqd $0, 0($SP)
79
80 /* Allocate a minimum stack frame for the called main.
81 * This is needed so that main has a place to save the
82 * link register when it calls another function.
83 */
84 stqd $SP, -160($SP)
85 ai $SP, $SP, -160
86
87 /* Call the program's main function. */
88 brsl $0, main
89
90 /* In this case main should not return; if it does
91 * there has been an error in the sequence. Execute
92 * stop-and-signal with code=0.
93 */
94.global exit
95.global _exit
96exit:
97_exit:
98 stop 0x0
99
100 /* Pad the size of this crt0.o to be multiple of 16 bytes. */
101.balignl 16, 0x0
102
diff --git a/arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped b/arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped
new file mode 100644
index 000000000000..39e54003f1df
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped
@@ -0,0 +1,191 @@
1/*
2 * spu_save_dump.h: Copyright (C) 2005 IBM.
3 * Hex-dump auto generated from spu_save.c.
4 * Do not edit!
5 */
6static unsigned int spu_save_code[] __page_aligned = {
70x20805000, 0x20805201, 0x20805402, 0x20805603,
80x20805804, 0x20805a05, 0x20805c06, 0x20805e07,
90x20806008, 0x20806209, 0x2080640a, 0x2080660b,
100x2080680c, 0x20806a0d, 0x20806c0e, 0x20806e0f,
110x4201c003, 0x33800184, 0x1c010204, 0x40200000,
120x24000190, 0x24004191, 0x24008192, 0x2400c193,
130x141fc205, 0x23fffd84, 0x1c100183, 0x217ffb85,
140x40800000, 0x409ff801, 0x24000080, 0x24fd8081,
150x1cd80081, 0x33000180, 0x00000000, 0x00000000,
160x01a00182, 0x3ec00083, 0xb1c38103, 0x01a00204,
170x3ec10082, 0x4201400d, 0xb1c38202, 0x01a00583,
180x34218682, 0x3ed80684, 0xb0408184, 0x24218682,
190x01a00603, 0x00200000, 0x34214682, 0x3ed40684,
200xb0408184, 0x40800003, 0x24214682, 0x21a00083,
210x40800082, 0x21a00b02, 0x4020007f, 0x1000251e,
220x40a80002, 0x32800008, 0x4205c00c, 0x00200000,
230x40a0000b, 0x3f82070f, 0x4080020a, 0x40800709,
240x3fe3078f, 0x3fbf0783, 0x3f200183, 0x3fbe0183,
250x3fe30187, 0x18008387, 0x4205c002, 0x3ac30404,
260x1cffc489, 0x00200000, 0x18008403, 0x38830402,
270x4cffc486, 0x3ac28185, 0xb0408584, 0x28830402,
280x1c020408, 0x38828182, 0xb0408385, 0x1802c387,
290x28828182, 0x217ff886, 0x04000582, 0x32800007,
300x21a00802, 0x3fbf0705, 0x3f200285, 0x3fbe0285,
310x3fe30285, 0x21a00885, 0x04000603, 0x21a00903,
320x40803c02, 0x21a00982, 0x04000386, 0x21a00a06,
330x40801202, 0x21a00a82, 0x73000003, 0x24200683,
340x01a00404, 0x00200000, 0x34204682, 0x3ec40683,
350xb0408203, 0x24204682, 0x01a00783, 0x00200000,
360x3421c682, 0x3edc0684, 0xb0408184, 0x2421c682,
370x21a00806, 0x21a00885, 0x3fbf0784, 0x3f200204,
380x3fbe0204, 0x3fe30204, 0x21a00904, 0x40804002,
390x21a00982, 0x21a00a06, 0x40805a02, 0x21a00a82,
400x04000683, 0x21a00803, 0x21a00885, 0x21a00904,
410x40848002, 0x21a00982, 0x21a00a06, 0x40801002,
420x21a00a82, 0x21a00a06, 0x40806602, 0x00200000,
430x35800009, 0x21a00a82, 0x40800083, 0x21a00b83,
440x01a00c02, 0x01a00d83, 0x00003ffb, 0x40800003,
450x4020007f, 0x35000000, 0x00000000, 0x00000000,
460x00000000, 0x00000000, 0x00000000, 0x00000000,
470x00000000, 0x00000000, 0x00000000, 0x00000000,
480x00000000, 0x00000000, 0x00000000, 0x00000000,
490x00000000, 0x00000000, 0x00000000, 0x00000000,
500x00000000, 0x00000000, 0x00000000, 0x00000000,
510x00000000, 0x00000000, 0x00000000, 0x00000000,
520x00000000, 0x00000000, 0x00000000, 0x00000000,
530x00000000, 0x00000000, 0x00000000, 0x00000000,
540x00000000, 0x00000000, 0x00000000, 0x00000000,
550x00000000, 0x00000000, 0x00000000, 0x00000000,
560x00000000, 0x00000000, 0x00000000, 0x00000000,
570x00000000, 0x00000000, 0x00000000, 0x00000000,
580x00000000, 0x00000000, 0x00000000, 0x00000000,
590x00000000, 0x00000000, 0x00000000, 0x00000000,
600x00000000, 0x00000000, 0x00000000, 0x00000000,
610x00000000, 0x00000000, 0x00000000, 0x00000000,
620x00000000, 0x00000000, 0x00000000, 0x00000000,
630x00000000, 0x00000000, 0x00000000, 0x00000000,
640x00000000, 0x00000000, 0x00000000, 0x00000000,
650x00000000, 0x00000000, 0x00000000, 0x00000000,
660x00000000, 0x00000000, 0x00000000, 0x00000000,
670x00000000, 0x00000000, 0x00000000, 0x00000000,
680x00000000, 0x00000000, 0x00000000, 0x00000000,
690x00000000, 0x00000000, 0x00000000, 0x00000000,
700x00000000, 0x00000000, 0x00000000, 0x00000000,
710x00000000, 0x00000000, 0x00000000, 0x00000000,
720x00000000, 0x00000000, 0x00000000, 0x00000000,
730x00000000, 0x00000000, 0x00000000, 0x00000000,
740x00000000, 0x00000000, 0x00000000, 0x00000000,
750x00000000, 0x00000000, 0x00000000, 0x00000000,
760x00000000, 0x00000000, 0x00000000, 0x00000000,
770x00000000, 0x00000000, 0x00000000, 0x00000000,
780x00000000, 0x00000000, 0x00000000, 0x00000000,
790x00000000, 0x00000000, 0x00000000, 0x00000000,
800x00000000, 0x00000000, 0x00000000, 0x00000000,
810x00000000, 0x00000000, 0x00000000, 0x00000000,
820x00000000, 0x00000000, 0x00000000, 0x00000000,
830x00000000, 0x00000000, 0x00000000, 0x00000000,
840x00000000, 0x00000000, 0x00000000, 0x00000000,
850x00000000, 0x00000000, 0x00000000, 0x00000000,
860x00000000, 0x00000000, 0x00000000, 0x00000000,
870x00000000, 0x00000000, 0x00000000, 0x00000000,
880x00000000, 0x00000000, 0x00000000, 0x00000000,
890x00000000, 0x00000000, 0x00000000, 0x00000000,
900x00000000, 0x00000000, 0x00000000, 0x00000000,
910x00000000, 0x00000000, 0x00000000, 0x00000000,
920x00000000, 0x00000000, 0x00000000, 0x00000000,
930x00000000, 0x00000000, 0x00000000, 0x00000000,
940x00000000, 0x00000000, 0x00000000, 0x00000000,
950x00000000, 0x00000000, 0x00000000, 0x00000000,
960x00000000, 0x00000000, 0x00000000, 0x00000000,
970x00000000, 0x00000000, 0x00000000, 0x00000000,
980x00000000, 0x00000000, 0x00000000, 0x00000000,
990x00000000, 0x00000000, 0x00000000, 0x00000000,
1000x00000000, 0x00000000, 0x00000000, 0x00000000,
1010x00000000, 0x00000000, 0x00000000, 0x00000000,
1020x00000000, 0x00000000, 0x00000000, 0x00000000,
1030x00000000, 0x00000000, 0x00000000, 0x00000000,
1040x00000000, 0x00000000, 0x00000000, 0x00000000,
1050x00000000, 0x00000000, 0x00000000, 0x00000000,
1060x00000000, 0x00000000, 0x00000000, 0x00000000,
1070x00000000, 0x00000000, 0x00000000, 0x00000000,
1080x00000000, 0x00000000, 0x00000000, 0x00000000,
1090x00000000, 0x00000000, 0x00000000, 0x00000000,
1100x00000000, 0x00000000, 0x00000000, 0x00000000,
1110x00000000, 0x00000000, 0x00000000, 0x00000000,
1120x00000000, 0x00000000, 0x00000000, 0x00000000,
1130x00000000, 0x00000000, 0x00000000, 0x00000000,
1140x00000000, 0x00000000, 0x00000000, 0x00000000,
1150x00000000, 0x00000000, 0x00000000, 0x00000000,
1160x00000000, 0x00000000, 0x00000000, 0x00000000,
1170x00000000, 0x00000000, 0x00000000, 0x00000000,
1180x00000000, 0x00000000, 0x00000000, 0x00000000,
1190x00000000, 0x00000000, 0x00000000, 0x00000000,
1200x00000000, 0x00000000, 0x00000000, 0x00000000,
1210x00000000, 0x00000000, 0x00000000, 0x00000000,
1220x00000000, 0x00000000, 0x00000000, 0x00000000,
1230x00000000, 0x00000000, 0x00000000, 0x00000000,
1240x00000000, 0x00000000, 0x00000000, 0x00000000,
1250x00000000, 0x00000000, 0x00000000, 0x00000000,
1260x00000000, 0x00000000, 0x00000000, 0x00000000,
1270x00000000, 0x00000000, 0x00000000, 0x00000000,
1280x00000000, 0x00000000, 0x00000000, 0x00000000,
1290x00000000, 0x00000000, 0x00000000, 0x00000000,
1300x00000000, 0x00000000, 0x00000000, 0x00000000,
1310x00000000, 0x00000000, 0x00000000, 0x00000000,
1320x00000000, 0x00000000, 0x00000000, 0x00000000,
1330x00000000, 0x00000000, 0x00000000, 0x00000000,
1340x00000000, 0x00000000, 0x00000000, 0x00000000,
1350x00000000, 0x00000000, 0x00000000, 0x00000000,
1360x00000000, 0x00000000, 0x00000000, 0x00000000,
1370x00000000, 0x00000000, 0x00000000, 0x00000000,
1380x00000000, 0x00000000, 0x00000000, 0x00000000,
1390x00000000, 0x00000000, 0x00000000, 0x00000000,
1400x00000000, 0x00000000, 0x00000000, 0x00000000,
1410x00000000, 0x00000000, 0x00000000, 0x00000000,
1420x00000000, 0x00000000, 0x00000000, 0x00000000,
1430x00000000, 0x00000000, 0x00000000, 0x00000000,
1440x00000000, 0x00000000, 0x00000000, 0x00000000,
1450x00000000, 0x00000000, 0x00000000, 0x00000000,
1460x00000000, 0x00000000, 0x00000000, 0x00000000,
1470x00000000, 0x00000000, 0x00000000, 0x00000000,
1480x00000000, 0x00000000, 0x00000000, 0x00000000,
1490x00000000, 0x00000000, 0x00000000, 0x00000000,
1500x00000000, 0x00000000, 0x00000000, 0x00000000,
1510x00000000, 0x00000000, 0x00000000, 0x00000000,
1520x00000000, 0x00000000, 0x00000000, 0x00000000,
1530x00000000, 0x00000000, 0x00000000, 0x00000000,
1540x00000000, 0x00000000, 0x00000000, 0x00000000,
1550x00000000, 0x00000000, 0x00000000, 0x00000000,
1560x00000000, 0x00000000, 0x00000000, 0x00000000,
1570x00000000, 0x00000000, 0x00000000, 0x00000000,
1580x00000000, 0x00000000, 0x00000000, 0x00000000,
1590x00000000, 0x00000000, 0x00000000, 0x00000000,
1600x00000000, 0x00000000, 0x00000000, 0x00000000,
1610x00000000, 0x00000000, 0x00000000, 0x00000000,
1620x00000000, 0x00000000, 0x00000000, 0x00000000,
1630x00000000, 0x00000000, 0x00000000, 0x00000000,
1640x00000000, 0x00000000, 0x00000000, 0x00000000,
1650x00000000, 0x00000000, 0x00000000, 0x00000000,
1660x00000000, 0x00000000, 0x00000000, 0x00000000,
1670x00000000, 0x00000000, 0x00000000, 0x00000000,
1680x00000000, 0x00000000, 0x00000000, 0x00000000,
1690x00000000, 0x00000000, 0x00000000, 0x00000000,
1700x00000000, 0x00000000, 0x00000000, 0x00000000,
1710x00000000, 0x00000000, 0x00000000, 0x00000000,
1720x00000000, 0x00000000, 0x00000000, 0x00000000,
1730x00000000, 0x00000000, 0x00000000, 0x00000000,
1740x00000000, 0x00000000, 0x00000000, 0x00000000,
1750x00000000, 0x00000000, 0x00000000, 0x00000000,
1760x00000000, 0x00000000, 0x00000000, 0x00000000,
1770x00000000, 0x00000000, 0x00000000, 0x00000000,
1780x00000000, 0x00000000, 0x00000000, 0x00000000,
1790x00000000, 0x00000000, 0x00000000, 0x00000000,
1800x00000000, 0x00000000, 0x00000000, 0x00000000,
1810x00000000, 0x00000000, 0x00000000, 0x00000000,
1820x00000000, 0x00000000, 0x00000000, 0x00000000,
1830x00000000, 0x00000000, 0x00000000, 0x00000000,
1840x00000000, 0x00000000, 0x00000000, 0x00000000,
1850x00000000, 0x00000000, 0x00000000, 0x00000000,
1860x00000000, 0x00000000, 0x00000000, 0x00000000,
1870x00000000, 0x00000000, 0x00000000, 0x00000000,
1880x00000000, 0x00000000, 0x00000000, 0x00000000,
1890x00000000, 0x00000000, 0x00000000, 0x00000000,
1900x00000000, 0x00000000, 0x00000000, 0x00000000,
191};
diff --git a/arch/powerpc/platforms/cell/spufs/spu_utils.h b/arch/powerpc/platforms/cell/spufs/spu_utils.h
new file mode 100644
index 000000000000..58359feb6c95
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/spu_utils.h
@@ -0,0 +1,160 @@
1/*
2 * utils.h: Utilities for SPU-side of the context switch operation.
3 *
4 * (C) Copyright IBM 2005
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, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef _SPU_CONTEXT_UTILS_H_
22#define _SPU_CONTEXT_UTILS_H_
23
24/*
25 * 64-bit safe EA.
26 */
27typedef union {
28 unsigned long long ull;
29 unsigned int ui[2];
30} addr64;
31
32/*
33 * 128-bit register template.
34 */
35typedef union {
36 unsigned int slot[4];
37 vector unsigned int v;
38} spu_reg128v;
39
40/*
41 * DMA list structure.
42 */
43struct dma_list_elem {
44 unsigned int size;
45 unsigned int ea_low;
46};
47
48/*
49 * Declare storage for 8-byte aligned DMA list.
50 */
51struct dma_list_elem dma_list[15] __attribute__ ((aligned(8)));
52
53/*
54 * External definition for storage
55 * declared in crt0.
56 */
57extern spu_reg128v regs_spill[NR_SPU_SPILL_REGS];
58
59/*
60 * Compute LSCSA byte offset for a given field.
61 */
62static struct spu_lscsa *dummy = (struct spu_lscsa *)0;
63#define LSCSA_BYTE_OFFSET(_field) \
64 ((char *)(&(dummy->_field)) - (char *)(&(dummy->gprs[0].slot[0])))
65#define LSCSA_QW_OFFSET(_field) (LSCSA_BYTE_OFFSET(_field) >> 4)
66
67static inline void set_event_mask(void)
68{
69 unsigned int event_mask = 0;
70
71 /* Save, Step 4:
72 * Restore, Step 1:
73 * Set the SPU_RdEventMsk channel to zero to mask
74 * all events.
75 */
76 spu_writech(SPU_WrEventMask, event_mask);
77}
78
79static inline void set_tag_mask(void)
80{
81 unsigned int tag_mask = 1;
82
83 /* Save, Step 5:
84 * Restore, Step 2:
85 * Set the SPU_WrTagMsk channel to '01' to unmask
86 * only tag group 0.
87 */
88 spu_writech(MFC_WrTagMask, tag_mask);
89}
90
91static inline void build_dma_list(addr64 lscsa_ea)
92{
93 unsigned int ea_low;
94 int i;
95
96 /* Save, Step 6:
97 * Restore, Step 3:
98 * Update the effective address for the CSA in the
99 * pre-canned DMA-list in local storage.
100 */
101 ea_low = lscsa_ea.ui[1];
102 ea_low += LSCSA_BYTE_OFFSET(ls[16384]);
103
104 for (i = 0; i < 15; i++, ea_low += 16384) {
105 dma_list[i].size = 16384;
106 dma_list[i].ea_low = ea_low;
107 }
108}
109
110static inline void enqueue_putllc(addr64 lscsa_ea)
111{
112 unsigned int ls = 0;
113 unsigned int size = 128;
114 unsigned int tag_id = 0;
115 unsigned int cmd = 0xB4; /* PUTLLC */
116
117 /* Save, Step 12:
118 * Restore, Step 7:
119 * Send a PUTLLC (tag 0) command to the MFC using
120 * an effective address in the CSA in order to
121 * remove any possible lock-line reservation.
122 */
123 spu_writech(MFC_LSA, ls);
124 spu_writech(MFC_EAH, lscsa_ea.ui[0]);
125 spu_writech(MFC_EAL, lscsa_ea.ui[1]);
126 spu_writech(MFC_Size, size);
127 spu_writech(MFC_TagID, tag_id);
128 spu_writech(MFC_Cmd, cmd);
129}
130
131static inline void set_tag_update(void)
132{
133 unsigned int update_any = 1;
134
135 /* Save, Step 15:
136 * Restore, Step 8:
137 * Write the MFC_TagUpdate channel with '01'.
138 */
139 spu_writech(MFC_WrTagUpdate, update_any);
140}
141
142static inline void read_tag_status(void)
143{
144 /* Save, Step 16:
145 * Restore, Step 9:
146 * Read the MFC_TagStat channel data.
147 */
148 spu_readch(MFC_RdTagStat);
149}
150
151static inline void read_llar_status(void)
152{
153 /* Save, Step 17:
154 * Restore, Step 10:
155 * Read the MFC_AtomicStat channel data.
156 */
157 spu_readch(MFC_RdAtomicStat);
158}
159
160#endif /* _SPU_CONTEXT_UTILS_H_ */
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
new file mode 100644
index 000000000000..db2601f0abd5
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -0,0 +1,163 @@
1/*
2 * SPU file system
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 *
6 * Author: Arnd Bergmann <arndb@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22#ifndef SPUFS_H
23#define SPUFS_H
24
25#include <linux/kref.h>
26#include <linux/rwsem.h>
27#include <linux/spinlock.h>
28#include <linux/fs.h>
29
30#include <asm/spu.h>
31#include <asm/spu_csa.h>
32
33/* The magic number for our file system */
34enum {
35 SPUFS_MAGIC = 0x23c9b64e,
36};
37
38struct spu_context_ops;
39
40#define SPU_CONTEXT_PREEMPT 0UL
41
42struct spu_context {
43 struct spu *spu; /* pointer to a physical SPU */
44 struct spu_state csa; /* SPU context save area. */
45 spinlock_t mmio_lock; /* protects mmio access */
46 struct address_space *local_store;/* local store backing store */
47
48 enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
49 struct rw_semaphore state_sema;
50 struct semaphore run_sema;
51
52 struct mm_struct *owner;
53
54 struct kref kref;
55 wait_queue_head_t ibox_wq;
56 wait_queue_head_t wbox_wq;
57 wait_queue_head_t stop_wq;
58 struct fasync_struct *ibox_fasync;
59 struct fasync_struct *wbox_fasync;
60 struct spu_context_ops *ops;
61 struct work_struct reap_work;
62 u64 flags;
63};
64
65/* SPU context query/set operations. */
66struct spu_context_ops {
67 int (*mbox_read) (struct spu_context * ctx, u32 * data);
68 u32(*mbox_stat_read) (struct spu_context * ctx);
69 unsigned int (*mbox_stat_poll)(struct spu_context *ctx,
70 unsigned int events);
71 int (*ibox_read) (struct spu_context * ctx, u32 * data);
72 int (*wbox_write) (struct spu_context * ctx, u32 data);
73 u32(*signal1_read) (struct spu_context * ctx);
74 void (*signal1_write) (struct spu_context * ctx, u32 data);
75 u32(*signal2_read) (struct spu_context * ctx);
76 void (*signal2_write) (struct spu_context * ctx, u32 data);
77 void (*signal1_type_set) (struct spu_context * ctx, u64 val);
78 u64(*signal1_type_get) (struct spu_context * ctx);
79 void (*signal2_type_set) (struct spu_context * ctx, u64 val);
80 u64(*signal2_type_get) (struct spu_context * ctx);
81 u32(*npc_read) (struct spu_context * ctx);
82 void (*npc_write) (struct spu_context * ctx, u32 data);
83 u32(*status_read) (struct spu_context * ctx);
84 char*(*get_ls) (struct spu_context * ctx);
85 void (*runcntl_write) (struct spu_context * ctx, u32 data);
86 void (*runcntl_stop) (struct spu_context * ctx);
87};
88
89extern struct spu_context_ops spu_hw_ops;
90extern struct spu_context_ops spu_backing_ops;
91
92struct spufs_inode_info {
93 struct spu_context *i_ctx;
94 struct inode vfs_inode;
95};
96#define SPUFS_I(inode) \
97 container_of(inode, struct spufs_inode_info, vfs_inode)
98
99extern struct tree_descr spufs_dir_contents[];
100
101/* system call implementation */
102long spufs_run_spu(struct file *file,
103 struct spu_context *ctx, u32 *npc, u32 *status);
104long spufs_create_thread(struct nameidata *nd,
105 unsigned int flags, mode_t mode);
106extern struct file_operations spufs_context_fops;
107
108/* context management */
109struct spu_context * alloc_spu_context(struct address_space *local_store);
110void destroy_spu_context(struct kref *kref);
111struct spu_context * get_spu_context(struct spu_context *ctx);
112int put_spu_context(struct spu_context *ctx);
113void spu_unmap_mappings(struct spu_context *ctx);
114
115void spu_forget(struct spu_context *ctx);
116void spu_acquire(struct spu_context *ctx);
117void spu_release(struct spu_context *ctx);
118int spu_acquire_runnable(struct spu_context *ctx);
119void spu_acquire_saved(struct spu_context *ctx);
120
121int spu_activate(struct spu_context *ctx, u64 flags);
122void spu_deactivate(struct spu_context *ctx);
123void spu_yield(struct spu_context *ctx);
124int __init spu_sched_init(void);
125void __exit spu_sched_exit(void);
126
127/*
128 * spufs_wait
129 * Same as wait_event_interruptible(), except that here
130 * we need to call spu_release(ctx) before sleeping, and
131 * then spu_acquire(ctx) when awoken.
132 */
133
134#define spufs_wait(wq, condition) \
135({ \
136 int __ret = 0; \
137 DEFINE_WAIT(__wait); \
138 for (;;) { \
139 prepare_to_wait(&(wq), &__wait, TASK_INTERRUPTIBLE); \
140 if (condition) \
141 break; \
142 if (!signal_pending(current)) { \
143 spu_release(ctx); \
144 schedule(); \
145 spu_acquire(ctx); \
146 continue; \
147 } \
148 __ret = -ERESTARTSYS; \
149 break; \
150 } \
151 finish_wait(&(wq), &__wait); \
152 __ret; \
153})
154
155size_t spu_wbox_write(struct spu_context *ctx, u32 data);
156size_t spu_ibox_read(struct spu_context *ctx, u32 *data);
157
158/* irq callback funcs. */
159void spufs_ibox_callback(struct spu *spu);
160void spufs_wbox_callback(struct spu *spu);
161void spufs_stop_callback(struct spu *spu);
162
163#endif
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
new file mode 100644
index 000000000000..1061c12b2edb
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -0,0 +1,2180 @@
1/*
2 * spu_switch.c
3 *
4 * (C) Copyright IBM Corp. 2005
5 *
6 * Author: Mark Nutter <mnutter@us.ibm.com>
7 *
8 * Host-side part of SPU context switch sequence outlined in
9 * Synergistic Processor Element, Book IV.
10 *
11 * A fully premptive switch of an SPE is very expensive in terms
12 * of time and system resources. SPE Book IV indicates that SPE
13 * allocation should follow a "serially reusable device" model,
14 * in which the SPE is assigned a task until it completes. When
15 * this is not possible, this sequence may be used to premptively
16 * save, and then later (optionally) restore the context of a
17 * program executing on an SPE.
18 *
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2, or (at your option)
23 * any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 */
34
35#include <linux/config.h>
36#include <linux/module.h>
37#include <linux/errno.h>
38#include <linux/sched.h>
39#include <linux/kernel.h>
40#include <linux/mm.h>
41#include <linux/vmalloc.h>
42#include <linux/smp.h>
43#include <linux/smp_lock.h>
44#include <linux/stddef.h>
45#include <linux/unistd.h>
46
47#include <asm/io.h>
48#include <asm/spu.h>
49#include <asm/spu_csa.h>
50#include <asm/mmu_context.h>
51
52#include "spu_save_dump.h"
53#include "spu_restore_dump.h"
54
55#if 0
56#define POLL_WHILE_TRUE(_c) { \
57 do { \
58 } while (_c); \
59 }
60#else
61#define RELAX_SPIN_COUNT 1000
62#define POLL_WHILE_TRUE(_c) { \
63 do { \
64 int _i; \
65 for (_i=0; _i<RELAX_SPIN_COUNT && (_c); _i++) { \
66 cpu_relax(); \
67 } \
68 if (unlikely(_c)) yield(); \
69 else break; \
70 } while (_c); \
71 }
72#endif /* debug */
73
74#define POLL_WHILE_FALSE(_c) POLL_WHILE_TRUE(!(_c))
75
76static inline void acquire_spu_lock(struct spu *spu)
77{
78 /* Save, Step 1:
79 * Restore, Step 1:
80 * Acquire SPU-specific mutual exclusion lock.
81 * TBD.
82 */
83}
84
85static inline void release_spu_lock(struct spu *spu)
86{
87 /* Restore, Step 76:
88 * Release SPU-specific mutual exclusion lock.
89 * TBD.
90 */
91}
92
93static inline int check_spu_isolate(struct spu_state *csa, struct spu *spu)
94{
95 struct spu_problem __iomem *prob = spu->problem;
96 u32 isolate_state;
97
98 /* Save, Step 2:
99 * Save, Step 6:
100 * If SPU_Status[E,L,IS] any field is '1', this
101 * SPU is in isolate state and cannot be context
102 * saved at this time.
103 */
104 isolate_state = SPU_STATUS_ISOLATED_STATE |
105 SPU_STATUS_ISOLATED_LOAD_STAUTUS | SPU_STATUS_ISOLATED_EXIT_STAUTUS;
106 return (in_be32(&prob->spu_status_R) & isolate_state) ? 1 : 0;
107}
108
109static inline void disable_interrupts(struct spu_state *csa, struct spu *spu)
110{
111 /* Save, Step 3:
112 * Restore, Step 2:
113 * Save INT_Mask_class0 in CSA.
114 * Write INT_MASK_class0 with value of 0.
115 * Save INT_Mask_class1 in CSA.
116 * Write INT_MASK_class1 with value of 0.
117 * Save INT_Mask_class2 in CSA.
118 * Write INT_MASK_class2 with value of 0.
119 */
120 spin_lock_irq(&spu->register_lock);
121 if (csa) {
122 csa->priv1.int_mask_class0_RW = spu_int_mask_get(spu, 0);
123 csa->priv1.int_mask_class1_RW = spu_int_mask_get(spu, 1);
124 csa->priv1.int_mask_class2_RW = spu_int_mask_get(spu, 2);
125 }
126 spu_int_mask_set(spu, 0, 0ul);
127 spu_int_mask_set(spu, 1, 0ul);
128 spu_int_mask_set(spu, 2, 0ul);
129 eieio();
130 spin_unlock_irq(&spu->register_lock);
131}
132
133static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu)
134{
135 /* Save, Step 4:
136 * Restore, Step 25.
137 * Set a software watchdog timer, which specifies the
138 * maximum allowable time for a context save sequence.
139 *
140 * For present, this implementation will not set a global
141 * watchdog timer, as virtualization & variable system load
142 * may cause unpredictable execution times.
143 */
144}
145
146static inline void inhibit_user_access(struct spu_state *csa, struct spu *spu)
147{
148 /* Save, Step 5:
149 * Restore, Step 3:
150 * Inhibit user-space access (if provided) to this
151 * SPU by unmapping the virtual pages assigned to
152 * the SPU memory-mapped I/O (MMIO) for problem
153 * state. TBD.
154 */
155}
156
157static inline void set_switch_pending(struct spu_state *csa, struct spu *spu)
158{
159 /* Save, Step 7:
160 * Restore, Step 5:
161 * Set a software context switch pending flag.
162 */
163 set_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags);
164 mb();
165}
166
167static inline void save_mfc_cntl(struct spu_state *csa, struct spu *spu)
168{
169 struct spu_priv2 __iomem *priv2 = spu->priv2;
170
171 /* Save, Step 8:
172 * Read and save MFC_CNTL[Ss].
173 */
174 if (csa) {
175 csa->priv2.mfc_control_RW = in_be64(&priv2->mfc_control_RW) &
176 MFC_CNTL_SUSPEND_DMA_STATUS_MASK;
177 }
178}
179
180static inline void save_spu_runcntl(struct spu_state *csa, struct spu *spu)
181{
182 struct spu_problem __iomem *prob = spu->problem;
183
184 /* Save, Step 9:
185 * Save SPU_Runcntl in the CSA. This value contains
186 * the "Application Desired State".
187 */
188 csa->prob.spu_runcntl_RW = in_be32(&prob->spu_runcntl_RW);
189}
190
191static inline void save_mfc_sr1(struct spu_state *csa, struct spu *spu)
192{
193 /* Save, Step 10:
194 * Save MFC_SR1 in the CSA.
195 */
196 csa->priv1.mfc_sr1_RW = spu_mfc_sr1_get(spu);
197}
198
199static inline void save_spu_status(struct spu_state *csa, struct spu *spu)
200{
201 struct spu_problem __iomem *prob = spu->problem;
202
203 /* Save, Step 11:
204 * Read SPU_Status[R], and save to CSA.
205 */
206 if ((in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING) == 0) {
207 csa->prob.spu_status_R = in_be32(&prob->spu_status_R);
208 } else {
209 u32 stopped;
210
211 out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP);
212 eieio();
213 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) &
214 SPU_STATUS_RUNNING);
215 stopped =
216 SPU_STATUS_INVALID_INSTR | SPU_STATUS_SINGLE_STEP |
217 SPU_STATUS_STOPPED_BY_HALT | SPU_STATUS_STOPPED_BY_STOP;
218 if ((in_be32(&prob->spu_status_R) & stopped) == 0)
219 csa->prob.spu_status_R = SPU_STATUS_RUNNING;
220 else
221 csa->prob.spu_status_R = in_be32(&prob->spu_status_R);
222 }
223}
224
225static inline void save_mfc_decr(struct spu_state *csa, struct spu *spu)
226{
227 struct spu_priv2 __iomem *priv2 = spu->priv2;
228
229 /* Save, Step 12:
230 * Read MFC_CNTL[Ds]. Update saved copy of
231 * CSA.MFC_CNTL[Ds].
232 */
233 if (in_be64(&priv2->mfc_control_RW) & MFC_CNTL_DECREMENTER_RUNNING) {
234 csa->priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING;
235 csa->suspend_time = get_cycles();
236 out_be64(&priv2->spu_chnlcntptr_RW, 7ULL);
237 eieio();
238 csa->spu_chnldata_RW[7] = in_be64(&priv2->spu_chnldata_RW);
239 eieio();
240 }
241}
242
243static inline void halt_mfc_decr(struct spu_state *csa, struct spu *spu)
244{
245 struct spu_priv2 __iomem *priv2 = spu->priv2;
246
247 /* Save, Step 13:
248 * Write MFC_CNTL[Dh] set to a '1' to halt
249 * the decrementer.
250 */
251 out_be64(&priv2->mfc_control_RW, MFC_CNTL_DECREMENTER_HALTED);
252 eieio();
253}
254
255static inline void save_timebase(struct spu_state *csa, struct spu *spu)
256{
257 /* Save, Step 14:
258 * Read PPE Timebase High and Timebase low registers
259 * and save in CSA. TBD.
260 */
261 csa->suspend_time = get_cycles();
262}
263
264static inline void remove_other_spu_access(struct spu_state *csa,
265 struct spu *spu)
266{
267 /* Save, Step 15:
268 * Remove other SPU access to this SPU by unmapping
269 * this SPU's pages from their address space. TBD.
270 */
271}
272
273static inline void do_mfc_mssync(struct spu_state *csa, struct spu *spu)
274{
275 struct spu_problem __iomem *prob = spu->problem;
276
277 /* Save, Step 16:
278 * Restore, Step 11.
279 * Write SPU_MSSync register. Poll SPU_MSSync[P]
280 * for a value of 0.
281 */
282 out_be64(&prob->spc_mssync_RW, 1UL);
283 POLL_WHILE_TRUE(in_be64(&prob->spc_mssync_RW) & MS_SYNC_PENDING);
284}
285
286static inline void issue_mfc_tlbie(struct spu_state *csa, struct spu *spu)
287{
288 /* Save, Step 17:
289 * Restore, Step 12.
290 * Restore, Step 48.
291 * Write TLB_Invalidate_Entry[IS,VPN,L,Lp]=0 register.
292 * Then issue a PPE sync instruction.
293 */
294 spu_tlb_invalidate(spu);
295 mb();
296}
297
298static inline void handle_pending_interrupts(struct spu_state *csa,
299 struct spu *spu)
300{
301 /* Save, Step 18:
302 * Handle any pending interrupts from this SPU
303 * here. This is OS or hypervisor specific. One
304 * option is to re-enable interrupts to handle any
305 * pending interrupts, with the interrupt handlers
306 * recognizing the software Context Switch Pending
307 * flag, to ensure the SPU execution or MFC command
308 * queue is not restarted. TBD.
309 */
310}
311
312static inline void save_mfc_queues(struct spu_state *csa, struct spu *spu)
313{
314 struct spu_priv2 __iomem *priv2 = spu->priv2;
315 int i;
316
317 /* Save, Step 19:
318 * If MFC_Cntl[Se]=0 then save
319 * MFC command queues.
320 */
321 if ((in_be64(&priv2->mfc_control_RW) & MFC_CNTL_DMA_QUEUES_EMPTY) == 0) {
322 for (i = 0; i < 8; i++) {
323 csa->priv2.puq[i].mfc_cq_data0_RW =
324 in_be64(&priv2->puq[i].mfc_cq_data0_RW);
325 csa->priv2.puq[i].mfc_cq_data1_RW =
326 in_be64(&priv2->puq[i].mfc_cq_data1_RW);
327 csa->priv2.puq[i].mfc_cq_data2_RW =
328 in_be64(&priv2->puq[i].mfc_cq_data2_RW);
329 csa->priv2.puq[i].mfc_cq_data3_RW =
330 in_be64(&priv2->puq[i].mfc_cq_data3_RW);
331 }
332 for (i = 0; i < 16; i++) {
333 csa->priv2.spuq[i].mfc_cq_data0_RW =
334 in_be64(&priv2->spuq[i].mfc_cq_data0_RW);
335 csa->priv2.spuq[i].mfc_cq_data1_RW =
336 in_be64(&priv2->spuq[i].mfc_cq_data1_RW);
337 csa->priv2.spuq[i].mfc_cq_data2_RW =
338 in_be64(&priv2->spuq[i].mfc_cq_data2_RW);
339 csa->priv2.spuq[i].mfc_cq_data3_RW =
340 in_be64(&priv2->spuq[i].mfc_cq_data3_RW);
341 }
342 }
343}
344
345static inline void save_ppu_querymask(struct spu_state *csa, struct spu *spu)
346{
347 struct spu_problem __iomem *prob = spu->problem;
348
349 /* Save, Step 20:
350 * Save the PPU_QueryMask register
351 * in the CSA.
352 */
353 csa->prob.dma_querymask_RW = in_be32(&prob->dma_querymask_RW);
354}
355
356static inline void save_ppu_querytype(struct spu_state *csa, struct spu *spu)
357{
358 struct spu_problem __iomem *prob = spu->problem;
359
360 /* Save, Step 21:
361 * Save the PPU_QueryType register
362 * in the CSA.
363 */
364 csa->prob.dma_querytype_RW = in_be32(&prob->dma_querytype_RW);
365}
366
367static inline void save_mfc_csr_tsq(struct spu_state *csa, struct spu *spu)
368{
369 struct spu_priv2 __iomem *priv2 = spu->priv2;
370
371 /* Save, Step 22:
372 * Save the MFC_CSR_TSQ register
373 * in the LSCSA.
374 */
375 csa->priv2.spu_tag_status_query_RW =
376 in_be64(&priv2->spu_tag_status_query_RW);
377}
378
379static inline void save_mfc_csr_cmd(struct spu_state *csa, struct spu *spu)
380{
381 struct spu_priv2 __iomem *priv2 = spu->priv2;
382
383 /* Save, Step 23:
384 * Save the MFC_CSR_CMD1 and MFC_CSR_CMD2
385 * registers in the CSA.
386 */
387 csa->priv2.spu_cmd_buf1_RW = in_be64(&priv2->spu_cmd_buf1_RW);
388 csa->priv2.spu_cmd_buf2_RW = in_be64(&priv2->spu_cmd_buf2_RW);
389}
390
391static inline void save_mfc_csr_ato(struct spu_state *csa, struct spu *spu)
392{
393 struct spu_priv2 __iomem *priv2 = spu->priv2;
394
395 /* Save, Step 24:
396 * Save the MFC_CSR_ATO register in
397 * the CSA.
398 */
399 csa->priv2.spu_atomic_status_RW = in_be64(&priv2->spu_atomic_status_RW);
400}
401
402static inline void save_mfc_tclass_id(struct spu_state *csa, struct spu *spu)
403{
404 /* Save, Step 25:
405 * Save the MFC_TCLASS_ID register in
406 * the CSA.
407 */
408 csa->priv1.mfc_tclass_id_RW = spu_mfc_tclass_id_get(spu);
409}
410
411static inline void set_mfc_tclass_id(struct spu_state *csa, struct spu *spu)
412{
413 /* Save, Step 26:
414 * Restore, Step 23.
415 * Write the MFC_TCLASS_ID register with
416 * the value 0x10000000.
417 */
418 spu_mfc_tclass_id_set(spu, 0x10000000);
419 eieio();
420}
421
422static inline void purge_mfc_queue(struct spu_state *csa, struct spu *spu)
423{
424 struct spu_priv2 __iomem *priv2 = spu->priv2;
425
426 /* Save, Step 27:
427 * Restore, Step 14.
428 * Write MFC_CNTL[Pc]=1 (purge queue).
429 */
430 out_be64(&priv2->mfc_control_RW, MFC_CNTL_PURGE_DMA_REQUEST);
431 eieio();
432}
433
434static inline void wait_purge_complete(struct spu_state *csa, struct spu *spu)
435{
436 struct spu_priv2 __iomem *priv2 = spu->priv2;
437
438 /* Save, Step 28:
439 * Poll MFC_CNTL[Ps] until value '11' is read
440 * (purge complete).
441 */
442 POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) &
443 MFC_CNTL_PURGE_DMA_COMPLETE);
444}
445
446static inline void save_mfc_slbs(struct spu_state *csa, struct spu *spu)
447{
448 struct spu_priv2 __iomem *priv2 = spu->priv2;
449 int i;
450
451 /* Save, Step 29:
452 * If MFC_SR1[R]='1', save SLBs in CSA.
453 */
454 if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) {
455 csa->priv2.slb_index_W = in_be64(&priv2->slb_index_W);
456 for (i = 0; i < 8; i++) {
457 out_be64(&priv2->slb_index_W, i);
458 eieio();
459 csa->slb_esid_RW[i] = in_be64(&priv2->slb_esid_RW);
460 csa->slb_vsid_RW[i] = in_be64(&priv2->slb_vsid_RW);
461 eieio();
462 }
463 }
464}
465
466static inline void setup_mfc_sr1(struct spu_state *csa, struct spu *spu)
467{
468 /* Save, Step 30:
469 * Restore, Step 18:
470 * Write MFC_SR1 with MFC_SR1[D=0,S=1] and
471 * MFC_SR1[TL,R,Pr,T] set correctly for the
472 * OS specific environment.
473 *
474 * Implementation note: The SPU-side code
475 * for save/restore is privileged, so the
476 * MFC_SR1[Pr] bit is not set.
477 *
478 */
479 spu_mfc_sr1_set(spu, (MFC_STATE1_MASTER_RUN_CONTROL_MASK |
480 MFC_STATE1_RELOCATE_MASK |
481 MFC_STATE1_BUS_TLBIE_MASK));
482}
483
484static inline void save_spu_npc(struct spu_state *csa, struct spu *spu)
485{
486 struct spu_problem __iomem *prob = spu->problem;
487
488 /* Save, Step 31:
489 * Save SPU_NPC in the CSA.
490 */
491 csa->prob.spu_npc_RW = in_be32(&prob->spu_npc_RW);
492}
493
494static inline void save_spu_privcntl(struct spu_state *csa, struct spu *spu)
495{
496 struct spu_priv2 __iomem *priv2 = spu->priv2;
497
498 /* Save, Step 32:
499 * Save SPU_PrivCntl in the CSA.
500 */
501 csa->priv2.spu_privcntl_RW = in_be64(&priv2->spu_privcntl_RW);
502}
503
504static inline void reset_spu_privcntl(struct spu_state *csa, struct spu *spu)
505{
506 struct spu_priv2 __iomem *priv2 = spu->priv2;
507
508 /* Save, Step 33:
509 * Restore, Step 16:
510 * Write SPU_PrivCntl[S,Le,A] fields reset to 0.
511 */
512 out_be64(&priv2->spu_privcntl_RW, 0UL);
513 eieio();
514}
515
516static inline void save_spu_lslr(struct spu_state *csa, struct spu *spu)
517{
518 struct spu_priv2 __iomem *priv2 = spu->priv2;
519
520 /* Save, Step 34:
521 * Save SPU_LSLR in the CSA.
522 */
523 csa->priv2.spu_lslr_RW = in_be64(&priv2->spu_lslr_RW);
524}
525
526static inline void reset_spu_lslr(struct spu_state *csa, struct spu *spu)
527{
528 struct spu_priv2 __iomem *priv2 = spu->priv2;
529
530 /* Save, Step 35:
531 * Restore, Step 17.
532 * Reset SPU_LSLR.
533 */
534 out_be64(&priv2->spu_lslr_RW, LS_ADDR_MASK);
535 eieio();
536}
537
538static inline void save_spu_cfg(struct spu_state *csa, struct spu *spu)
539{
540 struct spu_priv2 __iomem *priv2 = spu->priv2;
541
542 /* Save, Step 36:
543 * Save SPU_Cfg in the CSA.
544 */
545 csa->priv2.spu_cfg_RW = in_be64(&priv2->spu_cfg_RW);
546}
547
548static inline void save_pm_trace(struct spu_state *csa, struct spu *spu)
549{
550 /* Save, Step 37:
551 * Save PM_Trace_Tag_Wait_Mask in the CSA.
552 * Not performed by this implementation.
553 */
554}
555
556static inline void save_mfc_rag(struct spu_state *csa, struct spu *spu)
557{
558 /* Save, Step 38:
559 * Save RA_GROUP_ID register and the
560 * RA_ENABLE reigster in the CSA.
561 */
562 csa->priv1.resource_allocation_groupID_RW =
563 spu_resource_allocation_groupID_get(spu);
564 csa->priv1.resource_allocation_enable_RW =
565 spu_resource_allocation_enable_get(spu);
566}
567
568static inline void save_ppu_mb_stat(struct spu_state *csa, struct spu *spu)
569{
570 struct spu_problem __iomem *prob = spu->problem;
571
572 /* Save, Step 39:
573 * Save MB_Stat register in the CSA.
574 */
575 csa->prob.mb_stat_R = in_be32(&prob->mb_stat_R);
576}
577
578static inline void save_ppu_mb(struct spu_state *csa, struct spu *spu)
579{
580 struct spu_problem __iomem *prob = spu->problem;
581
582 /* Save, Step 40:
583 * Save the PPU_MB register in the CSA.
584 */
585 csa->prob.pu_mb_R = in_be32(&prob->pu_mb_R);
586}
587
588static inline void save_ppuint_mb(struct spu_state *csa, struct spu *spu)
589{
590 struct spu_priv2 __iomem *priv2 = spu->priv2;
591
592 /* Save, Step 41:
593 * Save the PPUINT_MB register in the CSA.
594 */
595 csa->priv2.puint_mb_R = in_be64(&priv2->puint_mb_R);
596}
597
598static inline void save_ch_part1(struct spu_state *csa, struct spu *spu)
599{
600 struct spu_priv2 __iomem *priv2 = spu->priv2;
601 u64 idx, ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL };
602 int i;
603
604 /* Save, Step 42:
605 * Save the following CH: [0,1,3,4,24,25,27]
606 */
607 for (i = 0; i < 7; i++) {
608 idx = ch_indices[i];
609 out_be64(&priv2->spu_chnlcntptr_RW, idx);
610 eieio();
611 csa->spu_chnldata_RW[idx] = in_be64(&priv2->spu_chnldata_RW);
612 csa->spu_chnlcnt_RW[idx] = in_be64(&priv2->spu_chnlcnt_RW);
613 out_be64(&priv2->spu_chnldata_RW, 0UL);
614 out_be64(&priv2->spu_chnlcnt_RW, 0UL);
615 eieio();
616 }
617}
618
619static inline void save_spu_mb(struct spu_state *csa, struct spu *spu)
620{
621 struct spu_priv2 __iomem *priv2 = spu->priv2;
622 int i;
623
624 /* Save, Step 43:
625 * Save SPU Read Mailbox Channel.
626 */
627 out_be64(&priv2->spu_chnlcntptr_RW, 29UL);
628 eieio();
629 csa->spu_chnlcnt_RW[29] = in_be64(&priv2->spu_chnlcnt_RW);
630 for (i = 0; i < 4; i++) {
631 csa->spu_mailbox_data[i] = in_be64(&priv2->spu_chnldata_RW);
632 }
633 out_be64(&priv2->spu_chnlcnt_RW, 0UL);
634 eieio();
635}
636
637static inline void save_mfc_cmd(struct spu_state *csa, struct spu *spu)
638{
639 struct spu_priv2 __iomem *priv2 = spu->priv2;
640
641 /* Save, Step 44:
642 * Save MFC_CMD Channel.
643 */
644 out_be64(&priv2->spu_chnlcntptr_RW, 21UL);
645 eieio();
646 csa->spu_chnlcnt_RW[21] = in_be64(&priv2->spu_chnlcnt_RW);
647 eieio();
648}
649
650static inline void reset_ch(struct spu_state *csa, struct spu *spu)
651{
652 struct spu_priv2 __iomem *priv2 = spu->priv2;
653 u64 ch_indices[4] = { 21UL, 23UL, 28UL, 30UL };
654 u64 ch_counts[4] = { 16UL, 1UL, 1UL, 1UL };
655 u64 idx;
656 int i;
657
658 /* Save, Step 45:
659 * Reset the following CH: [21, 23, 28, 30]
660 */
661 for (i = 0; i < 4; i++) {
662 idx = ch_indices[i];
663 out_be64(&priv2->spu_chnlcntptr_RW, idx);
664 eieio();
665 out_be64(&priv2->spu_chnlcnt_RW, ch_counts[i]);
666 eieio();
667 }
668}
669
670static inline void resume_mfc_queue(struct spu_state *csa, struct spu *spu)
671{
672 struct spu_priv2 __iomem *priv2 = spu->priv2;
673
674 /* Save, Step 46:
675 * Restore, Step 25.
676 * Write MFC_CNTL[Sc]=0 (resume queue processing).
677 */
678 out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESUME_DMA_QUEUE);
679}
680
681static inline void invalidate_slbs(struct spu_state *csa, struct spu *spu)
682{
683 struct spu_priv2 __iomem *priv2 = spu->priv2;
684
685 /* Save, Step 45:
686 * Restore, Step 19:
687 * If MFC_SR1[R]=1, write 0 to SLB_Invalidate_All.
688 */
689 if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) {
690 out_be64(&priv2->slb_invalidate_all_W, 0UL);
691 eieio();
692 }
693}
694
695static inline void get_kernel_slb(u64 ea, u64 slb[2])
696{
697 slb[0] = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | SLB_VSID_KERNEL;
698 slb[1] = (ea & ESID_MASK) | SLB_ESID_V;
699
700 /* Large pages are used for kernel text/data, but not vmalloc. */
701 if (cpu_has_feature(CPU_FTR_16M_PAGE)
702 && REGION_ID(ea) == KERNEL_REGION_ID)
703 slb[0] |= SLB_VSID_L;
704}
705
706static inline void load_mfc_slb(struct spu *spu, u64 slb[2], int slbe)
707{
708 struct spu_priv2 __iomem *priv2 = spu->priv2;
709
710 out_be64(&priv2->slb_index_W, slbe);
711 eieio();
712 out_be64(&priv2->slb_vsid_RW, slb[0]);
713 out_be64(&priv2->slb_esid_RW, slb[1]);
714 eieio();
715}
716
717static inline void setup_mfc_slbs(struct spu_state *csa, struct spu *spu)
718{
719 u64 code_slb[2];
720 u64 lscsa_slb[2];
721
722 /* Save, Step 47:
723 * Restore, Step 30.
724 * If MFC_SR1[R]=1, write 0 to SLB_Invalidate_All
725 * register, then initialize SLB_VSID and SLB_ESID
726 * to provide access to SPU context save code and
727 * LSCSA.
728 *
729 * This implementation places both the context
730 * switch code and LSCSA in kernel address space.
731 *
732 * Further this implementation assumes that the
733 * MFC_SR1[R]=1 (in other words, assume that
734 * translation is desired by OS environment).
735 */
736 invalidate_slbs(csa, spu);
737 get_kernel_slb((unsigned long)&spu_save_code[0], code_slb);
738 get_kernel_slb((unsigned long)csa->lscsa, lscsa_slb);
739 load_mfc_slb(spu, code_slb, 0);
740 if ((lscsa_slb[0] != code_slb[0]) || (lscsa_slb[1] != code_slb[1]))
741 load_mfc_slb(spu, lscsa_slb, 1);
742}
743
744static inline void set_switch_active(struct spu_state *csa, struct spu *spu)
745{
746 /* Save, Step 48:
747 * Restore, Step 23.
748 * Change the software context switch pending flag
749 * to context switch active.
750 */
751 set_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags);
752 clear_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags);
753 mb();
754}
755
756static inline void enable_interrupts(struct spu_state *csa, struct spu *spu)
757{
758 unsigned long class1_mask = CLASS1_ENABLE_SEGMENT_FAULT_INTR |
759 CLASS1_ENABLE_STORAGE_FAULT_INTR;
760
761 /* Save, Step 49:
762 * Restore, Step 22:
763 * Reset and then enable interrupts, as
764 * needed by OS.
765 *
766 * This implementation enables only class1
767 * (translation) interrupts.
768 */
769 spin_lock_irq(&spu->register_lock);
770 spu_int_stat_clear(spu, 0, ~0ul);
771 spu_int_stat_clear(spu, 1, ~0ul);
772 spu_int_stat_clear(spu, 2, ~0ul);
773 spu_int_mask_set(spu, 0, 0ul);
774 spu_int_mask_set(spu, 1, class1_mask);
775 spu_int_mask_set(spu, 2, 0ul);
776 spin_unlock_irq(&spu->register_lock);
777}
778
779static inline int send_mfc_dma(struct spu *spu, unsigned long ea,
780 unsigned int ls_offset, unsigned int size,
781 unsigned int tag, unsigned int rclass,
782 unsigned int cmd)
783{
784 struct spu_problem __iomem *prob = spu->problem;
785 union mfc_tag_size_class_cmd command;
786 unsigned int transfer_size;
787 volatile unsigned int status = 0x0;
788
789 while (size > 0) {
790 transfer_size =
791 (size > MFC_MAX_DMA_SIZE) ? MFC_MAX_DMA_SIZE : size;
792 command.u.mfc_size = transfer_size;
793 command.u.mfc_tag = tag;
794 command.u.mfc_rclassid = rclass;
795 command.u.mfc_cmd = cmd;
796 do {
797 out_be32(&prob->mfc_lsa_W, ls_offset);
798 out_be64(&prob->mfc_ea_W, ea);
799 out_be64(&prob->mfc_union_W.all64, command.all64);
800 status =
801 in_be32(&prob->mfc_union_W.by32.mfc_class_cmd32);
802 if (unlikely(status & 0x2)) {
803 cpu_relax();
804 }
805 } while (status & 0x3);
806 size -= transfer_size;
807 ea += transfer_size;
808 ls_offset += transfer_size;
809 }
810 return 0;
811}
812
813static inline void save_ls_16kb(struct spu_state *csa, struct spu *spu)
814{
815 unsigned long addr = (unsigned long)&csa->lscsa->ls[0];
816 unsigned int ls_offset = 0x0;
817 unsigned int size = 16384;
818 unsigned int tag = 0;
819 unsigned int rclass = 0;
820 unsigned int cmd = MFC_PUT_CMD;
821
822 /* Save, Step 50:
823 * Issue a DMA command to copy the first 16K bytes
824 * of local storage to the CSA.
825 */
826 send_mfc_dma(spu, addr, ls_offset, size, tag, rclass, cmd);
827}
828
829static inline void set_spu_npc(struct spu_state *csa, struct spu *spu)
830{
831 struct spu_problem __iomem *prob = spu->problem;
832
833 /* Save, Step 51:
834 * Restore, Step 31.
835 * Write SPU_NPC[IE]=0 and SPU_NPC[LSA] to entry
836 * point address of context save code in local
837 * storage.
838 *
839 * This implementation uses SPU-side save/restore
840 * programs with entry points at LSA of 0.
841 */
842 out_be32(&prob->spu_npc_RW, 0);
843 eieio();
844}
845
846static inline void set_signot1(struct spu_state *csa, struct spu *spu)
847{
848 struct spu_problem __iomem *prob = spu->problem;
849 union {
850 u64 ull;
851 u32 ui[2];
852 } addr64;
853
854 /* Save, Step 52:
855 * Restore, Step 32:
856 * Write SPU_Sig_Notify_1 register with upper 32-bits
857 * of the CSA.LSCSA effective address.
858 */
859 addr64.ull = (u64) csa->lscsa;
860 out_be32(&prob->signal_notify1, addr64.ui[0]);
861 eieio();
862}
863
864static inline void set_signot2(struct spu_state *csa, struct spu *spu)
865{
866 struct spu_problem __iomem *prob = spu->problem;
867 union {
868 u64 ull;
869 u32 ui[2];
870 } addr64;
871
872 /* Save, Step 53:
873 * Restore, Step 33:
874 * Write SPU_Sig_Notify_2 register with lower 32-bits
875 * of the CSA.LSCSA effective address.
876 */
877 addr64.ull = (u64) csa->lscsa;
878 out_be32(&prob->signal_notify2, addr64.ui[1]);
879 eieio();
880}
881
882static inline void send_save_code(struct spu_state *csa, struct spu *spu)
883{
884 unsigned long addr = (unsigned long)&spu_save_code[0];
885 unsigned int ls_offset = 0x0;
886 unsigned int size = sizeof(spu_save_code);
887 unsigned int tag = 0;
888 unsigned int rclass = 0;
889 unsigned int cmd = MFC_GETFS_CMD;
890
891 /* Save, Step 54:
892 * Issue a DMA command to copy context save code
893 * to local storage and start SPU.
894 */
895 send_mfc_dma(spu, addr, ls_offset, size, tag, rclass, cmd);
896}
897
898static inline void set_ppu_querymask(struct spu_state *csa, struct spu *spu)
899{
900 struct spu_problem __iomem *prob = spu->problem;
901
902 /* Save, Step 55:
903 * Restore, Step 38.
904 * Write PPU_QueryMask=1 (enable Tag Group 0)
905 * and issue eieio instruction.
906 */
907 out_be32(&prob->dma_querymask_RW, MFC_TAGID_TO_TAGMASK(0));
908 eieio();
909}
910
911static inline void wait_tag_complete(struct spu_state *csa, struct spu *spu)
912{
913 struct spu_problem __iomem *prob = spu->problem;
914 u32 mask = MFC_TAGID_TO_TAGMASK(0);
915 unsigned long flags;
916
917 /* Save, Step 56:
918 * Restore, Step 39.
919 * Restore, Step 39.
920 * Restore, Step 46.
921 * Poll PPU_TagStatus[gn] until 01 (Tag group 0 complete)
922 * or write PPU_QueryType[TS]=01 and wait for Tag Group
923 * Complete Interrupt. Write INT_Stat_Class0 or
924 * INT_Stat_Class2 with value of 'handled'.
925 */
926 POLL_WHILE_FALSE(in_be32(&prob->dma_tagstatus_R) & mask);
927
928 local_irq_save(flags);
929 spu_int_stat_clear(spu, 0, ~(0ul));
930 spu_int_stat_clear(spu, 2, ~(0ul));
931 local_irq_restore(flags);
932}
933
934static inline void wait_spu_stopped(struct spu_state *csa, struct spu *spu)
935{
936 struct spu_problem __iomem *prob = spu->problem;
937 unsigned long flags;
938
939 /* Save, Step 57:
940 * Restore, Step 40.
941 * Poll until SPU_Status[R]=0 or wait for SPU Class 0
942 * or SPU Class 2 interrupt. Write INT_Stat_class0
943 * or INT_Stat_class2 with value of handled.
944 */
945 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING);
946
947 local_irq_save(flags);
948 spu_int_stat_clear(spu, 0, ~(0ul));
949 spu_int_stat_clear(spu, 2, ~(0ul));
950 local_irq_restore(flags);
951}
952
953static inline int check_save_status(struct spu_state *csa, struct spu *spu)
954{
955 struct spu_problem __iomem *prob = spu->problem;
956 u32 complete;
957
958 /* Save, Step 54:
959 * If SPU_Status[P]=1 and SPU_Status[SC] = "success",
960 * context save succeeded, otherwise context save
961 * failed.
962 */
963 complete = ((SPU_SAVE_COMPLETE << SPU_STOP_STATUS_SHIFT) |
964 SPU_STATUS_STOPPED_BY_STOP);
965 return (in_be32(&prob->spu_status_R) != complete) ? 1 : 0;
966}
967
968static inline void terminate_spu_app(struct spu_state *csa, struct spu *spu)
969{
970 /* Restore, Step 4:
971 * If required, notify the "using application" that
972 * the SPU task has been terminated. TBD.
973 */
974}
975
976static inline void suspend_mfc(struct spu_state *csa, struct spu *spu)
977{
978 struct spu_priv2 __iomem *priv2 = spu->priv2;
979
980 /* Restore, Step 7:
981 * Restore, Step 47.
982 * Write MFC_Cntl[Dh,Sc]='1','1' to suspend
983 * the queue and halt the decrementer.
984 */
985 out_be64(&priv2->mfc_control_RW, MFC_CNTL_SUSPEND_DMA_QUEUE |
986 MFC_CNTL_DECREMENTER_HALTED);
987 eieio();
988}
989
990static inline void wait_suspend_mfc_complete(struct spu_state *csa,
991 struct spu *spu)
992{
993 struct spu_priv2 __iomem *priv2 = spu->priv2;
994
995 /* Restore, Step 8:
996 * Restore, Step 47.
997 * Poll MFC_CNTL[Ss] until 11 is returned.
998 */
999 POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) &
1000 MFC_CNTL_SUSPEND_COMPLETE);
1001}
1002
1003static inline int suspend_spe(struct spu_state *csa, struct spu *spu)
1004{
1005 struct spu_problem __iomem *prob = spu->problem;
1006
1007 /* Restore, Step 9:
1008 * If SPU_Status[R]=1, stop SPU execution
1009 * and wait for stop to complete.
1010 *
1011 * Returns 1 if SPU_Status[R]=1 on entry.
1012 * 0 otherwise
1013 */
1014 if (in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING) {
1015 if (in_be32(&prob->spu_status_R) &
1016 SPU_STATUS_ISOLATED_EXIT_STAUTUS) {
1017 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) &
1018 SPU_STATUS_RUNNING);
1019 }
1020 if ((in_be32(&prob->spu_status_R) &
1021 SPU_STATUS_ISOLATED_LOAD_STAUTUS)
1022 || (in_be32(&prob->spu_status_R) &
1023 SPU_STATUS_ISOLATED_STATE)) {
1024 out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP);
1025 eieio();
1026 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) &
1027 SPU_STATUS_RUNNING);
1028 out_be32(&prob->spu_runcntl_RW, 0x2);
1029 eieio();
1030 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) &
1031 SPU_STATUS_RUNNING);
1032 }
1033 if (in_be32(&prob->spu_status_R) &
1034 SPU_STATUS_WAITING_FOR_CHANNEL) {
1035 out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP);
1036 eieio();
1037 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) &
1038 SPU_STATUS_RUNNING);
1039 }
1040 return 1;
1041 }
1042 return 0;
1043}
1044
1045static inline void clear_spu_status(struct spu_state *csa, struct spu *spu)
1046{
1047 struct spu_problem __iomem *prob = spu->problem;
1048
1049 /* Restore, Step 10:
1050 * If SPU_Status[R]=0 and SPU_Status[E,L,IS]=1,
1051 * release SPU from isolate state.
1052 */
1053 if (!(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING)) {
1054 if (in_be32(&prob->spu_status_R) &
1055 SPU_STATUS_ISOLATED_EXIT_STAUTUS) {
1056 spu_mfc_sr1_set(spu,
1057 MFC_STATE1_MASTER_RUN_CONTROL_MASK);
1058 eieio();
1059 out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_RUNNABLE);
1060 eieio();
1061 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) &
1062 SPU_STATUS_RUNNING);
1063 }
1064 if ((in_be32(&prob->spu_status_R) &
1065 SPU_STATUS_ISOLATED_LOAD_STAUTUS)
1066 || (in_be32(&prob->spu_status_R) &
1067 SPU_STATUS_ISOLATED_STATE)) {
1068 spu_mfc_sr1_set(spu,
1069 MFC_STATE1_MASTER_RUN_CONTROL_MASK);
1070 eieio();
1071 out_be32(&prob->spu_runcntl_RW, 0x2);
1072 eieio();
1073 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) &
1074 SPU_STATUS_RUNNING);
1075 }
1076 }
1077}
1078
1079static inline void reset_ch_part1(struct spu_state *csa, struct spu *spu)
1080{
1081 struct spu_priv2 __iomem *priv2 = spu->priv2;
1082 u64 ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL };
1083 u64 idx;
1084 int i;
1085
1086 /* Restore, Step 20:
1087 * Reset the following CH: [0,1,3,4,24,25,27]
1088 */
1089 for (i = 0; i < 7; i++) {
1090 idx = ch_indices[i];
1091 out_be64(&priv2->spu_chnlcntptr_RW, idx);
1092 eieio();
1093 out_be64(&priv2->spu_chnldata_RW, 0UL);
1094 out_be64(&priv2->spu_chnlcnt_RW, 0UL);
1095 eieio();
1096 }
1097}
1098
1099static inline void reset_ch_part2(struct spu_state *csa, struct spu *spu)
1100{
1101 struct spu_priv2 __iomem *priv2 = spu->priv2;
1102 u64 ch_indices[5] = { 21UL, 23UL, 28UL, 29UL, 30UL };
1103 u64 ch_counts[5] = { 16UL, 1UL, 1UL, 0UL, 1UL };
1104 u64 idx;
1105 int i;
1106
1107 /* Restore, Step 21:
1108 * Reset the following CH: [21, 23, 28, 29, 30]
1109 */
1110 for (i = 0; i < 5; i++) {
1111 idx = ch_indices[i];
1112 out_be64(&priv2->spu_chnlcntptr_RW, idx);
1113 eieio();
1114 out_be64(&priv2->spu_chnlcnt_RW, ch_counts[i]);
1115 eieio();
1116 }
1117}
1118
1119static inline void setup_spu_status_part1(struct spu_state *csa,
1120 struct spu *spu)
1121{
1122 u32 status_P = SPU_STATUS_STOPPED_BY_STOP;
1123 u32 status_I = SPU_STATUS_INVALID_INSTR;
1124 u32 status_H = SPU_STATUS_STOPPED_BY_HALT;
1125 u32 status_S = SPU_STATUS_SINGLE_STEP;
1126 u32 status_S_I = SPU_STATUS_SINGLE_STEP | SPU_STATUS_INVALID_INSTR;
1127 u32 status_S_P = SPU_STATUS_SINGLE_STEP | SPU_STATUS_STOPPED_BY_STOP;
1128 u32 status_P_H = SPU_STATUS_STOPPED_BY_HALT |SPU_STATUS_STOPPED_BY_STOP;
1129 u32 status_P_I = SPU_STATUS_STOPPED_BY_STOP |SPU_STATUS_INVALID_INSTR;
1130 u32 status_code;
1131
1132 /* Restore, Step 27:
1133 * If the CSA.SPU_Status[I,S,H,P]=1 then add the correct
1134 * instruction sequence to the end of the SPU based restore
1135 * code (after the "context restored" stop and signal) to
1136 * restore the correct SPU status.
1137 *
1138 * NOTE: Rather than modifying the SPU executable, we
1139 * instead add a new 'stopped_status' field to the
1140 * LSCSA. The SPU-side restore reads this field and
1141 * takes the appropriate action when exiting.
1142 */
1143
1144 status_code =
1145 (csa->prob.spu_status_R >> SPU_STOP_STATUS_SHIFT) & 0xFFFF;
1146 if ((csa->prob.spu_status_R & status_P_I) == status_P_I) {
1147
1148 /* SPU_Status[P,I]=1 - Illegal Instruction followed
1149 * by Stop and Signal instruction, followed by 'br -4'.
1150 *
1151 */
1152 csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_P_I;
1153 csa->lscsa->stopped_status.slot[1] = status_code;
1154
1155 } else if ((csa->prob.spu_status_R & status_P_H) == status_P_H) {
1156
1157 /* SPU_Status[P,H]=1 - Halt Conditional, followed
1158 * by Stop and Signal instruction, followed by
1159 * 'br -4'.
1160 */
1161 csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_P_H;
1162 csa->lscsa->stopped_status.slot[1] = status_code;
1163
1164 } else if ((csa->prob.spu_status_R & status_S_P) == status_S_P) {
1165
1166 /* SPU_Status[S,P]=1 - Stop and Signal instruction
1167 * followed by 'br -4'.
1168 */
1169 csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_S_P;
1170 csa->lscsa->stopped_status.slot[1] = status_code;
1171
1172 } else if ((csa->prob.spu_status_R & status_S_I) == status_S_I) {
1173
1174 /* SPU_Status[S,I]=1 - Illegal instruction followed
1175 * by 'br -4'.
1176 */
1177 csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_S_I;
1178 csa->lscsa->stopped_status.slot[1] = status_code;
1179
1180 } else if ((csa->prob.spu_status_R & status_P) == status_P) {
1181
1182 /* SPU_Status[P]=1 - Stop and Signal instruction
1183 * followed by 'br -4'.
1184 */
1185 csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_P;
1186 csa->lscsa->stopped_status.slot[1] = status_code;
1187
1188 } else if ((csa->prob.spu_status_R & status_H) == status_H) {
1189
1190 /* SPU_Status[H]=1 - Halt Conditional, followed
1191 * by 'br -4'.
1192 */
1193 csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_H;
1194
1195 } else if ((csa->prob.spu_status_R & status_S) == status_S) {
1196
1197 /* SPU_Status[S]=1 - Two nop instructions.
1198 */
1199 csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_S;
1200
1201 } else if ((csa->prob.spu_status_R & status_I) == status_I) {
1202
1203 /* SPU_Status[I]=1 - Illegal instruction followed
1204 * by 'br -4'.
1205 */
1206 csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_I;
1207
1208 }
1209}
1210
1211static inline void setup_spu_status_part2(struct spu_state *csa,
1212 struct spu *spu)
1213{
1214 u32 mask;
1215
1216 /* Restore, Step 28:
1217 * If the CSA.SPU_Status[I,S,H,P,R]=0 then
1218 * add a 'br *' instruction to the end of
1219 * the SPU based restore code.
1220 *
1221 * NOTE: Rather than modifying the SPU executable, we
1222 * instead add a new 'stopped_status' field to the
1223 * LSCSA. The SPU-side restore reads this field and
1224 * takes the appropriate action when exiting.
1225 */
1226 mask = SPU_STATUS_INVALID_INSTR |
1227 SPU_STATUS_SINGLE_STEP |
1228 SPU_STATUS_STOPPED_BY_HALT |
1229 SPU_STATUS_STOPPED_BY_STOP | SPU_STATUS_RUNNING;
1230 if (!(csa->prob.spu_status_R & mask)) {
1231 csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_R;
1232 }
1233}
1234
1235static inline void restore_mfc_rag(struct spu_state *csa, struct spu *spu)
1236{
1237 /* Restore, Step 29:
1238 * Restore RA_GROUP_ID register and the
1239 * RA_ENABLE reigster from the CSA.
1240 */
1241 spu_resource_allocation_groupID_set(spu,
1242 csa->priv1.resource_allocation_groupID_RW);
1243 spu_resource_allocation_enable_set(spu,
1244 csa->priv1.resource_allocation_enable_RW);
1245}
1246
1247static inline void send_restore_code(struct spu_state *csa, struct spu *spu)
1248{
1249 unsigned long addr = (unsigned long)&spu_restore_code[0];
1250 unsigned int ls_offset = 0x0;
1251 unsigned int size = sizeof(spu_restore_code);
1252 unsigned int tag = 0;
1253 unsigned int rclass = 0;
1254 unsigned int cmd = MFC_GETFS_CMD;
1255
1256 /* Restore, Step 37:
1257 * Issue MFC DMA command to copy context
1258 * restore code to local storage.
1259 */
1260 send_mfc_dma(spu, addr, ls_offset, size, tag, rclass, cmd);
1261}
1262
1263static inline void setup_decr(struct spu_state *csa, struct spu *spu)
1264{
1265 /* Restore, Step 34:
1266 * If CSA.MFC_CNTL[Ds]=1 (decrementer was
1267 * running) then adjust decrementer, set
1268 * decrementer running status in LSCSA,
1269 * and set decrementer "wrapped" status
1270 * in LSCSA.
1271 */
1272 if (csa->priv2.mfc_control_RW & MFC_CNTL_DECREMENTER_RUNNING) {
1273 cycles_t resume_time = get_cycles();
1274 cycles_t delta_time = resume_time - csa->suspend_time;
1275
1276 csa->lscsa->decr.slot[0] = delta_time;
1277 }
1278}
1279
1280static inline void setup_ppu_mb(struct spu_state *csa, struct spu *spu)
1281{
1282 /* Restore, Step 35:
1283 * Copy the CSA.PU_MB data into the LSCSA.
1284 */
1285 csa->lscsa->ppu_mb.slot[0] = csa->prob.pu_mb_R;
1286}
1287
1288static inline void setup_ppuint_mb(struct spu_state *csa, struct spu *spu)
1289{
1290 /* Restore, Step 36:
1291 * Copy the CSA.PUINT_MB data into the LSCSA.
1292 */
1293 csa->lscsa->ppuint_mb.slot[0] = csa->priv2.puint_mb_R;
1294}
1295
1296static inline int check_restore_status(struct spu_state *csa, struct spu *spu)
1297{
1298 struct spu_problem __iomem *prob = spu->problem;
1299 u32 complete;
1300
1301 /* Restore, Step 40:
1302 * If SPU_Status[P]=1 and SPU_Status[SC] = "success",
1303 * context restore succeeded, otherwise context restore
1304 * failed.
1305 */
1306 complete = ((SPU_RESTORE_COMPLETE << SPU_STOP_STATUS_SHIFT) |
1307 SPU_STATUS_STOPPED_BY_STOP);
1308 return (in_be32(&prob->spu_status_R) != complete) ? 1 : 0;
1309}
1310
1311static inline void restore_spu_privcntl(struct spu_state *csa, struct spu *spu)
1312{
1313 struct spu_priv2 __iomem *priv2 = spu->priv2;
1314
1315 /* Restore, Step 41:
1316 * Restore SPU_PrivCntl from the CSA.
1317 */
1318 out_be64(&priv2->spu_privcntl_RW, csa->priv2.spu_privcntl_RW);
1319 eieio();
1320}
1321
1322static inline void restore_status_part1(struct spu_state *csa, struct spu *spu)
1323{
1324 struct spu_problem __iomem *prob = spu->problem;
1325 u32 mask;
1326
1327 /* Restore, Step 42:
1328 * If any CSA.SPU_Status[I,S,H,P]=1, then
1329 * restore the error or single step state.
1330 */
1331 mask = SPU_STATUS_INVALID_INSTR |
1332 SPU_STATUS_SINGLE_STEP |
1333 SPU_STATUS_STOPPED_BY_HALT | SPU_STATUS_STOPPED_BY_STOP;
1334 if (csa->prob.spu_status_R & mask) {
1335 out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_RUNNABLE);
1336 eieio();
1337 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) &
1338 SPU_STATUS_RUNNING);
1339 }
1340}
1341
1342static inline void restore_status_part2(struct spu_state *csa, struct spu *spu)
1343{
1344 struct spu_problem __iomem *prob = spu->problem;
1345 u32 mask;
1346
1347 /* Restore, Step 43:
1348 * If all CSA.SPU_Status[I,S,H,P,R]=0 then write
1349 * SPU_RunCntl[R0R1]='01', wait for SPU_Status[R]=1,
1350 * then write '00' to SPU_RunCntl[R0R1] and wait
1351 * for SPU_Status[R]=0.
1352 */
1353 mask = SPU_STATUS_INVALID_INSTR |
1354 SPU_STATUS_SINGLE_STEP |
1355 SPU_STATUS_STOPPED_BY_HALT |
1356 SPU_STATUS_STOPPED_BY_STOP | SPU_STATUS_RUNNING;
1357 if (!(csa->prob.spu_status_R & mask)) {
1358 out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_RUNNABLE);
1359 eieio();
1360 POLL_WHILE_FALSE(in_be32(&prob->spu_status_R) &
1361 SPU_STATUS_RUNNING);
1362 out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP);
1363 eieio();
1364 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) &
1365 SPU_STATUS_RUNNING);
1366 }
1367}
1368
1369static inline void restore_ls_16kb(struct spu_state *csa, struct spu *spu)
1370{
1371 unsigned long addr = (unsigned long)&csa->lscsa->ls[0];
1372 unsigned int ls_offset = 0x0;
1373 unsigned int size = 16384;
1374 unsigned int tag = 0;
1375 unsigned int rclass = 0;
1376 unsigned int cmd = MFC_GET_CMD;
1377
1378 /* Restore, Step 44:
1379 * Issue a DMA command to restore the first
1380 * 16kb of local storage from CSA.
1381 */
1382 send_mfc_dma(spu, addr, ls_offset, size, tag, rclass, cmd);
1383}
1384
1385static inline void clear_interrupts(struct spu_state *csa, struct spu *spu)
1386{
1387 /* Restore, Step 49:
1388 * Write INT_MASK_class0 with value of 0.
1389 * Write INT_MASK_class1 with value of 0.
1390 * Write INT_MASK_class2 with value of 0.
1391 * Write INT_STAT_class0 with value of -1.
1392 * Write INT_STAT_class1 with value of -1.
1393 * Write INT_STAT_class2 with value of -1.
1394 */
1395 spin_lock_irq(&spu->register_lock);
1396 spu_int_mask_set(spu, 0, 0ul);
1397 spu_int_mask_set(spu, 1, 0ul);
1398 spu_int_mask_set(spu, 2, 0ul);
1399 spu_int_stat_clear(spu, 0, ~0ul);
1400 spu_int_stat_clear(spu, 1, ~0ul);
1401 spu_int_stat_clear(spu, 2, ~0ul);
1402 spin_unlock_irq(&spu->register_lock);
1403}
1404
1405static inline void restore_mfc_queues(struct spu_state *csa, struct spu *spu)
1406{
1407 struct spu_priv2 __iomem *priv2 = spu->priv2;
1408 int i;
1409
1410 /* Restore, Step 50:
1411 * If MFC_Cntl[Se]!=0 then restore
1412 * MFC command queues.
1413 */
1414 if ((csa->priv2.mfc_control_RW & MFC_CNTL_DMA_QUEUES_EMPTY_MASK) == 0) {
1415 for (i = 0; i < 8; i++) {
1416 out_be64(&priv2->puq[i].mfc_cq_data0_RW,
1417 csa->priv2.puq[i].mfc_cq_data0_RW);
1418 out_be64(&priv2->puq[i].mfc_cq_data1_RW,
1419 csa->priv2.puq[i].mfc_cq_data1_RW);
1420 out_be64(&priv2->puq[i].mfc_cq_data2_RW,
1421 csa->priv2.puq[i].mfc_cq_data2_RW);
1422 out_be64(&priv2->puq[i].mfc_cq_data3_RW,
1423 csa->priv2.puq[i].mfc_cq_data3_RW);
1424 }
1425 for (i = 0; i < 16; i++) {
1426 out_be64(&priv2->spuq[i].mfc_cq_data0_RW,
1427 csa->priv2.spuq[i].mfc_cq_data0_RW);
1428 out_be64(&priv2->spuq[i].mfc_cq_data1_RW,
1429 csa->priv2.spuq[i].mfc_cq_data1_RW);
1430 out_be64(&priv2->spuq[i].mfc_cq_data2_RW,
1431 csa->priv2.spuq[i].mfc_cq_data2_RW);
1432 out_be64(&priv2->spuq[i].mfc_cq_data3_RW,
1433 csa->priv2.spuq[i].mfc_cq_data3_RW);
1434 }
1435 }
1436 eieio();
1437}
1438
1439static inline void restore_ppu_querymask(struct spu_state *csa, struct spu *spu)
1440{
1441 struct spu_problem __iomem *prob = spu->problem;
1442
1443 /* Restore, Step 51:
1444 * Restore the PPU_QueryMask register from CSA.
1445 */
1446 out_be32(&prob->dma_querymask_RW, csa->prob.dma_querymask_RW);
1447 eieio();
1448}
1449
1450static inline void restore_ppu_querytype(struct spu_state *csa, struct spu *spu)
1451{
1452 struct spu_problem __iomem *prob = spu->problem;
1453
1454 /* Restore, Step 52:
1455 * Restore the PPU_QueryType register from CSA.
1456 */
1457 out_be32(&prob->dma_querytype_RW, csa->prob.dma_querytype_RW);
1458 eieio();
1459}
1460
1461static inline void restore_mfc_csr_tsq(struct spu_state *csa, struct spu *spu)
1462{
1463 struct spu_priv2 __iomem *priv2 = spu->priv2;
1464
1465 /* Restore, Step 53:
1466 * Restore the MFC_CSR_TSQ register from CSA.
1467 */
1468 out_be64(&priv2->spu_tag_status_query_RW,
1469 csa->priv2.spu_tag_status_query_RW);
1470 eieio();
1471}
1472
1473static inline void restore_mfc_csr_cmd(struct spu_state *csa, struct spu *spu)
1474{
1475 struct spu_priv2 __iomem *priv2 = spu->priv2;
1476
1477 /* Restore, Step 54:
1478 * Restore the MFC_CSR_CMD1 and MFC_CSR_CMD2
1479 * registers from CSA.
1480 */
1481 out_be64(&priv2->spu_cmd_buf1_RW, csa->priv2.spu_cmd_buf1_RW);
1482 out_be64(&priv2->spu_cmd_buf2_RW, csa->priv2.spu_cmd_buf2_RW);
1483 eieio();
1484}
1485
1486static inline void restore_mfc_csr_ato(struct spu_state *csa, struct spu *spu)
1487{
1488 struct spu_priv2 __iomem *priv2 = spu->priv2;
1489
1490 /* Restore, Step 55:
1491 * Restore the MFC_CSR_ATO register from CSA.
1492 */
1493 out_be64(&priv2->spu_atomic_status_RW, csa->priv2.spu_atomic_status_RW);
1494}
1495
1496static inline void restore_mfc_tclass_id(struct spu_state *csa, struct spu *spu)
1497{
1498 /* Restore, Step 56:
1499 * Restore the MFC_TCLASS_ID register from CSA.
1500 */
1501 spu_mfc_tclass_id_set(spu, csa->priv1.mfc_tclass_id_RW);
1502 eieio();
1503}
1504
1505static inline void set_llr_event(struct spu_state *csa, struct spu *spu)
1506{
1507 u64 ch0_cnt, ch0_data;
1508 u64 ch1_data;
1509
1510 /* Restore, Step 57:
1511 * Set the Lock Line Reservation Lost Event by:
1512 * 1. OR CSA.SPU_Event_Status with bit 21 (Lr) set to 1.
1513 * 2. If CSA.SPU_Channel_0_Count=0 and
1514 * CSA.SPU_Wr_Event_Mask[Lr]=1 and
1515 * CSA.SPU_Event_Status[Lr]=0 then set
1516 * CSA.SPU_Event_Status_Count=1.
1517 */
1518 ch0_cnt = csa->spu_chnlcnt_RW[0];
1519 ch0_data = csa->spu_chnldata_RW[0];
1520 ch1_data = csa->spu_chnldata_RW[1];
1521 csa->spu_chnldata_RW[0] |= MFC_LLR_LOST_EVENT;
1522 if ((ch0_cnt == 0) && !(ch0_data & MFC_LLR_LOST_EVENT) &&
1523 (ch1_data & MFC_LLR_LOST_EVENT)) {
1524 csa->spu_chnlcnt_RW[0] = 1;
1525 }
1526}
1527
1528static inline void restore_decr_wrapped(struct spu_state *csa, struct spu *spu)
1529{
1530 /* Restore, Step 58:
1531 * If the status of the CSA software decrementer
1532 * "wrapped" flag is set, OR in a '1' to
1533 * CSA.SPU_Event_Status[Tm].
1534 */
1535 if (csa->lscsa->decr_status.slot[0] == 1) {
1536 csa->spu_chnldata_RW[0] |= 0x20;
1537 }
1538 if ((csa->lscsa->decr_status.slot[0] == 1) &&
1539 (csa->spu_chnlcnt_RW[0] == 0 &&
1540 ((csa->spu_chnldata_RW[2] & 0x20) == 0x0) &&
1541 ((csa->spu_chnldata_RW[0] & 0x20) != 0x1))) {
1542 csa->spu_chnlcnt_RW[0] = 1;
1543 }
1544}
1545
1546static inline void restore_ch_part1(struct spu_state *csa, struct spu *spu)
1547{
1548 struct spu_priv2 __iomem *priv2 = spu->priv2;
1549 u64 idx, ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL };
1550 int i;
1551
1552 /* Restore, Step 59:
1553 * Restore the following CH: [0,1,3,4,24,25,27]
1554 */
1555 for (i = 0; i < 7; i++) {
1556 idx = ch_indices[i];
1557 out_be64(&priv2->spu_chnlcntptr_RW, idx);
1558 eieio();
1559 out_be64(&priv2->spu_chnldata_RW, csa->spu_chnldata_RW[idx]);
1560 out_be64(&priv2->spu_chnlcnt_RW, csa->spu_chnlcnt_RW[idx]);
1561 eieio();
1562 }
1563}
1564
1565static inline void restore_ch_part2(struct spu_state *csa, struct spu *spu)
1566{
1567 struct spu_priv2 __iomem *priv2 = spu->priv2;
1568 u64 ch_indices[3] = { 9UL, 21UL, 23UL };
1569 u64 ch_counts[3] = { 1UL, 16UL, 1UL };
1570 u64 idx;
1571 int i;
1572
1573 /* Restore, Step 60:
1574 * Restore the following CH: [9,21,23].
1575 */
1576 ch_counts[0] = 1UL;
1577 ch_counts[1] = csa->spu_chnlcnt_RW[21];
1578 ch_counts[2] = 1UL;
1579 for (i = 0; i < 3; i++) {
1580 idx = ch_indices[i];
1581 out_be64(&priv2->spu_chnlcntptr_RW, idx);
1582 eieio();
1583 out_be64(&priv2->spu_chnlcnt_RW, ch_counts[i]);
1584 eieio();
1585 }
1586}
1587
1588static inline void restore_spu_lslr(struct spu_state *csa, struct spu *spu)
1589{
1590 struct spu_priv2 __iomem *priv2 = spu->priv2;
1591
1592 /* Restore, Step 61:
1593 * Restore the SPU_LSLR register from CSA.
1594 */
1595 out_be64(&priv2->spu_lslr_RW, csa->priv2.spu_lslr_RW);
1596 eieio();
1597}
1598
1599static inline void restore_spu_cfg(struct spu_state *csa, struct spu *spu)
1600{
1601 struct spu_priv2 __iomem *priv2 = spu->priv2;
1602
1603 /* Restore, Step 62:
1604 * Restore the SPU_Cfg register from CSA.
1605 */
1606 out_be64(&priv2->spu_cfg_RW, csa->priv2.spu_cfg_RW);
1607 eieio();
1608}
1609
1610static inline void restore_pm_trace(struct spu_state *csa, struct spu *spu)
1611{
1612 /* Restore, Step 63:
1613 * Restore PM_Trace_Tag_Wait_Mask from CSA.
1614 * Not performed by this implementation.
1615 */
1616}
1617
1618static inline void restore_spu_npc(struct spu_state *csa, struct spu *spu)
1619{
1620 struct spu_problem __iomem *prob = spu->problem;
1621
1622 /* Restore, Step 64:
1623 * Restore SPU_NPC from CSA.
1624 */
1625 out_be32(&prob->spu_npc_RW, csa->prob.spu_npc_RW);
1626 eieio();
1627}
1628
1629static inline void restore_spu_mb(struct spu_state *csa, struct spu *spu)
1630{
1631 struct spu_priv2 __iomem *priv2 = spu->priv2;
1632 int i;
1633
1634 /* Restore, Step 65:
1635 * Restore MFC_RdSPU_MB from CSA.
1636 */
1637 out_be64(&priv2->spu_chnlcntptr_RW, 29UL);
1638 eieio();
1639 out_be64(&priv2->spu_chnlcnt_RW, csa->spu_chnlcnt_RW[29]);
1640 for (i = 0; i < 4; i++) {
1641 out_be64(&priv2->spu_chnldata_RW, csa->spu_mailbox_data[i]);
1642 }
1643 eieio();
1644}
1645
1646static inline void check_ppu_mb_stat(struct spu_state *csa, struct spu *spu)
1647{
1648 struct spu_problem __iomem *prob = spu->problem;
1649 u32 dummy = 0;
1650
1651 /* Restore, Step 66:
1652 * If CSA.MB_Stat[P]=0 (mailbox empty) then
1653 * read from the PPU_MB register.
1654 */
1655 if ((csa->prob.mb_stat_R & 0xFF) == 0) {
1656 dummy = in_be32(&prob->pu_mb_R);
1657 eieio();
1658 }
1659}
1660
1661static inline void check_ppuint_mb_stat(struct spu_state *csa, struct spu *spu)
1662{
1663 struct spu_priv2 __iomem *priv2 = spu->priv2;
1664 u64 dummy = 0UL;
1665
1666 /* Restore, Step 66:
1667 * If CSA.MB_Stat[I]=0 (mailbox empty) then
1668 * read from the PPUINT_MB register.
1669 */
1670 if ((csa->prob.mb_stat_R & 0xFF0000) == 0) {
1671 dummy = in_be64(&priv2->puint_mb_R);
1672 eieio();
1673 spu_int_stat_clear(spu, 2, CLASS2_ENABLE_MAILBOX_INTR);
1674 eieio();
1675 }
1676}
1677
1678static inline void restore_mfc_slbs(struct spu_state *csa, struct spu *spu)
1679{
1680 struct spu_priv2 __iomem *priv2 = spu->priv2;
1681 int i;
1682
1683 /* Restore, Step 68:
1684 * If MFC_SR1[R]='1', restore SLBs from CSA.
1685 */
1686 if (csa->priv1.mfc_sr1_RW & MFC_STATE1_RELOCATE_MASK) {
1687 for (i = 0; i < 8; i++) {
1688 out_be64(&priv2->slb_index_W, i);
1689 eieio();
1690 out_be64(&priv2->slb_esid_RW, csa->slb_esid_RW[i]);
1691 out_be64(&priv2->slb_vsid_RW, csa->slb_vsid_RW[i]);
1692 eieio();
1693 }
1694 out_be64(&priv2->slb_index_W, csa->priv2.slb_index_W);
1695 eieio();
1696 }
1697}
1698
1699static inline void restore_mfc_sr1(struct spu_state *csa, struct spu *spu)
1700{
1701 /* Restore, Step 69:
1702 * Restore the MFC_SR1 register from CSA.
1703 */
1704 spu_mfc_sr1_set(spu, csa->priv1.mfc_sr1_RW);
1705 eieio();
1706}
1707
1708static inline void restore_other_spu_access(struct spu_state *csa,
1709 struct spu *spu)
1710{
1711 /* Restore, Step 70:
1712 * Restore other SPU mappings to this SPU. TBD.
1713 */
1714}
1715
1716static inline void restore_spu_runcntl(struct spu_state *csa, struct spu *spu)
1717{
1718 struct spu_problem __iomem *prob = spu->problem;
1719
1720 /* Restore, Step 71:
1721 * If CSA.SPU_Status[R]=1 then write
1722 * SPU_RunCntl[R0R1]='01'.
1723 */
1724 if (csa->prob.spu_status_R & SPU_STATUS_RUNNING) {
1725 out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_RUNNABLE);
1726 eieio();
1727 }
1728}
1729
1730static inline void restore_mfc_cntl(struct spu_state *csa, struct spu *spu)
1731{
1732 struct spu_priv2 __iomem *priv2 = spu->priv2;
1733
1734 /* Restore, Step 72:
1735 * Restore the MFC_CNTL register for the CSA.
1736 */
1737 out_be64(&priv2->mfc_control_RW, csa->priv2.mfc_control_RW);
1738 eieio();
1739}
1740
1741static inline void enable_user_access(struct spu_state *csa, struct spu *spu)
1742{
1743 /* Restore, Step 73:
1744 * Enable user-space access (if provided) to this
1745 * SPU by mapping the virtual pages assigned to
1746 * the SPU memory-mapped I/O (MMIO) for problem
1747 * state. TBD.
1748 */
1749}
1750
1751static inline void reset_switch_active(struct spu_state *csa, struct spu *spu)
1752{
1753 /* Restore, Step 74:
1754 * Reset the "context switch active" flag.
1755 */
1756 clear_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags);
1757 mb();
1758}
1759
1760static inline void reenable_interrupts(struct spu_state *csa, struct spu *spu)
1761{
1762 /* Restore, Step 75:
1763 * Re-enable SPU interrupts.
1764 */
1765 spin_lock_irq(&spu->register_lock);
1766 spu_int_mask_set(spu, 0, csa->priv1.int_mask_class0_RW);
1767 spu_int_mask_set(spu, 1, csa->priv1.int_mask_class1_RW);
1768 spu_int_mask_set(spu, 2, csa->priv1.int_mask_class2_RW);
1769 spin_unlock_irq(&spu->register_lock);
1770}
1771
1772static int quiece_spu(struct spu_state *prev, struct spu *spu)
1773{
1774 /*
1775 * Combined steps 2-18 of SPU context save sequence, which
1776 * quiesce the SPU state (disable SPU execution, MFC command
1777 * queues, decrementer, SPU interrupts, etc.).
1778 *
1779 * Returns 0 on success.
1780 * 2 if failed step 2.
1781 * 6 if failed step 6.
1782 */
1783
1784 if (check_spu_isolate(prev, spu)) { /* Step 2. */
1785 return 2;
1786 }
1787 disable_interrupts(prev, spu); /* Step 3. */
1788 set_watchdog_timer(prev, spu); /* Step 4. */
1789 inhibit_user_access(prev, spu); /* Step 5. */
1790 if (check_spu_isolate(prev, spu)) { /* Step 6. */
1791 return 6;
1792 }
1793 set_switch_pending(prev, spu); /* Step 7. */
1794 save_mfc_cntl(prev, spu); /* Step 8. */
1795 save_spu_runcntl(prev, spu); /* Step 9. */
1796 save_mfc_sr1(prev, spu); /* Step 10. */
1797 save_spu_status(prev, spu); /* Step 11. */
1798 save_mfc_decr(prev, spu); /* Step 12. */
1799 halt_mfc_decr(prev, spu); /* Step 13. */
1800 save_timebase(prev, spu); /* Step 14. */
1801 remove_other_spu_access(prev, spu); /* Step 15. */
1802 do_mfc_mssync(prev, spu); /* Step 16. */
1803 issue_mfc_tlbie(prev, spu); /* Step 17. */
1804 handle_pending_interrupts(prev, spu); /* Step 18. */
1805
1806 return 0;
1807}
1808
1809static void save_csa(struct spu_state *prev, struct spu *spu)
1810{
1811 /*
1812 * Combine steps 19-44 of SPU context save sequence, which
1813 * save regions of the privileged & problem state areas.
1814 */
1815
1816 save_mfc_queues(prev, spu); /* Step 19. */
1817 save_ppu_querymask(prev, spu); /* Step 20. */
1818 save_ppu_querytype(prev, spu); /* Step 21. */
1819 save_mfc_csr_tsq(prev, spu); /* Step 22. */
1820 save_mfc_csr_cmd(prev, spu); /* Step 23. */
1821 save_mfc_csr_ato(prev, spu); /* Step 24. */
1822 save_mfc_tclass_id(prev, spu); /* Step 25. */
1823 set_mfc_tclass_id(prev, spu); /* Step 26. */
1824 purge_mfc_queue(prev, spu); /* Step 27. */
1825 wait_purge_complete(prev, spu); /* Step 28. */
1826 save_mfc_slbs(prev, spu); /* Step 29. */
1827 setup_mfc_sr1(prev, spu); /* Step 30. */
1828 save_spu_npc(prev, spu); /* Step 31. */
1829 save_spu_privcntl(prev, spu); /* Step 32. */
1830 reset_spu_privcntl(prev, spu); /* Step 33. */
1831 save_spu_lslr(prev, spu); /* Step 34. */
1832 reset_spu_lslr(prev, spu); /* Step 35. */
1833 save_spu_cfg(prev, spu); /* Step 36. */
1834 save_pm_trace(prev, spu); /* Step 37. */
1835 save_mfc_rag(prev, spu); /* Step 38. */
1836 save_ppu_mb_stat(prev, spu); /* Step 39. */
1837 save_ppu_mb(prev, spu); /* Step 40. */
1838 save_ppuint_mb(prev, spu); /* Step 41. */
1839 save_ch_part1(prev, spu); /* Step 42. */
1840 save_spu_mb(prev, spu); /* Step 43. */
1841 save_mfc_cmd(prev, spu); /* Step 44. */
1842 reset_ch(prev, spu); /* Step 45. */
1843}
1844
1845static void save_lscsa(struct spu_state *prev, struct spu *spu)
1846{
1847 /*
1848 * Perform steps 46-57 of SPU context save sequence,
1849 * which save regions of the local store and register
1850 * file.
1851 */
1852
1853 resume_mfc_queue(prev, spu); /* Step 46. */
1854 setup_mfc_slbs(prev, spu); /* Step 47. */
1855 set_switch_active(prev, spu); /* Step 48. */
1856 enable_interrupts(prev, spu); /* Step 49. */
1857 save_ls_16kb(prev, spu); /* Step 50. */
1858 set_spu_npc(prev, spu); /* Step 51. */
1859 set_signot1(prev, spu); /* Step 52. */
1860 set_signot2(prev, spu); /* Step 53. */
1861 send_save_code(prev, spu); /* Step 54. */
1862 set_ppu_querymask(prev, spu); /* Step 55. */
1863 wait_tag_complete(prev, spu); /* Step 56. */
1864 wait_spu_stopped(prev, spu); /* Step 57. */
1865}
1866
1867static void harvest(struct spu_state *prev, struct spu *spu)
1868{
1869 /*
1870 * Perform steps 2-25 of SPU context restore sequence,
1871 * which resets an SPU either after a failed save, or
1872 * when using SPU for first time.
1873 */
1874
1875 disable_interrupts(prev, spu); /* Step 2. */
1876 inhibit_user_access(prev, spu); /* Step 3. */
1877 terminate_spu_app(prev, spu); /* Step 4. */
1878 set_switch_pending(prev, spu); /* Step 5. */
1879 remove_other_spu_access(prev, spu); /* Step 6. */
1880 suspend_mfc(prev, spu); /* Step 7. */
1881 wait_suspend_mfc_complete(prev, spu); /* Step 8. */
1882 if (!suspend_spe(prev, spu)) /* Step 9. */
1883 clear_spu_status(prev, spu); /* Step 10. */
1884 do_mfc_mssync(prev, spu); /* Step 11. */
1885 issue_mfc_tlbie(prev, spu); /* Step 12. */
1886 handle_pending_interrupts(prev, spu); /* Step 13. */
1887 purge_mfc_queue(prev, spu); /* Step 14. */
1888 wait_purge_complete(prev, spu); /* Step 15. */
1889 reset_spu_privcntl(prev, spu); /* Step 16. */
1890 reset_spu_lslr(prev, spu); /* Step 17. */
1891 setup_mfc_sr1(prev, spu); /* Step 18. */
1892 invalidate_slbs(prev, spu); /* Step 19. */
1893 reset_ch_part1(prev, spu); /* Step 20. */
1894 reset_ch_part2(prev, spu); /* Step 21. */
1895 enable_interrupts(prev, spu); /* Step 22. */
1896 set_switch_active(prev, spu); /* Step 23. */
1897 set_mfc_tclass_id(prev, spu); /* Step 24. */
1898 resume_mfc_queue(prev, spu); /* Step 25. */
1899}
1900
1901static void restore_lscsa(struct spu_state *next, struct spu *spu)
1902{
1903 /*
1904 * Perform steps 26-40 of SPU context restore sequence,
1905 * which restores regions of the local store and register
1906 * file.
1907 */
1908
1909 set_watchdog_timer(next, spu); /* Step 26. */
1910 setup_spu_status_part1(next, spu); /* Step 27. */
1911 setup_spu_status_part2(next, spu); /* Step 28. */
1912 restore_mfc_rag(next, spu); /* Step 29. */
1913 setup_mfc_slbs(next, spu); /* Step 30. */
1914 set_spu_npc(next, spu); /* Step 31. */
1915 set_signot1(next, spu); /* Step 32. */
1916 set_signot2(next, spu); /* Step 33. */
1917 setup_decr(next, spu); /* Step 34. */
1918 setup_ppu_mb(next, spu); /* Step 35. */
1919 setup_ppuint_mb(next, spu); /* Step 36. */
1920 send_restore_code(next, spu); /* Step 37. */
1921 set_ppu_querymask(next, spu); /* Step 38. */
1922 wait_tag_complete(next, spu); /* Step 39. */
1923 wait_spu_stopped(next, spu); /* Step 40. */
1924}
1925
1926static void restore_csa(struct spu_state *next, struct spu *spu)
1927{
1928 /*
1929 * Combine steps 41-76 of SPU context restore sequence, which
1930 * restore regions of the privileged & problem state areas.
1931 */
1932
1933 restore_spu_privcntl(next, spu); /* Step 41. */
1934 restore_status_part1(next, spu); /* Step 42. */
1935 restore_status_part2(next, spu); /* Step 43. */
1936 restore_ls_16kb(next, spu); /* Step 44. */
1937 wait_tag_complete(next, spu); /* Step 45. */
1938 suspend_mfc(next, spu); /* Step 46. */
1939 wait_suspend_mfc_complete(next, spu); /* Step 47. */
1940 issue_mfc_tlbie(next, spu); /* Step 48. */
1941 clear_interrupts(next, spu); /* Step 49. */
1942 restore_mfc_queues(next, spu); /* Step 50. */
1943 restore_ppu_querymask(next, spu); /* Step 51. */
1944 restore_ppu_querytype(next, spu); /* Step 52. */
1945 restore_mfc_csr_tsq(next, spu); /* Step 53. */
1946 restore_mfc_csr_cmd(next, spu); /* Step 54. */
1947 restore_mfc_csr_ato(next, spu); /* Step 55. */
1948 restore_mfc_tclass_id(next, spu); /* Step 56. */
1949 set_llr_event(next, spu); /* Step 57. */
1950 restore_decr_wrapped(next, spu); /* Step 58. */
1951 restore_ch_part1(next, spu); /* Step 59. */
1952 restore_ch_part2(next, spu); /* Step 60. */
1953 restore_spu_lslr(next, spu); /* Step 61. */
1954 restore_spu_cfg(next, spu); /* Step 62. */
1955 restore_pm_trace(next, spu); /* Step 63. */
1956 restore_spu_npc(next, spu); /* Step 64. */
1957 restore_spu_mb(next, spu); /* Step 65. */
1958 check_ppu_mb_stat(next, spu); /* Step 66. */
1959 check_ppuint_mb_stat(next, spu); /* Step 67. */
1960 restore_mfc_slbs(next, spu); /* Step 68. */
1961 restore_mfc_sr1(next, spu); /* Step 69. */
1962 restore_other_spu_access(next, spu); /* Step 70. */
1963 restore_spu_runcntl(next, spu); /* Step 71. */
1964 restore_mfc_cntl(next, spu); /* Step 72. */
1965 enable_user_access(next, spu); /* Step 73. */
1966 reset_switch_active(next, spu); /* Step 74. */
1967 reenable_interrupts(next, spu); /* Step 75. */
1968}
1969
1970static int __do_spu_save(struct spu_state *prev, struct spu *spu)
1971{
1972 int rc;
1973
1974 /*
1975 * SPU context save can be broken into three phases:
1976 *
1977 * (a) quiesce [steps 2-16].
1978 * (b) save of CSA, performed by PPE [steps 17-42]
1979 * (c) save of LSCSA, mostly performed by SPU [steps 43-52].
1980 *
1981 * Returns 0 on success.
1982 * 2,6 if failed to quiece SPU
1983 * 53 if SPU-side of save failed.
1984 */
1985
1986 rc = quiece_spu(prev, spu); /* Steps 2-16. */
1987 switch (rc) {
1988 default:
1989 case 2:
1990 case 6:
1991 harvest(prev, spu);
1992 return rc;
1993 break;
1994 case 0:
1995 break;
1996 }
1997 save_csa(prev, spu); /* Steps 17-43. */
1998 save_lscsa(prev, spu); /* Steps 44-53. */
1999 return check_save_status(prev, spu); /* Step 54. */
2000}
2001
2002static int __do_spu_restore(struct spu_state *next, struct spu *spu)
2003{
2004 int rc;
2005
2006 /*
2007 * SPU context restore can be broken into three phases:
2008 *
2009 * (a) harvest (or reset) SPU [steps 2-24].
2010 * (b) restore LSCSA [steps 25-40], mostly performed by SPU.
2011 * (c) restore CSA [steps 41-76], performed by PPE.
2012 *
2013 * The 'harvest' step is not performed here, but rather
2014 * as needed below.
2015 */
2016
2017 restore_lscsa(next, spu); /* Steps 24-39. */
2018 rc = check_restore_status(next, spu); /* Step 40. */
2019 switch (rc) {
2020 default:
2021 /* Failed. Return now. */
2022 return rc;
2023 break;
2024 case 0:
2025 /* Fall through to next step. */
2026 break;
2027 }
2028 restore_csa(next, spu);
2029
2030 return 0;
2031}
2032
2033/**
2034 * spu_save - SPU context save, with locking.
2035 * @prev: pointer to SPU context save area, to be saved.
2036 * @spu: pointer to SPU iomem structure.
2037 *
2038 * Acquire locks, perform the save operation then return.
2039 */
2040int spu_save(struct spu_state *prev, struct spu *spu)
2041{
2042 int rc;
2043
2044 acquire_spu_lock(spu); /* Step 1. */
2045 rc = __do_spu_save(prev, spu); /* Steps 2-53. */
2046 release_spu_lock(spu);
2047 if (rc) {
2048 panic("%s failed on SPU[%d], rc=%d.\n",
2049 __func__, spu->number, rc);
2050 }
2051 return rc;
2052}
2053
2054/**
2055 * spu_restore - SPU context restore, with harvest and locking.
2056 * @new: pointer to SPU context save area, to be restored.
2057 * @spu: pointer to SPU iomem structure.
2058 *
2059 * Perform harvest + restore, as we may not be coming
2060 * from a previous succesful save operation, and the
2061 * hardware state is unknown.
2062 */
2063int spu_restore(struct spu_state *new, struct spu *spu)
2064{
2065 int rc;
2066
2067 acquire_spu_lock(spu);
2068 harvest(NULL, spu);
2069 spu->stop_code = 0;
2070 spu->dar = 0;
2071 spu->dsisr = 0;
2072 spu->slb_replace = 0;
2073 spu->class_0_pending = 0;
2074 rc = __do_spu_restore(new, spu);
2075 release_spu_lock(spu);
2076 if (rc) {
2077 panic("%s failed on SPU[%d] rc=%d.\n",
2078 __func__, spu->number, rc);
2079 }
2080 return rc;
2081}
2082
2083/**
2084 * spu_harvest - SPU harvest (reset) operation
2085 * @spu: pointer to SPU iomem structure.
2086 *
2087 * Perform SPU harvest (reset) operation.
2088 */
2089void spu_harvest(struct spu *spu)
2090{
2091 acquire_spu_lock(spu);
2092 harvest(NULL, spu);
2093 release_spu_lock(spu);
2094}
2095
2096static void init_prob(struct spu_state *csa)
2097{
2098 csa->spu_chnlcnt_RW[9] = 1;
2099 csa->spu_chnlcnt_RW[21] = 16;
2100 csa->spu_chnlcnt_RW[23] = 1;
2101 csa->spu_chnlcnt_RW[28] = 1;
2102 csa->spu_chnlcnt_RW[30] = 1;
2103 csa->prob.spu_runcntl_RW = SPU_RUNCNTL_STOP;
2104}
2105
2106static void init_priv1(struct spu_state *csa)
2107{
2108 /* Enable decode, relocate, tlbie response, master runcntl. */
2109 csa->priv1.mfc_sr1_RW = MFC_STATE1_LOCAL_STORAGE_DECODE_MASK |
2110 MFC_STATE1_MASTER_RUN_CONTROL_MASK |
2111 MFC_STATE1_PROBLEM_STATE_MASK |
2112 MFC_STATE1_RELOCATE_MASK | MFC_STATE1_BUS_TLBIE_MASK;
2113
2114 /* Set storage description. */
2115 csa->priv1.mfc_sdr_RW = mfspr(SPRN_SDR1);
2116
2117 /* Enable OS-specific set of interrupts. */
2118 csa->priv1.int_mask_class0_RW = CLASS0_ENABLE_DMA_ALIGNMENT_INTR |
2119 CLASS0_ENABLE_INVALID_DMA_COMMAND_INTR |
2120 CLASS0_ENABLE_SPU_ERROR_INTR;
2121 csa->priv1.int_mask_class1_RW = CLASS1_ENABLE_SEGMENT_FAULT_INTR |
2122 CLASS1_ENABLE_STORAGE_FAULT_INTR;
2123 csa->priv1.int_mask_class2_RW = CLASS2_ENABLE_SPU_STOP_INTR |
2124 CLASS2_ENABLE_SPU_HALT_INTR;
2125}
2126
2127static void init_priv2(struct spu_state *csa)
2128{
2129 csa->priv2.spu_lslr_RW = LS_ADDR_MASK;
2130 csa->priv2.mfc_control_RW = MFC_CNTL_RESUME_DMA_QUEUE |
2131 MFC_CNTL_NORMAL_DMA_QUEUE_OPERATION |
2132 MFC_CNTL_DMA_QUEUES_EMPTY_MASK;
2133}
2134
2135/**
2136 * spu_alloc_csa - allocate and initialize an SPU context save area.
2137 *
2138 * Allocate and initialize the contents of an SPU context save area.
2139 * This includes enabling address translation, interrupt masks, etc.,
2140 * as appropriate for the given OS environment.
2141 *
2142 * Note that storage for the 'lscsa' is allocated separately,
2143 * as it is by far the largest of the context save regions,
2144 * and may need to be pinned or otherwise specially aligned.
2145 */
2146void spu_init_csa(struct spu_state *csa)
2147{
2148 struct spu_lscsa *lscsa;
2149 unsigned char *p;
2150
2151 if (!csa)
2152 return;
2153 memset(csa, 0, sizeof(struct spu_state));
2154
2155 lscsa = vmalloc(sizeof(struct spu_lscsa));
2156 if (!lscsa)
2157 return;
2158
2159 memset(lscsa, 0, sizeof(struct spu_lscsa));
2160 csa->lscsa = lscsa;
2161 csa->register_lock = SPIN_LOCK_UNLOCKED;
2162
2163 /* Set LS pages reserved to allow for user-space mapping. */
2164 for (p = lscsa->ls; p < lscsa->ls + LS_SIZE; p += PAGE_SIZE)
2165 SetPageReserved(vmalloc_to_page(p));
2166
2167 init_prob(csa);
2168 init_priv1(csa);
2169 init_priv2(csa);
2170}
2171
2172void spu_fini_csa(struct spu_state *csa)
2173{
2174 /* Clear reserved bit before vfree. */
2175 unsigned char *p;
2176 for (p = csa->lscsa->ls; p < csa->lscsa->ls + LS_SIZE; p += PAGE_SIZE)
2177 ClearPageReserved(vmalloc_to_page(p));
2178
2179 vfree(csa->lscsa);
2180}
diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
new file mode 100644
index 000000000000..d549aa7ebea6
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -0,0 +1,101 @@
1#include <linux/file.h>
2#include <linux/fs.h>
3#include <linux/module.h>
4#include <linux/mount.h>
5#include <linux/namei.h>
6
7#include <asm/uaccess.h>
8
9#include "spufs.h"
10
11/**
12 * sys_spu_run - run code loaded into an SPU
13 *
14 * @unpc: next program counter for the SPU
15 * @ustatus: status of the SPU
16 *
17 * This system call transfers the control of execution of a
18 * user space thread to an SPU. It will return when the
19 * SPU has finished executing or when it hits an error
20 * condition and it will be interrupted if a signal needs
21 * to be delivered to a handler in user space.
22 *
23 * The next program counter is set to the passed value
24 * before the SPU starts fetching code and the user space
25 * pointer gets updated with the new value when returning
26 * from kernel space.
27 *
28 * The status value returned from spu_run reflects the
29 * value of the spu_status register after the SPU has stopped.
30 *
31 */
32long do_spu_run(struct file *filp, __u32 __user *unpc, __u32 __user *ustatus)
33{
34 long ret;
35 struct spufs_inode_info *i;
36 u32 npc, status;
37
38 ret = -EFAULT;
39 if (get_user(npc, unpc) || get_user(status, ustatus))
40 goto out;
41
42 /* check if this file was created by spu_create */
43 ret = -EINVAL;
44 if (filp->f_op != &spufs_context_fops)
45 goto out;
46
47 i = SPUFS_I(filp->f_dentry->d_inode);
48 ret = spufs_run_spu(filp, i->i_ctx, &npc, &status);
49
50 if (put_user(npc, unpc) || put_user(status, ustatus))
51 ret = -EFAULT;
52out:
53 return ret;
54}
55
56#ifndef MODULE
57asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
58{
59 int fput_needed;
60 struct file *filp;
61 long ret;
62
63 ret = -EBADF;
64 filp = fget_light(fd, &fput_needed);
65 if (filp) {
66 ret = do_spu_run(filp, unpc, ustatus);
67 fput_light(filp, fput_needed);
68 }
69
70 return ret;
71}
72#endif
73
74asmlinkage long sys_spu_create(const char __user *pathname,
75 unsigned int flags, mode_t mode)
76{
77 char *tmp;
78 int ret;
79
80 tmp = getname(pathname);
81 ret = PTR_ERR(tmp);
82 if (!IS_ERR(tmp)) {
83 struct nameidata nd;
84
85 ret = path_lookup(tmp, LOOKUP_PARENT|
86 LOOKUP_OPEN|LOOKUP_CREATE, &nd);
87 if (!ret) {
88 ret = spufs_create_thread(&nd, flags, mode);
89 path_release(&nd);
90 }
91 putname(tmp);
92 }
93
94 return ret;
95}
96
97struct spufs_calls spufs_calls = {
98 .create_thread = sys_spu_create,
99 .spu_run = do_spu_run,
100 .owner = THIS_MODULE,
101};
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index dda5f2c72c25..4ec8ba737e7d 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -49,7 +49,6 @@
49#include <asm/hydra.h> 49#include <asm/hydra.h>
50#include <asm/sections.h> 50#include <asm/sections.h>
51#include <asm/time.h> 51#include <asm/time.h>
52#include <asm/btext.h>
53#include <asm/i8259.h> 52#include <asm/i8259.h>
54#include <asm/mpic.h> 53#include <asm/mpic.h>
55#include <asm/rtas.h> 54#include <asm/rtas.h>
@@ -58,7 +57,6 @@
58#include "chrp.h" 57#include "chrp.h"
59 58
60void rtas_indicator_progress(char *, unsigned short); 59void rtas_indicator_progress(char *, unsigned short);
61void btext_progress(char *, unsigned short);
62 60
63int _chrp_type; 61int _chrp_type;
64EXPORT_SYMBOL(_chrp_type); 62EXPORT_SYMBOL(_chrp_type);
@@ -264,11 +262,6 @@ void __init chrp_setup_arch(void)
264 ppc_md.set_rtc_time = rtas_set_rtc_time; 262 ppc_md.set_rtc_time = rtas_set_rtc_time;
265 } 263 }
266 264
267#ifdef CONFIG_BOOTX_TEXT
268 if (ppc_md.progress == NULL && boot_text_mapped)
269 ppc_md.progress = btext_progress;
270#endif
271
272#ifdef CONFIG_BLK_DEV_INITRD 265#ifdef CONFIG_BLK_DEV_INITRD
273 /* this is fine for chrp */ 266 /* this is fine for chrp */
274 initrd_below_start_ok = 1; 267 initrd_below_start_ok = 1;
@@ -522,12 +515,3 @@ void __init chrp_init(void)
522 smp_ops = &chrp_smp_ops; 515 smp_ops = &chrp_smp_ops;
523#endif /* CONFIG_SMP */ 516#endif /* CONFIG_SMP */
524} 517}
525
526#ifdef CONFIG_BOOTX_TEXT
527void
528btext_progress(char *s, unsigned short hex)
529{
530 btext_drawstring(s);
531 btext_drawstring("\n");
532}
533#endif /* CONFIG_BOOTX_TEXT */
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index a58daa153686..42e978e4897a 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -35,161 +35,138 @@
35#include <linux/irq.h> 35#include <linux/irq.h>
36#include <linux/spinlock.h> 36#include <linux/spinlock.h>
37 37
38#include <asm/paca.h>
38#include <asm/iseries/hv_types.h> 39#include <asm/iseries/hv_types.h>
39#include <asm/iseries/hv_lp_event.h> 40#include <asm/iseries/hv_lp_event.h>
40#include <asm/iseries/hv_call_xm.h> 41#include <asm/iseries/hv_call_xm.h>
42#include <asm/iseries/it_lp_queue.h>
41 43
42#include "irq.h" 44#include "irq.h"
43#include "call_pci.h" 45#include "call_pci.h"
44 46
45static long Pci_Interrupt_Count; 47#if defined(CONFIG_SMP)
46static long Pci_Event_Count; 48extern void iSeries_smp_message_recv(struct pt_regs *);
47 49#endif
48enum XmPciLpEvent_Subtype {
49 XmPciLpEvent_BusCreated = 0, // PHB has been created
50 XmPciLpEvent_BusError = 1, // PHB has failed
51 XmPciLpEvent_BusFailed = 2, // Msg to Secondary, Primary failed bus
52 XmPciLpEvent_NodeFailed = 4, // Multi-adapter bridge has failed
53 XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered
54 XmPciLpEvent_BusRecovered = 12, // PHB has been recovered
55 XmPciLpEvent_UnQuiesceBus = 18, // Secondary bus unqiescing
56 XmPciLpEvent_BridgeError = 21, // Bridge Error
57 XmPciLpEvent_SlotInterrupt = 22 // Slot interrupt
58};
59
60struct XmPciLpEvent_BusInterrupt {
61 HvBusNumber busNumber;
62 HvSubBusNumber subBusNumber;
63};
64 50
65struct XmPciLpEvent_NodeInterrupt { 51enum pci_event_type {
66 HvBusNumber busNumber; 52 pe_bus_created = 0, /* PHB has been created */
67 HvSubBusNumber subBusNumber; 53 pe_bus_error = 1, /* PHB has failed */
68 HvAgentId deviceId; 54 pe_bus_failed = 2, /* Msg to Secondary, Primary failed bus */
55 pe_node_failed = 4, /* Multi-adapter bridge has failed */
56 pe_node_recovered = 5, /* Multi-adapter bridge has recovered */
57 pe_bus_recovered = 12, /* PHB has been recovered */
58 pe_unquiese_bus = 18, /* Secondary bus unqiescing */
59 pe_bridge_error = 21, /* Bridge Error */
60 pe_slot_interrupt = 22 /* Slot interrupt */
69}; 61};
70 62
71struct XmPciLpEvent { 63struct pci_event {
72 struct HvLpEvent hvLpEvent; 64 struct HvLpEvent event;
73
74 union { 65 union {
75 u64 alignData; // Align on an 8-byte boundary 66 u64 __align; /* Align on an 8-byte boundary */
76
77 struct { 67 struct {
78 u32 fisr; 68 u32 fisr;
79 HvBusNumber busNumber; 69 HvBusNumber bus_number;
80 HvSubBusNumber subBusNumber; 70 HvSubBusNumber sub_bus_number;
81 HvAgentId deviceId; 71 HvAgentId dev_id;
82 } slotInterrupt; 72 } slot;
83 73 struct {
84 struct XmPciLpEvent_BusInterrupt busFailed; 74 HvBusNumber bus_number;
85 struct XmPciLpEvent_BusInterrupt busRecovered; 75 HvSubBusNumber sub_bus_number;
86 struct XmPciLpEvent_BusInterrupt busCreated; 76 } bus;
87 77 struct {
88 struct XmPciLpEvent_NodeInterrupt nodeFailed; 78 HvBusNumber bus_number;
89 struct XmPciLpEvent_NodeInterrupt nodeRecovered; 79 HvSubBusNumber sub_bus_number;
90 80 HvAgentId dev_id;
91 } eventData; 81 } node;
92 82 } data;
93}; 83};
94 84
95static void intReceived(struct XmPciLpEvent *eventParm, 85static DEFINE_SPINLOCK(pending_irqs_lock);
96 struct pt_regs *regsParm) 86static int num_pending_irqs;
87static int pending_irqs[NR_IRQS];
88
89static void int_received(struct pci_event *event, struct pt_regs *regs)
97{ 90{
98 int irq; 91 int irq;
99#ifdef CONFIG_IRQSTACKS
100 struct thread_info *curtp, *irqtp;
101#endif
102 92
103 ++Pci_Interrupt_Count; 93 switch (event->event.xSubtype) {
104 94 case pe_slot_interrupt:
105 switch (eventParm->hvLpEvent.xSubtype) { 95 irq = event->event.xCorrelationToken;
106 case XmPciLpEvent_SlotInterrupt: 96 if (irq < NR_IRQS) {
107 irq = eventParm->hvLpEvent.xCorrelationToken; 97 spin_lock(&pending_irqs_lock);
108 /* Dispatch the interrupt handlers for this irq */ 98 pending_irqs[irq]++;
109#ifdef CONFIG_IRQSTACKS 99 num_pending_irqs++;
110 /* Switch to the irq stack to handle this */ 100 spin_unlock(&pending_irqs_lock);
111 curtp = current_thread_info(); 101 } else {
112 irqtp = hardirq_ctx[smp_processor_id()]; 102 printk(KERN_WARNING "int_received: bad irq number %d\n",
113 if (curtp != irqtp) { 103 irq);
114 irqtp->task = curtp->task; 104 HvCallPci_eoi(event->data.slot.bus_number,
115 irqtp->flags = 0; 105 event->data.slot.sub_bus_number,
116 call___do_IRQ(irq, regsParm, irqtp); 106 event->data.slot.dev_id);
117 irqtp->task = NULL; 107 }
118 if (irqtp->flags)
119 set_bits(irqtp->flags, &curtp->flags);
120 } else
121#endif
122 __do_IRQ(irq, regsParm);
123 HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
124 eventParm->eventData.slotInterrupt.subBusNumber,
125 eventParm->eventData.slotInterrupt.deviceId);
126 break; 108 break;
127 /* Ignore error recovery events for now */ 109 /* Ignore error recovery events for now */
128 case XmPciLpEvent_BusCreated: 110 case pe_bus_created:
129 printk(KERN_INFO "intReceived: system bus %d created\n", 111 printk(KERN_INFO "int_received: system bus %d created\n",
130 eventParm->eventData.busCreated.busNumber); 112 event->data.bus.bus_number);
131 break; 113 break;
132 case XmPciLpEvent_BusError: 114 case pe_bus_error:
133 case XmPciLpEvent_BusFailed: 115 case pe_bus_failed:
134 printk(KERN_INFO "intReceived: system bus %d failed\n", 116 printk(KERN_INFO "int_received: system bus %d failed\n",
135 eventParm->eventData.busFailed.busNumber); 117 event->data.bus.bus_number);
136 break; 118 break;
137 case XmPciLpEvent_BusRecovered: 119 case pe_bus_recovered:
138 case XmPciLpEvent_UnQuiesceBus: 120 case pe_unquiese_bus:
139 printk(KERN_INFO "intReceived: system bus %d recovered\n", 121 printk(KERN_INFO "int_received: system bus %d recovered\n",
140 eventParm->eventData.busRecovered.busNumber); 122 event->data.bus.bus_number);
141 break; 123 break;
142 case XmPciLpEvent_NodeFailed: 124 case pe_node_failed:
143 case XmPciLpEvent_BridgeError: 125 case pe_bridge_error:
144 printk(KERN_INFO 126 printk(KERN_INFO
145 "intReceived: multi-adapter bridge %d/%d/%d failed\n", 127 "int_received: multi-adapter bridge %d/%d/%d failed\n",
146 eventParm->eventData.nodeFailed.busNumber, 128 event->data.node.bus_number,
147 eventParm->eventData.nodeFailed.subBusNumber, 129 event->data.node.sub_bus_number,
148 eventParm->eventData.nodeFailed.deviceId); 130 event->data.node.dev_id);
149 break; 131 break;
150 case XmPciLpEvent_NodeRecovered: 132 case pe_node_recovered:
151 printk(KERN_INFO 133 printk(KERN_INFO
152 "intReceived: multi-adapter bridge %d/%d/%d recovered\n", 134 "int_received: multi-adapter bridge %d/%d/%d recovered\n",
153 eventParm->eventData.nodeRecovered.busNumber, 135 event->data.node.bus_number,
154 eventParm->eventData.nodeRecovered.subBusNumber, 136 event->data.node.sub_bus_number,
155 eventParm->eventData.nodeRecovered.deviceId); 137 event->data.node.dev_id);
156 break; 138 break;
157 default: 139 default:
158 printk(KERN_ERR 140 printk(KERN_ERR
159 "intReceived: unrecognized event subtype 0x%x\n", 141 "int_received: unrecognized event subtype 0x%x\n",
160 eventParm->hvLpEvent.xSubtype); 142 event->event.xSubtype);
161 break; 143 break;
162 } 144 }
163} 145}
164 146
165static void XmPciLpEvent_handler(struct HvLpEvent *eventParm, 147static void pci_event_handler(struct HvLpEvent *event, struct pt_regs *regs)
166 struct pt_regs *regsParm)
167{ 148{
168#ifdef CONFIG_PCI 149 if (event && (event->xType == HvLpEvent_Type_PciIo)) {
169 ++Pci_Event_Count; 150 switch (event->xFlags.xFunction) {
170
171 if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) {
172 switch (eventParm->xFlags.xFunction) {
173 case HvLpEvent_Function_Int: 151 case HvLpEvent_Function_Int:
174 intReceived((struct XmPciLpEvent *)eventParm, regsParm); 152 int_received((struct pci_event *)event, regs);
175 break; 153 break;
176 case HvLpEvent_Function_Ack: 154 case HvLpEvent_Function_Ack:
177 printk(KERN_ERR 155 printk(KERN_ERR
178 "XmPciLpEvent_handler: unexpected ack received\n"); 156 "pci_event_handler: unexpected ack received\n");
179 break; 157 break;
180 default: 158 default:
181 printk(KERN_ERR 159 printk(KERN_ERR
182 "XmPciLpEvent_handler: unexpected event function %d\n", 160 "pci_event_handler: unexpected event function %d\n",
183 (int)eventParm->xFlags.xFunction); 161 (int)event->xFlags.xFunction);
184 break; 162 break;
185 } 163 }
186 } else if (eventParm) 164 } else if (event)
187 printk(KERN_ERR 165 printk(KERN_ERR
188 "XmPciLpEvent_handler: Unrecognized PCI event type 0x%x\n", 166 "pci_event_handler: Unrecognized PCI event type 0x%x\n",
189 (int)eventParm->xType); 167 (int)event->xType);
190 else 168 else
191 printk(KERN_ERR "XmPciLpEvent_handler: NULL event received\n"); 169 printk(KERN_ERR "pci_event_handler: NULL event received\n");
192#endif
193} 170}
194 171
195/* 172/*
@@ -199,20 +176,21 @@ static void XmPciLpEvent_handler(struct HvLpEvent *eventParm,
199void __init iSeries_init_IRQ(void) 176void __init iSeries_init_IRQ(void)
200{ 177{
201 /* Register PCI event handler and open an event path */ 178 /* Register PCI event handler and open an event path */
202 int xRc; 179 int ret;
203 180
204 xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, 181 ret = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo,
205 &XmPciLpEvent_handler); 182 &pci_event_handler);
206 if (xRc == 0) { 183 if (ret == 0) {
207 xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0); 184 ret = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0);
208 if (xRc != 0) 185 if (ret != 0)
209 printk(KERN_ERR "iSeries_init_IRQ: open event path " 186 printk(KERN_ERR "iseries_init_IRQ: open event path "
210 "failed with rc 0x%x\n", xRc); 187 "failed with rc 0x%x\n", ret);
211 } else 188 } else
212 printk(KERN_ERR "iSeries_init_IRQ: register handler " 189 printk(KERN_ERR "iseries_init_IRQ: register handler "
213 "failed with rc 0x%x\n", xRc); 190 "failed with rc 0x%x\n", ret);
214} 191}
215 192
193#define REAL_IRQ_TO_SUBBUS(irq) (((irq) >> 14) & 0xff)
216#define REAL_IRQ_TO_BUS(irq) ((((irq) >> 6) & 0xff) + 1) 194#define REAL_IRQ_TO_BUS(irq) ((((irq) >> 6) & 0xff) + 1)
217#define REAL_IRQ_TO_IDSEL(irq) ((((irq) >> 3) & 7) + 1) 195#define REAL_IRQ_TO_IDSEL(irq) ((((irq) >> 3) & 7) + 1)
218#define REAL_IRQ_TO_FUNC(irq) ((irq) & 7) 196#define REAL_IRQ_TO_FUNC(irq) ((irq) & 7)
@@ -221,40 +199,40 @@ void __init iSeries_init_IRQ(void)
221 * This will be called by device drivers (via enable_IRQ) 199 * This will be called by device drivers (via enable_IRQ)
222 * to enable INTA in the bridge interrupt status register. 200 * to enable INTA in the bridge interrupt status register.
223 */ 201 */
224static void iSeries_enable_IRQ(unsigned int irq) 202static void iseries_enable_IRQ(unsigned int irq)
225{ 203{
226 u32 bus, deviceId, function, mask; 204 u32 bus, dev_id, function, mask;
227 const u32 subBus = 0; 205 const u32 sub_bus = 0;
228 unsigned int rirq = virt_irq_to_real_map[irq]; 206 unsigned int rirq = virt_irq_to_real_map[irq];
229 207
230 /* The IRQ has already been locked by the caller */ 208 /* The IRQ has already been locked by the caller */
231 bus = REAL_IRQ_TO_BUS(rirq); 209 bus = REAL_IRQ_TO_BUS(rirq);
232 function = REAL_IRQ_TO_FUNC(rirq); 210 function = REAL_IRQ_TO_FUNC(rirq);
233 deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; 211 dev_id = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
234 212
235 /* Unmask secondary INTA */ 213 /* Unmask secondary INTA */
236 mask = 0x80000000; 214 mask = 0x80000000;
237 HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask); 215 HvCallPci_unmaskInterrupts(bus, sub_bus, dev_id, mask);
238} 216}
239 217
240/* This is called by iSeries_activate_IRQs */ 218/* This is called by iseries_activate_IRQs */
241static unsigned int iSeries_startup_IRQ(unsigned int irq) 219static unsigned int iseries_startup_IRQ(unsigned int irq)
242{ 220{
243 u32 bus, deviceId, function, mask; 221 u32 bus, dev_id, function, mask;
244 const u32 subBus = 0; 222 const u32 sub_bus = 0;
245 unsigned int rirq = virt_irq_to_real_map[irq]; 223 unsigned int rirq = virt_irq_to_real_map[irq];
246 224
247 bus = REAL_IRQ_TO_BUS(rirq); 225 bus = REAL_IRQ_TO_BUS(rirq);
248 function = REAL_IRQ_TO_FUNC(rirq); 226 function = REAL_IRQ_TO_FUNC(rirq);
249 deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; 227 dev_id = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
250 228
251 /* Link the IRQ number to the bridge */ 229 /* Link the IRQ number to the bridge */
252 HvCallXm_connectBusUnit(bus, subBus, deviceId, irq); 230 HvCallXm_connectBusUnit(bus, sub_bus, dev_id, irq);
253 231
254 /* Unmask bridge interrupts in the FISR */ 232 /* Unmask bridge interrupts in the FISR */
255 mask = 0x01010000 << function; 233 mask = 0x01010000 << function;
256 HvCallPci_unmaskFisr(bus, subBus, deviceId, mask); 234 HvCallPci_unmaskFisr(bus, sub_bus, dev_id, mask);
257 iSeries_enable_IRQ(irq); 235 iseries_enable_IRQ(irq);
258 return 0; 236 return 0;
259} 237}
260 238
@@ -279,78 +257,115 @@ void __init iSeries_activate_IRQs()
279} 257}
280 258
281/* this is not called anywhere currently */ 259/* this is not called anywhere currently */
282static void iSeries_shutdown_IRQ(unsigned int irq) 260static void iseries_shutdown_IRQ(unsigned int irq)
283{ 261{
284 u32 bus, deviceId, function, mask; 262 u32 bus, dev_id, function, mask;
285 const u32 subBus = 0; 263 const u32 sub_bus = 0;
286 unsigned int rirq = virt_irq_to_real_map[irq]; 264 unsigned int rirq = virt_irq_to_real_map[irq];
287 265
288 /* irq should be locked by the caller */ 266 /* irq should be locked by the caller */
289 bus = REAL_IRQ_TO_BUS(rirq); 267 bus = REAL_IRQ_TO_BUS(rirq);
290 function = REAL_IRQ_TO_FUNC(rirq); 268 function = REAL_IRQ_TO_FUNC(rirq);
291 deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; 269 dev_id = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
292 270
293 /* Invalidate the IRQ number in the bridge */ 271 /* Invalidate the IRQ number in the bridge */
294 HvCallXm_connectBusUnit(bus, subBus, deviceId, 0); 272 HvCallXm_connectBusUnit(bus, sub_bus, dev_id, 0);
295 273
296 /* Mask bridge interrupts in the FISR */ 274 /* Mask bridge interrupts in the FISR */
297 mask = 0x01010000 << function; 275 mask = 0x01010000 << function;
298 HvCallPci_maskFisr(bus, subBus, deviceId, mask); 276 HvCallPci_maskFisr(bus, sub_bus, dev_id, mask);
299} 277}
300 278
301/* 279/*
302 * This will be called by device drivers (via disable_IRQ) 280 * This will be called by device drivers (via disable_IRQ)
303 * to disable INTA in the bridge interrupt status register. 281 * to disable INTA in the bridge interrupt status register.
304 */ 282 */
305static void iSeries_disable_IRQ(unsigned int irq) 283static void iseries_disable_IRQ(unsigned int irq)
306{ 284{
307 u32 bus, deviceId, function, mask; 285 u32 bus, dev_id, function, mask;
308 const u32 subBus = 0; 286 const u32 sub_bus = 0;
309 unsigned int rirq = virt_irq_to_real_map[irq]; 287 unsigned int rirq = virt_irq_to_real_map[irq];
310 288
311 /* The IRQ has already been locked by the caller */ 289 /* The IRQ has already been locked by the caller */
312 bus = REAL_IRQ_TO_BUS(rirq); 290 bus = REAL_IRQ_TO_BUS(rirq);
313 function = REAL_IRQ_TO_FUNC(rirq); 291 function = REAL_IRQ_TO_FUNC(rirq);
314 deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; 292 dev_id = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
315 293
316 /* Mask secondary INTA */ 294 /* Mask secondary INTA */
317 mask = 0x80000000; 295 mask = 0x80000000;
318 HvCallPci_maskInterrupts(bus, subBus, deviceId, mask); 296 HvCallPci_maskInterrupts(bus, sub_bus, dev_id, mask);
319} 297}
320 298
321/* 299static void iseries_end_IRQ(unsigned int irq)
322 * This does nothing because there is not enough information
323 * provided to do the EOI HvCall. This is done by XmPciLpEvent.c
324 */
325static void iSeries_end_IRQ(unsigned int irq)
326{ 300{
301 unsigned int rirq = virt_irq_to_real_map[irq];
302
303 HvCallPci_eoi(REAL_IRQ_TO_BUS(rirq), REAL_IRQ_TO_SUBBUS(rirq),
304 (REAL_IRQ_TO_IDSEL(rirq) << 4) + REAL_IRQ_TO_FUNC(rirq));
327} 305}
328 306
329static hw_irq_controller iSeries_IRQ_handler = { 307static hw_irq_controller iSeries_IRQ_handler = {
330 .typename = "iSeries irq controller", 308 .typename = "iSeries irq controller",
331 .startup = iSeries_startup_IRQ, 309 .startup = iseries_startup_IRQ,
332 .shutdown = iSeries_shutdown_IRQ, 310 .shutdown = iseries_shutdown_IRQ,
333 .enable = iSeries_enable_IRQ, 311 .enable = iseries_enable_IRQ,
334 .disable = iSeries_disable_IRQ, 312 .disable = iseries_disable_IRQ,
335 .end = iSeries_end_IRQ 313 .end = iseries_end_IRQ
336}; 314};
337 315
338/* 316/*
339 * This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot 317 * This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot
340 * It calculates the irq value for the slot. 318 * It calculates the irq value for the slot.
341 * Note that subBusNumber is always 0 (at the moment at least). 319 * Note that sub_bus is always 0 (at the moment at least).
342 */ 320 */
343int __init iSeries_allocate_IRQ(HvBusNumber busNumber, 321int __init iSeries_allocate_IRQ(HvBusNumber bus,
344 HvSubBusNumber subBusNumber, HvAgentId deviceId) 322 HvSubBusNumber sub_bus, HvAgentId dev_id)
345{ 323{
346 int virtirq; 324 int virtirq;
347 unsigned int realirq; 325 unsigned int realirq;
348 u8 idsel = (deviceId >> 4); 326 u8 idsel = (dev_id >> 4);
349 u8 function = deviceId & 7; 327 u8 function = dev_id & 7;
350 328
351 realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function; 329 realirq = (((((sub_bus << 8) + (bus - 1)) << 3) + (idsel - 1)) << 3)
330 + function;
352 virtirq = virt_irq_create_mapping(realirq); 331 virtirq = virt_irq_create_mapping(realirq);
353 332
354 irq_desc[virtirq].handler = &iSeries_IRQ_handler; 333 irq_desc[virtirq].handler = &iSeries_IRQ_handler;
355 return virtirq; 334 return virtirq;
356} 335}
336
337/*
338 * Get the next pending IRQ.
339 */
340int iSeries_get_irq(struct pt_regs *regs)
341{
342 struct paca_struct *lpaca;
343 /* -2 means ignore this interrupt */
344 int irq = -2;
345
346 lpaca = get_paca();
347#ifdef CONFIG_SMP
348 if (lpaca->lppaca.int_dword.fields.ipi_cnt) {
349 lpaca->lppaca.int_dword.fields.ipi_cnt = 0;
350 iSeries_smp_message_recv(regs);
351 }
352#endif /* CONFIG_SMP */
353 if (hvlpevent_is_pending())
354 process_hvlpevents(regs);
355
356 if (num_pending_irqs) {
357 spin_lock(&pending_irqs_lock);
358 for (irq = 0; irq < NR_IRQS; irq++) {
359 if (pending_irqs[irq]) {
360 pending_irqs[irq]--;
361 num_pending_irqs--;
362 break;
363 }
364 }
365 spin_unlock(&pending_irqs_lock);
366 if (irq >= NR_IRQS)
367 irq = -2;
368 }
369
370 return irq;
371}
diff --git a/arch/powerpc/platforms/iseries/irq.h b/arch/powerpc/platforms/iseries/irq.h
index 5f643f16ecc0..b9c801ba5a47 100644
--- a/arch/powerpc/platforms/iseries/irq.h
+++ b/arch/powerpc/platforms/iseries/irq.h
@@ -4,5 +4,6 @@
4extern void iSeries_init_IRQ(void); 4extern void iSeries_init_IRQ(void);
5extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId); 5extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId);
6extern void iSeries_activate_IRQs(void); 6extern void iSeries_activate_IRQs(void);
7extern int iSeries_get_irq(struct pt_regs *);
7 8
8#endif /* _ISERIES_IRQ_H */ 9#endif /* _ISERIES_IRQ_H */
diff --git a/arch/powerpc/platforms/iseries/lpardata.c b/arch/powerpc/platforms/iseries/lpardata.c
index bb8c91537f35..ea72385aaf0a 100644
--- a/arch/powerpc/platforms/iseries/lpardata.c
+++ b/arch/powerpc/platforms/iseries/lpardata.c
@@ -225,3 +225,10 @@ struct ItVpdAreas itVpdAreas = {
225 0,0 225 0,0
226 } 226 }
227}; 227};
228
229struct ItLpRegSave iseries_reg_save[] = {
230 [0 ... (NR_CPUS-1)] = {
231 .xDesc = 0xd397d9e2, /* "LpRS" */
232 .xSize = sizeof(struct ItLpRegSave),
233 },
234};
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index da26639190db..ad5ef80500ce 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -571,16 +571,6 @@ static void iSeries_show_cpuinfo(struct seq_file *m)
571 571
572/* 572/*
573 * Document me. 573 * Document me.
574 * and Implement me.
575 */
576static int iSeries_get_irq(struct pt_regs *regs)
577{
578 /* -2 means ignore this interrupt */
579 return -2;
580}
581
582/*
583 * Document me.
584 */ 574 */
585static void iSeries_restart(char *cmd) 575static void iSeries_restart(char *cmd)
586{ 576{
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index 7ece8983a105..dd73e38bfb7d 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -51,6 +51,7 @@
51#include <asm/pgtable.h> 51#include <asm/pgtable.h>
52#include <asm/bitops.h> 52#include <asm/bitops.h>
53#include <asm/io.h> 53#include <asm/io.h>
54#include <asm/kexec.h>
54#include <asm/pci-bridge.h> 55#include <asm/pci-bridge.h>
55#include <asm/iommu.h> 56#include <asm/iommu.h>
56#include <asm/machdep.h> 57#include <asm/machdep.h>
@@ -191,24 +192,10 @@ static void __init maple_init_early(void)
191 */ 192 */
192 hpte_init_native(); 193 hpte_init_native();
193 194
194 /* Find the serial port */
195 generic_find_legacy_serial_ports(&physport, &default_speed);
196
197 DBG("phys port addr: %lx\n", (long)physport);
198
199 if (physport) {
200 void *comport;
201 /* Map the uart for udbg. */
202 comport = (void *)ioremap(physport, 16);
203 udbg_init_uart(comport, default_speed);
204
205 DBG("Hello World !\n");
206 }
207
208 /* Setup interrupt mapping options */ 195 /* Setup interrupt mapping options */
209 ppc64_interrupt_controller = IC_OPEN_PIC; 196 ppc64_interrupt_controller = IC_OPEN_PIC;
210 197
211 iommu_init_early_u3(); 198 iommu_init_early_dart();
212 199
213 DBG(" <- maple_init_early\n"); 200 DBG(" <- maple_init_early\n");
214} 201}
@@ -270,7 +257,7 @@ static int __init maple_probe(int platform)
270 * occupies having to be broken up so the DART itself is not 257 * occupies having to be broken up so the DART itself is not
271 * part of the cacheable linar mapping 258 * part of the cacheable linar mapping
272 */ 259 */
273 alloc_u3_dart_table(); 260 alloc_dart_table();
274 261
275 return 1; 262 return 1;
276} 263}
@@ -292,4 +279,9 @@ struct machdep_calls __initdata maple_md = {
292 .calibrate_decr = generic_calibrate_decr, 279 .calibrate_decr = generic_calibrate_decr,
293 .progress = maple_progress, 280 .progress = maple_progress,
294 .idle_loop = native_idle, 281 .idle_loop = native_idle,
282#ifdef CONFIG_KEXEC
283 .machine_kexec = default_machine_kexec,
284 .machine_kexec_prepare = default_machine_kexec_prepare,
285 .machine_crash_shutdown = default_machine_crash_shutdown,
286#endif
295}; 287};
diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
index c9df44fcf571..78093d7f97af 100644
--- a/arch/powerpc/platforms/powermac/Makefile
+++ b/arch/powerpc/platforms/powermac/Makefile
@@ -1,9 +1,14 @@
1CFLAGS_bootx_init.o += -fPIC
2
1obj-y += pic.o setup.o time.o feature.o pci.o \ 3obj-y += pic.o setup.o time.o feature.o pci.o \
2 sleep.o low_i2c.o cache.o 4 sleep.o low_i2c.o cache.o pfunc_core.o \
5 pfunc_base.o
3obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o 6obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o
4obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o 7obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o
5obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o 8obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o
6obj-$(CONFIG_NVRAM) += nvram.o 9obj-$(CONFIG_NVRAM) += nvram.o
7# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff 10# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff
8obj-$(CONFIG_PPC64) += nvram.o 11obj-$(CONFIG_PPC64) += nvram.o
12obj-$(CONFIG_PPC32) += bootx_init.o
9obj-$(CONFIG_SMP) += smp.o 13obj-$(CONFIG_SMP) += smp.o
14obj-$(CONFIG_PPC_MERGE) += udbg_scc.o udbg_adb.o
diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
new file mode 100644
index 000000000000..fa8b4d7b5ded
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/bootx_init.c
@@ -0,0 +1,547 @@
1/*
2 * Early boot support code for BootX bootloader
3 *
4 * Copyright (C) 2005 Ben. Herrenschmidt (benh@kernel.crashing.org)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/config.h>
13#include <linux/kernel.h>
14#include <linux/string.h>
15#include <linux/init.h>
16#include <linux/version.h>
17#include <asm/sections.h>
18#include <asm/prom.h>
19#include <asm/page.h>
20#include <asm/bootx.h>
21#include <asm/bootinfo.h>
22#include <asm/btext.h>
23#include <asm/io.h>
24
25#undef DEBUG
26#define SET_BOOT_BAT
27
28#ifdef DEBUG
29#define DBG(fmt...) do { bootx_printf(fmt); } while(0)
30#else
31#define DBG(fmt...) do { } while(0)
32#endif
33
34extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
35
36static unsigned long __initdata bootx_dt_strbase;
37static unsigned long __initdata bootx_dt_strend;
38static unsigned long __initdata bootx_node_chosen;
39static boot_infos_t * __initdata bootx_info;
40static char __initdata bootx_disp_path[256];
41
42/* Is boot-info compatible ? */
43#define BOOT_INFO_IS_COMPATIBLE(bi) \
44 ((bi)->compatible_version <= BOOT_INFO_VERSION)
45#define BOOT_INFO_IS_V2_COMPATIBLE(bi) ((bi)->version >= 2)
46#define BOOT_INFO_IS_V4_COMPATIBLE(bi) ((bi)->version >= 4)
47
48#ifdef CONFIG_BOOTX_TEXT
49static void __init bootx_printf(const char *format, ...)
50{
51 const char *p, *q, *s;
52 va_list args;
53 unsigned long v;
54
55 va_start(args, format);
56 for (p = format; *p != 0; p = q) {
57 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
58 ;
59 if (q > p)
60 btext_drawtext(p, q - p);
61 if (*q == 0)
62 break;
63 if (*q == '\n') {
64 ++q;
65 btext_flushline();
66 btext_drawstring("\r\n");
67 btext_flushline();
68 continue;
69 }
70 ++q;
71 if (*q == 0)
72 break;
73 switch (*q) {
74 case 's':
75 ++q;
76 s = va_arg(args, const char *);
77 if (s == NULL)
78 s = "<NULL>";
79 btext_drawstring(s);
80 break;
81 case 'x':
82 ++q;
83 v = va_arg(args, unsigned long);
84 btext_drawhex(v);
85 break;
86 }
87 }
88}
89#else /* CONFIG_BOOTX_TEXT */
90static void __init bootx_printf(const char *format, ...) {}
91#endif /* CONFIG_BOOTX_TEXT */
92
93static void * __init bootx_early_getprop(unsigned long base,
94 unsigned long node,
95 char *prop)
96{
97 struct bootx_dt_node *np = (struct bootx_dt_node *)(base + node);
98 u32 *ppp = &np->properties;
99
100 while(*ppp) {
101 struct bootx_dt_prop *pp =
102 (struct bootx_dt_prop *)(base + *ppp);
103
104 if (strcmp((char *)((unsigned long)pp->name + base),
105 prop) == 0) {
106 return (void *)((unsigned long)pp->value + base);
107 }
108 ppp = &pp->next;
109 }
110 return NULL;
111}
112
113#define dt_push_token(token, mem) \
114 do { \
115 *(mem) = _ALIGN_UP(*(mem),4); \
116 *((u32 *)*(mem)) = token; \
117 *(mem) += 4; \
118 } while(0)
119
120static unsigned long __init bootx_dt_find_string(char *str)
121{
122 char *s, *os;
123
124 s = os = (char *)bootx_dt_strbase;
125 s += 4;
126 while (s < (char *)bootx_dt_strend) {
127 if (strcmp(s, str) == 0)
128 return s - os;
129 s += strlen(s) + 1;
130 }
131 return 0;
132}
133
134static void __init bootx_dt_add_prop(char *name, void *data, int size,
135 unsigned long *mem_end)
136{
137 unsigned long soff = bootx_dt_find_string(name);
138 if (data == NULL)
139 size = 0;
140 if (soff == 0) {
141 bootx_printf("WARNING: Can't find string index for <%s>\n",
142 name);
143 return;
144 }
145 if (size > 0x20000) {
146 bootx_printf("WARNING: ignoring large property ");
147 bootx_printf("%s length 0x%x\n", name, size);
148 return;
149 }
150 dt_push_token(OF_DT_PROP, mem_end);
151 dt_push_token(size, mem_end);
152 dt_push_token(soff, mem_end);
153
154 /* push property content */
155 if (size && data) {
156 memcpy((void *)*mem_end, data, size);
157 *mem_end = _ALIGN_UP(*mem_end + size, 4);
158 }
159}
160
161static void __init bootx_add_chosen_props(unsigned long base,
162 unsigned long *mem_end)
163{
164 u32 val = _MACH_Pmac;
165
166 bootx_dt_add_prop("linux,platform", &val, 4, mem_end);
167
168 if (bootx_info->kernelParamsOffset) {
169 char *args = (char *)((unsigned long)bootx_info) +
170 bootx_info->kernelParamsOffset;
171 bootx_dt_add_prop("bootargs", args, strlen(args) + 1, mem_end);
172 }
173 if (bootx_info->ramDisk) {
174 val = ((unsigned long)bootx_info) + bootx_info->ramDisk;
175 bootx_dt_add_prop("linux,initrd-start", &val, 4, mem_end);
176 val += bootx_info->ramDiskSize;
177 bootx_dt_add_prop("linux,initrd-end", &val, 4, mem_end);
178 }
179 if (strlen(bootx_disp_path))
180 bootx_dt_add_prop("linux,stdout-path", bootx_disp_path,
181 strlen(bootx_disp_path) + 1, mem_end);
182}
183
184static void __init bootx_add_display_props(unsigned long base,
185 unsigned long *mem_end)
186{
187 bootx_dt_add_prop("linux,boot-display", NULL, 0, mem_end);
188 bootx_dt_add_prop("linux,opened", NULL, 0, mem_end);
189}
190
191static void __init bootx_dt_add_string(char *s, unsigned long *mem_end)
192{
193 unsigned int l = strlen(s) + 1;
194 memcpy((void *)*mem_end, s, l);
195 bootx_dt_strend = *mem_end = *mem_end + l;
196}
197
198static void __init bootx_scan_dt_build_strings(unsigned long base,
199 unsigned long node,
200 unsigned long *mem_end)
201{
202 struct bootx_dt_node *np = (struct bootx_dt_node *)(base + node);
203 u32 *cpp, *ppp = &np->properties;
204 unsigned long soff;
205 char *namep;
206
207 /* Keep refs to known nodes */
208 namep = np->full_name ? (char *)(base + np->full_name) : NULL;
209 if (namep == NULL) {
210 bootx_printf("Node without a full name !\n");
211 namep = "";
212 }
213 DBG("* strings: %s\n", namep);
214
215 if (!strcmp(namep, "/chosen")) {
216 DBG(" detected /chosen ! adding properties names !\n");
217 bootx_dt_add_string("linux,platform", mem_end);
218 bootx_dt_add_string("linux,stdout-path", mem_end);
219 bootx_dt_add_string("linux,initrd-start", mem_end);
220 bootx_dt_add_string("linux,initrd-end", mem_end);
221 bootx_dt_add_string("bootargs", mem_end);
222 bootx_node_chosen = node;
223 }
224 if (node == bootx_info->dispDeviceRegEntryOffset) {
225 DBG(" detected display ! adding properties names !\n");
226 bootx_dt_add_string("linux,boot-display", mem_end);
227 bootx_dt_add_string("linux,opened", mem_end);
228 strncpy(bootx_disp_path, namep, 255);
229 }
230
231 /* get and store all property names */
232 while (*ppp) {
233 struct bootx_dt_prop *pp =
234 (struct bootx_dt_prop *)(base + *ppp);
235
236 namep = pp->name ? (char *)(base + pp->name) : NULL;
237 if (namep == NULL || strcmp(namep, "name") == 0)
238 goto next;
239 /* get/create string entry */
240 soff = bootx_dt_find_string(namep);
241 if (soff == 0)
242 bootx_dt_add_string(namep, mem_end);
243 next:
244 ppp = &pp->next;
245 }
246
247 /* do all our children */
248 cpp = &np->child;
249 while(*cpp) {
250 np = (struct bootx_dt_node *)(base + *cpp);
251 bootx_scan_dt_build_strings(base, *cpp, mem_end);
252 cpp = &np->sibling;
253 }
254}
255
256static void __init bootx_scan_dt_build_struct(unsigned long base,
257 unsigned long node,
258 unsigned long *mem_end)
259{
260 struct bootx_dt_node *np = (struct bootx_dt_node *)(base + node);
261 u32 *cpp, *ppp = &np->properties;
262 char *namep, *p, *ep, *lp;
263 int l;
264
265 dt_push_token(OF_DT_BEGIN_NODE, mem_end);
266
267 /* get the node's full name */
268 namep = np->full_name ? (char *)(base + np->full_name) : NULL;
269 if (namep == NULL)
270 namep = "";
271 l = strlen(namep);
272
273 DBG("* struct: %s\n", namep);
274
275 /* Fixup an Apple bug where they have bogus \0 chars in the
276 * middle of the path in some properties, and extract
277 * the unit name (everything after the last '/').
278 */
279 memcpy((void *)*mem_end, namep, l + 1);
280 namep = (char *)*mem_end;
281 for (lp = p = namep, ep = namep + l; p < ep; p++) {
282 if (*p == '/')
283 lp = namep;
284 else if (*p != 0)
285 *lp++ = *p;
286 }
287 *lp = 0;
288 *mem_end = _ALIGN_UP((unsigned long)lp + 1, 4);
289
290 /* get and store all properties */
291 while (*ppp) {
292 struct bootx_dt_prop *pp =
293 (struct bootx_dt_prop *)(base + *ppp);
294
295 namep = pp->name ? (char *)(base + pp->name) : NULL;
296 /* Skip "name" */
297 if (namep == NULL || !strcmp(namep, "name"))
298 goto next;
299 /* Skip "bootargs" in /chosen too as we replace it */
300 if (node == bootx_node_chosen && !strcmp(namep, "bootargs"))
301 goto next;
302
303 /* push property head */
304 bootx_dt_add_prop(namep,
305 pp->value ? (void *)(base + pp->value): NULL,
306 pp->length, mem_end);
307 next:
308 ppp = &pp->next;
309 }
310
311 if (node == bootx_node_chosen)
312 bootx_add_chosen_props(base, mem_end);
313 if (node == bootx_info->dispDeviceRegEntryOffset)
314 bootx_add_display_props(base, mem_end);
315
316 /* do all our children */
317 cpp = &np->child;
318 while(*cpp) {
319 np = (struct bootx_dt_node *)(base + *cpp);
320 bootx_scan_dt_build_struct(base, *cpp, mem_end);
321 cpp = &np->sibling;
322 }
323
324 dt_push_token(OF_DT_END_NODE, mem_end);
325}
326
327static unsigned long __init bootx_flatten_dt(unsigned long start)
328{
329 boot_infos_t *bi = bootx_info;
330 unsigned long mem_start, mem_end;
331 struct boot_param_header *hdr;
332 unsigned long base;
333 u64 *rsvmap;
334
335 /* Start using memory after the big blob passed by BootX, get
336 * some space for the header
337 */
338 mem_start = mem_end = _ALIGN_UP(((unsigned long)bi) + start, 4);
339 DBG("Boot params header at: %x\n", mem_start);
340 hdr = (struct boot_param_header *)mem_start;
341 mem_end += sizeof(struct boot_param_header);
342 rsvmap = (u64 *)(_ALIGN_UP(mem_end, 8));
343 hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - mem_start;
344 mem_end = ((unsigned long)rsvmap) + 8 * sizeof(u64);
345
346 /* Get base of tree */
347 base = ((unsigned long)bi) + bi->deviceTreeOffset;
348
349 /* Build string array */
350 DBG("Building string array at: %x\n", mem_end);
351 DBG("Device Tree Base=%x\n", base);
352 bootx_dt_strbase = mem_end;
353 mem_end += 4;
354 bootx_dt_strend = mem_end;
355 bootx_scan_dt_build_strings(base, 4, &mem_end);
356 hdr->off_dt_strings = bootx_dt_strbase - mem_start;
357 hdr->dt_strings_size = bootx_dt_strend - bootx_dt_strbase;
358
359 /* Build structure */
360 mem_end = _ALIGN(mem_end, 16);
361 DBG("Building device tree structure at: %x\n", mem_end);
362 hdr->off_dt_struct = mem_end - mem_start;
363 bootx_scan_dt_build_struct(base, 4, &mem_end);
364 dt_push_token(OF_DT_END, &mem_end);
365
366 /* Finish header */
367 hdr->boot_cpuid_phys = 0;
368 hdr->magic = OF_DT_HEADER;
369 hdr->totalsize = mem_end - mem_start;
370 hdr->version = OF_DT_VERSION;
371 /* Version 16 is not backward compatible */
372 hdr->last_comp_version = 0x10;
373
374 /* Reserve the whole thing and copy the reserve map in, we
375 * also bump mem_reserve_cnt to cause further reservations to
376 * fail since it's too late.
377 */
378 mem_end = _ALIGN(mem_end, PAGE_SIZE);
379 DBG("End of boot params: %x\n", mem_end);
380 rsvmap[0] = mem_start;
381 rsvmap[1] = mem_end;
382 rsvmap[2] = 0;
383 rsvmap[3] = 0;
384
385 return (unsigned long)hdr;
386}
387
388
389#ifdef CONFIG_BOOTX_TEXT
390static void __init btext_welcome(boot_infos_t *bi)
391{
392 unsigned long flags;
393 unsigned long pvr;
394
395 bootx_printf("Welcome to Linux, kernel " UTS_RELEASE "\n");
396 bootx_printf("\nlinked at : 0x%x", KERNELBASE);
397 bootx_printf("\nframe buffer at : 0x%x", bi->dispDeviceBase);
398 bootx_printf(" (phys), 0x%x", bi->logicalDisplayBase);
399 bootx_printf(" (log)");
400 bootx_printf("\nklimit : 0x%x",(unsigned long)klimit);
401 bootx_printf("\nboot_info at : 0x%x", bi);
402 __asm__ __volatile__ ("mfmsr %0" : "=r" (flags));
403 bootx_printf("\nMSR : 0x%x", flags);
404 __asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr));
405 bootx_printf("\nPVR : 0x%x", pvr);
406 pvr >>= 16;
407 if (pvr > 1) {
408 __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));
409 bootx_printf("\nHID0 : 0x%x", flags);
410 }
411 if (pvr == 8 || pvr == 12 || pvr == 0x800c) {
412 __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));
413 bootx_printf("\nICTC : 0x%x", flags);
414 }
415#ifdef DEBUG
416 bootx_printf("\n\n");
417 bootx_printf("bi->deviceTreeOffset : 0x%x\n",
418 bi->deviceTreeOffset);
419 bootx_printf("bi->deviceTreeSize : 0x%x\n",
420 bi->deviceTreeSize);
421#endif
422 bootx_printf("\n\n");
423}
424#endif /* CONFIG_BOOTX_TEXT */
425
426void __init bootx_init(unsigned long r3, unsigned long r4)
427{
428 boot_infos_t *bi = (boot_infos_t *) r4;
429 unsigned long hdr;
430 unsigned long space;
431 unsigned long ptr, x;
432 char *model;
433 unsigned long offset = reloc_offset();
434
435 reloc_got2(offset);
436
437 bootx_info = bi;
438
439 /* We haven't cleared any bss at this point, make sure
440 * what we need is initialized
441 */
442 bootx_dt_strbase = bootx_dt_strend = 0;
443 bootx_node_chosen = 0;
444 bootx_disp_path[0] = 0;
445
446 if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
447 bi->logicalDisplayBase = bi->dispDeviceBase;
448
449#ifdef CONFIG_BOOTX_TEXT
450 btext_setup_display(bi->dispDeviceRect[2] - bi->dispDeviceRect[0],
451 bi->dispDeviceRect[3] - bi->dispDeviceRect[1],
452 bi->dispDeviceDepth, bi->dispDeviceRowBytes,
453 (unsigned long)bi->logicalDisplayBase);
454 btext_clearscreen();
455 btext_flushscreen();
456#endif /* CONFIG_BOOTX_TEXT */
457
458 /*
459 * Test if boot-info is compatible. Done only in config
460 * CONFIG_BOOTX_TEXT since there is nothing much we can do
461 * with an incompatible version, except display a message
462 * and eventually hang the processor...
463 *
464 * I'll try to keep enough of boot-info compatible in the
465 * future to always allow display of this message;
466 */
467 if (!BOOT_INFO_IS_COMPATIBLE(bi)) {
468 bootx_printf(" !!! WARNING - Incompatible version"
469 " of BootX !!!\n\n\n");
470 for (;;)
471 ;
472 }
473 if (bi->architecture != BOOT_ARCH_PCI) {
474 bootx_printf(" !!! WARNING - Usupported machine"
475 " architecture !\n");
476 for (;;)
477 ;
478 }
479
480#ifdef CONFIG_BOOTX_TEXT
481 btext_welcome(bi);
482#endif
483 /* New BootX enters kernel with MMU off, i/os are not allowed
484 * here. This hack will have been done by the boostrap anyway.
485 */
486 if (bi->version < 4) {
487 /*
488 * XXX If this is an iMac, turn off the USB controller.
489 */
490 model = (char *) bootx_early_getprop(r4 + bi->deviceTreeOffset,
491 4, "model");
492 if (model
493 && (strcmp(model, "iMac,1") == 0
494 || strcmp(model, "PowerMac1,1") == 0)) {
495 bootx_printf("iMac,1 detected, shutting down USB \n");
496 out_le32((unsigned *)0x80880008, 1); /* XXX */
497 }
498 }
499
500 /* Get a pointer that points above the device tree, args, ramdisk,
501 * etc... to use for generating the flattened tree
502 */
503 if (bi->version < 5) {
504 space = bi->deviceTreeOffset + bi->deviceTreeSize;
505 if (bi->ramDisk)
506 space = bi->ramDisk + bi->ramDiskSize;
507 } else
508 space = bi->totalParamsSize;
509
510 bootx_printf("Total space used by parameters & ramdisk: %x \n", space);
511
512 /* New BootX will have flushed all TLBs and enters kernel with
513 * MMU switched OFF, so this should not be useful anymore.
514 */
515 if (bi->version < 4) {
516 bootx_printf("Touching pages...\n");
517
518 /*
519 * Touch each page to make sure the PTEs for them
520 * are in the hash table - the aim is to try to avoid
521 * getting DSI exceptions while copying the kernel image.
522 */
523 for (ptr = ((unsigned long) &_stext) & PAGE_MASK;
524 ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
525 x = *(volatile unsigned long *)ptr;
526 }
527
528 /* Ok, now we need to generate a flattened device-tree to pass
529 * to the kernel
530 */
531 bootx_printf("Preparing boot params...\n");
532
533 hdr = bootx_flatten_dt(space);
534
535#ifdef CONFIG_BOOTX_TEXT
536#ifdef SET_BOOT_BAT
537 bootx_printf("Preparing BAT...\n");
538 btext_prepare_BAT();
539#else
540 btext_unmap();
541#endif
542#endif
543
544 reloc_got2(-offset);
545
546 __start(hdr, KERNELBASE + offset, 0);
547}
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
index 39150342c6f1..a4b50c4109c2 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -28,6 +28,7 @@
28#include <asm/cputable.h> 28#include <asm/cputable.h>
29#include <asm/time.h> 29#include <asm/time.h>
30#include <asm/smu.h> 30#include <asm/smu.h>
31#include <asm/pmac_pfunc.h>
31 32
32#undef DEBUG 33#undef DEBUG
33 34
@@ -85,6 +86,10 @@ static u32 *g5_pmode_data;
85static int g5_pmode_max; 86static int g5_pmode_max;
86static int g5_pmode_cur; 87static int g5_pmode_cur;
87 88
89static void (*g5_switch_volt)(int speed_mode);
90static int (*g5_switch_freq)(int speed_mode);
91static int (*g5_query_freq)(void);
92
88static DECLARE_MUTEX(g5_switch_mutex); 93static DECLARE_MUTEX(g5_switch_mutex);
89 94
90 95
@@ -92,9 +97,11 @@ static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */
92static int g5_fvt_count; /* number of op. points */ 97static int g5_fvt_count; /* number of op. points */
93static int g5_fvt_cur; /* current op. point */ 98static int g5_fvt_cur; /* current op. point */
94 99
95/* ----------------- real hardware interface */ 100/*
101 * SMU based voltage switching for Neo2 platforms
102 */
96 103
97static void g5_switch_volt(int speed_mode) 104static void g5_smu_switch_volt(int speed_mode)
98{ 105{
99 struct smu_simple_cmd cmd; 106 struct smu_simple_cmd cmd;
100 107
@@ -105,26 +112,57 @@ static void g5_switch_volt(int speed_mode)
105 wait_for_completion(&comp); 112 wait_for_completion(&comp);
106} 113}
107 114
108static int g5_switch_freq(int speed_mode) 115/*
116 * Platform function based voltage/vdnap switching for Neo2
117 */
118
119static struct pmf_function *pfunc_set_vdnap0;
120static struct pmf_function *pfunc_vdnap0_complete;
121
122static void g5_vdnap_switch_volt(int speed_mode)
109{ 123{
110 struct cpufreq_freqs freqs; 124 struct pmf_args args;
111 int to; 125 u32 slew, done = 0;
126 unsigned long timeout;
112 127
113 if (g5_pmode_cur == speed_mode) 128 slew = (speed_mode == CPUFREQ_LOW) ? 1 : 0;
114 return 0; 129 args.count = 1;
130 args.u[0].p = &slew;
115 131
116 down(&g5_switch_mutex); 132 pmf_call_one(pfunc_set_vdnap0, &args);
117 133
118 freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency; 134 /* It's an irq GPIO so we should be able to just block here,
119 freqs.new = g5_cpu_freqs[speed_mode].frequency; 135 * I'll do that later after I've properly tested the IRQ code for
120 freqs.cpu = 0; 136 * platform functions
137 */
138 timeout = jiffies + HZ/10;
139 while(!time_after(jiffies, timeout)) {
140 args.count = 1;
141 args.u[0].p = &done;
142 pmf_call_one(pfunc_vdnap0_complete, &args);
143 if (done)
144 break;
145 msleep(1);
146 }
147 if (done == 0)
148 printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n");
149}
121 150
122 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 151
152/*
153 * SCOM based frequency switching for 970FX rev3
154 */
155static int g5_scom_switch_freq(int speed_mode)
156{
157 unsigned long flags;
158 int to;
123 159
124 /* If frequency is going up, first ramp up the voltage */ 160 /* If frequency is going up, first ramp up the voltage */
125 if (speed_mode < g5_pmode_cur) 161 if (speed_mode < g5_pmode_cur)
126 g5_switch_volt(speed_mode); 162 g5_switch_volt(speed_mode);
127 163
164 local_irq_save(flags);
165
128 /* Clear PCR high */ 166 /* Clear PCR high */
129 scom970_write(SCOM_PCR, 0); 167 scom970_write(SCOM_PCR, 0);
130 /* Clear PCR low */ 168 /* Clear PCR low */
@@ -147,6 +185,8 @@ static int g5_switch_freq(int speed_mode)
147 udelay(100); 185 udelay(100);
148 } 186 }
149 187
188 local_irq_restore(flags);
189
150 /* If frequency is going down, last ramp the voltage */ 190 /* If frequency is going down, last ramp the voltage */
151 if (speed_mode > g5_pmode_cur) 191 if (speed_mode > g5_pmode_cur)
152 g5_switch_volt(speed_mode); 192 g5_switch_volt(speed_mode);
@@ -154,14 +194,10 @@ static int g5_switch_freq(int speed_mode)
154 g5_pmode_cur = speed_mode; 194 g5_pmode_cur = speed_mode;
155 ppc_proc_freq = g5_cpu_freqs[speed_mode].frequency * 1000ul; 195 ppc_proc_freq = g5_cpu_freqs[speed_mode].frequency * 1000ul;
156 196
157 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
158
159 up(&g5_switch_mutex);
160
161 return 0; 197 return 0;
162} 198}
163 199
164static int g5_query_freq(void) 200static int g5_scom_query_freq(void)
165{ 201{
166 unsigned long psr = scom970_read(SCOM_PSR); 202 unsigned long psr = scom970_read(SCOM_PSR);
167 int i; 203 int i;
@@ -173,7 +209,104 @@ static int g5_query_freq(void)
173 return i; 209 return i;
174} 210}
175 211
176/* ----------------- cpufreq bookkeeping */ 212/*
213 * Platform function based voltage switching for PowerMac7,2 & 7,3
214 */
215
216static struct pmf_function *pfunc_cpu0_volt_high;
217static struct pmf_function *pfunc_cpu0_volt_low;
218static struct pmf_function *pfunc_cpu1_volt_high;
219static struct pmf_function *pfunc_cpu1_volt_low;
220
221static void g5_pfunc_switch_volt(int speed_mode)
222{
223 if (speed_mode == CPUFREQ_HIGH) {
224 if (pfunc_cpu0_volt_high)
225 pmf_call_one(pfunc_cpu0_volt_high, NULL);
226 if (pfunc_cpu1_volt_high)
227 pmf_call_one(pfunc_cpu1_volt_high, NULL);
228 } else {
229 if (pfunc_cpu0_volt_low)
230 pmf_call_one(pfunc_cpu0_volt_low, NULL);
231 if (pfunc_cpu1_volt_low)
232 pmf_call_one(pfunc_cpu1_volt_low, NULL);
233 }
234 msleep(10); /* should be faster , to fix */
235}
236
237/*
238 * Platform function based frequency switching for PowerMac7,2 & 7,3
239 */
240
241static struct pmf_function *pfunc_cpu_setfreq_high;
242static struct pmf_function *pfunc_cpu_setfreq_low;
243static struct pmf_function *pfunc_cpu_getfreq;
244static struct pmf_function *pfunc_slewing_done;;
245
246static int g5_pfunc_switch_freq(int speed_mode)
247{
248 struct pmf_args args;
249 u32 done = 0;
250 unsigned long timeout;
251
252 /* If frequency is going up, first ramp up the voltage */
253 if (speed_mode < g5_pmode_cur)
254 g5_switch_volt(speed_mode);
255
256 /* Do it */
257 if (speed_mode == CPUFREQ_HIGH)
258 pmf_call_one(pfunc_cpu_setfreq_high, NULL);
259 else
260 pmf_call_one(pfunc_cpu_setfreq_low, NULL);
261
262 /* It's an irq GPIO so we should be able to just block here,
263 * I'll do that later after I've properly tested the IRQ code for
264 * platform functions
265 */
266 timeout = jiffies + HZ/10;
267 while(!time_after(jiffies, timeout)) {
268 args.count = 1;
269 args.u[0].p = &done;
270 pmf_call_one(pfunc_slewing_done, &args);
271 if (done)
272 break;
273 msleep(1);
274 }
275 if (done == 0)
276 printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n");
277
278 /* If frequency is going down, last ramp the voltage */
279 if (speed_mode > g5_pmode_cur)
280 g5_switch_volt(speed_mode);
281
282 g5_pmode_cur = speed_mode;
283 ppc_proc_freq = g5_cpu_freqs[speed_mode].frequency * 1000ul;
284
285 return 0;
286}
287
288static int g5_pfunc_query_freq(void)
289{
290 struct pmf_args args;
291 u32 val = 0;
292
293 args.count = 1;
294 args.u[0].p = &val;
295 pmf_call_one(pfunc_cpu_getfreq, &args);
296 return val ? CPUFREQ_HIGH : CPUFREQ_LOW;
297}
298
299/*
300 * Fake voltage switching for platforms with missing support
301 */
302
303static void g5_dummy_switch_volt(int speed_mode)
304{
305}
306
307/*
308 * Common interface to the cpufreq core
309 */
177 310
178static int g5_cpufreq_verify(struct cpufreq_policy *policy) 311static int g5_cpufreq_verify(struct cpufreq_policy *policy)
179{ 312{
@@ -183,13 +316,30 @@ static int g5_cpufreq_verify(struct cpufreq_policy *policy)
183static int g5_cpufreq_target(struct cpufreq_policy *policy, 316static int g5_cpufreq_target(struct cpufreq_policy *policy,
184 unsigned int target_freq, unsigned int relation) 317 unsigned int target_freq, unsigned int relation)
185{ 318{
186 unsigned int newstate = 0; 319 unsigned int newstate = 0;
320 struct cpufreq_freqs freqs;
321 int rc;
187 322
188 if (cpufreq_frequency_table_target(policy, g5_cpu_freqs, 323 if (cpufreq_frequency_table_target(policy, g5_cpu_freqs,
189 target_freq, relation, &newstate)) 324 target_freq, relation, &newstate))
190 return -EINVAL; 325 return -EINVAL;
191 326
192 return g5_switch_freq(newstate); 327 if (g5_pmode_cur == newstate)
328 return 0;
329
330 down(&g5_switch_mutex);
331
332 freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency;
333 freqs.new = g5_cpu_freqs[newstate].frequency;
334 freqs.cpu = 0;
335
336 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
337 rc = g5_switch_freq(newstate);
338 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
339
340 up(&g5_switch_mutex);
341
342 return rc;
193} 343}
194 344
195static unsigned int g5_cpufreq_get_speed(unsigned int cpu) 345static unsigned int g5_cpufreq_get_speed(unsigned int cpu)
@@ -205,6 +355,7 @@ static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy)
205 policy->governor = CPUFREQ_DEFAULT_GOVERNOR; 355 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
206 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; 356 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
207 policy->cur = g5_cpu_freqs[g5_query_freq()].frequency; 357 policy->cur = g5_cpu_freqs[g5_query_freq()].frequency;
358 policy->cpus = cpu_possible_map;
208 cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu); 359 cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu);
209 360
210 return cpufreq_frequency_table_cpuinfo(policy, 361 return cpufreq_frequency_table_cpuinfo(policy,
@@ -224,19 +375,39 @@ static struct cpufreq_driver g5_cpufreq_driver = {
224}; 375};
225 376
226 377
227static int __init g5_cpufreq_init(void) 378static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
228{ 379{
229 struct device_node *cpunode; 380 struct device_node *cpunode;
230 unsigned int psize, ssize; 381 unsigned int psize, ssize;
231 struct smu_sdbp_header *shdr;
232 unsigned long max_freq; 382 unsigned long max_freq;
233 u32 *valp; 383 char *freq_method, *volt_method;
384 u32 *valp, pvr_hi;
385 int use_volts_vdnap = 0;
386 int use_volts_smu = 0;
234 int rc = -ENODEV; 387 int rc = -ENODEV;
235 388
236 /* Look for CPU and SMU nodes */ 389 /* Check supported platforms */
237 cpunode = of_find_node_by_type(NULL, "cpu"); 390 if (machine_is_compatible("PowerMac8,1") ||
238 if (!cpunode) { 391 machine_is_compatible("PowerMac8,2") ||
239 DBG("No CPU node !\n"); 392 machine_is_compatible("PowerMac9,1"))
393 use_volts_smu = 1;
394 else if (machine_is_compatible("PowerMac11,2"))
395 use_volts_vdnap = 1;
396 else
397 return -ENODEV;
398
399 /* Get first CPU node */
400 for (cpunode = NULL;
401 (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
402 u32 *reg =
403 (u32 *)get_property(cpunode, "reg", NULL);
404 if (reg == NULL || (*reg) != 0)
405 continue;
406 if (!strcmp(cpunode->type, "cpu"))
407 break;
408 }
409 if (cpunode == NULL) {
410 printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n");
240 return -ENODEV; 411 return -ENODEV;
241 } 412 }
242 413
@@ -246,8 +417,9 @@ static int __init g5_cpufreq_init(void)
246 DBG("No cpu-version property !\n"); 417 DBG("No cpu-version property !\n");
247 goto bail_noprops; 418 goto bail_noprops;
248 } 419 }
249 if (((*valp) >> 16) != 0x3c) { 420 pvr_hi = (*valp) >> 16;
250 DBG("Wrong CPU version: %08x\n", *valp); 421 if (pvr_hi != 0x3c && pvr_hi != 0x44) {
422 printk(KERN_ERR "cpufreq: Unsupported CPU version\n");
251 goto bail_noprops; 423 goto bail_noprops;
252 } 424 }
253 425
@@ -259,18 +431,50 @@ static int __init g5_cpufreq_init(void)
259 } 431 }
260 g5_pmode_max = psize / sizeof(u32) - 1; 432 g5_pmode_max = psize / sizeof(u32) - 1;
261 433
262 /* Look for the FVT table */ 434 if (use_volts_smu) {
263 shdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL); 435 struct smu_sdbp_header *shdr;
264 if (!shdr) 436
265 goto bail_noprops; 437 /* Look for the FVT table */
266 g5_fvt_table = (struct smu_sdbp_fvt *)&shdr[1]; 438 shdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
267 ssize = (shdr->len * sizeof(u32)) - sizeof(struct smu_sdbp_header); 439 if (!shdr)
268 g5_fvt_count = ssize / sizeof(struct smu_sdbp_fvt); 440 goto bail_noprops;
269 g5_fvt_cur = 0; 441 g5_fvt_table = (struct smu_sdbp_fvt *)&shdr[1];
270 442 ssize = (shdr->len * sizeof(u32)) -
271 /* Sanity checking */ 443 sizeof(struct smu_sdbp_header);
272 if (g5_fvt_count < 1 || g5_pmode_max < 1) 444 g5_fvt_count = ssize / sizeof(struct smu_sdbp_fvt);
273 goto bail_noprops; 445 g5_fvt_cur = 0;
446
447 /* Sanity checking */
448 if (g5_fvt_count < 1 || g5_pmode_max < 1)
449 goto bail_noprops;
450
451 g5_switch_volt = g5_smu_switch_volt;
452 volt_method = "SMU";
453 } else if (use_volts_vdnap) {
454 struct device_node *root;
455
456 root = of_find_node_by_path("/");
457 if (root == NULL) {
458 printk(KERN_ERR "cpufreq: Can't find root of "
459 "device tree\n");
460 goto bail_noprops;
461 }
462 pfunc_set_vdnap0 = pmf_find_function(root, "set-vdnap0");
463 pfunc_vdnap0_complete =
464 pmf_find_function(root, "slewing-done");
465 if (pfunc_set_vdnap0 == NULL ||
466 pfunc_vdnap0_complete == NULL) {
467 printk(KERN_ERR "cpufreq: Can't find required "
468 "platform function\n");
469 goto bail_noprops;
470 }
471
472 g5_switch_volt = g5_vdnap_switch_volt;
473 volt_method = "GPIO";
474 } else {
475 g5_switch_volt = g5_dummy_switch_volt;
476 volt_method = "none";
477 }
274 478
275 /* 479 /*
276 * From what I see, clock-frequency is always the maximal frequency. 480 * From what I see, clock-frequency is always the maximal frequency.
@@ -286,19 +490,23 @@ static int __init g5_cpufreq_init(void)
286 g5_cpu_freqs[0].frequency = max_freq; 490 g5_cpu_freqs[0].frequency = max_freq;
287 g5_cpu_freqs[1].frequency = max_freq/2; 491 g5_cpu_freqs[1].frequency = max_freq/2;
288 492
289 /* Check current frequency */ 493 /* Set callbacks */
290 g5_pmode_cur = g5_query_freq(); 494 g5_switch_freq = g5_scom_switch_freq;
291 if (g5_pmode_cur > 1) 495 g5_query_freq = g5_scom_query_freq;
292 /* We don't support anything but 1:1 and 1:2, fixup ... */ 496 freq_method = "SCOM";
293 g5_pmode_cur = 1;
294 497
295 /* Force apply current frequency to make sure everything is in 498 /* Force apply current frequency to make sure everything is in
296 * sync (voltage is right for example). Firmware may leave us with 499 * sync (voltage is right for example). Firmware may leave us with
297 * a strange setting ... 500 * a strange setting ...
298 */ 501 */
299 g5_switch_freq(g5_pmode_cur); 502 g5_switch_volt(CPUFREQ_HIGH);
503 msleep(10);
504 g5_pmode_cur = -1;
505 g5_switch_freq(g5_query_freq());
300 506
301 printk(KERN_INFO "Registering G5 CPU frequency driver\n"); 507 printk(KERN_INFO "Registering G5 CPU frequency driver\n");
508 printk(KERN_INFO "Frequency method: %s, Voltage method: %s\n",
509 freq_method, volt_method);
302 printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n", 510 printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n",
303 g5_cpu_freqs[1].frequency/1000, 511 g5_cpu_freqs[1].frequency/1000,
304 g5_cpu_freqs[0].frequency/1000, 512 g5_cpu_freqs[0].frequency/1000,
@@ -317,6 +525,200 @@ static int __init g5_cpufreq_init(void)
317 return rc; 525 return rc;
318} 526}
319 527
528static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
529{
530 struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL;
531 u8 *eeprom = NULL;
532 u32 *valp;
533 u64 max_freq, min_freq, ih, il;
534 int has_volt = 1, rc = 0;
535
536 /* Get first CPU node */
537 for (cpunode = NULL;
538 (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
539 if (!strcmp(cpunode->type, "cpu"))
540 break;
541 }
542 if (cpunode == NULL) {
543 printk(KERN_ERR "cpufreq: Can't find any CPU node\n");
544 return -ENODEV;
545 }
546
547 /* Lookup the cpuid eeprom node */
548 cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0");
549 if (cpuid != NULL)
550 eeprom = (u8 *)get_property(cpuid, "cpuid", NULL);
551 if (eeprom == NULL) {
552 printk(KERN_ERR "cpufreq: Can't find cpuid EEPROM !\n");
553 rc = -ENODEV;
554 goto bail;
555 }
556
557 /* Lookup the i2c hwclock */
558 for (hwclock = NULL;
559 (hwclock = of_find_node_by_name(hwclock, "i2c-hwclock")) != NULL;){
560 char *loc = get_property(hwclock, "hwctrl-location", NULL);
561 if (loc == NULL)
562 continue;
563 if (strcmp(loc, "CPU CLOCK"))
564 continue;
565 if (!get_property(hwclock, "platform-get-frequency", NULL))
566 continue;
567 break;
568 }
569 if (hwclock == NULL) {
570 printk(KERN_ERR "cpufreq: Can't find i2c clock chip !\n");
571 rc = -ENODEV;
572 goto bail;
573 }
574
575 DBG("cpufreq: i2c clock chip found: %s\n", hwclock->full_name);
576
577 /* Now get all the platform functions */
578 pfunc_cpu_getfreq =
579 pmf_find_function(hwclock, "get-frequency");
580 pfunc_cpu_setfreq_high =
581 pmf_find_function(hwclock, "set-frequency-high");
582 pfunc_cpu_setfreq_low =
583 pmf_find_function(hwclock, "set-frequency-low");
584 pfunc_slewing_done =
585 pmf_find_function(hwclock, "slewing-done");
586 pfunc_cpu0_volt_high =
587 pmf_find_function(hwclock, "set-voltage-high-0");
588 pfunc_cpu0_volt_low =
589 pmf_find_function(hwclock, "set-voltage-low-0");
590 pfunc_cpu1_volt_high =
591 pmf_find_function(hwclock, "set-voltage-high-1");
592 pfunc_cpu1_volt_low =
593 pmf_find_function(hwclock, "set-voltage-low-1");
594
595 /* Check we have minimum requirements */
596 if (pfunc_cpu_getfreq == NULL || pfunc_cpu_setfreq_high == NULL ||
597 pfunc_cpu_setfreq_low == NULL || pfunc_slewing_done == NULL) {
598 printk(KERN_ERR "cpufreq: Can't find platform functions !\n");
599 rc = -ENODEV;
600 goto bail;
601 }
602
603 /* Check that we have complete sets */
604 if (pfunc_cpu0_volt_high == NULL || pfunc_cpu0_volt_low == NULL) {
605 pmf_put_function(pfunc_cpu0_volt_high);
606 pmf_put_function(pfunc_cpu0_volt_low);
607 pfunc_cpu0_volt_high = pfunc_cpu0_volt_low = NULL;
608 has_volt = 0;
609 }
610 if (!has_volt ||
611 pfunc_cpu1_volt_high == NULL || pfunc_cpu1_volt_low == NULL) {
612 pmf_put_function(pfunc_cpu1_volt_high);
613 pmf_put_function(pfunc_cpu1_volt_low);
614 pfunc_cpu1_volt_high = pfunc_cpu1_volt_low = NULL;
615 }
616
617 /* Note: The device tree also contains a "platform-set-values"
618 * function for which I haven't quite figured out the usage. It
619 * might have to be called on init and/or wakeup, I'm not too sure
620 * but things seem to work fine without it so far ...
621 */
622
623 /* Get max frequency from device-tree */
624 valp = (u32 *)get_property(cpunode, "clock-frequency", NULL);
625 if (!valp) {
626 printk(KERN_ERR "cpufreq: Can't find CPU frequency !\n");
627 rc = -ENODEV;
628 goto bail;
629 }
630
631 max_freq = (*valp)/1000;
632
633 /* Now calculate reduced frequency by using the cpuid input freq
634 * ratio. This requires 64 bits math unless we are willing to lose
635 * some precision
636 */
637 ih = *((u32 *)(eeprom + 0x10));
638 il = *((u32 *)(eeprom + 0x20));
639 min_freq = 0;
640 if (ih != 0 && il != 0)
641 min_freq = (max_freq * il) / ih;
642
643 /* Sanity check */
644 if (min_freq >= max_freq || min_freq < 1000) {
645 printk(KERN_ERR "cpufreq: Can't calculate low frequency !\n");
646 rc = -ENODEV;
647 goto bail;
648 }
649 g5_cpu_freqs[0].frequency = max_freq;
650 g5_cpu_freqs[1].frequency = min_freq;
651
652 /* Set callbacks */
653 g5_switch_volt = g5_pfunc_switch_volt;
654 g5_switch_freq = g5_pfunc_switch_freq;
655 g5_query_freq = g5_pfunc_query_freq;
656
657 /* Force apply current frequency to make sure everything is in
658 * sync (voltage is right for example). Firmware may leave us with
659 * a strange setting ...
660 */
661 g5_switch_volt(CPUFREQ_HIGH);
662 msleep(10);
663 g5_pmode_cur = -1;
664 g5_switch_freq(g5_query_freq());
665
666 printk(KERN_INFO "Registering G5 CPU frequency driver\n");
667 printk(KERN_INFO "Frequency method: i2c/pfunc, "
668 "Voltage method: %s\n", has_volt ? "i2c/pfunc" : "none");
669 printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n",
670 g5_cpu_freqs[1].frequency/1000,
671 g5_cpu_freqs[0].frequency/1000,
672 g5_cpu_freqs[g5_pmode_cur].frequency/1000);
673
674 rc = cpufreq_register_driver(&g5_cpufreq_driver);
675 bail:
676 if (rc != 0) {
677 pmf_put_function(pfunc_cpu_getfreq);
678 pmf_put_function(pfunc_cpu_setfreq_high);
679 pmf_put_function(pfunc_cpu_setfreq_low);
680 pmf_put_function(pfunc_slewing_done);
681 pmf_put_function(pfunc_cpu0_volt_high);
682 pmf_put_function(pfunc_cpu0_volt_low);
683 pmf_put_function(pfunc_cpu1_volt_high);
684 pmf_put_function(pfunc_cpu1_volt_low);
685 }
686 of_node_put(hwclock);
687 of_node_put(cpuid);
688 of_node_put(cpunode);
689
690 return rc;
691}
692
693static int __init g5_rm31_cpufreq_init(struct device_node *cpus)
694{
695 /* NYI */
696 return 0;
697}
698
699static int __init g5_cpufreq_init(void)
700{
701 struct device_node *cpus;
702 int rc;
703
704 cpus = of_find_node_by_path("/cpus");
705 if (cpus == NULL) {
706 DBG("No /cpus node !\n");
707 return -ENODEV;
708 }
709
710 if (machine_is_compatible("PowerMac7,2") ||
711 machine_is_compatible("PowerMac7,3"))
712 rc = g5_pm72_cpufreq_init(cpus);
713 else if (machine_is_compatible("RackMac3,1"))
714 rc = g5_rm31_cpufreq_init(cpus);
715 else
716 rc = g5_neo2_cpufreq_init(cpus);
717
718 of_node_put(cpus);
719 return rc;
720}
721
320module_init(g5_cpufreq_init); 722module_init(g5_cpufreq_init);
321 723
322 724
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index f6e22da2a5da..558dd0692092 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -58,12 +58,11 @@ extern int powersave_lowspeed;
58extern int powersave_nap; 58extern int powersave_nap;
59extern struct device_node *k2_skiplist[2]; 59extern struct device_node *k2_skiplist[2];
60 60
61
62/* 61/*
63 * We use a single global lock to protect accesses. Each driver has 62 * We use a single global lock to protect accesses. Each driver has
64 * to take care of its own locking 63 * to take care of its own locking
65 */ 64 */
66static DEFINE_SPINLOCK(feature_lock); 65DEFINE_SPINLOCK(feature_lock);
67 66
68#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags); 67#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags);
69#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags); 68#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags);
@@ -101,26 +100,17 @@ static const char *macio_names[] =
101 "Keylargo", 100 "Keylargo",
102 "Pangea", 101 "Pangea",
103 "Intrepid", 102 "Intrepid",
104 "K2" 103 "K2",
104 "Shasta",
105}; 105};
106 106
107 107
108struct device_node *uninorth_node;
109u32 __iomem *uninorth_base;
108 110
109/*
110 * Uninorth reg. access. Note that Uni-N regs are big endian
111 */
112
113#define UN_REG(r) (uninorth_base + ((r) >> 2))
114#define UN_IN(r) (in_be32(UN_REG(r)))
115#define UN_OUT(r,v) (out_be32(UN_REG(r), (v)))
116#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
117#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
118
119static struct device_node *uninorth_node;
120static u32 __iomem *uninorth_base;
121static u32 uninorth_rev; 111static u32 uninorth_rev;
122static int uninorth_u3; 112static int uninorth_maj;
123static void __iomem *u3_ht; 113static void __iomem *u3_ht_base;
124 114
125/* 115/*
126 * For each motherboard family, we have a table of functions pointers 116 * For each motherboard family, we have a table of functions pointers
@@ -1399,8 +1389,15 @@ static long g5_fw_enable(struct device_node *node, long param, long value)
1399static long g5_mpic_enable(struct device_node *node, long param, long value) 1389static long g5_mpic_enable(struct device_node *node, long param, long value)
1400{ 1390{
1401 unsigned long flags; 1391 unsigned long flags;
1392 struct device_node *parent = of_get_parent(node);
1393 int is_u3;
1402 1394
1403 if (node->parent == NULL || strcmp(node->parent->name, "u3")) 1395 if (parent == NULL)
1396 return 0;
1397 is_u3 = strcmp(parent->name, "u3") == 0 ||
1398 strcmp(parent->name, "u4") == 0;
1399 of_node_put(parent);
1400 if (!is_u3)
1404 return 0; 1401 return 0;
1405 1402
1406 LOCK(flags); 1403 LOCK(flags);
@@ -1445,20 +1442,53 @@ static long g5_i2s_enable(struct device_node *node, long param, long value)
1445 /* Very crude implementation for now */ 1442 /* Very crude implementation for now */
1446 struct macio_chip *macio = &macio_chips[0]; 1443 struct macio_chip *macio = &macio_chips[0];
1447 unsigned long flags; 1444 unsigned long flags;
1448 1445 int cell;
1449 if (value == 0) 1446 u32 fcrs[3][3] = {
1450 return 0; /* don't disable yet */ 1447 { 0,
1448 K2_FCR1_I2S0_CELL_ENABLE |
1449 K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE,
1450 KL3_I2S0_CLK18_ENABLE
1451 },
1452 { KL0_SCC_A_INTF_ENABLE,
1453 K2_FCR1_I2S1_CELL_ENABLE |
1454 K2_FCR1_I2S1_CLK_ENABLE_BIT | K2_FCR1_I2S1_ENABLE,
1455 KL3_I2S1_CLK18_ENABLE
1456 },
1457 { KL0_SCC_B_INTF_ENABLE,
1458 SH_FCR1_I2S2_CELL_ENABLE |
1459 SH_FCR1_I2S2_CLK_ENABLE_BIT | SH_FCR1_I2S2_ENABLE,
1460 SH_FCR3_I2S2_CLK18_ENABLE
1461 },
1462 };
1463
1464 if (macio->type != macio_keylargo2 && macio->type != macio_shasta)
1465 return -ENODEV;
1466 if (strncmp(node->name, "i2s-", 4))
1467 return -ENODEV;
1468 cell = node->name[4] - 'a';
1469 switch(cell) {
1470 case 0:
1471 case 1:
1472 break;
1473 case 2:
1474 if (macio->type == macio_shasta)
1475 break;
1476 default:
1477 return -ENODEV;
1478 }
1451 1479
1452 LOCK(flags); 1480 LOCK(flags);
1453 MACIO_BIS(KEYLARGO_FCR3, KL3_CLK45_ENABLE | KL3_CLK49_ENABLE | 1481 if (value) {
1454 KL3_I2S0_CLK18_ENABLE); 1482 MACIO_BIC(KEYLARGO_FCR0, fcrs[cell][0]);
1455 udelay(10); 1483 MACIO_BIS(KEYLARGO_FCR1, fcrs[cell][1]);
1456 MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_I2S0_CELL_ENABLE | 1484 MACIO_BIS(KEYLARGO_FCR3, fcrs[cell][2]);
1457 K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE); 1485 } else {
1486 MACIO_BIC(KEYLARGO_FCR3, fcrs[cell][2]);
1487 MACIO_BIC(KEYLARGO_FCR1, fcrs[cell][1]);
1488 MACIO_BIS(KEYLARGO_FCR0, fcrs[cell][0]);
1489 }
1458 udelay(10); 1490 udelay(10);
1459 MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_I2S0_RESET);
1460 UNLOCK(flags); 1491 UNLOCK(flags);
1461 udelay(10);
1462 1492
1463 return 0; 1493 return 0;
1464} 1494}
@@ -1473,7 +1503,7 @@ static long g5_reset_cpu(struct device_node *node, long param, long value)
1473 struct device_node *np; 1503 struct device_node *np;
1474 1504
1475 macio = &macio_chips[0]; 1505 macio = &macio_chips[0];
1476 if (macio->type != macio_keylargo2) 1506 if (macio->type != macio_keylargo2 && macio->type != macio_shasta)
1477 return -ENODEV; 1507 return -ENODEV;
1478 1508
1479 np = find_path_device("/cpus"); 1509 np = find_path_device("/cpus");
@@ -1512,14 +1542,17 @@ static long g5_reset_cpu(struct device_node *node, long param, long value)
1512 */ 1542 */
1513void g5_phy_disable_cpu1(void) 1543void g5_phy_disable_cpu1(void)
1514{ 1544{
1515 UN_OUT(U3_API_PHY_CONFIG_1, 0); 1545 if (uninorth_maj == 3)
1546 UN_OUT(U3_API_PHY_CONFIG_1, 0);
1516} 1547}
1517#endif /* CONFIG_POWER4 */ 1548#endif /* CONFIG_POWER4 */
1518 1549
1519#ifndef CONFIG_POWER4 1550#ifndef CONFIG_POWER4
1520 1551
1521static void 1552
1522keylargo_shutdown(struct macio_chip *macio, int sleep_mode) 1553#ifdef CONFIG_PM
1554
1555static void keylargo_shutdown(struct macio_chip *macio, int sleep_mode)
1523{ 1556{
1524 u32 temp; 1557 u32 temp;
1525 1558
@@ -1572,8 +1605,7 @@ keylargo_shutdown(struct macio_chip *macio, int sleep_mode)
1572 (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); 1605 (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
1573} 1606}
1574 1607
1575static void 1608static void pangea_shutdown(struct macio_chip *macio, int sleep_mode)
1576pangea_shutdown(struct macio_chip *macio, int sleep_mode)
1577{ 1609{
1578 u32 temp; 1610 u32 temp;
1579 1611
@@ -1606,8 +1638,7 @@ pangea_shutdown(struct macio_chip *macio, int sleep_mode)
1606 (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); 1638 (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
1607} 1639}
1608 1640
1609static void 1641static void intrepid_shutdown(struct macio_chip *macio, int sleep_mode)
1610intrepid_shutdown(struct macio_chip *macio, int sleep_mode)
1611{ 1642{
1612 u32 temp; 1643 u32 temp;
1613 1644
@@ -1635,124 +1666,6 @@ intrepid_shutdown(struct macio_chip *macio, int sleep_mode)
1635} 1666}
1636 1667
1637 1668
1638void pmac_tweak_clock_spreading(int enable)
1639{
1640 struct macio_chip *macio = &macio_chips[0];
1641
1642 /* Hack for doing clock spreading on some machines PowerBooks and
1643 * iBooks. This implements the "platform-do-clockspreading" OF
1644 * property as decoded manually on various models. For safety, we also
1645 * check the product ID in the device-tree in cases we'll whack the i2c
1646 * chip to make reasonably sure we won't set wrong values in there
1647 *
1648 * Of course, ultimately, we have to implement a real parser for
1649 * the platform-do-* stuff...
1650 */
1651
1652 if (macio->type == macio_intrepid) {
1653 struct device_node *clock =
1654 of_find_node_by_path("/uni-n@f8000000/hw-clock");
1655 if (clock && get_property(clock, "platform-do-clockspreading",
1656 NULL)) {
1657 printk(KERN_INFO "%sabling clock spreading on Intrepid"
1658 " ASIC\n", enable ? "En" : "Dis");
1659 if (enable)
1660 UN_OUT(UNI_N_CLOCK_SPREADING, 2);
1661 else
1662 UN_OUT(UNI_N_CLOCK_SPREADING, 0);
1663 mdelay(40);
1664 }
1665 of_node_put(clock);
1666 }
1667
1668 while (machine_is_compatible("PowerBook5,2") ||
1669 machine_is_compatible("PowerBook5,3") ||
1670 machine_is_compatible("PowerBook6,2") ||
1671 machine_is_compatible("PowerBook6,3")) {
1672 struct device_node *ui2c = of_find_node_by_type(NULL, "i2c");
1673 struct device_node *dt = of_find_node_by_name(NULL, "device-tree");
1674 u8 buffer[9];
1675 u32 *productID;
1676 int i, rc, changed = 0;
1677
1678 if (dt == NULL)
1679 break;
1680 productID = (u32 *)get_property(dt, "pid#", NULL);
1681 if (productID == NULL)
1682 break;
1683 while(ui2c) {
1684 struct device_node *p = of_get_parent(ui2c);
1685 if (p && !strcmp(p->name, "uni-n"))
1686 break;
1687 ui2c = of_find_node_by_type(ui2c, "i2c");
1688 }
1689 if (ui2c == NULL)
1690 break;
1691 DBG("Trying to bump clock speed for PID: %08x...\n", *productID);
1692 rc = pmac_low_i2c_open(ui2c, 1);
1693 if (rc != 0)
1694 break;
1695 pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
1696 rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
1697 DBG("read result: %d,", rc);
1698 if (rc != 0) {
1699 pmac_low_i2c_close(ui2c);
1700 break;
1701 }
1702 for (i=0; i<9; i++)
1703 DBG(" %02x", buffer[i]);
1704 DBG("\n");
1705
1706 switch(*productID) {
1707 case 0x1182: /* AlBook 12" rev 2 */
1708 case 0x1183: /* iBook G4 12" */
1709 buffer[0] = (buffer[0] & 0x8f) | 0x70;
1710 buffer[2] = (buffer[2] & 0x7f) | 0x00;
1711 buffer[5] = (buffer[5] & 0x80) | 0x31;
1712 buffer[6] = (buffer[6] & 0x40) | 0xb0;
1713 buffer[7] = (buffer[7] & 0x00) | (enable ? 0xc0 : 0xba);
1714 buffer[8] = (buffer[8] & 0x00) | 0x30;
1715 changed = 1;
1716 break;
1717 case 0x3142: /* AlBook 15" (ATI M10) */
1718 case 0x3143: /* AlBook 17" (ATI M10) */
1719 buffer[0] = (buffer[0] & 0xaf) | 0x50;
1720 buffer[2] = (buffer[2] & 0x7f) | 0x00;
1721 buffer[5] = (buffer[5] & 0x80) | 0x31;
1722 buffer[6] = (buffer[6] & 0x40) | 0xb0;
1723 buffer[7] = (buffer[7] & 0x00) | (enable ? 0xd0 : 0xc0);
1724 buffer[8] = (buffer[8] & 0x00) | 0x30;
1725 changed = 1;
1726 break;
1727 default:
1728 DBG("i2c-hwclock: Machine model not handled\n");
1729 break;
1730 }
1731 if (!changed) {
1732 pmac_low_i2c_close(ui2c);
1733 break;
1734 }
1735 printk(KERN_INFO "%sabling clock spreading on i2c clock chip\n",
1736 enable ? "En" : "Dis");
1737
1738 pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
1739 rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
1740 DBG("write result: %d,", rc);
1741 pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
1742 rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
1743 DBG("read result: %d,", rc);
1744 if (rc != 0) {
1745 pmac_low_i2c_close(ui2c);
1746 break;
1747 }
1748 for (i=0; i<9; i++)
1749 DBG(" %02x", buffer[i]);
1750 pmac_low_i2c_close(ui2c);
1751 break;
1752 }
1753}
1754
1755
1756static int 1669static int
1757core99_sleep(void) 1670core99_sleep(void)
1758{ 1671{
@@ -1909,6 +1822,8 @@ core99_wake_up(void)
1909 return 0; 1822 return 0;
1910} 1823}
1911 1824
1825#endif /* CONFIG_PM */
1826
1912static long 1827static long
1913core99_sleep_state(struct device_node *node, long param, long value) 1828core99_sleep_state(struct device_node *node, long param, long value)
1914{ 1829{
@@ -1930,10 +1845,13 @@ core99_sleep_state(struct device_node *node, long param, long value)
1930 if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) 1845 if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
1931 return -EPERM; 1846 return -EPERM;
1932 1847
1848#ifdef CONFIG_PM
1933 if (value == 1) 1849 if (value == 1)
1934 return core99_sleep(); 1850 return core99_sleep();
1935 else if (value == 0) 1851 else if (value == 0)
1936 return core99_wake_up(); 1852 return core99_wake_up();
1853
1854#endif /* CONFIG_PM */
1937 return 0; 1855 return 0;
1938} 1856}
1939 1857
@@ -2057,7 +1975,9 @@ static struct feature_table_entry core99_features[] = {
2057 { PMAC_FTR_USB_ENABLE, core99_usb_enable }, 1975 { PMAC_FTR_USB_ENABLE, core99_usb_enable },
2058 { PMAC_FTR_1394_ENABLE, core99_firewire_enable }, 1976 { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
2059 { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power }, 1977 { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
1978#ifdef CONFIG_PM
2060 { PMAC_FTR_SLEEP_STATE, core99_sleep_state }, 1979 { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
1980#endif
2061#ifdef CONFIG_SMP 1981#ifdef CONFIG_SMP
2062 { PMAC_FTR_RESET_CPU, core99_reset_cpu }, 1982 { PMAC_FTR_RESET_CPU, core99_reset_cpu },
2063#endif /* CONFIG_SMP */ 1983#endif /* CONFIG_SMP */
@@ -2427,6 +2347,14 @@ static struct pmac_mb_def pmac_mb_defs[] = {
2427 PMAC_TYPE_POWERMAC_G5_U3L, g5_features, 2347 PMAC_TYPE_POWERMAC_G5_U3L, g5_features,
2428 0, 2348 0,
2429 }, 2349 },
2350 { "PowerMac11,2", "PowerMac G5 Dual Core",
2351 PMAC_TYPE_POWERMAC_G5_U3L, g5_features,
2352 0,
2353 },
2354 { "PowerMac12,1", "iMac G5 (iSight)",
2355 PMAC_TYPE_POWERMAC_G5_U3L, g5_features,
2356 0,
2357 },
2430 { "RackMac3,1", "XServe G5", 2358 { "RackMac3,1", "XServe G5",
2431 PMAC_TYPE_XSERVE_G5, g5_features, 2359 PMAC_TYPE_XSERVE_G5, g5_features,
2432 0, 2360 0,
@@ -2539,6 +2467,11 @@ static int __init probe_motherboard(void)
2539 pmac_mb.model_name = "Unknown K2-based"; 2467 pmac_mb.model_name = "Unknown K2-based";
2540 pmac_mb.features = g5_features; 2468 pmac_mb.features = g5_features;
2541 break; 2469 break;
2470 case macio_shasta:
2471 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_SHASTA;
2472 pmac_mb.model_name = "Unknown Shasta-based";
2473 pmac_mb.features = g5_features;
2474 break;
2542#endif /* CONFIG_POWER4 */ 2475#endif /* CONFIG_POWER4 */
2543 default: 2476 default:
2544 return -ENODEV; 2477 return -ENODEV;
@@ -2607,6 +2540,8 @@ found:
2607 */ 2540 */
2608static void __init probe_uninorth(void) 2541static void __init probe_uninorth(void)
2609{ 2542{
2543 u32 *addrp;
2544 phys_addr_t address;
2610 unsigned long actrl; 2545 unsigned long actrl;
2611 2546
2612 /* Locate core99 Uni-N */ 2547 /* Locate core99 Uni-N */
@@ -2614,22 +2549,31 @@ static void __init probe_uninorth(void)
2614 /* Locate G5 u3 */ 2549 /* Locate G5 u3 */
2615 if (uninorth_node == NULL) { 2550 if (uninorth_node == NULL) {
2616 uninorth_node = of_find_node_by_name(NULL, "u3"); 2551 uninorth_node = of_find_node_by_name(NULL, "u3");
2617 uninorth_u3 = 1; 2552 uninorth_maj = 3;
2618 } 2553 }
2619 if (uninorth_node && uninorth_node->n_addrs > 0) { 2554 /* Locate G5 u4 */
2620 unsigned long address = uninorth_node->addrs[0].address; 2555 if (uninorth_node == NULL) {
2621 uninorth_base = ioremap(address, 0x40000); 2556 uninorth_node = of_find_node_by_name(NULL, "u4");
2622 uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); 2557 uninorth_maj = 4;
2623 if (uninorth_u3) 2558 }
2624 u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000); 2559 if (uninorth_node == NULL)
2625 } else
2626 uninorth_node = NULL;
2627
2628 if (!uninorth_node)
2629 return; 2560 return;
2630 2561
2631 printk(KERN_INFO "Found %s memory controller & host bridge, revision: %d\n", 2562 addrp = (u32 *)get_property(uninorth_node, "reg", NULL);
2632 uninorth_u3 ? "U3" : "UniNorth", uninorth_rev); 2563 if (addrp == NULL)
2564 return;
2565 address = of_translate_address(uninorth_node, addrp);
2566 if (address == 0)
2567 return;
2568 uninorth_base = ioremap(address, 0x40000);
2569 uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
2570 if (uninorth_maj == 3 || uninorth_maj == 4)
2571 u3_ht_base = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
2572
2573 printk(KERN_INFO "Found %s memory controller & host bridge"
2574 " @ 0x%08x revision: 0x%02x\n", uninorth_maj == 3 ? "U3" :
2575 uninorth_maj == 4 ? "U4" : "UniNorth",
2576 (unsigned int)address, uninorth_rev);
2633 printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base); 2577 printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
2634 2578
2635 /* Set the arbitrer QAck delay according to what Apple does 2579 /* Set the arbitrer QAck delay according to what Apple does
@@ -2637,7 +2581,8 @@ static void __init probe_uninorth(void)
2637 if (uninorth_rev < 0x11) { 2581 if (uninorth_rev < 0x11) {
2638 actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK; 2582 actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK;
2639 actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : 2583 actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 :
2640 UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT; 2584 UNI_N_ARB_CTRL_QACK_DELAY) <<
2585 UNI_N_ARB_CTRL_QACK_DELAY_SHIFT;
2641 UN_OUT(UNI_N_ARB_CTRL, actrl); 2586 UN_OUT(UNI_N_ARB_CTRL, actrl);
2642 } 2587 }
2643 2588
@@ -2645,7 +2590,8 @@ static void __init probe_uninorth(void)
2645 * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI 2590 * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI
2646 * memory timeout 2591 * memory timeout
2647 */ 2592 */
2648 if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0) 2593 if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) ||
2594 uninorth_rev == 0xc0)
2649 UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff); 2595 UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff);
2650} 2596}
2651 2597
@@ -2653,18 +2599,17 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ
2653{ 2599{
2654 struct device_node* node; 2600 struct device_node* node;
2655 int i; 2601 int i;
2656 volatile u32 __iomem * base; 2602 volatile u32 __iomem *base;
2657 u32* revp; 2603 u32 *addrp, *revp;
2604 phys_addr_t addr;
2605 u64 size;
2658 2606
2659 node = find_devices(name); 2607 for (node = NULL; (node = of_find_node_by_name(node, name)) != NULL;) {
2660 if (!node || !node->n_addrs) 2608 if (!compat)
2661 return; 2609 break;
2662 if (compat) 2610 if (device_is_compatible(node, compat))
2663 do { 2611 break;
2664 if (device_is_compatible(node, compat)) 2612 }
2665 break;
2666 node = node->next;
2667 } while (node);
2668 if (!node) 2613 if (!node)
2669 return; 2614 return;
2670 for(i=0; i<MAX_MACIO_CHIPS; i++) { 2615 for(i=0; i<MAX_MACIO_CHIPS; i++) {
@@ -2673,22 +2618,38 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ
2673 if (macio_chips[i].of_node == node) 2618 if (macio_chips[i].of_node == node)
2674 return; 2619 return;
2675 } 2620 }
2621
2676 if (i >= MAX_MACIO_CHIPS) { 2622 if (i >= MAX_MACIO_CHIPS) {
2677 printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n"); 2623 printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
2678 printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name); 2624 printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
2679 return; 2625 return;
2680 } 2626 }
2681 base = ioremap(node->addrs[0].address, node->addrs[0].size); 2627 addrp = of_get_pci_address(node, 0, &size, NULL);
2628 if (addrp == NULL) {
2629 printk(KERN_ERR "pmac_feature: %s: can't find base !\n",
2630 node->full_name);
2631 return;
2632 }
2633 addr = of_translate_address(node, addrp);
2634 if (addr == 0) {
2635 printk(KERN_ERR "pmac_feature: %s, can't translate base !\n",
2636 node->full_name);
2637 return;
2638 }
2639 base = ioremap(addr, (unsigned long)size);
2682 if (!base) { 2640 if (!base) {
2683 printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n"); 2641 printk(KERN_ERR "pmac_feature: %s, can't map mac-io chip !\n",
2642 node->full_name);
2684 return; 2643 return;
2685 } 2644 }
2686 if (type == macio_keylargo) { 2645 if (type == macio_keylargo || type == macio_keylargo2) {
2687 u32 *did = (u32 *)get_property(node, "device-id", NULL); 2646 u32 *did = (u32 *)get_property(node, "device-id", NULL);
2688 if (*did == 0x00000025) 2647 if (*did == 0x00000025)
2689 type = macio_pangea; 2648 type = macio_pangea;
2690 if (*did == 0x0000003e) 2649 if (*did == 0x0000003e)
2691 type = macio_intrepid; 2650 type = macio_intrepid;
2651 if (*did == 0x0000004f)
2652 type = macio_shasta;
2692 } 2653 }
2693 macio_chips[i].of_node = node; 2654 macio_chips[i].of_node = node;
2694 macio_chips[i].type = type; 2655 macio_chips[i].type = type;
@@ -2787,7 +2748,8 @@ set_initial_features(void)
2787 } 2748 }
2788 2749
2789#ifdef CONFIG_POWER4 2750#ifdef CONFIG_POWER4
2790 if (macio_chips[0].type == macio_keylargo2) { 2751 if (macio_chips[0].type == macio_keylargo2 ||
2752 macio_chips[0].type == macio_shasta) {
2791#ifndef CONFIG_SMP 2753#ifndef CONFIG_SMP
2792 /* On SMP machines running UP, we have the second CPU eating 2754 /* On SMP machines running UP, we have the second CPU eating
2793 * bus cycles. We need to take it off the bus. This is done 2755 * bus cycles. We need to take it off the bus. This is done
@@ -2896,12 +2858,6 @@ set_initial_features(void)
2896 MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N); 2858 MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
2897 } 2859 }
2898 2860
2899 /* Some machine models need the clock chip to be properly setup for
2900 * clock spreading now. This should be a platform function but we
2901 * don't do these at the moment
2902 */
2903 pmac_tweak_clock_spreading(1);
2904
2905#endif /* CONFIG_POWER4 */ 2861#endif /* CONFIG_POWER4 */
2906 2862
2907 /* On all machines, switch modem & serial ports off */ 2863 /* On all machines, switch modem & serial ports off */
@@ -2929,9 +2885,6 @@ pmac_feature_init(void)
2929 return; 2885 return;
2930 } 2886 }
2931 2887
2932 /* Setup low-level i2c stuffs */
2933 pmac_init_low_i2c();
2934
2935 /* Probe machine type */ 2888 /* Probe machine type */
2936 if (probe_motherboard()) 2889 if (probe_motherboard())
2937 printk(KERN_WARNING "Unknown PowerMac !\n"); 2890 printk(KERN_WARNING "Unknown PowerMac !\n");
@@ -2942,26 +2895,6 @@ pmac_feature_init(void)
2942 set_initial_features(); 2895 set_initial_features();
2943} 2896}
2944 2897
2945int __init pmac_feature_late_init(void)
2946{
2947#if 0
2948 struct device_node *np;
2949
2950 /* Request some resources late */
2951 if (uninorth_node)
2952 request_OF_resource(uninorth_node, 0, NULL);
2953 np = find_devices("hammerhead");
2954 if (np)
2955 request_OF_resource(np, 0, NULL);
2956 np = find_devices("interrupt-controller");
2957 if (np)
2958 request_OF_resource(np, 0, NULL);
2959#endif
2960 return 0;
2961}
2962
2963device_initcall(pmac_feature_late_init);
2964
2965#if 0 2898#if 0
2966static void dump_HT_speeds(char *name, u32 cfg, u32 frq) 2899static void dump_HT_speeds(char *name, u32 cfg, u32 frq)
2967{ 2900{
@@ -2984,9 +2917,9 @@ void __init pmac_check_ht_link(void)
2984 u8 px_bus, px_devfn; 2917 u8 px_bus, px_devfn;
2985 struct pci_controller *px_hose; 2918 struct pci_controller *px_hose;
2986 2919
2987 (void)in_be32(u3_ht + U3_HT_LINK_COMMAND); 2920 (void)in_be32(u3_ht_base + U3_HT_LINK_COMMAND);
2988 ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG); 2921 ucfg = cfg = in_be32(u3_ht_base + U3_HT_LINK_CONFIG);
2989 ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ); 2922 ufreq = freq = in_be32(u3_ht_base + U3_HT_LINK_FREQ);
2990 dump_HT_speeds("U3 HyperTransport", cfg, freq); 2923 dump_HT_speeds("U3 HyperTransport", cfg, freq);
2991 2924
2992 pcix_node = of_find_compatible_node(NULL, "pci", "pci-x"); 2925 pcix_node = of_find_compatible_node(NULL, "pci", "pci-x");
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index f3f39e8e337a..535c802b369f 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -1,22 +1,34 @@
1/* 1/*
2 * arch/ppc/platforms/pmac_low_i2c.c 2 * arch/powerpc/platforms/powermac/low_i2c.c
3 * 3 *
4 * Copyright (C) 2003 Ben. Herrenschmidt (benh@kernel.crashing.org) 4 * Copyright (C) 2003-2005 Ben. Herrenschmidt (benh@kernel.crashing.org)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 * 10 *
11 * This file contains some low-level i2c access routines that 11 * The linux i2c layer isn't completely suitable for our needs for various
12 * need to be used by various bits of the PowerMac platform code 12 * reasons ranging from too late initialisation to semantics not perfectly
13 * at times where the real asynchronous & interrupt driven driver 13 * matching some requirements of the apple platform functions etc...
14 * cannot be used. The API borrows some semantics from the darwin 14 *
15 * driver in order to ease the implementation of the platform 15 * This file thus provides a simple low level unified i2c interface for
16 * properties parser 16 * powermac that covers the various types of i2c busses used in Apple machines.
17 * For now, keywest, PMU and SMU, though we could add Cuda, or other bit
18 * banging busses found on older chipstes in earlier machines if we ever need
19 * one of them.
20 *
21 * The drivers in this file are synchronous/blocking. In addition, the
22 * keywest one is fairly slow due to the use of msleep instead of interrupts
23 * as the interrupt is currently used by i2c-keywest. In the long run, we
24 * might want to get rid of those high-level interfaces to linux i2c layer
25 * either completely (converting all drivers) or replacing them all with a
26 * single stub driver on top of this one. Once done, the interrupt will be
27 * available for our use.
17 */ 28 */
18 29
19#undef DEBUG 30#undef DEBUG
31#undef DEBUG_LOW
20 32
21#include <linux/config.h> 33#include <linux/config.h>
22#include <linux/types.h> 34#include <linux/types.h>
@@ -25,66 +37,91 @@
25#include <linux/module.h> 37#include <linux/module.h>
26#include <linux/adb.h> 38#include <linux/adb.h>
27#include <linux/pmu.h> 39#include <linux/pmu.h>
40#include <linux/delay.h>
41#include <linux/completion.h>
42#include <linux/platform_device.h>
43#include <linux/interrupt.h>
44#include <linux/completion.h>
45#include <linux/timer.h>
28#include <asm/keylargo.h> 46#include <asm/keylargo.h>
29#include <asm/uninorth.h> 47#include <asm/uninorth.h>
30#include <asm/io.h> 48#include <asm/io.h>
31#include <asm/prom.h> 49#include <asm/prom.h>
32#include <asm/machdep.h> 50#include <asm/machdep.h>
51#include <asm/smu.h>
52#include <asm/pmac_pfunc.h>
33#include <asm/pmac_low_i2c.h> 53#include <asm/pmac_low_i2c.h>
34 54
35#define MAX_LOW_I2C_HOST 4
36
37#ifdef DEBUG 55#ifdef DEBUG
38#define DBG(x...) do {\ 56#define DBG(x...) do {\
39 printk(KERN_DEBUG "KW:" x); \ 57 printk(KERN_DEBUG "low_i2c:" x); \
40 } while(0) 58 } while(0)
41#else 59#else
42#define DBG(x...) 60#define DBG(x...)
43#endif 61#endif
44 62
45struct low_i2c_host; 63#ifdef DEBUG_LOW
46 64#define DBG_LOW(x...) do {\
47typedef int (*low_i2c_func_t)(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len); 65 printk(KERN_DEBUG "low_i2c:" x); \
66 } while(0)
67#else
68#define DBG_LOW(x...)
69#endif
48 70
49struct low_i2c_host
50{
51 struct device_node *np; /* OF device node */
52 struct semaphore mutex; /* Access mutex for use by i2c-keywest */
53 low_i2c_func_t func; /* Access function */
54 unsigned int is_open : 1; /* Poor man's access control */
55 int mode; /* Current mode */
56 int channel; /* Current channel */
57 int num_channels; /* Number of channels */
58 void __iomem *base; /* For keywest-i2c, base address */
59 int bsteps; /* And register stepping */
60 int speed; /* And speed */
61};
62 71
63static struct low_i2c_host low_i2c_hosts[MAX_LOW_I2C_HOST]; 72static int pmac_i2c_force_poll = 1;
64 73
65/* No locking is necessary on allocation, we are running way before 74/*
66 * anything can race with us 75 * A bus structure. Each bus in the system has such a structure associated.
67 */ 76 */
68static struct low_i2c_host *find_low_i2c_host(struct device_node *np) 77struct pmac_i2c_bus
69{ 78{
70 int i; 79 struct list_head link;
80 struct device_node *controller;
81 struct device_node *busnode;
82 int type;
83 int flags;
84 struct i2c_adapter *adapter;
85 void *hostdata;
86 int channel; /* some hosts have multiple */
87 int mode; /* current mode */
88 struct semaphore sem;
89 int opened;
90 int polled; /* open mode */
91 struct platform_device *platform_dev;
92
93 /* ops */
94 int (*open)(struct pmac_i2c_bus *bus);
95 void (*close)(struct pmac_i2c_bus *bus);
96 int (*xfer)(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
97 u32 subaddr, u8 *data, int len);
98};
71 99
72 for (i = 0; i < MAX_LOW_I2C_HOST; i++) 100static LIST_HEAD(pmac_i2c_busses);
73 if (low_i2c_hosts[i].np == np)
74 return &low_i2c_hosts[i];
75 return NULL;
76}
77 101
78/* 102/*
79 * 103 * Keywest implementation
80 * i2c-keywest implementation (UniNorth, U2, U3, Keylargo's)
81 *
82 */ 104 */
83 105
84/* 106struct pmac_i2c_host_kw
85 * Keywest i2c definitions borrowed from drivers/i2c/i2c-keywest.h, 107{
86 * should be moved somewhere in include/asm-ppc/ 108 struct semaphore mutex; /* Access mutex for use by
87 */ 109 * i2c-keywest */
110 void __iomem *base; /* register base address */
111 int bsteps; /* register stepping */
112 int speed; /* speed */
113 int irq;
114 u8 *data;
115 unsigned len;
116 int state;
117 int rw;
118 int polled;
119 int result;
120 struct completion complete;
121 spinlock_t lock;
122 struct timer_list timeout_timer;
123};
124
88/* Register indices */ 125/* Register indices */
89typedef enum { 126typedef enum {
90 reg_mode = 0, 127 reg_mode = 0,
@@ -97,6 +134,8 @@ typedef enum {
97 reg_data 134 reg_data
98} reg_t; 135} reg_t;
99 136
137/* The Tumbler audio equalizer can be really slow sometimes */
138#define KW_POLL_TIMEOUT (2*HZ)
100 139
101/* Mode register */ 140/* Mode register */
102#define KW_I2C_MODE_100KHZ 0x00 141#define KW_I2C_MODE_100KHZ 0x00
@@ -140,8 +179,9 @@ enum {
140}; 179};
141 180
142#define WRONG_STATE(name) do {\ 181#define WRONG_STATE(name) do {\
143 printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s (isr: %02x)\n", \ 182 printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s " \
144 name, __kw_state_names[state], isr); \ 183 "(isr: %02x)\n", \
184 name, __kw_state_names[host->state], isr); \
145 } while(0) 185 } while(0)
146 186
147static const char *__kw_state_names[] = { 187static const char *__kw_state_names[] = {
@@ -153,120 +193,137 @@ static const char *__kw_state_names[] = {
153 "state_dead" 193 "state_dead"
154}; 194};
155 195
156static inline u8 __kw_read_reg(struct low_i2c_host *host, reg_t reg) 196static inline u8 __kw_read_reg(struct pmac_i2c_host_kw *host, reg_t reg)
157{ 197{
158 return readb(host->base + (((unsigned int)reg) << host->bsteps)); 198 return readb(host->base + (((unsigned int)reg) << host->bsteps));
159} 199}
160 200
161static inline void __kw_write_reg(struct low_i2c_host *host, reg_t reg, u8 val) 201static inline void __kw_write_reg(struct pmac_i2c_host_kw *host,
202 reg_t reg, u8 val)
162{ 203{
163 writeb(val, host->base + (((unsigned)reg) << host->bsteps)); 204 writeb(val, host->base + (((unsigned)reg) << host->bsteps));
164 (void)__kw_read_reg(host, reg_subaddr); 205 (void)__kw_read_reg(host, reg_subaddr);
165} 206}
166 207
167#define kw_write_reg(reg, val) __kw_write_reg(host, reg, val) 208#define kw_write_reg(reg, val) __kw_write_reg(host, reg, val)
168#define kw_read_reg(reg) __kw_read_reg(host, reg) 209#define kw_read_reg(reg) __kw_read_reg(host, reg)
169
170 210
171/* Don't schedule, the g5 fan controller is too 211static u8 kw_i2c_wait_interrupt(struct pmac_i2c_host_kw *host)
172 * timing sensitive
173 */
174static u8 kw_wait_interrupt(struct low_i2c_host* host)
175{ 212{
176 int i, j; 213 int i, j;
177 u8 isr; 214 u8 isr;
178 215
179 for (i = 0; i < 100000; i++) { 216 for (i = 0; i < 1000; i++) {
180 isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK; 217 isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK;
181 if (isr != 0) 218 if (isr != 0)
182 return isr; 219 return isr;
183 220
184 /* This code is used with the timebase frozen, we cannot rely 221 /* This code is used with the timebase frozen, we cannot rely
185 * on udelay ! For now, just use a bogus loop 222 * on udelay nor schedule when in polled mode !
223 * For now, just use a bogus loop....
186 */ 224 */
187 for (j = 1; j < 10000; j++) 225 if (host->polled) {
188 mb(); 226 for (j = 1; j < 100000; j++)
227 mb();
228 } else
229 msleep(1);
189 } 230 }
190 return isr; 231 return isr;
191} 232}
192 233
193static int kw_handle_interrupt(struct low_i2c_host *host, int state, int rw, int *rc, u8 **data, int *len, u8 isr) 234static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr)
194{ 235{
195 u8 ack; 236 u8 ack;
196 237
197 DBG("kw_handle_interrupt(%s, isr: %x)\n", __kw_state_names[state], isr); 238 DBG_LOW("kw_handle_interrupt(%s, isr: %x)\n",
239 __kw_state_names[host->state], isr);
240
241 if (host->state == state_idle) {
242 printk(KERN_WARNING "low_i2c: Keywest got an out of state"
243 " interrupt, ignoring\n");
244 kw_write_reg(reg_isr, isr);
245 return;
246 }
198 247
199 if (isr == 0) { 248 if (isr == 0) {
200 if (state != state_stop) { 249 if (host->state != state_stop) {
201 DBG("KW: Timeout !\n"); 250 DBG_LOW("KW: Timeout !\n");
202 *rc = -EIO; 251 host->result = -EIO;
203 goto stop; 252 goto stop;
204 } 253 }
205 if (state == state_stop) { 254 if (host->state == state_stop) {
206 ack = kw_read_reg(reg_status); 255 ack = kw_read_reg(reg_status);
207 if (!(ack & KW_I2C_STAT_BUSY)) { 256 if (ack & KW_I2C_STAT_BUSY)
208 state = state_idle; 257 kw_write_reg(reg_status, 0);
209 kw_write_reg(reg_ier, 0x00); 258 host->state = state_idle;
210 } 259 kw_write_reg(reg_ier, 0x00);
260 if (!host->polled)
261 complete(&host->complete);
211 } 262 }
212 return state; 263 return;
213 } 264 }
214 265
215 if (isr & KW_I2C_IRQ_ADDR) { 266 if (isr & KW_I2C_IRQ_ADDR) {
216 ack = kw_read_reg(reg_status); 267 ack = kw_read_reg(reg_status);
217 if (state != state_addr) { 268 if (host->state != state_addr) {
218 kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); 269 kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
219 WRONG_STATE("KW_I2C_IRQ_ADDR"); 270 WRONG_STATE("KW_I2C_IRQ_ADDR");
220 *rc = -EIO; 271 host->result = -EIO;
221 goto stop; 272 goto stop;
222 } 273 }
223 if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { 274 if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
224 *rc = -ENODEV; 275 host->result = -ENODEV;
225 DBG("KW: NAK on address\n"); 276 DBG_LOW("KW: NAK on address\n");
226 return state_stop; 277 host->state = state_stop;
278 return;
227 } else { 279 } else {
228 if (rw) { 280 if (host->len == 0) {
229 state = state_read; 281 kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
230 if (*len > 1) 282 goto stop;
231 kw_write_reg(reg_control, KW_I2C_CTL_AAK); 283 }
284 if (host->rw) {
285 host->state = state_read;
286 if (host->len > 1)
287 kw_write_reg(reg_control,
288 KW_I2C_CTL_AAK);
232 } else { 289 } else {
233 state = state_write; 290 host->state = state_write;
234 kw_write_reg(reg_data, **data); 291 kw_write_reg(reg_data, *(host->data++));
235 (*data)++; (*len)--; 292 host->len--;
236 } 293 }
237 } 294 }
238 kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); 295 kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
239 } 296 }
240 297
241 if (isr & KW_I2C_IRQ_DATA) { 298 if (isr & KW_I2C_IRQ_DATA) {
242 if (state == state_read) { 299 if (host->state == state_read) {
243 **data = kw_read_reg(reg_data); 300 *(host->data++) = kw_read_reg(reg_data);
244 (*data)++; (*len)--; 301 host->len--;
245 kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); 302 kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
246 if ((*len) == 0) 303 if (host->len == 0)
247 state = state_stop; 304 host->state = state_stop;
248 else if ((*len) == 1) 305 else if (host->len == 1)
249 kw_write_reg(reg_control, 0); 306 kw_write_reg(reg_control, 0);
250 } else if (state == state_write) { 307 } else if (host->state == state_write) {
251 ack = kw_read_reg(reg_status); 308 ack = kw_read_reg(reg_status);
252 if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { 309 if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
253 DBG("KW: nack on data write\n"); 310 DBG_LOW("KW: nack on data write\n");
254 *rc = -EIO; 311 host->result = -EIO;
255 goto stop; 312 goto stop;
256 } else if (*len) { 313 } else if (host->len) {
257 kw_write_reg(reg_data, **data); 314 kw_write_reg(reg_data, *(host->data++));
258 (*data)++; (*len)--; 315 host->len--;
259 } else { 316 } else {
260 kw_write_reg(reg_control, KW_I2C_CTL_STOP); 317 kw_write_reg(reg_control, KW_I2C_CTL_STOP);
261 state = state_stop; 318 host->state = state_stop;
262 *rc = 0; 319 host->result = 0;
263 } 320 }
264 kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); 321 kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
265 } else { 322 } else {
266 kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); 323 kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
267 WRONG_STATE("KW_I2C_IRQ_DATA"); 324 WRONG_STATE("KW_I2C_IRQ_DATA");
268 if (state != state_stop) { 325 if (host->state != state_stop) {
269 *rc = -EIO; 326 host->result = -EIO;
270 goto stop; 327 goto stop;
271 } 328 }
272 } 329 }
@@ -274,98 +331,194 @@ static int kw_handle_interrupt(struct low_i2c_host *host, int state, int rw, int
274 331
275 if (isr & KW_I2C_IRQ_STOP) { 332 if (isr & KW_I2C_IRQ_STOP) {
276 kw_write_reg(reg_isr, KW_I2C_IRQ_STOP); 333 kw_write_reg(reg_isr, KW_I2C_IRQ_STOP);
277 if (state != state_stop) { 334 if (host->state != state_stop) {
278 WRONG_STATE("KW_I2C_IRQ_STOP"); 335 WRONG_STATE("KW_I2C_IRQ_STOP");
279 *rc = -EIO; 336 host->result = -EIO;
280 } 337 }
281 return state_idle; 338 host->state = state_idle;
339 if (!host->polled)
340 complete(&host->complete);
282 } 341 }
283 342
284 if (isr & KW_I2C_IRQ_START) 343 if (isr & KW_I2C_IRQ_START)
285 kw_write_reg(reg_isr, KW_I2C_IRQ_START); 344 kw_write_reg(reg_isr, KW_I2C_IRQ_START);
286 345
287 return state; 346 return;
288
289 stop: 347 stop:
290 kw_write_reg(reg_control, KW_I2C_CTL_STOP); 348 kw_write_reg(reg_control, KW_I2C_CTL_STOP);
291 return state_stop; 349 host->state = state_stop;
350 return;
292} 351}
293 352
294static int keywest_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 subaddr, u8 *data, int len) 353/* Interrupt handler */
354static irqreturn_t kw_i2c_irq(int irq, void *dev_id, struct pt_regs *regs)
295{ 355{
356 struct pmac_i2c_host_kw *host = dev_id;
357 unsigned long flags;
358
359 spin_lock_irqsave(&host->lock, flags);
360 del_timer(&host->timeout_timer);
361 kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr));
362 if (host->state != state_idle) {
363 host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT;
364 add_timer(&host->timeout_timer);
365 }
366 spin_unlock_irqrestore(&host->lock, flags);
367 return IRQ_HANDLED;
368}
369
370static void kw_i2c_timeout(unsigned long data)
371{
372 struct pmac_i2c_host_kw *host = (struct pmac_i2c_host_kw *)data;
373 unsigned long flags;
374
375 spin_lock_irqsave(&host->lock, flags);
376 kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr));
377 if (host->state != state_idle) {
378 host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT;
379 add_timer(&host->timeout_timer);
380 }
381 spin_unlock_irqrestore(&host->lock, flags);
382}
383
384static int kw_i2c_open(struct pmac_i2c_bus *bus)
385{
386 struct pmac_i2c_host_kw *host = bus->hostdata;
387 down(&host->mutex);
388 return 0;
389}
390
391static void kw_i2c_close(struct pmac_i2c_bus *bus)
392{
393 struct pmac_i2c_host_kw *host = bus->hostdata;
394 up(&host->mutex);
395}
396
397static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
398 u32 subaddr, u8 *data, int len)
399{
400 struct pmac_i2c_host_kw *host = bus->hostdata;
296 u8 mode_reg = host->speed; 401 u8 mode_reg = host->speed;
297 int state = state_addr; 402 int use_irq = host->irq != NO_IRQ && !bus->polled;
298 int rc = 0;
299 403
300 /* Setup mode & subaddress if any */ 404 /* Setup mode & subaddress if any */
301 switch(host->mode) { 405 switch(bus->mode) {
302 case pmac_low_i2c_mode_dumb: 406 case pmac_i2c_mode_dumb:
303 printk(KERN_ERR "low_i2c: Dumb mode not supported !\n");
304 return -EINVAL; 407 return -EINVAL;
305 case pmac_low_i2c_mode_std: 408 case pmac_i2c_mode_std:
306 mode_reg |= KW_I2C_MODE_STANDARD; 409 mode_reg |= KW_I2C_MODE_STANDARD;
410 if (subsize != 0)
411 return -EINVAL;
307 break; 412 break;
308 case pmac_low_i2c_mode_stdsub: 413 case pmac_i2c_mode_stdsub:
309 mode_reg |= KW_I2C_MODE_STANDARDSUB; 414 mode_reg |= KW_I2C_MODE_STANDARDSUB;
415 if (subsize != 1)
416 return -EINVAL;
310 break; 417 break;
311 case pmac_low_i2c_mode_combined: 418 case pmac_i2c_mode_combined:
312 mode_reg |= KW_I2C_MODE_COMBINED; 419 mode_reg |= KW_I2C_MODE_COMBINED;
420 if (subsize != 1)
421 return -EINVAL;
313 break; 422 break;
314 } 423 }
315 424
316 /* Setup channel & clear pending irqs */ 425 /* Setup channel & clear pending irqs */
317 kw_write_reg(reg_isr, kw_read_reg(reg_isr)); 426 kw_write_reg(reg_isr, kw_read_reg(reg_isr));
318 kw_write_reg(reg_mode, mode_reg | (host->channel << 4)); 427 kw_write_reg(reg_mode, mode_reg | (bus->channel << 4));
319 kw_write_reg(reg_status, 0); 428 kw_write_reg(reg_status, 0);
320 429
321 /* Set up address and r/w bit */ 430 /* Set up address and r/w bit, strip possible stale bus number from
322 kw_write_reg(reg_addr, addr); 431 * address top bits
432 */
433 kw_write_reg(reg_addr, addrdir & 0xff);
323 434
324 /* Set up the sub address */ 435 /* Set up the sub address */
325 if ((mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB 436 if ((mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB
326 || (mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED) 437 || (mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED)
327 kw_write_reg(reg_subaddr, subaddr); 438 kw_write_reg(reg_subaddr, subaddr);
328 439
329 /* Start sending address & disable interrupt*/ 440 /* Prepare for async operations */
330 kw_write_reg(reg_ier, 0 /*KW_I2C_IRQ_MASK*/); 441 host->data = data;
442 host->len = len;
443 host->state = state_addr;
444 host->result = 0;
445 host->rw = (addrdir & 1);
446 host->polled = bus->polled;
447
448 /* Enable interrupt if not using polled mode and interrupt is
449 * available
450 */
451 if (use_irq) {
452 /* Clear completion */
453 INIT_COMPLETION(host->complete);
454 /* Ack stale interrupts */
455 kw_write_reg(reg_isr, kw_read_reg(reg_isr));
456 /* Arm timeout */
457 host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT;
458 add_timer(&host->timeout_timer);
459 /* Enable emission */
460 kw_write_reg(reg_ier, KW_I2C_IRQ_MASK);
461 }
462
463 /* Start sending address */
331 kw_write_reg(reg_control, KW_I2C_CTL_XADDR); 464 kw_write_reg(reg_control, KW_I2C_CTL_XADDR);
332 465
333 /* State machine, to turn into an interrupt handler */ 466 /* Wait for completion */
334 while(state != state_idle) { 467 if (use_irq)
335 u8 isr = kw_wait_interrupt(host); 468 wait_for_completion(&host->complete);
336 state = kw_handle_interrupt(host, state, addr & 1, &rc, &data, &len, isr); 469 else {
470 while(host->state != state_idle) {
471 unsigned long flags;
472
473 u8 isr = kw_i2c_wait_interrupt(host);
474 spin_lock_irqsave(&host->lock, flags);
475 kw_i2c_handle_interrupt(host, isr);
476 spin_unlock_irqrestore(&host->lock, flags);
477 }
337 } 478 }
338 479
339 return rc; 480 /* Disable emission */
481 kw_write_reg(reg_ier, 0);
482
483 return host->result;
340} 484}
341 485
342static void keywest_low_i2c_add(struct device_node *np) 486static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
343{ 487{
344 struct low_i2c_host *host = find_low_i2c_host(NULL); 488 struct pmac_i2c_host_kw *host;
345 u32 *psteps, *prate, steps, aoffset = 0; 489 u32 *psteps, *prate, *addrp, steps;
346 struct device_node *parent;
347 490
491 host = kzalloc(sizeof(struct pmac_i2c_host_kw), GFP_KERNEL);
348 if (host == NULL) { 492 if (host == NULL) {
349 printk(KERN_ERR "low_i2c: Can't allocate host for %s\n", 493 printk(KERN_ERR "low_i2c: Can't allocate host for %s\n",
350 np->full_name); 494 np->full_name);
351 return; 495 return NULL;
352 } 496 }
353 memset(host, 0, sizeof(*host));
354 497
498 /* Apple is kind enough to provide a valid AAPL,address property
499 * on all i2c keywest nodes so far ... we would have to fallback
500 * to macio parsing if that wasn't the case
501 */
502 addrp = (u32 *)get_property(np, "AAPL,address", NULL);
503 if (addrp == NULL) {
504 printk(KERN_ERR "low_i2c: Can't find address for %s\n",
505 np->full_name);
506 kfree(host);
507 return NULL;
508 }
355 init_MUTEX(&host->mutex); 509 init_MUTEX(&host->mutex);
356 host->np = of_node_get(np); 510 init_completion(&host->complete);
511 spin_lock_init(&host->lock);
512 init_timer(&host->timeout_timer);
513 host->timeout_timer.function = kw_i2c_timeout;
514 host->timeout_timer.data = (unsigned long)host;
515
357 psteps = (u32 *)get_property(np, "AAPL,address-step", NULL); 516 psteps = (u32 *)get_property(np, "AAPL,address-step", NULL);
358 steps = psteps ? (*psteps) : 0x10; 517 steps = psteps ? (*psteps) : 0x10;
359 for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++) 518 for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++)
360 steps >>= 1; 519 steps >>= 1;
361 parent = of_get_parent(np);
362 host->num_channels = 1;
363 if (parent && parent->name[0] == 'u') {
364 host->num_channels = 2;
365 aoffset = 3;
366 }
367 /* Select interface rate */ 520 /* Select interface rate */
368 host->speed = KW_I2C_MODE_100KHZ; 521 host->speed = KW_I2C_MODE_25KHZ;
369 prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL); 522 prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL);
370 if (prate) switch(*prate) { 523 if (prate) switch(*prate) {
371 case 100: 524 case 100:
@@ -378,146 +531,981 @@ static void keywest_low_i2c_add(struct device_node *np)
378 host->speed = KW_I2C_MODE_25KHZ; 531 host->speed = KW_I2C_MODE_25KHZ;
379 break; 532 break;
380 } 533 }
534 if (np->n_intrs > 0)
535 host->irq = np->intrs[0].line;
536 else
537 host->irq = NO_IRQ;
538
539 host->base = ioremap((*addrp), 0x1000);
540 if (host->base == NULL) {
541 printk(KERN_ERR "low_i2c: Can't map registers for %s\n",
542 np->full_name);
543 kfree(host);
544 return NULL;
545 }
546
547 /* Make sure IRA is disabled */
548 kw_write_reg(reg_ier, 0);
549
550 /* Request chip interrupt */
551 if (request_irq(host->irq, kw_i2c_irq, SA_SHIRQ, "keywest i2c", host))
552 host->irq = NO_IRQ;
553
554 printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n",
555 *addrp, host->irq, np->full_name);
381 556
382 host->mode = pmac_low_i2c_mode_std; 557 return host;
383 host->base = ioremap(np->addrs[0].address + aoffset,
384 np->addrs[0].size);
385 host->func = keywest_low_i2c_func;
386} 558}
387 559
560
561static void __init kw_i2c_add(struct pmac_i2c_host_kw *host,
562 struct device_node *controller,
563 struct device_node *busnode,
564 int channel)
565{
566 struct pmac_i2c_bus *bus;
567
568 bus = kzalloc(sizeof(struct pmac_i2c_bus), GFP_KERNEL);
569 if (bus == NULL)
570 return;
571
572 bus->controller = of_node_get(controller);
573 bus->busnode = of_node_get(busnode);
574 bus->type = pmac_i2c_bus_keywest;
575 bus->hostdata = host;
576 bus->channel = channel;
577 bus->mode = pmac_i2c_mode_std;
578 bus->open = kw_i2c_open;
579 bus->close = kw_i2c_close;
580 bus->xfer = kw_i2c_xfer;
581 init_MUTEX(&bus->sem);
582 if (controller == busnode)
583 bus->flags = pmac_i2c_multibus;
584 list_add(&bus->link, &pmac_i2c_busses);
585
586 printk(KERN_INFO " channel %d bus %s\n", channel,
587 (controller == busnode) ? "<multibus>" : busnode->full_name);
588}
589
590static void __init kw_i2c_probe(void)
591{
592 struct device_node *np, *child, *parent;
593
594 /* Probe keywest-i2c busses */
595 for (np = NULL;
596 (np = of_find_compatible_node(np, "i2c","keywest-i2c")) != NULL;){
597 struct pmac_i2c_host_kw *host;
598 int multibus, chans, i;
599
600 /* Found one, init a host structure */
601 host = kw_i2c_host_init(np);
602 if (host == NULL)
603 continue;
604
605 /* Now check if we have a multibus setup (old style) or if we
606 * have proper bus nodes. Note that the "new" way (proper bus
607 * nodes) might cause us to not create some busses that are
608 * kept hidden in the device-tree. In the future, we might
609 * want to work around that by creating busses without a node
610 * but not for now
611 */
612 child = of_get_next_child(np, NULL);
613 multibus = !child || strcmp(child->name, "i2c-bus");
614 of_node_put(child);
615
616 /* For a multibus setup, we get the bus count based on the
617 * parent type
618 */
619 if (multibus) {
620 parent = of_get_parent(np);
621 if (parent == NULL)
622 continue;
623 chans = parent->name[0] == 'u' ? 2 : 1;
624 for (i = 0; i < chans; i++)
625 kw_i2c_add(host, np, np, i);
626 } else {
627 for (child = NULL;
628 (child = of_get_next_child(np, child)) != NULL;) {
629 u32 *reg =
630 (u32 *)get_property(child, "reg", NULL);
631 if (reg == NULL)
632 continue;
633 kw_i2c_add(host, np, child, *reg);
634 }
635 }
636 }
637}
638
639
388/* 640/*
389 * 641 *
390 * PMU implementation 642 * PMU implementation
391 * 643 *
392 */ 644 */
393 645
394
395#ifdef CONFIG_ADB_PMU 646#ifdef CONFIG_ADB_PMU
396 647
397static int pmu_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len) 648/*
649 * i2c command block to the PMU
650 */
651struct pmu_i2c_hdr {
652 u8 bus;
653 u8 mode;
654 u8 bus2;
655 u8 address;
656 u8 sub_addr;
657 u8 comb_addr;
658 u8 count;
659 u8 data[];
660};
661
662static void pmu_i2c_complete(struct adb_request *req)
398{ 663{
399 // TODO 664 complete(req->arg);
400 return -ENODEV;
401} 665}
402 666
403static void pmu_low_i2c_add(struct device_node *np) 667static int pmu_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
668 u32 subaddr, u8 *data, int len)
404{ 669{
405 struct low_i2c_host *host = find_low_i2c_host(NULL); 670 struct adb_request *req = bus->hostdata;
671 struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req->data[1];
672 struct completion comp;
673 int read = addrdir & 1;
674 int retry;
675 int rc = 0;
406 676
407 if (host == NULL) { 677 /* For now, limit ourselves to 16 bytes transfers */
408 printk(KERN_ERR "low_i2c: Can't allocate host for %s\n", 678 if (len > 16)
409 np->full_name); 679 return -EINVAL;
410 return; 680
681 init_completion(&comp);
682
683 for (retry = 0; retry < 16; retry++) {
684 memset(req, 0, sizeof(struct adb_request));
685 hdr->bus = bus->channel;
686 hdr->count = len;
687
688 switch(bus->mode) {
689 case pmac_i2c_mode_std:
690 if (subsize != 0)
691 return -EINVAL;
692 hdr->address = addrdir;
693 hdr->mode = PMU_I2C_MODE_SIMPLE;
694 break;
695 case pmac_i2c_mode_stdsub:
696 case pmac_i2c_mode_combined:
697 if (subsize != 1)
698 return -EINVAL;
699 hdr->address = addrdir & 0xfe;
700 hdr->comb_addr = addrdir;
701 hdr->sub_addr = subaddr;
702 if (bus->mode == pmac_i2c_mode_stdsub)
703 hdr->mode = PMU_I2C_MODE_STDSUB;
704 else
705 hdr->mode = PMU_I2C_MODE_COMBINED;
706 break;
707 default:
708 return -EINVAL;
709 }
710
711 INIT_COMPLETION(comp);
712 req->data[0] = PMU_I2C_CMD;
713 req->reply[0] = 0xff;
714 req->nbytes = sizeof(struct pmu_i2c_hdr) + 1;
715 req->done = pmu_i2c_complete;
716 req->arg = &comp;
717 if (!read && len) {
718 memcpy(hdr->data, data, len);
719 req->nbytes += len;
720 }
721 rc = pmu_queue_request(req);
722 if (rc)
723 return rc;
724 wait_for_completion(&comp);
725 if (req->reply[0] == PMU_I2C_STATUS_OK)
726 break;
727 msleep(15);
411 } 728 }
412 memset(host, 0, sizeof(*host)); 729 if (req->reply[0] != PMU_I2C_STATUS_OK)
730 return -EIO;
413 731
414 init_MUTEX(&host->mutex); 732 for (retry = 0; retry < 16; retry++) {
415 host->np = of_node_get(np); 733 memset(req, 0, sizeof(struct adb_request));
416 host->num_channels = 3; 734
417 host->mode = pmac_low_i2c_mode_std; 735 /* I know that looks like a lot, slow as hell, but darwin
418 host->func = pmu_low_i2c_func; 736 * does it so let's be on the safe side for now
737 */
738 msleep(15);
739
740 hdr->bus = PMU_I2C_BUS_STATUS;
741
742 INIT_COMPLETION(comp);
743 req->data[0] = PMU_I2C_CMD;
744 req->reply[0] = 0xff;
745 req->nbytes = 2;
746 req->done = pmu_i2c_complete;
747 req->arg = &comp;
748 rc = pmu_queue_request(req);
749 if (rc)
750 return rc;
751 wait_for_completion(&comp);
752
753 if (req->reply[0] == PMU_I2C_STATUS_OK && !read)
754 return 0;
755 if (req->reply[0] == PMU_I2C_STATUS_DATAREAD && read) {
756 int rlen = req->reply_len - 1;
757
758 if (rlen != len) {
759 printk(KERN_WARNING "low_i2c: PMU returned %d"
760 " bytes, expected %d !\n", rlen, len);
761 return -EIO;
762 }
763 if (len)
764 memcpy(data, &req->reply[1], len);
765 return 0;
766 }
767 }
768 return -EIO;
769}
770
771static void __init pmu_i2c_probe(void)
772{
773 struct pmac_i2c_bus *bus;
774 struct device_node *busnode;
775 int channel, sz;
776
777 if (!pmu_present())
778 return;
779
780 /* There might or might not be a "pmu-i2c" node, we use that
781 * or via-pmu itself, whatever we find. I haven't seen a machine
782 * with separate bus nodes, so we assume a multibus setup
783 */
784 busnode = of_find_node_by_name(NULL, "pmu-i2c");
785 if (busnode == NULL)
786 busnode = of_find_node_by_name(NULL, "via-pmu");
787 if (busnode == NULL)
788 return;
789
790 printk(KERN_INFO "PMU i2c %s\n", busnode->full_name);
791
792 /*
793 * We add bus 1 and 2 only for now, bus 0 is "special"
794 */
795 for (channel = 1; channel <= 2; channel++) {
796 sz = sizeof(struct pmac_i2c_bus) + sizeof(struct adb_request);
797 bus = kzalloc(sz, GFP_KERNEL);
798 if (bus == NULL)
799 return;
800
801 bus->controller = busnode;
802 bus->busnode = busnode;
803 bus->type = pmac_i2c_bus_pmu;
804 bus->channel = channel;
805 bus->mode = pmac_i2c_mode_std;
806 bus->hostdata = bus + 1;
807 bus->xfer = pmu_i2c_xfer;
808 init_MUTEX(&bus->sem);
809 bus->flags = pmac_i2c_multibus;
810 list_add(&bus->link, &pmac_i2c_busses);
811
812 printk(KERN_INFO " channel %d bus <multibus>\n", channel);
813 }
419} 814}
420 815
421#endif /* CONFIG_ADB_PMU */ 816#endif /* CONFIG_ADB_PMU */
422 817
423void __init pmac_init_low_i2c(void) 818
819/*
820 *
821 * SMU implementation
822 *
823 */
824
825#ifdef CONFIG_PMAC_SMU
826
827static void smu_i2c_complete(struct smu_i2c_cmd *cmd, void *misc)
424{ 828{
425 struct device_node *np; 829 complete(misc);
830}
426 831
427 /* Probe keywest-i2c busses */ 832static int smu_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
428 np = of_find_compatible_node(NULL, "i2c", "keywest-i2c"); 833 u32 subaddr, u8 *data, int len)
429 while(np) { 834{
430 keywest_low_i2c_add(np); 835 struct smu_i2c_cmd *cmd = bus->hostdata;
431 np = of_find_compatible_node(np, "i2c", "keywest-i2c"); 836 struct completion comp;
837 int read = addrdir & 1;
838 int rc = 0;
839
840 if ((read && len > SMU_I2C_READ_MAX) ||
841 ((!read) && len > SMU_I2C_WRITE_MAX))
842 return -EINVAL;
843
844 memset(cmd, 0, sizeof(struct smu_i2c_cmd));
845 cmd->info.bus = bus->channel;
846 cmd->info.devaddr = addrdir;
847 cmd->info.datalen = len;
848
849 switch(bus->mode) {
850 case pmac_i2c_mode_std:
851 if (subsize != 0)
852 return -EINVAL;
853 cmd->info.type = SMU_I2C_TRANSFER_SIMPLE;
854 break;
855 case pmac_i2c_mode_stdsub:
856 case pmac_i2c_mode_combined:
857 if (subsize > 3 || subsize < 1)
858 return -EINVAL;
859 cmd->info.sublen = subsize;
860 /* that's big-endian only but heh ! */
861 memcpy(&cmd->info.subaddr, ((char *)&subaddr) + (4 - subsize),
862 subsize);
863 if (bus->mode == pmac_i2c_mode_stdsub)
864 cmd->info.type = SMU_I2C_TRANSFER_STDSUB;
865 else
866 cmd->info.type = SMU_I2C_TRANSFER_COMBINED;
867 break;
868 default:
869 return -EINVAL;
432 } 870 }
871 if (!read && len)
872 memcpy(cmd->info.data, data, len);
873
874 init_completion(&comp);
875 cmd->done = smu_i2c_complete;
876 cmd->misc = &comp;
877 rc = smu_queue_i2c(cmd);
878 if (rc < 0)
879 return rc;
880 wait_for_completion(&comp);
881 rc = cmd->status;
882
883 if (read && len)
884 memcpy(data, cmd->info.data, len);
885 return rc < 0 ? rc : 0;
886}
887
888static void __init smu_i2c_probe(void)
889{
890 struct device_node *controller, *busnode;
891 struct pmac_i2c_bus *bus;
892 u32 *reg;
893 int sz;
894
895 if (!smu_present())
896 return;
897
898 controller = of_find_node_by_name(NULL, "smu-i2c-control");
899 if (controller == NULL)
900 controller = of_find_node_by_name(NULL, "smu");
901 if (controller == NULL)
902 return;
903
904 printk(KERN_INFO "SMU i2c %s\n", controller->full_name);
905
906 /* Look for childs, note that they might not be of the right
907 * type as older device trees mix i2c busses and other thigns
908 * at the same level
909 */
910 for (busnode = NULL;
911 (busnode = of_get_next_child(controller, busnode)) != NULL;) {
912 if (strcmp(busnode->type, "i2c") &&
913 strcmp(busnode->type, "i2c-bus"))
914 continue;
915 reg = (u32 *)get_property(busnode, "reg", NULL);
916 if (reg == NULL)
917 continue;
918
919 sz = sizeof(struct pmac_i2c_bus) + sizeof(struct smu_i2c_cmd);
920 bus = kzalloc(sz, GFP_KERNEL);
921 if (bus == NULL)
922 return;
923
924 bus->controller = controller;
925 bus->busnode = of_node_get(busnode);
926 bus->type = pmac_i2c_bus_smu;
927 bus->channel = *reg;
928 bus->mode = pmac_i2c_mode_std;
929 bus->hostdata = bus + 1;
930 bus->xfer = smu_i2c_xfer;
931 init_MUTEX(&bus->sem);
932 bus->flags = 0;
933 list_add(&bus->link, &pmac_i2c_busses);
934
935 printk(KERN_INFO " channel %x bus %s\n",
936 bus->channel, busnode->full_name);
937 }
938}
939
940#endif /* CONFIG_PMAC_SMU */
941
942/*
943 *
944 * Core code
945 *
946 */
433 947
434#ifdef CONFIG_ADB_PMU
435 /* Probe PMU busses */
436 np = of_find_node_by_name(NULL, "via-pmu");
437 if (np)
438 pmu_low_i2c_add(np);
439#endif /* CONFIG_ADB_PMU */
440 948
441 /* TODO: Add CUDA support as well */ 949struct pmac_i2c_bus *pmac_i2c_find_bus(struct device_node *node)
950{
951 struct device_node *p = of_node_get(node);
952 struct device_node *prev = NULL;
953 struct pmac_i2c_bus *bus;
954
955 while(p) {
956 list_for_each_entry(bus, &pmac_i2c_busses, link) {
957 if (p == bus->busnode) {
958 if (prev && bus->flags & pmac_i2c_multibus) {
959 u32 *reg;
960 reg = (u32 *)get_property(prev, "reg",
961 NULL);
962 if (!reg)
963 continue;
964 if (((*reg) >> 8) != bus->channel)
965 continue;
966 }
967 of_node_put(p);
968 of_node_put(prev);
969 return bus;
970 }
971 }
972 of_node_put(prev);
973 prev = p;
974 p = of_get_parent(p);
975 }
976 return NULL;
442} 977}
978EXPORT_SYMBOL_GPL(pmac_i2c_find_bus);
979
980u8 pmac_i2c_get_dev_addr(struct device_node *device)
981{
982 u32 *reg = (u32 *)get_property(device, "reg", NULL);
983
984 if (reg == NULL)
985 return 0;
986
987 return (*reg) & 0xff;
988}
989EXPORT_SYMBOL_GPL(pmac_i2c_get_dev_addr);
990
991struct device_node *pmac_i2c_get_controller(struct pmac_i2c_bus *bus)
992{
993 return bus->controller;
994}
995EXPORT_SYMBOL_GPL(pmac_i2c_get_controller);
996
997struct device_node *pmac_i2c_get_bus_node(struct pmac_i2c_bus *bus)
998{
999 return bus->busnode;
1000}
1001EXPORT_SYMBOL_GPL(pmac_i2c_get_bus_node);
1002
1003int pmac_i2c_get_type(struct pmac_i2c_bus *bus)
1004{
1005 return bus->type;
1006}
1007EXPORT_SYMBOL_GPL(pmac_i2c_get_type);
1008
1009int pmac_i2c_get_flags(struct pmac_i2c_bus *bus)
1010{
1011 return bus->flags;
1012}
1013EXPORT_SYMBOL_GPL(pmac_i2c_get_flags);
1014
1015int pmac_i2c_get_channel(struct pmac_i2c_bus *bus)
1016{
1017 return bus->channel;
1018}
1019EXPORT_SYMBOL_GPL(pmac_i2c_get_channel);
1020
1021
1022void pmac_i2c_attach_adapter(struct pmac_i2c_bus *bus,
1023 struct i2c_adapter *adapter)
1024{
1025 WARN_ON(bus->adapter != NULL);
1026 bus->adapter = adapter;
1027}
1028EXPORT_SYMBOL_GPL(pmac_i2c_attach_adapter);
1029
1030void pmac_i2c_detach_adapter(struct pmac_i2c_bus *bus,
1031 struct i2c_adapter *adapter)
1032{
1033 WARN_ON(bus->adapter != adapter);
1034 bus->adapter = NULL;
1035}
1036EXPORT_SYMBOL_GPL(pmac_i2c_detach_adapter);
1037
1038struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus)
1039{
1040 return bus->adapter;
1041}
1042EXPORT_SYMBOL_GPL(pmac_i2c_get_adapter);
1043
1044struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter)
1045{
1046 struct pmac_i2c_bus *bus;
1047
1048 list_for_each_entry(bus, &pmac_i2c_busses, link)
1049 if (bus->adapter == adapter)
1050 return bus;
1051 return NULL;
1052}
1053EXPORT_SYMBOL_GPL(pmac_i2c_adapter_to_bus);
1054
1055extern int pmac_i2c_match_adapter(struct device_node *dev,
1056 struct i2c_adapter *adapter)
1057{
1058 struct pmac_i2c_bus *bus = pmac_i2c_find_bus(dev);
1059
1060 if (bus == NULL)
1061 return 0;
1062 return (bus->adapter == adapter);
1063}
1064EXPORT_SYMBOL_GPL(pmac_i2c_match_adapter);
443 1065
444int pmac_low_i2c_lock(struct device_node *np) 1066int pmac_low_i2c_lock(struct device_node *np)
445{ 1067{
446 struct low_i2c_host *host = find_low_i2c_host(np); 1068 struct pmac_i2c_bus *bus, *found = NULL;
447 1069
448 if (!host) 1070 list_for_each_entry(bus, &pmac_i2c_busses, link) {
1071 if (np == bus->controller) {
1072 found = bus;
1073 break;
1074 }
1075 }
1076 if (!found)
449 return -ENODEV; 1077 return -ENODEV;
450 down(&host->mutex); 1078 return pmac_i2c_open(bus, 0);
451 return 0;
452} 1079}
453EXPORT_SYMBOL(pmac_low_i2c_lock); 1080EXPORT_SYMBOL_GPL(pmac_low_i2c_lock);
454 1081
455int pmac_low_i2c_unlock(struct device_node *np) 1082int pmac_low_i2c_unlock(struct device_node *np)
456{ 1083{
457 struct low_i2c_host *host = find_low_i2c_host(np); 1084 struct pmac_i2c_bus *bus, *found = NULL;
458 1085
459 if (!host) 1086 list_for_each_entry(bus, &pmac_i2c_busses, link) {
1087 if (np == bus->controller) {
1088 found = bus;
1089 break;
1090 }
1091 }
1092 if (!found)
460 return -ENODEV; 1093 return -ENODEV;
461 up(&host->mutex); 1094 pmac_i2c_close(bus);
462 return 0; 1095 return 0;
463} 1096}
464EXPORT_SYMBOL(pmac_low_i2c_unlock); 1097EXPORT_SYMBOL_GPL(pmac_low_i2c_unlock);
465 1098
466 1099
467int pmac_low_i2c_open(struct device_node *np, int channel) 1100int pmac_i2c_open(struct pmac_i2c_bus *bus, int polled)
468{ 1101{
469 struct low_i2c_host *host = find_low_i2c_host(np); 1102 int rc;
1103
1104 down(&bus->sem);
1105 bus->polled = polled || pmac_i2c_force_poll;
1106 bus->opened = 1;
1107 bus->mode = pmac_i2c_mode_std;
1108 if (bus->open && (rc = bus->open(bus)) != 0) {
1109 bus->opened = 0;
1110 up(&bus->sem);
1111 return rc;
1112 }
1113 return 0;
1114}
1115EXPORT_SYMBOL_GPL(pmac_i2c_open);
470 1116
471 if (!host) 1117void pmac_i2c_close(struct pmac_i2c_bus *bus)
472 return -ENODEV; 1118{
1119 WARN_ON(!bus->opened);
1120 if (bus->close)
1121 bus->close(bus);
1122 bus->opened = 0;
1123 up(&bus->sem);
1124}
1125EXPORT_SYMBOL_GPL(pmac_i2c_close);
473 1126
474 if (channel >= host->num_channels) 1127int pmac_i2c_setmode(struct pmac_i2c_bus *bus, int mode)
1128{
1129 WARN_ON(!bus->opened);
1130
1131 /* Report me if you see the error below as there might be a new
1132 * "combined4" mode that I need to implement for the SMU bus
1133 */
1134 if (mode < pmac_i2c_mode_dumb || mode > pmac_i2c_mode_combined) {
1135 printk(KERN_ERR "low_i2c: Invalid mode %d requested on"
1136 " bus %s !\n", mode, bus->busnode->full_name);
475 return -EINVAL; 1137 return -EINVAL;
476 1138 }
477 down(&host->mutex); 1139 bus->mode = mode;
478 host->is_open = 1;
479 host->channel = channel;
480 1140
481 return 0; 1141 return 0;
482} 1142}
483EXPORT_SYMBOL(pmac_low_i2c_open); 1143EXPORT_SYMBOL_GPL(pmac_i2c_setmode);
484 1144
485int pmac_low_i2c_close(struct device_node *np) 1145int pmac_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
1146 u32 subaddr, u8 *data, int len)
486{ 1147{
487 struct low_i2c_host *host = find_low_i2c_host(np); 1148 int rc;
488 1149
489 if (!host) 1150 WARN_ON(!bus->opened);
490 return -ENODEV;
491 1151
492 host->is_open = 0; 1152 DBG("xfer() chan=%d, addrdir=0x%x, mode=%d, subsize=%d, subaddr=0x%x,"
493 up(&host->mutex); 1153 " %d bytes, bus %s\n", bus->channel, addrdir, bus->mode, subsize,
1154 subaddr, len, bus->busnode->full_name);
494 1155
495 return 0; 1156 rc = bus->xfer(bus, addrdir, subsize, subaddr, data, len);
1157
1158#ifdef DEBUG
1159 if (rc)
1160 DBG("xfer error %d\n", rc);
1161#endif
1162 return rc;
496} 1163}
497EXPORT_SYMBOL(pmac_low_i2c_close); 1164EXPORT_SYMBOL_GPL(pmac_i2c_xfer);
1165
1166/* some quirks for platform function decoding */
1167enum {
1168 pmac_i2c_quirk_invmask = 0x00000001u,
1169};
498 1170
499int pmac_low_i2c_setmode(struct device_node *np, int mode) 1171static void pmac_i2c_devscan(void (*callback)(struct device_node *dev,
1172 int quirks))
500{ 1173{
501 struct low_i2c_host *host = find_low_i2c_host(np); 1174 struct pmac_i2c_bus *bus;
1175 struct device_node *np;
1176 static struct whitelist_ent {
1177 char *name;
1178 char *compatible;
1179 int quirks;
1180 } whitelist[] = {
1181 /* XXX Study device-tree's & apple drivers are get the quirks
1182 * right !
1183 */
1184 { "i2c-hwclock", NULL, pmac_i2c_quirk_invmask },
1185 { "i2c-cpu-voltage", NULL, 0},
1186 { "temp-monitor", NULL, 0 },
1187 { "supply-monitor", NULL, 0 },
1188 { NULL, NULL, 0 },
1189 };
1190
1191 /* Only some devices need to have platform functions instanciated
1192 * here. For now, we have a table. Others, like 9554 i2c GPIOs used
1193 * on Xserve, if we ever do a driver for them, will use their own
1194 * platform function instance
1195 */
1196 list_for_each_entry(bus, &pmac_i2c_busses, link) {
1197 for (np = NULL;
1198 (np = of_get_next_child(bus->busnode, np)) != NULL;) {
1199 struct whitelist_ent *p;
1200 /* If multibus, check if device is on that bus */
1201 if (bus->flags & pmac_i2c_multibus)
1202 if (bus != pmac_i2c_find_bus(np))
1203 continue;
1204 for (p = whitelist; p->name != NULL; p++) {
1205 if (strcmp(np->name, p->name))
1206 continue;
1207 if (p->compatible &&
1208 !device_is_compatible(np, p->compatible))
1209 continue;
1210 callback(np, p->quirks);
1211 break;
1212 }
1213 }
1214 }
1215}
502 1216
503 if (!host) 1217#define MAX_I2C_DATA 64
504 return -ENODEV; 1218
505 WARN_ON(!host->is_open); 1219struct pmac_i2c_pf_inst
506 host->mode = mode; 1220{
1221 struct pmac_i2c_bus *bus;
1222 u8 addr;
1223 u8 buffer[MAX_I2C_DATA];
1224 u8 scratch[MAX_I2C_DATA];
1225 int bytes;
1226 int quirks;
1227};
1228
1229static void* pmac_i2c_do_begin(struct pmf_function *func, struct pmf_args *args)
1230{
1231 struct pmac_i2c_pf_inst *inst;
1232 struct pmac_i2c_bus *bus;
1233
1234 bus = pmac_i2c_find_bus(func->node);
1235 if (bus == NULL) {
1236 printk(KERN_ERR "low_i2c: Can't find bus for %s (pfunc)\n",
1237 func->node->full_name);
1238 return NULL;
1239 }
1240 if (pmac_i2c_open(bus, 0)) {
1241 printk(KERN_ERR "low_i2c: Can't open i2c bus for %s (pfunc)\n",
1242 func->node->full_name);
1243 return NULL;
1244 }
1245
1246 /* XXX might need GFP_ATOMIC when called during the suspend process,
1247 * but then, there are already lots of issues with suspending when
1248 * near OOM that need to be resolved, the allocator itself should
1249 * probably make GFP_NOIO implicit during suspend
1250 */
1251 inst = kzalloc(sizeof(struct pmac_i2c_pf_inst), GFP_KERNEL);
1252 if (inst == NULL) {
1253 pmac_i2c_close(bus);
1254 return NULL;
1255 }
1256 inst->bus = bus;
1257 inst->addr = pmac_i2c_get_dev_addr(func->node);
1258 inst->quirks = (int)(long)func->driver_data;
1259 return inst;
1260}
1261
1262static void pmac_i2c_do_end(struct pmf_function *func, void *instdata)
1263{
1264 struct pmac_i2c_pf_inst *inst = instdata;
1265
1266 if (inst == NULL)
1267 return;
1268 pmac_i2c_close(inst->bus);
1269 if (inst)
1270 kfree(inst);
1271}
1272
1273static int pmac_i2c_do_read(PMF_STD_ARGS, u32 len)
1274{
1275 struct pmac_i2c_pf_inst *inst = instdata;
1276
1277 inst->bytes = len;
1278 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_read, 0, 0,
1279 inst->buffer, len);
1280}
1281
1282static int pmac_i2c_do_write(PMF_STD_ARGS, u32 len, const u8 *data)
1283{
1284 struct pmac_i2c_pf_inst *inst = instdata;
1285
1286 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 0, 0,
1287 (u8 *)data, len);
1288}
1289
1290/* This function is used to do the masking & OR'ing for the "rmw" type
1291 * callbacks. Ze should apply the mask and OR in the values in the
1292 * buffer before writing back. The problem is that it seems that
1293 * various darwin drivers implement the mask/or differently, thus
1294 * we need to check the quirks first
1295 */
1296static void pmac_i2c_do_apply_rmw(struct pmac_i2c_pf_inst *inst,
1297 u32 len, const u8 *mask, const u8 *val)
1298{
1299 int i;
1300
1301 if (inst->quirks & pmac_i2c_quirk_invmask) {
1302 for (i = 0; i < len; i ++)
1303 inst->scratch[i] = (inst->buffer[i] & mask[i]) | val[i];
1304 } else {
1305 for (i = 0; i < len; i ++)
1306 inst->scratch[i] = (inst->buffer[i] & ~mask[i])
1307 | (val[i] & mask[i]);
1308 }
1309}
1310
1311static int pmac_i2c_do_rmw(PMF_STD_ARGS, u32 masklen, u32 valuelen,
1312 u32 totallen, const u8 *maskdata,
1313 const u8 *valuedata)
1314{
1315 struct pmac_i2c_pf_inst *inst = instdata;
1316
1317 if (masklen > inst->bytes || valuelen > inst->bytes ||
1318 totallen > inst->bytes || valuelen > masklen)
1319 return -EINVAL;
1320
1321 pmac_i2c_do_apply_rmw(inst, masklen, maskdata, valuedata);
1322
1323 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 0, 0,
1324 inst->scratch, totallen);
1325}
1326
1327static int pmac_i2c_do_read_sub(PMF_STD_ARGS, u8 subaddr, u32 len)
1328{
1329 struct pmac_i2c_pf_inst *inst = instdata;
1330
1331 inst->bytes = len;
1332 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_read, 1, subaddr,
1333 inst->buffer, len);
1334}
1335
1336static int pmac_i2c_do_write_sub(PMF_STD_ARGS, u8 subaddr, u32 len,
1337 const u8 *data)
1338{
1339 struct pmac_i2c_pf_inst *inst = instdata;
1340
1341 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 1,
1342 subaddr, (u8 *)data, len);
1343}
507 1344
1345static int pmac_i2c_do_set_mode(PMF_STD_ARGS, int mode)
1346{
1347 struct pmac_i2c_pf_inst *inst = instdata;
1348
1349 return pmac_i2c_setmode(inst->bus, mode);
1350}
1351
1352static int pmac_i2c_do_rmw_sub(PMF_STD_ARGS, u8 subaddr, u32 masklen,
1353 u32 valuelen, u32 totallen, const u8 *maskdata,
1354 const u8 *valuedata)
1355{
1356 struct pmac_i2c_pf_inst *inst = instdata;
1357
1358 if (masklen > inst->bytes || valuelen > inst->bytes ||
1359 totallen > inst->bytes || valuelen > masklen)
1360 return -EINVAL;
1361
1362 pmac_i2c_do_apply_rmw(inst, masklen, maskdata, valuedata);
1363
1364 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 1,
1365 subaddr, inst->scratch, totallen);
1366}
1367
1368static int pmac_i2c_do_mask_and_comp(PMF_STD_ARGS, u32 len,
1369 const u8 *maskdata,
1370 const u8 *valuedata)
1371{
1372 struct pmac_i2c_pf_inst *inst = instdata;
1373 int i, match;
1374
1375 /* Get return value pointer, it's assumed to be a u32 */
1376 if (!args || !args->count || !args->u[0].p)
1377 return -EINVAL;
1378
1379 /* Check buffer */
1380 if (len > inst->bytes)
1381 return -EINVAL;
1382
1383 for (i = 0, match = 1; match && i < len; i ++)
1384 if ((inst->buffer[i] & maskdata[i]) != valuedata[i])
1385 match = 0;
1386 *args->u[0].p = match;
508 return 0; 1387 return 0;
509} 1388}
510EXPORT_SYMBOL(pmac_low_i2c_setmode);
511 1389
512int pmac_low_i2c_xfer(struct device_node *np, u8 addrdir, u8 subaddr, u8 *data, int len) 1390static int pmac_i2c_do_delay(PMF_STD_ARGS, u32 duration)
513{ 1391{
514 struct low_i2c_host *host = find_low_i2c_host(np); 1392 msleep((duration + 999) / 1000);
1393 return 0;
1394}
515 1395
516 if (!host)
517 return -ENODEV;
518 WARN_ON(!host->is_open);
519 1396
520 return host->func(host, addrdir, subaddr, data, len); 1397static struct pmf_handlers pmac_i2c_pfunc_handlers = {
1398 .begin = pmac_i2c_do_begin,
1399 .end = pmac_i2c_do_end,
1400 .read_i2c = pmac_i2c_do_read,
1401 .write_i2c = pmac_i2c_do_write,
1402 .rmw_i2c = pmac_i2c_do_rmw,
1403 .read_i2c_sub = pmac_i2c_do_read_sub,
1404 .write_i2c_sub = pmac_i2c_do_write_sub,
1405 .rmw_i2c_sub = pmac_i2c_do_rmw_sub,
1406 .set_i2c_mode = pmac_i2c_do_set_mode,
1407 .mask_and_compare = pmac_i2c_do_mask_and_comp,
1408 .delay = pmac_i2c_do_delay,
1409};
1410
1411static void __init pmac_i2c_dev_create(struct device_node *np, int quirks)
1412{
1413 DBG("dev_create(%s)\n", np->full_name);
1414
1415 pmf_register_driver(np, &pmac_i2c_pfunc_handlers,
1416 (void *)(long)quirks);
1417}
1418
1419static void __init pmac_i2c_dev_init(struct device_node *np, int quirks)
1420{
1421 DBG("dev_create(%s)\n", np->full_name);
1422
1423 pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_INIT, NULL);
1424}
1425
1426static void pmac_i2c_dev_suspend(struct device_node *np, int quirks)
1427{
1428 DBG("dev_suspend(%s)\n", np->full_name);
1429 pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_SLEEP, NULL);
1430}
1431
1432static void pmac_i2c_dev_resume(struct device_node *np, int quirks)
1433{
1434 DBG("dev_resume(%s)\n", np->full_name);
1435 pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_WAKE, NULL);
1436}
1437
1438void pmac_pfunc_i2c_suspend(void)
1439{
1440 pmac_i2c_devscan(pmac_i2c_dev_suspend);
1441}
1442
1443void pmac_pfunc_i2c_resume(void)
1444{
1445 pmac_i2c_devscan(pmac_i2c_dev_resume);
1446}
1447
1448/*
1449 * Initialize us: probe all i2c busses on the machine, instantiate
1450 * busses and platform functions as needed.
1451 */
1452/* This is non-static as it might be called early by smp code */
1453int __init pmac_i2c_init(void)
1454{
1455 static int i2c_inited;
1456
1457 if (i2c_inited)
1458 return 0;
1459 i2c_inited = 1;
1460
1461 /* Probe keywest-i2c busses */
1462 kw_i2c_probe();
1463
1464#ifdef CONFIG_ADB_PMU
1465 /* Probe PMU i2c busses */
1466 pmu_i2c_probe();
1467#endif
1468
1469#ifdef CONFIG_PMAC_SMU
1470 /* Probe SMU i2c busses */
1471 smu_i2c_probe();
1472#endif
1473
1474 /* Now add plaform functions for some known devices */
1475 pmac_i2c_devscan(pmac_i2c_dev_create);
1476
1477 return 0;
521} 1478}
522EXPORT_SYMBOL(pmac_low_i2c_xfer); 1479arch_initcall(pmac_i2c_init);
1480
1481/* Since pmac_i2c_init can be called too early for the platform device
1482 * registration, we need to do it at a later time. In our case, subsys
1483 * happens to fit well, though I agree it's a bit of a hack...
1484 */
1485static int __init pmac_i2c_create_platform_devices(void)
1486{
1487 struct pmac_i2c_bus *bus;
1488 int i = 0;
1489
1490 /* In the case where we are initialized from smp_init(), we must
1491 * not use the timer (and thus the irq). It's safe from now on
1492 * though
1493 */
1494 pmac_i2c_force_poll = 0;
1495
1496 /* Create platform devices */
1497 list_for_each_entry(bus, &pmac_i2c_busses, link) {
1498 bus->platform_dev =
1499 platform_device_alloc("i2c-powermac", i++);
1500 if (bus->platform_dev == NULL)
1501 return -ENOMEM;
1502 bus->platform_dev->dev.platform_data = bus;
1503 platform_device_add(bus->platform_dev);
1504 }
1505
1506 /* Now call platform "init" functions */
1507 pmac_i2c_devscan(pmac_i2c_dev_init);
523 1508
1509 return 0;
1510}
1511subsys_initcall(pmac_i2c_create_platform_devices);
diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c
index 4042e2f06ee0..3ebd045a3350 100644
--- a/arch/powerpc/platforms/powermac/nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -514,7 +514,7 @@ static void core99_nvram_sync(void)
514#endif 514#endif
515} 515}
516 516
517static int __init core99_nvram_setup(struct device_node *dp) 517static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr)
518{ 518{
519 int i; 519 int i;
520 u32 gen_bank0, gen_bank1; 520 u32 gen_bank0, gen_bank1;
@@ -528,7 +528,7 @@ static int __init core99_nvram_setup(struct device_node *dp)
528 printk(KERN_ERR "nvram: can't allocate ram image\n"); 528 printk(KERN_ERR "nvram: can't allocate ram image\n");
529 return -ENOMEM; 529 return -ENOMEM;
530 } 530 }
531 nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2); 531 nvram_data = ioremap(addr, NVRAM_SIZE*2);
532 nvram_naddrs = 1; /* Make sure we get the correct case */ 532 nvram_naddrs = 1; /* Make sure we get the correct case */
533 533
534 DBG("nvram: Checking bank 0...\n"); 534 DBG("nvram: Checking bank 0...\n");
@@ -549,6 +549,7 @@ static int __init core99_nvram_setup(struct device_node *dp)
549 ppc_md.nvram_write = core99_nvram_write; 549 ppc_md.nvram_write = core99_nvram_write;
550 ppc_md.nvram_size = core99_nvram_size; 550 ppc_md.nvram_size = core99_nvram_size;
551 ppc_md.nvram_sync = core99_nvram_sync; 551 ppc_md.nvram_sync = core99_nvram_sync;
552 ppc_md.machine_shutdown = core99_nvram_sync;
552 /* 553 /*
553 * Maybe we could be smarter here though making an exclusive list 554 * Maybe we could be smarter here though making an exclusive list
554 * of known flash chips is a bit nasty as older OF didn't provide us 555 * of known flash chips is a bit nasty as older OF didn't provide us
@@ -569,34 +570,48 @@ static int __init core99_nvram_setup(struct device_node *dp)
569int __init pmac_nvram_init(void) 570int __init pmac_nvram_init(void)
570{ 571{
571 struct device_node *dp; 572 struct device_node *dp;
573 struct resource r1, r2;
574 unsigned int s1 = 0, s2 = 0;
572 int err = 0; 575 int err = 0;
573 576
574 nvram_naddrs = 0; 577 nvram_naddrs = 0;
575 578
576 dp = find_devices("nvram"); 579 dp = of_find_node_by_name(NULL, "nvram");
577 if (dp == NULL) { 580 if (dp == NULL) {
578 printk(KERN_ERR "Can't find NVRAM device\n"); 581 printk(KERN_ERR "Can't find NVRAM device\n");
579 return -ENODEV; 582 return -ENODEV;
580 } 583 }
581 nvram_naddrs = dp->n_addrs; 584
585 /* Try to obtain an address */
586 if (of_address_to_resource(dp, 0, &r1) == 0) {
587 nvram_naddrs = 1;
588 s1 = (r1.end - r1.start) + 1;
589 if (of_address_to_resource(dp, 1, &r2) == 0) {
590 nvram_naddrs = 2;
591 s2 = (r2.end - r2.start) + 1;
592 }
593 }
594
582 is_core_99 = device_is_compatible(dp, "nvram,flash"); 595 is_core_99 = device_is_compatible(dp, "nvram,flash");
583 if (is_core_99) 596 if (is_core_99) {
584 err = core99_nvram_setup(dp); 597 err = core99_nvram_setup(dp, r1.start);
598 goto bail;
599 }
600
585#ifdef CONFIG_PPC32 601#ifdef CONFIG_PPC32
586 else if (_machine == _MACH_chrp && nvram_naddrs == 1) { 602 if (_machine == _MACH_chrp && nvram_naddrs == 1) {
587 nvram_data = ioremap(dp->addrs[0].address + isa_mem_base, 603 nvram_data = ioremap(r1.start, s1);
588 dp->addrs[0].size);
589 nvram_mult = 1; 604 nvram_mult = 1;
590 ppc_md.nvram_read_val = direct_nvram_read_byte; 605 ppc_md.nvram_read_val = direct_nvram_read_byte;
591 ppc_md.nvram_write_val = direct_nvram_write_byte; 606 ppc_md.nvram_write_val = direct_nvram_write_byte;
592 } else if (nvram_naddrs == 1) { 607 } else if (nvram_naddrs == 1) {
593 nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size); 608 nvram_data = ioremap(r1.start, s1);
594 nvram_mult = (dp->addrs[0].size + NVRAM_SIZE - 1) / NVRAM_SIZE; 609 nvram_mult = (s1 + NVRAM_SIZE - 1) / NVRAM_SIZE;
595 ppc_md.nvram_read_val = direct_nvram_read_byte; 610 ppc_md.nvram_read_val = direct_nvram_read_byte;
596 ppc_md.nvram_write_val = direct_nvram_write_byte; 611 ppc_md.nvram_write_val = direct_nvram_write_byte;
597 } else if (nvram_naddrs == 2) { 612 } else if (nvram_naddrs == 2) {
598 nvram_addr = ioremap(dp->addrs[0].address, dp->addrs[0].size); 613 nvram_addr = ioremap(r1.start, s1);
599 nvram_data = ioremap(dp->addrs[1].address, dp->addrs[1].size); 614 nvram_data = ioremap(r2.start, s2);
600 ppc_md.nvram_read_val = indirect_nvram_read_byte; 615 ppc_md.nvram_read_val = indirect_nvram_read_byte;
601 ppc_md.nvram_write_val = indirect_nvram_write_byte; 616 ppc_md.nvram_write_val = indirect_nvram_write_byte;
602 } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) { 617 } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
@@ -605,13 +620,15 @@ int __init pmac_nvram_init(void)
605 ppc_md.nvram_read_val = pmu_nvram_read_byte; 620 ppc_md.nvram_read_val = pmu_nvram_read_byte;
606 ppc_md.nvram_write_val = pmu_nvram_write_byte; 621 ppc_md.nvram_write_val = pmu_nvram_write_byte;
607#endif /* CONFIG_ADB_PMU */ 622#endif /* CONFIG_ADB_PMU */
608 } 623 } else {
609#endif
610 else {
611 printk(KERN_ERR "Incompatible type of NVRAM\n"); 624 printk(KERN_ERR "Incompatible type of NVRAM\n");
612 return -ENXIO; 625 err = -ENXIO;
613 } 626 }
614 lookup_partitions(); 627#endif /* CONFIG_PPC32 */
628bail:
629 of_node_put(dp);
630 if (err == 0)
631 lookup_partitions();
615 return err; 632 return err;
616} 633}
617 634
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 443be526cde7..f671ed253901 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Support for PCI bridges found on Power Macintoshes. 2 * Support for PCI bridges found on Power Macintoshes.
3 * 3 *
4 * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org) 4 * Copyright (C) 2003-2005 Benjamin Herrenschmuidt (benh@kernel.crashing.org)
5 * Copyright (C) 1997 Paul Mackerras (paulus@samba.org) 5 * Copyright (C) 1997 Paul Mackerras (paulus@samba.org)
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
@@ -25,7 +25,7 @@
25#include <asm/pmac_feature.h> 25#include <asm/pmac_feature.h>
26#include <asm/grackle.h> 26#include <asm/grackle.h>
27#ifdef CONFIG_PPC64 27#ifdef CONFIG_PPC64
28#include <asm/iommu.h> 28//#include <asm/iommu.h>
29#include <asm/ppc-pci.h> 29#include <asm/ppc-pci.h>
30#endif 30#endif
31 31
@@ -44,6 +44,7 @@ static int add_bridge(struct device_node *dev);
44static int has_uninorth; 44static int has_uninorth;
45#ifdef CONFIG_PPC64 45#ifdef CONFIG_PPC64
46static struct pci_controller *u3_agp; 46static struct pci_controller *u3_agp;
47static struct pci_controller *u4_pcie;
47static struct pci_controller *u3_ht; 48static struct pci_controller *u3_ht;
48#endif /* CONFIG_PPC64 */ 49#endif /* CONFIG_PPC64 */
49 50
@@ -97,11 +98,8 @@ static void __init fixup_bus_range(struct device_node *bridge)
97 98
98 /* Lookup the "bus-range" property for the hose */ 99 /* Lookup the "bus-range" property for the hose */
99 bus_range = (int *) get_property(bridge, "bus-range", &len); 100 bus_range = (int *) get_property(bridge, "bus-range", &len);
100 if (bus_range == NULL || len < 2 * sizeof(int)) { 101 if (bus_range == NULL || len < 2 * sizeof(int))
101 printk(KERN_WARNING "Can't get bus-range for %s\n",
102 bridge->full_name);
103 return; 102 return;
104 }
105 bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); 103 bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
106} 104}
107 105
@@ -128,14 +126,14 @@ static void __init fixup_bus_range(struct device_node *bridge)
128 */ 126 */
129 127
130#define MACRISC_CFA0(devfn, off) \ 128#define MACRISC_CFA0(devfn, off) \
131 ((1 << (unsigned long)PCI_SLOT(dev_fn)) \ 129 ((1 << (unsigned int)PCI_SLOT(dev_fn)) \
132 | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \ 130 | (((unsigned int)PCI_FUNC(dev_fn)) << 8) \
133 | (((unsigned long)(off)) & 0xFCUL)) 131 | (((unsigned int)(off)) & 0xFCUL))
134 132
135#define MACRISC_CFA1(bus, devfn, off) \ 133#define MACRISC_CFA1(bus, devfn, off) \
136 ((((unsigned long)(bus)) << 16) \ 134 ((((unsigned int)(bus)) << 16) \
137 |(((unsigned long)(devfn)) << 8) \ 135 |(((unsigned int)(devfn)) << 8) \
138 |(((unsigned long)(off)) & 0xFCUL) \ 136 |(((unsigned int)(off)) & 0xFCUL) \
139 |1UL) 137 |1UL)
140 138
141static unsigned long macrisc_cfg_access(struct pci_controller* hose, 139static unsigned long macrisc_cfg_access(struct pci_controller* hose,
@@ -168,7 +166,8 @@ static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
168 hose = pci_bus_to_host(bus); 166 hose = pci_bus_to_host(bus);
169 if (hose == NULL) 167 if (hose == NULL)
170 return PCIBIOS_DEVICE_NOT_FOUND; 168 return PCIBIOS_DEVICE_NOT_FOUND;
171 169 if (offset >= 0x100)
170 return PCIBIOS_BAD_REGISTER_NUMBER;
172 addr = macrisc_cfg_access(hose, bus->number, devfn, offset); 171 addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
173 if (!addr) 172 if (!addr)
174 return PCIBIOS_DEVICE_NOT_FOUND; 173 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -199,7 +198,8 @@ static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
199 hose = pci_bus_to_host(bus); 198 hose = pci_bus_to_host(bus);
200 if (hose == NULL) 199 if (hose == NULL)
201 return PCIBIOS_DEVICE_NOT_FOUND; 200 return PCIBIOS_DEVICE_NOT_FOUND;
202 201 if (offset >= 0x100)
202 return PCIBIOS_BAD_REGISTER_NUMBER;
203 addr = macrisc_cfg_access(hose, bus->number, devfn, offset); 203 addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
204 if (!addr) 204 if (!addr)
205 return PCIBIOS_DEVICE_NOT_FOUND; 205 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -234,12 +234,13 @@ static struct pci_ops macrisc_pci_ops =
234/* 234/*
235 * Verify that a specific (bus, dev_fn) exists on chaos 235 * Verify that a specific (bus, dev_fn) exists on chaos
236 */ 236 */
237static int 237static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
238chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
239{ 238{
240 struct device_node *np; 239 struct device_node *np;
241 u32 *vendor, *device; 240 u32 *vendor, *device;
242 241
242 if (offset >= 0x100)
243 return PCIBIOS_BAD_REGISTER_NUMBER;
243 np = pci_busdev_to_OF_node(bus, devfn); 244 np = pci_busdev_to_OF_node(bus, devfn);
244 if (np == NULL) 245 if (np == NULL)
245 return PCIBIOS_DEVICE_NOT_FOUND; 246 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -285,15 +286,13 @@ static struct pci_ops chaos_pci_ops =
285}; 286};
286 287
287static void __init setup_chaos(struct pci_controller *hose, 288static void __init setup_chaos(struct pci_controller *hose,
288 struct reg_property *addr) 289 struct resource *addr)
289{ 290{
290 /* assume a `chaos' bridge */ 291 /* assume a `chaos' bridge */
291 hose->ops = &chaos_pci_ops; 292 hose->ops = &chaos_pci_ops;
292 hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); 293 hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
293 hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); 294 hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000);
294} 295}
295#else
296#define setup_chaos(hose, addr)
297#endif /* CONFIG_PPC32 */ 296#endif /* CONFIG_PPC32 */
298 297
299#ifdef CONFIG_PPC64 298#ifdef CONFIG_PPC64
@@ -326,7 +325,7 @@ static int u3_ht_skip_device(struct pci_controller *hose,
326 else 325 else
327 busdn = hose->arch_data; 326 busdn = hose->arch_data;
328 for (dn = busdn->child; dn; dn = dn->sibling) 327 for (dn = busdn->child; dn; dn = dn->sibling)
329 if (dn->data && PCI_DN(dn)->devfn == devfn) 328 if (PCI_DN(dn) && PCI_DN(dn)->devfn == devfn)
330 break; 329 break;
331 if (dn == NULL) 330 if (dn == NULL)
332 return -1; 331 return -1;
@@ -343,10 +342,10 @@ static int u3_ht_skip_device(struct pci_controller *hose,
343} 342}
344 343
345#define U3_HT_CFA0(devfn, off) \ 344#define U3_HT_CFA0(devfn, off) \
346 ((((unsigned long)devfn) << 8) | offset) 345 ((((unsigned int)devfn) << 8) | offset)
347#define U3_HT_CFA1(bus, devfn, off) \ 346#define U3_HT_CFA1(bus, devfn, off) \
348 (U3_HT_CFA0(devfn, off) \ 347 (U3_HT_CFA0(devfn, off) \
349 + (((unsigned long)bus) << 16) \ 348 + (((unsigned int)bus) << 16) \
350 + 0x01000000UL) 349 + 0x01000000UL)
351 350
352static unsigned long u3_ht_cfg_access(struct pci_controller* hose, 351static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
@@ -356,9 +355,11 @@ static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
356 /* For now, we don't self probe U3 HT bridge */ 355 /* For now, we don't self probe U3 HT bridge */
357 if (PCI_SLOT(devfn) == 0) 356 if (PCI_SLOT(devfn) == 0)
358 return 0; 357 return 0;
359 return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset); 358 return ((unsigned long)hose->cfg_data) +
359 U3_HT_CFA0(devfn, offset);
360 } else 360 } else
361 return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset); 361 return ((unsigned long)hose->cfg_data) +
362 U3_HT_CFA1(bus, devfn, offset);
362} 363}
363 364
364static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, 365static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
@@ -370,7 +371,8 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
370 hose = pci_bus_to_host(bus); 371 hose = pci_bus_to_host(bus);
371 if (hose == NULL) 372 if (hose == NULL)
372 return PCIBIOS_DEVICE_NOT_FOUND; 373 return PCIBIOS_DEVICE_NOT_FOUND;
373 374 if (offset >= 0x100)
375 return PCIBIOS_BAD_REGISTER_NUMBER;
374 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); 376 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
375 if (!addr) 377 if (!addr)
376 return PCIBIOS_DEVICE_NOT_FOUND; 378 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -419,7 +421,8 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
419 hose = pci_bus_to_host(bus); 421 hose = pci_bus_to_host(bus);
420 if (hose == NULL) 422 if (hose == NULL)
421 return PCIBIOS_DEVICE_NOT_FOUND; 423 return PCIBIOS_DEVICE_NOT_FOUND;
422 424 if (offset >= 0x100)
425 return PCIBIOS_BAD_REGISTER_NUMBER;
423 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); 426 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
424 if (!addr) 427 if (!addr)
425 return PCIBIOS_DEVICE_NOT_FOUND; 428 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -459,6 +462,112 @@ static struct pci_ops u3_ht_pci_ops =
459 u3_ht_read_config, 462 u3_ht_read_config,
460 u3_ht_write_config 463 u3_ht_write_config
461}; 464};
465
466#define U4_PCIE_CFA0(devfn, off) \
467 ((1 << ((unsigned int)PCI_SLOT(dev_fn))) \
468 | (((unsigned int)PCI_FUNC(dev_fn)) << 8) \
469 | ((((unsigned int)(off)) >> 8) << 28) \
470 | (((unsigned int)(off)) & 0xfcU))
471
472#define U4_PCIE_CFA1(bus, devfn, off) \
473 ((((unsigned int)(bus)) << 16) \
474 |(((unsigned int)(devfn)) << 8) \
475 | ((((unsigned int)(off)) >> 8) << 28) \
476 |(((unsigned int)(off)) & 0xfcU) \
477 |1UL)
478
479static unsigned long u4_pcie_cfg_access(struct pci_controller* hose,
480 u8 bus, u8 dev_fn, int offset)
481{
482 unsigned int caddr;
483
484 if (bus == hose->first_busno) {
485 caddr = U4_PCIE_CFA0(dev_fn, offset);
486 } else
487 caddr = U4_PCIE_CFA1(bus, dev_fn, offset);
488
489 /* Uninorth will return garbage if we don't read back the value ! */
490 do {
491 out_le32(hose->cfg_addr, caddr);
492 } while (in_le32(hose->cfg_addr) != caddr);
493
494 offset &= 0x03;
495 return ((unsigned long)hose->cfg_data) + offset;
496}
497
498static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
499 int offset, int len, u32 *val)
500{
501 struct pci_controller *hose;
502 unsigned long addr;
503
504 hose = pci_bus_to_host(bus);
505 if (hose == NULL)
506 return PCIBIOS_DEVICE_NOT_FOUND;
507 if (offset >= 0x1000)
508 return PCIBIOS_BAD_REGISTER_NUMBER;
509 addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset);
510 if (!addr)
511 return PCIBIOS_DEVICE_NOT_FOUND;
512 /*
513 * Note: the caller has already checked that offset is
514 * suitably aligned and that len is 1, 2 or 4.
515 */
516 switch (len) {
517 case 1:
518 *val = in_8((u8 *)addr);
519 break;
520 case 2:
521 *val = in_le16((u16 *)addr);
522 break;
523 default:
524 *val = in_le32((u32 *)addr);
525 break;
526 }
527 return PCIBIOS_SUCCESSFUL;
528}
529
530static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
531 int offset, int len, u32 val)
532{
533 struct pci_controller *hose;
534 unsigned long addr;
535
536 hose = pci_bus_to_host(bus);
537 if (hose == NULL)
538 return PCIBIOS_DEVICE_NOT_FOUND;
539 if (offset >= 0x1000)
540 return PCIBIOS_BAD_REGISTER_NUMBER;
541 addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset);
542 if (!addr)
543 return PCIBIOS_DEVICE_NOT_FOUND;
544 /*
545 * Note: the caller has already checked that offset is
546 * suitably aligned and that len is 1, 2 or 4.
547 */
548 switch (len) {
549 case 1:
550 out_8((u8 *)addr, val);
551 (void) in_8((u8 *)addr);
552 break;
553 case 2:
554 out_le16((u16 *)addr, val);
555 (void) in_le16((u16 *)addr);
556 break;
557 default:
558 out_le32((u32 *)addr, val);
559 (void) in_le32((u32 *)addr);
560 break;
561 }
562 return PCIBIOS_SUCCESSFUL;
563}
564
565static struct pci_ops u4_pcie_pci_ops =
566{
567 u4_pcie_read_config,
568 u4_pcie_write_config
569};
570
462#endif /* CONFIG_PPC64 */ 571#endif /* CONFIG_PPC64 */
463 572
464#ifdef CONFIG_PPC32 573#ifdef CONFIG_PPC32
@@ -532,7 +641,8 @@ static void __init init_p2pbridge(void)
532 } 641 }
533 if (early_read_config_word(hose, bus, devfn, 642 if (early_read_config_word(hose, bus, devfn,
534 PCI_BRIDGE_CONTROL, &val) < 0) { 643 PCI_BRIDGE_CONTROL, &val) < 0) {
535 printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n"); 644 printk(KERN_ERR "init_p2pbridge: couldn't read bridge"
645 " control\n");
536 return; 646 return;
537 } 647 }
538 val &= ~PCI_BRIDGE_CTL_MASTER_ABORT; 648 val &= ~PCI_BRIDGE_CTL_MASTER_ABORT;
@@ -576,36 +686,38 @@ static void __init fixup_nec_usb2(void)
576 continue; 686 continue;
577 early_read_config_dword(hose, bus, devfn, 0xe4, &data); 687 early_read_config_dword(hose, bus, devfn, 0xe4, &data);
578 if (data & 1UL) { 688 if (data & 1UL) {
579 printk("Found NEC PD720100A USB2 chip with disabled EHCI, fixing up...\n"); 689 printk("Found NEC PD720100A USB2 chip with disabled"
690 " EHCI, fixing up...\n");
580 data &= ~1UL; 691 data &= ~1UL;
581 early_write_config_dword(hose, bus, devfn, 0xe4, data); 692 early_write_config_dword(hose, bus, devfn, 0xe4, data);
582 early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE, 693 early_write_config_byte(hose, bus,
694 devfn | 2, PCI_INTERRUPT_LINE,
583 nec->intrs[0].line); 695 nec->intrs[0].line);
584 } 696 }
585 } 697 }
586} 698}
587 699
588static void __init setup_bandit(struct pci_controller *hose, 700static void __init setup_bandit(struct pci_controller *hose,
589 struct reg_property *addr) 701 struct resource *addr)
590{ 702{
591 hose->ops = &macrisc_pci_ops; 703 hose->ops = &macrisc_pci_ops;
592 hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); 704 hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
593 hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); 705 hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000);
594 init_bandit(hose); 706 init_bandit(hose);
595} 707}
596 708
597static int __init setup_uninorth(struct pci_controller *hose, 709static int __init setup_uninorth(struct pci_controller *hose,
598 struct reg_property *addr) 710 struct resource *addr)
599{ 711{
600 pci_assign_all_buses = 1; 712 pci_assign_all_buses = 1;
601 has_uninorth = 1; 713 has_uninorth = 1;
602 hose->ops = &macrisc_pci_ops; 714 hose->ops = &macrisc_pci_ops;
603 hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); 715 hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
604 hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); 716 hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000);
605 /* We "know" that the bridge at f2000000 has the PCI slots. */ 717 /* We "know" that the bridge at f2000000 has the PCI slots. */
606 return addr->address == 0xf2000000; 718 return addr->start == 0xf2000000;
607} 719}
608#endif 720#endif /* CONFIG_PPC32 */
609 721
610#ifdef CONFIG_PPC64 722#ifdef CONFIG_PPC64
611static void __init setup_u3_agp(struct pci_controller* hose) 723static void __init setup_u3_agp(struct pci_controller* hose)
@@ -625,15 +737,36 @@ static void __init setup_u3_agp(struct pci_controller* hose)
625 hose->ops = &macrisc_pci_ops; 737 hose->ops = &macrisc_pci_ops;
626 hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000); 738 hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
627 hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000); 739 hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
628
629 u3_agp = hose; 740 u3_agp = hose;
630} 741}
631 742
743static void __init setup_u4_pcie(struct pci_controller* hose)
744{
745 /* We currently only implement the "non-atomic" config space, to
746 * be optimised later.
747 */
748 hose->ops = &u4_pcie_pci_ops;
749 hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
750 hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
751
752 /* The bus contains a bridge from root -> device, we need to
753 * make it visible on bus 0 so that we pick the right type
754 * of config cycles. If we didn't, we would have to force all
755 * config cycles to be type 1. So we override the "bus-range"
756 * property here
757 */
758 hose->first_busno = 0x00;
759 hose->last_busno = 0xff;
760 u4_pcie = hose;
761}
762
632static void __init setup_u3_ht(struct pci_controller* hose) 763static void __init setup_u3_ht(struct pci_controller* hose)
633{ 764{
634 struct device_node *np = (struct device_node *)hose->arch_data; 765 struct device_node *np = (struct device_node *)hose->arch_data;
766 struct pci_controller *other = NULL;
635 int i, cur; 767 int i, cur;
636 768
769
637 hose->ops = &u3_ht_pci_ops; 770 hose->ops = &u3_ht_pci_ops;
638 771
639 /* We hard code the address because of the different size of 772 /* We hard code the address because of the different size of
@@ -667,11 +800,20 @@ static void __init setup_u3_ht(struct pci_controller* hose)
667 800
668 u3_ht = hose; 801 u3_ht = hose;
669 802
670 if (u3_agp == NULL) { 803 if (u3_agp != NULL)
671 DBG("U3 has no AGP, using full resource range\n"); 804 other = u3_agp;
805 else if (u4_pcie != NULL)
806 other = u4_pcie;
807
808 if (other == NULL) {
809 DBG("U3/4 has no AGP/PCIE, using full resource range\n");
672 return; 810 return;
673 } 811 }
674 812
813 /* Fixup bus range vs. PCIE */
814 if (u4_pcie)
815 hose->last_busno = u4_pcie->first_busno - 1;
816
675 /* We "remove" the AGP resources from the resources allocated to HT, 817 /* We "remove" the AGP resources from the resources allocated to HT,
676 * that is we create "holes". However, that code does assumptions 818 * that is we create "holes". However, that code does assumptions
677 * that so far happen to be true (cross fingers...), typically that 819 * that so far happen to be true (cross fingers...), typically that
@@ -679,7 +821,7 @@ static void __init setup_u3_ht(struct pci_controller* hose)
679 */ 821 */
680 cur = 0; 822 cur = 0;
681 for (i=0; i<3; i++) { 823 for (i=0; i<3; i++) {
682 struct resource *res = &u3_agp->mem_resources[i]; 824 struct resource *res = &other->mem_resources[i];
683 if (res->flags != IORESOURCE_MEM) 825 if (res->flags != IORESOURCE_MEM)
684 continue; 826 continue;
685 /* We don't care about "fine" resources */ 827 /* We don't care about "fine" resources */
@@ -722,7 +864,7 @@ static void __init setup_u3_ht(struct pci_controller* hose)
722 hose->mem_resources[cur-1].end = res->start - 1; 864 hose->mem_resources[cur-1].end = res->start - 1;
723 } 865 }
724} 866}
725#endif 867#endif /* CONFIG_PPC64 */
726 868
727/* 869/*
728 * We assume that if we have a G3 powermac, we have one bridge called 870 * We assume that if we have a G3 powermac, we have one bridge called
@@ -733,24 +875,17 @@ static int __init add_bridge(struct device_node *dev)
733{ 875{
734 int len; 876 int len;
735 struct pci_controller *hose; 877 struct pci_controller *hose;
736#ifdef CONFIG_PPC32 878 struct resource rsrc;
737 struct reg_property *addr;
738#endif
739 char *disp_name; 879 char *disp_name;
740 int *bus_range; 880 int *bus_range;
741 int primary = 1; 881 int primary = 1, has_address = 0;
742 882
743 DBG("Adding PCI host bridge %s\n", dev->full_name); 883 DBG("Adding PCI host bridge %s\n", dev->full_name);
744 884
745#ifdef CONFIG_PPC32 885 /* Fetch host bridge registers address */
746 /* XXX fix this */ 886 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
747 addr = (struct reg_property *) get_property(dev, "reg", &len); 887
748 if (addr == NULL || len < sizeof(*addr)) { 888 /* Get bus range if any */
749 printk(KERN_WARNING "Can't use %s: no address\n",
750 dev->full_name);
751 return -ENODEV;
752 }
753#endif
754 bus_range = (int *) get_property(dev, "bus-range", &len); 889 bus_range = (int *) get_property(dev, "bus-range", &len);
755 if (bus_range == NULL || len < 2 * sizeof(int)) { 890 if (bus_range == NULL || len < 2 * sizeof(int)) {
756 printk(KERN_WARNING "Can't get bus-range for %s, assume" 891 printk(KERN_WARNING "Can't get bus-range for %s, assume"
@@ -770,6 +905,8 @@ static int __init add_bridge(struct device_node *dev)
770 hose->last_busno = bus_range ? bus_range[1] : 0xff; 905 hose->last_busno = bus_range ? bus_range[1] : 0xff;
771 906
772 disp_name = NULL; 907 disp_name = NULL;
908
909 /* 64 bits only bridges */
773#ifdef CONFIG_PPC64 910#ifdef CONFIG_PPC64
774 if (device_is_compatible(dev, "u3-agp")) { 911 if (device_is_compatible(dev, "u3-agp")) {
775 setup_u3_agp(hose); 912 setup_u3_agp(hose);
@@ -779,28 +916,37 @@ static int __init add_bridge(struct device_node *dev)
779 setup_u3_ht(hose); 916 setup_u3_ht(hose);
780 disp_name = "U3-HT"; 917 disp_name = "U3-HT";
781 primary = 1; 918 primary = 1;
919 } else if (device_is_compatible(dev, "u4-pcie")) {
920 setup_u4_pcie(hose);
921 disp_name = "U4-PCIE";
922 primary = 0;
782 } 923 }
783 printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n", 924 printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number:"
784 disp_name, hose->first_busno, hose->last_busno); 925 " %d->%d\n", disp_name, hose->first_busno, hose->last_busno);
785#else 926#endif /* CONFIG_PPC64 */
927
928 /* 32 bits only bridges */
929#ifdef CONFIG_PPC32
786 if (device_is_compatible(dev, "uni-north")) { 930 if (device_is_compatible(dev, "uni-north")) {
787 primary = setup_uninorth(hose, addr); 931 primary = setup_uninorth(hose, &rsrc);
788 disp_name = "UniNorth"; 932 disp_name = "UniNorth";
789 } else if (strcmp(dev->name, "pci") == 0) { 933 } else if (strcmp(dev->name, "pci") == 0) {
790 /* XXX assume this is a mpc106 (grackle) */ 934 /* XXX assume this is a mpc106 (grackle) */
791 setup_grackle(hose); 935 setup_grackle(hose);
792 disp_name = "Grackle (MPC106)"; 936 disp_name = "Grackle (MPC106)";
793 } else if (strcmp(dev->name, "bandit") == 0) { 937 } else if (strcmp(dev->name, "bandit") == 0) {
794 setup_bandit(hose, addr); 938 setup_bandit(hose, &rsrc);
795 disp_name = "Bandit"; 939 disp_name = "Bandit";
796 } else if (strcmp(dev->name, "chaos") == 0) { 940 } else if (strcmp(dev->name, "chaos") == 0) {
797 setup_chaos(hose, addr); 941 setup_chaos(hose, &rsrc);
798 disp_name = "Chaos"; 942 disp_name = "Chaos";
799 primary = 0; 943 primary = 0;
800 } 944 }
801 printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. Firmware bus number: %d->%d\n", 945 printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. "
802 disp_name, addr->address, hose->first_busno, hose->last_busno); 946 "Firmware bus number: %d->%d\n",
803#endif 947 disp_name, rsrc.start, hose->first_busno, hose->last_busno);
948#endif /* CONFIG_PPC32 */
949
804 DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", 950 DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
805 hose, hose->cfg_addr, hose->cfg_data); 951 hose, hose->cfg_addr, hose->cfg_data);
806 952
@@ -814,8 +960,7 @@ static int __init add_bridge(struct device_node *dev)
814 return 0; 960 return 0;
815} 961}
816 962
817static void __init 963static void __init pcibios_fixup_OF_interrupts(void)
818pcibios_fixup_OF_interrupts(void)
819{ 964{
820 struct pci_dev* dev = NULL; 965 struct pci_dev* dev = NULL;
821 966
@@ -835,8 +980,7 @@ pcibios_fixup_OF_interrupts(void)
835 } 980 }
836} 981}
837 982
838void __init 983void __init pmac_pcibios_fixup(void)
839pmac_pcibios_fixup(void)
840{ 984{
841 /* Fixup interrupts according to OF tree */ 985 /* Fixup interrupts according to OF tree */
842 pcibios_fixup_OF_interrupts(); 986 pcibios_fixup_OF_interrupts();
@@ -899,6 +1043,8 @@ void __init pmac_pci_init(void)
899 pci_setup_phb_io(u3_ht, 1); 1043 pci_setup_phb_io(u3_ht, 1);
900 if (u3_agp) 1044 if (u3_agp)
901 pci_setup_phb_io(u3_agp, 0); 1045 pci_setup_phb_io(u3_agp, 0);
1046 if (u4_pcie)
1047 pci_setup_phb_io(u4_pcie, 0);
902 1048
903 /* 1049 /*
904 * On ppc64, fixup the IO resources on our host bridges as 1050 * On ppc64, fixup the IO resources on our host bridges as
@@ -911,7 +1057,8 @@ void __init pmac_pci_init(void)
911 1057
912 /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We 1058 /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We
913 * assume there is no P2P bridge on the AGP bus, which should be a 1059 * assume there is no P2P bridge on the AGP bus, which should be a
914 * safe assumptions hopefully. 1060 * safe assumptions for now. We should do something better in the
1061 * future though
915 */ 1062 */
916 if (u3_agp) { 1063 if (u3_agp) {
917 struct device_node *np = u3_agp->arch_data; 1064 struct device_node *np = u3_agp->arch_data;
@@ -919,7 +1066,6 @@ void __init pmac_pci_init(void)
919 for (np = np->child; np; np = np->sibling) 1066 for (np = np->child; np; np = np->sibling)
920 PCI_DN(np)->busno = 0xf0; 1067 PCI_DN(np)->busno = 0xf0;
921 } 1068 }
922
923 /* pmac_check_ht_link(); */ 1069 /* pmac_check_ht_link(); */
924 1070
925 /* Tell pci.c to not use the common resource allocation mechanism */ 1071 /* Tell pci.c to not use the common resource allocation mechanism */
@@ -1126,7 +1272,8 @@ void pmac_pci_fixup_pciata(struct pci_dev* dev)
1126 good: 1272 good:
1127 pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); 1273 pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
1128 if ((progif & 5) != 5) { 1274 if ((progif & 5) != 5) {
1129 printk(KERN_INFO "Forcing PCI IDE into native mode: %s\n", pci_name(dev)); 1275 printk(KERN_INFO "Forcing PCI IDE into native mode: %s\n",
1276 pci_name(dev));
1130 (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5); 1277 (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5);
1131 if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) || 1278 if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) ||
1132 (progif & 5) != 5) 1279 (progif & 5) != 5)
@@ -1152,7 +1299,8 @@ static void fixup_k2_sata(struct pci_dev* dev)
1152 for (i = 0; i < 6; i++) { 1299 for (i = 0; i < 6; i++) {
1153 dev->resource[i].start = dev->resource[i].end = 0; 1300 dev->resource[i].start = dev->resource[i].end = 0;
1154 dev->resource[i].flags = 0; 1301 dev->resource[i].flags = 0;
1155 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0); 1302 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i,
1303 0);
1156 } 1304 }
1157 } else { 1305 } else {
1158 pci_read_config_word(dev, PCI_COMMAND, &cmd); 1306 pci_read_config_word(dev, PCI_COMMAND, &cmd);
@@ -1161,7 +1309,8 @@ static void fixup_k2_sata(struct pci_dev* dev)
1161 for (i = 0; i < 5; i++) { 1309 for (i = 0; i < 5; i++) {
1162 dev->resource[i].start = dev->resource[i].end = 0; 1310 dev->resource[i].start = dev->resource[i].end = 0;
1163 dev->resource[i].flags = 0; 1311 dev->resource[i].flags = 0;
1164 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0); 1312 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i,
1313 0);
1165 } 1314 }
1166 } 1315 }
1167} 1316}
diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c
new file mode 100644
index 000000000000..4ffd2a9832a0
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/pfunc_base.c
@@ -0,0 +1,405 @@
1#include <linux/config.h>
2#include <linux/types.h>
3#include <linux/init.h>
4#include <linux/delay.h>
5#include <linux/kernel.h>
6#include <linux/interrupt.h>
7#include <linux/spinlock.h>
8
9#include <asm/pmac_feature.h>
10#include <asm/pmac_pfunc.h>
11
12#define DBG(fmt...) printk(fmt)
13
14static irqreturn_t macio_gpio_irq(int irq, void *data, struct pt_regs *regs)
15{
16 pmf_do_irq(data);
17
18 return IRQ_HANDLED;
19}
20
21static int macio_do_gpio_irq_enable(struct pmf_function *func)
22{
23 if (func->node->n_intrs < 1)
24 return -EINVAL;
25
26 return request_irq(func->node->intrs[0].line, macio_gpio_irq, 0,
27 func->node->name, func);
28}
29
30static int macio_do_gpio_irq_disable(struct pmf_function *func)
31{
32 if (func->node->n_intrs < 1)
33 return -EINVAL;
34
35 free_irq(func->node->intrs[0].line, func);
36 return 0;
37}
38
39static int macio_do_gpio_write(PMF_STD_ARGS, u8 value, u8 mask)
40{
41 u8 __iomem *addr = (u8 __iomem *)func->driver_data;
42 unsigned long flags;
43 u8 tmp;
44
45 /* Check polarity */
46 if (args && args->count && !args->u[0].v)
47 value = ~value;
48
49 /* Toggle the GPIO */
50 spin_lock_irqsave(&feature_lock, flags);
51 tmp = readb(addr);
52 tmp = (tmp & ~mask) | (value & mask);
53 DBG("Do write 0x%02x to GPIO %s (%p)\n",
54 tmp, func->node->full_name, addr);
55 writeb(tmp, addr);
56 spin_unlock_irqrestore(&feature_lock, flags);
57
58 return 0;
59}
60
61static int macio_do_gpio_read(PMF_STD_ARGS, u8 mask, int rshift, u8 xor)
62{
63 u8 __iomem *addr = (u8 __iomem *)func->driver_data;
64 u32 value;
65
66 /* Check if we have room for reply */
67 if (args == NULL || args->count == 0 || args->u[0].p == NULL)
68 return -EINVAL;
69
70 value = readb(addr);
71 *args->u[0].p = ((value & mask) >> rshift) ^ xor;
72
73 return 0;
74}
75
76static int macio_do_delay(PMF_STD_ARGS, u32 duration)
77{
78 /* assume we can sleep ! */
79 msleep((duration + 999) / 1000);
80 return 0;
81}
82
83static struct pmf_handlers macio_gpio_handlers = {
84 .irq_enable = macio_do_gpio_irq_enable,
85 .irq_disable = macio_do_gpio_irq_disable,
86 .write_gpio = macio_do_gpio_write,
87 .read_gpio = macio_do_gpio_read,
88 .delay = macio_do_delay,
89};
90
91static void macio_gpio_init_one(struct macio_chip *macio)
92{
93 struct device_node *gparent, *gp;
94
95 /*
96 * Find the "gpio" parent node
97 */
98
99 for (gparent = NULL;
100 (gparent = of_get_next_child(macio->of_node, gparent)) != NULL;)
101 if (strcmp(gparent->name, "gpio") == 0)
102 break;
103 if (gparent == NULL)
104 return;
105
106 DBG("Installing GPIO functions for macio %s\n",
107 macio->of_node->full_name);
108
109 /*
110 * Ok, got one, we dont need anything special to track them down, so
111 * we just create them all
112 */
113 for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;) {
114 u32 *reg = (u32 *)get_property(gp, "reg", NULL);
115 unsigned long offset;
116 if (reg == NULL)
117 continue;
118 offset = *reg;
119 /* Deal with old style device-tree. We can safely hard code the
120 * offset for now too even if it's a bit gross ...
121 */
122 if (offset < 0x50)
123 offset += 0x50;
124 offset += (unsigned long)macio->base;
125 pmf_register_driver(gp, &macio_gpio_handlers, (void *)offset);
126 }
127
128 DBG("Calling initial GPIO functions for macio %s\n",
129 macio->of_node->full_name);
130
131 /* And now we run all the init ones */
132 for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;)
133 pmf_do_functions(gp, NULL, 0, PMF_FLAGS_ON_INIT, NULL);
134
135 /* Note: We do not at this point implement the "at sleep" or "at wake"
136 * functions. I yet to find any for GPIOs anyway
137 */
138}
139
140static int macio_do_write_reg32(PMF_STD_ARGS, u32 offset, u32 value, u32 mask)
141{
142 struct macio_chip *macio = func->driver_data;
143 unsigned long flags;
144
145 spin_lock_irqsave(&feature_lock, flags);
146 MACIO_OUT32(offset, (MACIO_IN32(offset) & ~mask) | (value & mask));
147 spin_unlock_irqrestore(&feature_lock, flags);
148 return 0;
149}
150
151static int macio_do_read_reg32(PMF_STD_ARGS, u32 offset)
152{
153 struct macio_chip *macio = func->driver_data;
154
155 /* Check if we have room for reply */
156 if (args == NULL || args->count == 0 || args->u[0].p == NULL)
157 return -EINVAL;
158
159 *args->u[0].p = MACIO_IN32(offset);
160 return 0;
161}
162
163static int macio_do_write_reg8(PMF_STD_ARGS, u32 offset, u8 value, u8 mask)
164{
165 struct macio_chip *macio = func->driver_data;
166 unsigned long flags;
167
168 spin_lock_irqsave(&feature_lock, flags);
169 MACIO_OUT8(offset, (MACIO_IN8(offset) & ~mask) | (value & mask));
170 spin_unlock_irqrestore(&feature_lock, flags);
171 return 0;
172}
173
174static int macio_do_read_reg8(PMF_STD_ARGS, u32 offset)
175{
176 struct macio_chip *macio = func->driver_data;
177
178 /* Check if we have room for reply */
179 if (args == NULL || args->count == 0 || args->u[0].p == NULL)
180 return -EINVAL;
181
182 *((u8 *)(args->u[0].p)) = MACIO_IN8(offset);
183 return 0;
184}
185
186static int macio_do_read_reg32_msrx(PMF_STD_ARGS, u32 offset, u32 mask,
187 u32 shift, u32 xor)
188{
189 struct macio_chip *macio = func->driver_data;
190
191 /* Check if we have room for reply */
192 if (args == NULL || args->count == 0 || args->u[0].p == NULL)
193 return -EINVAL;
194
195 *args->u[0].p = ((MACIO_IN32(offset) & mask) >> shift) ^ xor;
196 return 0;
197}
198
199static int macio_do_read_reg8_msrx(PMF_STD_ARGS, u32 offset, u32 mask,
200 u32 shift, u32 xor)
201{
202 struct macio_chip *macio = func->driver_data;
203
204 /* Check if we have room for reply */
205 if (args == NULL || args->count == 0 || args->u[0].p == NULL)
206 return -EINVAL;
207
208 *((u8 *)(args->u[0].p)) = ((MACIO_IN8(offset) & mask) >> shift) ^ xor;
209 return 0;
210}
211
212static int macio_do_write_reg32_slm(PMF_STD_ARGS, u32 offset, u32 shift,
213 u32 mask)
214{
215 struct macio_chip *macio = func->driver_data;
216 unsigned long flags;
217 u32 tmp, val;
218
219 /* Check args */
220 if (args == NULL || args->count == 0)
221 return -EINVAL;
222
223 spin_lock_irqsave(&feature_lock, flags);
224 tmp = MACIO_IN32(offset);
225 val = args->u[0].v << shift;
226 tmp = (tmp & ~mask) | (val & mask);
227 MACIO_OUT32(offset, tmp);
228 spin_unlock_irqrestore(&feature_lock, flags);
229 return 0;
230}
231
232static int macio_do_write_reg8_slm(PMF_STD_ARGS, u32 offset, u32 shift,
233 u32 mask)
234{
235 struct macio_chip *macio = func->driver_data;
236 unsigned long flags;
237 u32 tmp, val;
238
239 /* Check args */
240 if (args == NULL || args->count == 0)
241 return -EINVAL;
242
243 spin_lock_irqsave(&feature_lock, flags);
244 tmp = MACIO_IN8(offset);
245 val = args->u[0].v << shift;
246 tmp = (tmp & ~mask) | (val & mask);
247 MACIO_OUT8(offset, tmp);
248 spin_unlock_irqrestore(&feature_lock, flags);
249 return 0;
250}
251
252static struct pmf_handlers macio_mmio_handlers = {
253 .write_reg32 = macio_do_write_reg32,
254 .read_reg32 = macio_do_read_reg32,
255 .write_reg8 = macio_do_write_reg8,
256 .read_reg32 = macio_do_read_reg8,
257 .read_reg32_msrx = macio_do_read_reg32_msrx,
258 .read_reg8_msrx = macio_do_read_reg8_msrx,
259 .write_reg32_slm = macio_do_write_reg32_slm,
260 .write_reg8_slm = macio_do_write_reg8_slm,
261 .delay = macio_do_delay,
262};
263
264static void macio_mmio_init_one(struct macio_chip *macio)
265{
266 DBG("Installing MMIO functions for macio %s\n",
267 macio->of_node->full_name);
268
269 pmf_register_driver(macio->of_node, &macio_mmio_handlers, macio);
270}
271
272static struct device_node *unin_hwclock;
273
274static int unin_do_write_reg32(PMF_STD_ARGS, u32 offset, u32 value, u32 mask)
275{
276 unsigned long flags;
277
278 spin_lock_irqsave(&feature_lock, flags);
279 /* This is fairly bogus in darwin, but it should work for our needs
280 * implemeted that way:
281 */
282 UN_OUT(offset, (UN_IN(offset) & ~mask) | (value & mask));
283 spin_unlock_irqrestore(&feature_lock, flags);
284 return 0;
285}
286
287
288static struct pmf_handlers unin_mmio_handlers = {
289 .write_reg32 = unin_do_write_reg32,
290 .delay = macio_do_delay,
291};
292
293static void uninorth_install_pfunc(void)
294{
295 struct device_node *np;
296
297 DBG("Installing functions for UniN %s\n",
298 uninorth_node->full_name);
299
300 /*
301 * Install handlers for the bridge itself
302 */
303 pmf_register_driver(uninorth_node, &unin_mmio_handlers, NULL);
304 pmf_do_functions(uninorth_node, NULL, 0, PMF_FLAGS_ON_INIT, NULL);
305
306
307 /*
308 * Install handlers for the hwclock child if any
309 */
310 for (np = NULL; (np = of_get_next_child(uninorth_node, np)) != NULL;)
311 if (strcmp(np->name, "hw-clock") == 0) {
312 unin_hwclock = np;
313 break;
314 }
315 if (unin_hwclock) {
316 DBG("Installing functions for UniN clock %s\n",
317 unin_hwclock->full_name);
318 pmf_register_driver(unin_hwclock, &unin_mmio_handlers, NULL);
319 pmf_do_functions(unin_hwclock, NULL, 0, PMF_FLAGS_ON_INIT,
320 NULL);
321 }
322}
323
324/* We export this as the SMP code might init us early */
325int __init pmac_pfunc_base_install(void)
326{
327 static int pfbase_inited;
328 int i;
329
330 if (pfbase_inited)
331 return 0;
332 pfbase_inited = 1;
333
334
335 DBG("Installing base platform functions...\n");
336
337 /*
338 * Locate mac-io chips and install handlers
339 */
340 for (i = 0 ; i < MAX_MACIO_CHIPS; i++) {
341 if (macio_chips[i].of_node) {
342 macio_mmio_init_one(&macio_chips[i]);
343 macio_gpio_init_one(&macio_chips[i]);
344 }
345 }
346
347 /*
348 * Install handlers for northbridge and direct mapped hwclock
349 * if any. We do not implement the config space access callback
350 * which is only ever used for functions that we do not call in
351 * the current driver (enabling/disabling cells in U2, mostly used
352 * to restore the PCI settings, we do that differently)
353 */
354 if (uninorth_node && uninorth_base)
355 uninorth_install_pfunc();
356
357 DBG("All base functions installed\n");
358
359 return 0;
360}
361
362arch_initcall(pmac_pfunc_base_install);
363
364#ifdef CONFIG_PM
365
366/* Those can be called by pmac_feature. Ultimately, I should use a sysdev
367 * or a device, but for now, that's good enough until I sort out some
368 * ordering issues. Also, we do not bother with GPIOs, as so far I yet have
369 * to see a case where a GPIO function has the on-suspend or on-resume bit
370 */
371void pmac_pfunc_base_suspend(void)
372{
373 int i;
374
375 for (i = 0 ; i < MAX_MACIO_CHIPS; i++) {
376 if (macio_chips[i].of_node)
377 pmf_do_functions(macio_chips[i].of_node, NULL, 0,
378 PMF_FLAGS_ON_SLEEP, NULL);
379 }
380 if (uninorth_node)
381 pmf_do_functions(uninorth_node, NULL, 0,
382 PMF_FLAGS_ON_SLEEP, NULL);
383 if (unin_hwclock)
384 pmf_do_functions(unin_hwclock, NULL, 0,
385 PMF_FLAGS_ON_SLEEP, NULL);
386}
387
388void pmac_pfunc_base_resume(void)
389{
390 int i;
391
392 if (unin_hwclock)
393 pmf_do_functions(unin_hwclock, NULL, 0,
394 PMF_FLAGS_ON_WAKE, NULL);
395 if (uninorth_node)
396 pmf_do_functions(uninorth_node, NULL, 0,
397 PMF_FLAGS_ON_WAKE, NULL);
398 for (i = 0 ; i < MAX_MACIO_CHIPS; i++) {
399 if (macio_chips[i].of_node)
400 pmf_do_functions(macio_chips[i].of_node, NULL, 0,
401 PMF_FLAGS_ON_WAKE, NULL);
402 }
403}
404
405#endif /* CONFIG_PM */
diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c
new file mode 100644
index 000000000000..c32c623001dc
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/pfunc_core.c
@@ -0,0 +1,989 @@
1/*
2 *
3 * FIXME: Properly make this race free with refcounting etc...
4 *
5 * FIXME: LOCKING !!!
6 */
7
8#include <linux/config.h>
9#include <linux/init.h>
10#include <linux/delay.h>
11#include <linux/kernel.h>
12#include <linux/spinlock.h>
13#include <linux/module.h>
14
15#include <asm/semaphore.h>
16#include <asm/prom.h>
17#include <asm/pmac_pfunc.h>
18
19/* Debug */
20#define LOG_PARSE(fmt...)
21#define LOG_ERROR(fmt...) printk(fmt)
22#define LOG_BLOB(t,b,c)
23#define DBG(fmt...) printk(fmt)
24
25/* Command numbers */
26#define PMF_CMD_LIST 0
27#define PMF_CMD_WRITE_GPIO 1
28#define PMF_CMD_READ_GPIO 2
29#define PMF_CMD_WRITE_REG32 3
30#define PMF_CMD_READ_REG32 4
31#define PMF_CMD_WRITE_REG16 5
32#define PMF_CMD_READ_REG16 6
33#define PMF_CMD_WRITE_REG8 7
34#define PMF_CMD_READ_REG8 8
35#define PMF_CMD_DELAY 9
36#define PMF_CMD_WAIT_REG32 10
37#define PMF_CMD_WAIT_REG16 11
38#define PMF_CMD_WAIT_REG8 12
39#define PMF_CMD_READ_I2C 13
40#define PMF_CMD_WRITE_I2C 14
41#define PMF_CMD_RMW_I2C 15
42#define PMF_CMD_GEN_I2C 16
43#define PMF_CMD_SHIFT_BYTES_RIGHT 17
44#define PMF_CMD_SHIFT_BYTES_LEFT 18
45#define PMF_CMD_READ_CFG 19
46#define PMF_CMD_WRITE_CFG 20
47#define PMF_CMD_RMW_CFG 21
48#define PMF_CMD_READ_I2C_SUBADDR 22
49#define PMF_CMD_WRITE_I2C_SUBADDR 23
50#define PMF_CMD_SET_I2C_MODE 24
51#define PMF_CMD_RMW_I2C_SUBADDR 25
52#define PMF_CMD_READ_REG32_MASK_SHR_XOR 26
53#define PMF_CMD_READ_REG16_MASK_SHR_XOR 27
54#define PMF_CMD_READ_REG8_MASK_SHR_XOR 28
55#define PMF_CMD_WRITE_REG32_SHL_MASK 29
56#define PMF_CMD_WRITE_REG16_SHL_MASK 30
57#define PMF_CMD_WRITE_REG8_SHL_MASK 31
58#define PMF_CMD_MASK_AND_COMPARE 32
59#define PMF_CMD_COUNT 33
60
61/* This structure holds the state of the parser while walking through
62 * a function definition
63 */
64struct pmf_cmd {
65 const void *cmdptr;
66 const void *cmdend;
67 struct pmf_function *func;
68 void *instdata;
69 struct pmf_args *args;
70 int error;
71};
72
73#if 0
74/* Debug output */
75static void print_blob(const char *title, const void *blob, int bytes)
76{
77 printk("%s", title);
78 while(bytes--) {
79 printk("%02x ", *((u8 *)blob));
80 blob += 1;
81 }
82 printk("\n");
83}
84#endif
85
86/*
87 * Parser helpers
88 */
89
90static u32 pmf_next32(struct pmf_cmd *cmd)
91{
92 u32 value;
93 if ((cmd->cmdend - cmd->cmdptr) < 4) {
94 cmd->error = 1;
95 return 0;
96 }
97 value = *((u32 *)cmd->cmdptr);
98 cmd->cmdptr += 4;
99 return value;
100}
101
102static const void* pmf_next_blob(struct pmf_cmd *cmd, int count)
103{
104 const void *value;
105 if ((cmd->cmdend - cmd->cmdptr) < count) {
106 cmd->error = 1;
107 return NULL;
108 }
109 value = cmd->cmdptr;
110 cmd->cmdptr += count;
111 return value;
112}
113
114/*
115 * Individual command parsers
116 */
117
118#define PMF_PARSE_CALL(name, cmd, handlers, p...) \
119 do { \
120 if (cmd->error) \
121 return -ENXIO; \
122 if (handlers == NULL) \
123 return 0; \
124 if (handlers->name) \
125 return handlers->name(cmd->func, cmd->instdata, \
126 cmd->args, p); \
127 return -1; \
128 } while(0) \
129
130
131static int pmf_parser_write_gpio(struct pmf_cmd *cmd, struct pmf_handlers *h)
132{
133 u8 value = (u8)pmf_next32(cmd);
134 u8 mask = (u8)pmf_next32(cmd);
135
136 LOG_PARSE("pmf: write_gpio(value: %02x, mask: %02x)\n", value, mask);
137
138 PMF_PARSE_CALL(write_gpio, cmd, h, value, mask);
139}
140
141static int pmf_parser_read_gpio(struct pmf_cmd *cmd, struct pmf_handlers *h)
142{
143 u8 mask = (u8)pmf_next32(cmd);
144 int rshift = (int)pmf_next32(cmd);
145 u8 xor = (u8)pmf_next32(cmd);
146
147 LOG_PARSE("pmf: read_gpio(mask: %02x, rshift: %d, xor: %02x)\n",
148 mask, rshift, xor);
149
150 PMF_PARSE_CALL(read_gpio, cmd, h, mask, rshift, xor);
151}
152
153static int pmf_parser_write_reg32(struct pmf_cmd *cmd, struct pmf_handlers *h)
154{
155 u32 offset = pmf_next32(cmd);
156 u32 value = pmf_next32(cmd);
157 u32 mask = pmf_next32(cmd);
158
159 LOG_PARSE("pmf: write_reg32(offset: %08x, value: %08x, mask: %08x)\n",
160 offset, value, mask);
161
162 PMF_PARSE_CALL(write_reg32, cmd, h, offset, value, mask);
163}
164
165static int pmf_parser_read_reg32(struct pmf_cmd *cmd, struct pmf_handlers *h)
166{
167 u32 offset = pmf_next32(cmd);
168
169 LOG_PARSE("pmf: read_reg32(offset: %08x)\n", offset);
170
171 PMF_PARSE_CALL(read_reg32, cmd, h, offset);
172}
173
174
175static int pmf_parser_write_reg16(struct pmf_cmd *cmd, struct pmf_handlers *h)
176{
177 u32 offset = pmf_next32(cmd);
178 u16 value = (u16)pmf_next32(cmd);
179 u16 mask = (u16)pmf_next32(cmd);
180
181 LOG_PARSE("pmf: write_reg16(offset: %08x, value: %04x, mask: %04x)\n",
182 offset, value, mask);
183
184 PMF_PARSE_CALL(write_reg16, cmd, h, offset, value, mask);
185}
186
187static int pmf_parser_read_reg16(struct pmf_cmd *cmd, struct pmf_handlers *h)
188{
189 u32 offset = pmf_next32(cmd);
190
191 LOG_PARSE("pmf: read_reg16(offset: %08x)\n", offset);
192
193 PMF_PARSE_CALL(read_reg16, cmd, h, offset);
194}
195
196
197static int pmf_parser_write_reg8(struct pmf_cmd *cmd, struct pmf_handlers *h)
198{
199 u32 offset = pmf_next32(cmd);
200 u8 value = (u16)pmf_next32(cmd);
201 u8 mask = (u16)pmf_next32(cmd);
202
203 LOG_PARSE("pmf: write_reg8(offset: %08x, value: %02x, mask: %02x)\n",
204 offset, value, mask);
205
206 PMF_PARSE_CALL(write_reg8, cmd, h, offset, value, mask);
207}
208
209static int pmf_parser_read_reg8(struct pmf_cmd *cmd, struct pmf_handlers *h)
210{
211 u32 offset = pmf_next32(cmd);
212
213 LOG_PARSE("pmf: read_reg8(offset: %08x)\n", offset);
214
215 PMF_PARSE_CALL(read_reg8, cmd, h, offset);
216}
217
218static int pmf_parser_delay(struct pmf_cmd *cmd, struct pmf_handlers *h)
219{
220 u32 duration = pmf_next32(cmd);
221
222 LOG_PARSE("pmf: delay(duration: %d us)\n", duration);
223
224 PMF_PARSE_CALL(delay, cmd, h, duration);
225}
226
227static int pmf_parser_wait_reg32(struct pmf_cmd *cmd, struct pmf_handlers *h)
228{
229 u32 offset = pmf_next32(cmd);
230 u32 value = pmf_next32(cmd);
231 u32 mask = pmf_next32(cmd);
232
233 LOG_PARSE("pmf: wait_reg32(offset: %08x, comp_value: %08x,mask: %08x)\n",
234 offset, value, mask);
235
236 PMF_PARSE_CALL(wait_reg32, cmd, h, offset, value, mask);
237}
238
239static int pmf_parser_wait_reg16(struct pmf_cmd *cmd, struct pmf_handlers *h)
240{
241 u32 offset = pmf_next32(cmd);
242 u16 value = (u16)pmf_next32(cmd);
243 u16 mask = (u16)pmf_next32(cmd);
244
245 LOG_PARSE("pmf: wait_reg16(offset: %08x, comp_value: %04x,mask: %04x)\n",
246 offset, value, mask);
247
248 PMF_PARSE_CALL(wait_reg16, cmd, h, offset, value, mask);
249}
250
251static int pmf_parser_wait_reg8(struct pmf_cmd *cmd, struct pmf_handlers *h)
252{
253 u32 offset = pmf_next32(cmd);
254 u8 value = (u8)pmf_next32(cmd);
255 u8 mask = (u8)pmf_next32(cmd);
256
257 LOG_PARSE("pmf: wait_reg8(offset: %08x, comp_value: %02x,mask: %02x)\n",
258 offset, value, mask);
259
260 PMF_PARSE_CALL(wait_reg8, cmd, h, offset, value, mask);
261}
262
263static int pmf_parser_read_i2c(struct pmf_cmd *cmd, struct pmf_handlers *h)
264{
265 u32 bytes = pmf_next32(cmd);
266
267 LOG_PARSE("pmf: read_i2c(bytes: %ud)\n", bytes);
268
269 PMF_PARSE_CALL(read_i2c, cmd, h, bytes);
270}
271
272static int pmf_parser_write_i2c(struct pmf_cmd *cmd, struct pmf_handlers *h)
273{
274 u32 bytes = pmf_next32(cmd);
275 const void *blob = pmf_next_blob(cmd, bytes);
276
277 LOG_PARSE("pmf: write_i2c(bytes: %ud) ...\n", bytes);
278 LOG_BLOB("pmf: data: \n", blob, bytes);
279
280 PMF_PARSE_CALL(write_i2c, cmd, h, bytes, blob);
281}
282
283
284static int pmf_parser_rmw_i2c(struct pmf_cmd *cmd, struct pmf_handlers *h)
285{
286 u32 maskbytes = pmf_next32(cmd);
287 u32 valuesbytes = pmf_next32(cmd);
288 u32 totalbytes = pmf_next32(cmd);
289 const void *maskblob = pmf_next_blob(cmd, maskbytes);
290 const void *valuesblob = pmf_next_blob(cmd, valuesbytes);
291
292 LOG_PARSE("pmf: rmw_i2c(maskbytes: %ud, valuebytes: %ud, "
293 "totalbytes: %d) ...\n",
294 maskbytes, valuesbytes, totalbytes);
295 LOG_BLOB("pmf: mask data: \n", maskblob, maskbytes);
296 LOG_BLOB("pmf: values data: \n", valuesblob, valuesbytes);
297
298 PMF_PARSE_CALL(rmw_i2c, cmd, h, maskbytes, valuesbytes, totalbytes,
299 maskblob, valuesblob);
300}
301
302static int pmf_parser_read_cfg(struct pmf_cmd *cmd, struct pmf_handlers *h)
303{
304 u32 offset = pmf_next32(cmd);
305 u32 bytes = pmf_next32(cmd);
306
307 LOG_PARSE("pmf: read_cfg(offset: %x, bytes: %ud)\n", offset, bytes);
308
309 PMF_PARSE_CALL(read_cfg, cmd, h, offset, bytes);
310}
311
312
313static int pmf_parser_write_cfg(struct pmf_cmd *cmd, struct pmf_handlers *h)
314{
315 u32 offset = pmf_next32(cmd);
316 u32 bytes = pmf_next32(cmd);
317 const void *blob = pmf_next_blob(cmd, bytes);
318
319 LOG_PARSE("pmf: write_cfg(offset: %x, bytes: %ud)\n", offset, bytes);
320 LOG_BLOB("pmf: data: \n", blob, bytes);
321
322 PMF_PARSE_CALL(write_cfg, cmd, h, offset, bytes, blob);
323}
324
325static int pmf_parser_rmw_cfg(struct pmf_cmd *cmd, struct pmf_handlers *h)
326{
327 u32 offset = pmf_next32(cmd);
328 u32 maskbytes = pmf_next32(cmd);
329 u32 valuesbytes = pmf_next32(cmd);
330 u32 totalbytes = pmf_next32(cmd);
331 const void *maskblob = pmf_next_blob(cmd, maskbytes);
332 const void *valuesblob = pmf_next_blob(cmd, valuesbytes);
333
334 LOG_PARSE("pmf: rmw_cfg(maskbytes: %ud, valuebytes: %ud,"
335 " totalbytes: %d) ...\n",
336 maskbytes, valuesbytes, totalbytes);
337 LOG_BLOB("pmf: mask data: \n", maskblob, maskbytes);
338 LOG_BLOB("pmf: values data: \n", valuesblob, valuesbytes);
339
340 PMF_PARSE_CALL(rmw_cfg, cmd, h, offset, maskbytes, valuesbytes,
341 totalbytes, maskblob, valuesblob);
342}
343
344
345static int pmf_parser_read_i2c_sub(struct pmf_cmd *cmd, struct pmf_handlers *h)
346{
347 u8 subaddr = (u8)pmf_next32(cmd);
348 u32 bytes = pmf_next32(cmd);
349
350 LOG_PARSE("pmf: read_i2c_sub(subaddr: %x, bytes: %ud)\n",
351 subaddr, bytes);
352
353 PMF_PARSE_CALL(read_i2c_sub, cmd, h, subaddr, bytes);
354}
355
356static int pmf_parser_write_i2c_sub(struct pmf_cmd *cmd, struct pmf_handlers *h)
357{
358 u8 subaddr = (u8)pmf_next32(cmd);
359 u32 bytes = pmf_next32(cmd);
360 const void *blob = pmf_next_blob(cmd, bytes);
361
362 LOG_PARSE("pmf: write_i2c_sub(subaddr: %x, bytes: %ud) ...\n",
363 subaddr, bytes);
364 LOG_BLOB("pmf: data: \n", blob, bytes);
365
366 PMF_PARSE_CALL(write_i2c_sub, cmd, h, subaddr, bytes, blob);
367}
368
369static int pmf_parser_set_i2c_mode(struct pmf_cmd *cmd, struct pmf_handlers *h)
370{
371 u32 mode = pmf_next32(cmd);
372
373 LOG_PARSE("pmf: set_i2c_mode(mode: %d)\n", mode);
374
375 PMF_PARSE_CALL(set_i2c_mode, cmd, h, mode);
376}
377
378
379static int pmf_parser_rmw_i2c_sub(struct pmf_cmd *cmd, struct pmf_handlers *h)
380{
381 u8 subaddr = (u8)pmf_next32(cmd);
382 u32 maskbytes = pmf_next32(cmd);
383 u32 valuesbytes = pmf_next32(cmd);
384 u32 totalbytes = pmf_next32(cmd);
385 const void *maskblob = pmf_next_blob(cmd, maskbytes);
386 const void *valuesblob = pmf_next_blob(cmd, valuesbytes);
387
388 LOG_PARSE("pmf: rmw_i2c_sub(subaddr: %x, maskbytes: %ud, valuebytes: %ud"
389 ", totalbytes: %d) ...\n",
390 subaddr, maskbytes, valuesbytes, totalbytes);
391 LOG_BLOB("pmf: mask data: \n", maskblob, maskbytes);
392 LOG_BLOB("pmf: values data: \n", valuesblob, valuesbytes);
393
394 PMF_PARSE_CALL(rmw_i2c_sub, cmd, h, subaddr, maskbytes, valuesbytes,
395 totalbytes, maskblob, valuesblob);
396}
397
398static int pmf_parser_read_reg32_msrx(struct pmf_cmd *cmd,
399 struct pmf_handlers *h)
400{
401 u32 offset = pmf_next32(cmd);
402 u32 mask = pmf_next32(cmd);
403 u32 shift = pmf_next32(cmd);
404 u32 xor = pmf_next32(cmd);
405
406 LOG_PARSE("pmf: read_reg32_msrx(offset: %x, mask: %x, shift: %x,"
407 " xor: %x\n", offset, mask, shift, xor);
408
409 PMF_PARSE_CALL(read_reg32_msrx, cmd, h, offset, mask, shift, xor);
410}
411
412static int pmf_parser_read_reg16_msrx(struct pmf_cmd *cmd,
413 struct pmf_handlers *h)
414{
415 u32 offset = pmf_next32(cmd);
416 u32 mask = pmf_next32(cmd);
417 u32 shift = pmf_next32(cmd);
418 u32 xor = pmf_next32(cmd);
419
420 LOG_PARSE("pmf: read_reg16_msrx(offset: %x, mask: %x, shift: %x,"
421 " xor: %x\n", offset, mask, shift, xor);
422
423 PMF_PARSE_CALL(read_reg16_msrx, cmd, h, offset, mask, shift, xor);
424}
425static int pmf_parser_read_reg8_msrx(struct pmf_cmd *cmd,
426 struct pmf_handlers *h)
427{
428 u32 offset = pmf_next32(cmd);
429 u32 mask = pmf_next32(cmd);
430 u32 shift = pmf_next32(cmd);
431 u32 xor = pmf_next32(cmd);
432
433 LOG_PARSE("pmf: read_reg8_msrx(offset: %x, mask: %x, shift: %x,"
434 " xor: %x\n", offset, mask, shift, xor);
435
436 PMF_PARSE_CALL(read_reg8_msrx, cmd, h, offset, mask, shift, xor);
437}
438
439static int pmf_parser_write_reg32_slm(struct pmf_cmd *cmd,
440 struct pmf_handlers *h)
441{
442 u32 offset = pmf_next32(cmd);
443 u32 shift = pmf_next32(cmd);
444 u32 mask = pmf_next32(cmd);
445
446 LOG_PARSE("pmf: write_reg32_slm(offset: %x, shift: %x, mask: %x\n",
447 offset, shift, mask);
448
449 PMF_PARSE_CALL(write_reg32_slm, cmd, h, offset, shift, mask);
450}
451
452static int pmf_parser_write_reg16_slm(struct pmf_cmd *cmd,
453 struct pmf_handlers *h)
454{
455 u32 offset = pmf_next32(cmd);
456 u32 shift = pmf_next32(cmd);
457 u32 mask = pmf_next32(cmd);
458
459 LOG_PARSE("pmf: write_reg16_slm(offset: %x, shift: %x, mask: %x\n",
460 offset, shift, mask);
461
462 PMF_PARSE_CALL(write_reg16_slm, cmd, h, offset, shift, mask);
463}
464
465static int pmf_parser_write_reg8_slm(struct pmf_cmd *cmd,
466 struct pmf_handlers *h)
467{
468 u32 offset = pmf_next32(cmd);
469 u32 shift = pmf_next32(cmd);
470 u32 mask = pmf_next32(cmd);
471
472 LOG_PARSE("pmf: write_reg8_slm(offset: %x, shift: %x, mask: %x\n",
473 offset, shift, mask);
474
475 PMF_PARSE_CALL(write_reg8_slm, cmd, h, offset, shift, mask);
476}
477
478static int pmf_parser_mask_and_compare(struct pmf_cmd *cmd,
479 struct pmf_handlers *h)
480{
481 u32 bytes = pmf_next32(cmd);
482 const void *maskblob = pmf_next_blob(cmd, bytes);
483 const void *valuesblob = pmf_next_blob(cmd, bytes);
484
485 LOG_PARSE("pmf: mask_and_compare(length: %ud ...\n", bytes);
486 LOG_BLOB("pmf: mask data: \n", maskblob, bytes);
487 LOG_BLOB("pmf: values data: \n", valuesblob, bytes);
488
489 PMF_PARSE_CALL(mask_and_compare, cmd, h,
490 bytes, maskblob, valuesblob);
491}
492
493
494typedef int (*pmf_cmd_parser_t)(struct pmf_cmd *cmd, struct pmf_handlers *h);
495
496static pmf_cmd_parser_t pmf_parsers[PMF_CMD_COUNT] =
497{
498 NULL,
499 pmf_parser_write_gpio,
500 pmf_parser_read_gpio,
501 pmf_parser_write_reg32,
502 pmf_parser_read_reg32,
503 pmf_parser_write_reg16,
504 pmf_parser_read_reg16,
505 pmf_parser_write_reg8,
506 pmf_parser_read_reg8,
507 pmf_parser_delay,
508 pmf_parser_wait_reg32,
509 pmf_parser_wait_reg16,
510 pmf_parser_wait_reg8,
511 pmf_parser_read_i2c,
512 pmf_parser_write_i2c,
513 pmf_parser_rmw_i2c,
514 NULL, /* Bogus command */
515 NULL, /* Shift bytes right: NYI */
516 NULL, /* Shift bytes left: NYI */
517 pmf_parser_read_cfg,
518 pmf_parser_write_cfg,
519 pmf_parser_rmw_cfg,
520 pmf_parser_read_i2c_sub,
521 pmf_parser_write_i2c_sub,
522 pmf_parser_set_i2c_mode,
523 pmf_parser_rmw_i2c_sub,
524 pmf_parser_read_reg32_msrx,
525 pmf_parser_read_reg16_msrx,
526 pmf_parser_read_reg8_msrx,
527 pmf_parser_write_reg32_slm,
528 pmf_parser_write_reg16_slm,
529 pmf_parser_write_reg8_slm,
530 pmf_parser_mask_and_compare,
531};
532
533struct pmf_device {
534 struct list_head link;
535 struct device_node *node;
536 struct pmf_handlers *handlers;
537 struct list_head functions;
538 struct kref ref;
539};
540
541static LIST_HEAD(pmf_devices);
542static spinlock_t pmf_lock = SPIN_LOCK_UNLOCKED;
543
544static void pmf_release_device(struct kref *kref)
545{
546 struct pmf_device *dev = container_of(kref, struct pmf_device, ref);
547 kfree(dev);
548}
549
550static inline void pmf_put_device(struct pmf_device *dev)
551{
552 kref_put(&dev->ref, pmf_release_device);
553}
554
555static inline struct pmf_device *pmf_get_device(struct pmf_device *dev)
556{
557 kref_get(&dev->ref);
558 return dev;
559}
560
561static inline struct pmf_device *pmf_find_device(struct device_node *np)
562{
563 struct pmf_device *dev;
564
565 list_for_each_entry(dev, &pmf_devices, link) {
566 if (dev->node == np)
567 return pmf_get_device(dev);
568 }
569 return NULL;
570}
571
572static int pmf_parse_one(struct pmf_function *func,
573 struct pmf_handlers *handlers,
574 void *instdata, struct pmf_args *args)
575{
576 struct pmf_cmd cmd;
577 u32 ccode;
578 int count, rc;
579
580 cmd.cmdptr = func->data;
581 cmd.cmdend = func->data + func->length;
582 cmd.func = func;
583 cmd.instdata = instdata;
584 cmd.args = args;
585 cmd.error = 0;
586
587 LOG_PARSE("pmf: func %s, %d bytes, %s...\n",
588 func->name, func->length,
589 handlers ? "executing" : "parsing");
590
591 /* One subcommand to parse for now */
592 count = 1;
593
594 while(count-- && cmd.cmdptr < cmd.cmdend) {
595 /* Get opcode */
596 ccode = pmf_next32(&cmd);
597 /* Check if we are hitting a command list, fetch new count */
598 if (ccode == 0) {
599 count = pmf_next32(&cmd) - 1;
600 ccode = pmf_next32(&cmd);
601 }
602 if (cmd.error) {
603 LOG_ERROR("pmf: parse error, not enough data\n");
604 return -ENXIO;
605 }
606 if (ccode >= PMF_CMD_COUNT) {
607 LOG_ERROR("pmf: command code %d unknown !\n", ccode);
608 return -ENXIO;
609 }
610 if (pmf_parsers[ccode] == NULL) {
611 LOG_ERROR("pmf: no parser for command %d !\n", ccode);
612 return -ENXIO;
613 }
614 rc = pmf_parsers[ccode](&cmd, handlers);
615 if (rc != 0) {
616 LOG_ERROR("pmf: parser for command %d returned"
617 " error %d\n", ccode, rc);
618 return rc;
619 }
620 }
621
622 /* We are doing an initial parse pass, we need to adjust the size */
623 if (handlers == NULL)
624 func->length = cmd.cmdptr - func->data;
625
626 return 0;
627}
628
629static int pmf_add_function_prop(struct pmf_device *dev, void *driverdata,
630 const char *name, u32 *data,
631 unsigned int length)
632{
633 int count = 0;
634 struct pmf_function *func = NULL;
635
636 DBG("pmf: Adding functions for platform-do-%s\n", name);
637
638 while (length >= 12) {
639 /* Allocate a structure */
640 func = kzalloc(sizeof(struct pmf_function), GFP_KERNEL);
641 if (func == NULL)
642 goto bail;
643 kref_init(&func->ref);
644 INIT_LIST_HEAD(&func->irq_clients);
645 func->node = dev->node;
646 func->driver_data = driverdata;
647 func->name = name;
648 func->phandle = data[0];
649 func->flags = data[1];
650 data += 2;
651 length -= 8;
652 func->data = data;
653 func->length = length;
654 func->dev = dev;
655 DBG("pmf: idx %d: flags=%08x, phandle=%08x "
656 " %d bytes remaining, parsing...\n",
657 count+1, func->flags, func->phandle, length);
658 if (pmf_parse_one(func, NULL, NULL, NULL)) {
659 kfree(func);
660 goto bail;
661 }
662 length -= func->length;
663 data = (u32 *)(((u8 *)data) + func->length);
664 list_add(&func->link, &dev->functions);
665 pmf_get_device(dev);
666 count++;
667 }
668 bail:
669 DBG("pmf: Added %d functions\n", count);
670
671 return count;
672}
673
674static int pmf_add_functions(struct pmf_device *dev, void *driverdata)
675{
676 struct property *pp;
677#define PP_PREFIX "platform-do-"
678 const int plen = strlen(PP_PREFIX);
679 int count = 0;
680
681 for (pp = dev->node->properties; pp != 0; pp = pp->next) {
682 char *name;
683 if (strncmp(pp->name, PP_PREFIX, plen) != 0)
684 continue;
685 name = pp->name + plen;
686 if (strlen(name) && pp->length >= 12)
687 count += pmf_add_function_prop(dev, driverdata, name,
688 (u32 *)pp->value,
689 pp->length);
690 }
691 return count;
692}
693
694
695int pmf_register_driver(struct device_node *np,
696 struct pmf_handlers *handlers,
697 void *driverdata)
698{
699 struct pmf_device *dev;
700 unsigned long flags;
701 int rc = 0;
702
703 if (handlers == NULL)
704 return -EINVAL;
705
706 DBG("pmf: registering driver for node %s\n", np->full_name);
707
708 spin_lock_irqsave(&pmf_lock, flags);
709 dev = pmf_find_device(np);
710 spin_unlock_irqrestore(&pmf_lock, flags);
711 if (dev != NULL) {
712 DBG("pmf: already there !\n");
713 pmf_put_device(dev);
714 return -EBUSY;
715 }
716
717 dev = kzalloc(sizeof(struct pmf_device), GFP_KERNEL);
718 if (dev == NULL) {
719 DBG("pmf: no memory !\n");
720 return -ENOMEM;
721 }
722 kref_init(&dev->ref);
723 dev->node = of_node_get(np);
724 dev->handlers = handlers;
725 INIT_LIST_HEAD(&dev->functions);
726
727 rc = pmf_add_functions(dev, driverdata);
728 if (rc == 0) {
729 DBG("pmf: no functions, disposing.. \n");
730 of_node_put(np);
731 kfree(dev);
732 return -ENODEV;
733 }
734
735 spin_lock_irqsave(&pmf_lock, flags);
736 list_add(&dev->link, &pmf_devices);
737 spin_unlock_irqrestore(&pmf_lock, flags);
738
739 return 0;
740}
741EXPORT_SYMBOL_GPL(pmf_register_driver);
742
743struct pmf_function *pmf_get_function(struct pmf_function *func)
744{
745 if (!try_module_get(func->dev->handlers->owner))
746 return NULL;
747 kref_get(&func->ref);
748 return func;
749}
750EXPORT_SYMBOL_GPL(pmf_get_function);
751
752static void pmf_release_function(struct kref *kref)
753{
754 struct pmf_function *func =
755 container_of(kref, struct pmf_function, ref);
756 pmf_put_device(func->dev);
757 kfree(func);
758}
759
760static inline void __pmf_put_function(struct pmf_function *func)
761{
762 kref_put(&func->ref, pmf_release_function);
763}
764
765void pmf_put_function(struct pmf_function *func)
766{
767 if (func == NULL)
768 return;
769 module_put(func->dev->handlers->owner);
770 __pmf_put_function(func);
771}
772EXPORT_SYMBOL_GPL(pmf_put_function);
773
774void pmf_unregister_driver(struct device_node *np)
775{
776 struct pmf_device *dev;
777 unsigned long flags;
778
779 DBG("pmf: unregistering driver for node %s\n", np->full_name);
780
781 spin_lock_irqsave(&pmf_lock, flags);
782 dev = pmf_find_device(np);
783 if (dev == NULL) {
784 DBG("pmf: not such driver !\n");
785 spin_unlock_irqrestore(&pmf_lock, flags);
786 return;
787 }
788 list_del(&dev->link);
789
790 while(!list_empty(&dev->functions)) {
791 struct pmf_function *func =
792 list_entry(dev->functions.next, typeof(*func), link);
793 list_del(&func->link);
794 __pmf_put_function(func);
795 }
796
797 pmf_put_device(dev);
798 spin_unlock_irqrestore(&pmf_lock, flags);
799}
800EXPORT_SYMBOL_GPL(pmf_unregister_driver);
801
802struct pmf_function *__pmf_find_function(struct device_node *target,
803 const char *name, u32 flags)
804{
805 struct device_node *actor = of_node_get(target);
806 struct pmf_device *dev;
807 struct pmf_function *func, *result = NULL;
808 char fname[64];
809 u32 *prop, ph;
810
811 /*
812 * Look for a "platform-*" function reference. If we can't find
813 * one, then we fallback to a direct call attempt
814 */
815 snprintf(fname, 63, "platform-%s", name);
816 prop = (u32 *)get_property(target, fname, NULL);
817 if (prop == NULL)
818 goto find_it;
819 ph = *prop;
820 if (ph == 0)
821 goto find_it;
822
823 /*
824 * Ok, now try to find the actor. If we can't find it, we fail,
825 * there is no point in falling back there
826 */
827 of_node_put(actor);
828 actor = of_find_node_by_phandle(ph);
829 if (actor == NULL)
830 return NULL;
831 find_it:
832 dev = pmf_find_device(actor);
833 if (dev == NULL)
834 return NULL;
835
836 list_for_each_entry(func, &dev->functions, link) {
837 if (name && strcmp(name, func->name))
838 continue;
839 if (func->phandle && target->node != func->phandle)
840 continue;
841 if ((func->flags & flags) == 0)
842 continue;
843 result = func;
844 break;
845 }
846 of_node_put(actor);
847 pmf_put_device(dev);
848 return result;
849}
850
851
852int pmf_register_irq_client(struct device_node *target,
853 const char *name,
854 struct pmf_irq_client *client)
855{
856 struct pmf_function *func;
857 unsigned long flags;
858
859 spin_lock_irqsave(&pmf_lock, flags);
860 func = __pmf_find_function(target, name, PMF_FLAGS_INT_GEN);
861 if (func == NULL) {
862 spin_unlock_irqrestore(&pmf_lock, flags);
863 return -ENODEV;
864 }
865 list_add(&client->link, &func->irq_clients);
866 spin_unlock_irqrestore(&pmf_lock, flags);
867
868 return 0;
869}
870EXPORT_SYMBOL_GPL(pmf_register_irq_client);
871
872void pmf_unregister_irq_client(struct device_node *np,
873 const char *name,
874 struct pmf_irq_client *client)
875{
876 unsigned long flags;
877
878 spin_lock_irqsave(&pmf_lock, flags);
879 list_del(&client->link);
880 spin_unlock_irqrestore(&pmf_lock, flags);
881}
882EXPORT_SYMBOL_GPL(pmf_unregister_irq_client);
883
884
885void pmf_do_irq(struct pmf_function *func)
886{
887 unsigned long flags;
888 struct pmf_irq_client *client;
889
890 /* For now, using a spinlock over the whole function. Can be made
891 * to drop the lock using 2 lists if necessary
892 */
893 spin_lock_irqsave(&pmf_lock, flags);
894 list_for_each_entry(client, &func->irq_clients, link) {
895 if (!try_module_get(client->owner))
896 continue;
897 client->handler(client->data);
898 module_put(client->owner);
899 }
900 spin_unlock_irqrestore(&pmf_lock, flags);
901}
902EXPORT_SYMBOL_GPL(pmf_do_irq);
903
904
905int pmf_call_one(struct pmf_function *func, struct pmf_args *args)
906{
907 struct pmf_device *dev = func->dev;
908 void *instdata = NULL;
909 int rc = 0;
910
911 DBG(" ** pmf_call_one(%s/%s) **\n", dev->node->full_name, func->name);
912
913 if (dev->handlers->begin)
914 instdata = dev->handlers->begin(func, args);
915 rc = pmf_parse_one(func, dev->handlers, instdata, args);
916 if (dev->handlers->end)
917 dev->handlers->end(func, instdata);
918
919 return rc;
920}
921EXPORT_SYMBOL_GPL(pmf_call_one);
922
923int pmf_do_functions(struct device_node *np, const char *name,
924 u32 phandle, u32 fflags, struct pmf_args *args)
925{
926 struct pmf_device *dev;
927 struct pmf_function *func, *tmp;
928 unsigned long flags;
929 int rc = -ENODEV;
930
931 spin_lock_irqsave(&pmf_lock, flags);
932
933 dev = pmf_find_device(np);
934 if (dev == NULL) {
935 spin_unlock_irqrestore(&pmf_lock, flags);
936 return -ENODEV;
937 }
938 list_for_each_entry_safe(func, tmp, &dev->functions, link) {
939 if (name && strcmp(name, func->name))
940 continue;
941 if (phandle && func->phandle && phandle != func->phandle)
942 continue;
943 if ((func->flags & fflags) == 0)
944 continue;
945 if (pmf_get_function(func) == NULL)
946 continue;
947 spin_unlock_irqrestore(&pmf_lock, flags);
948 rc = pmf_call_one(func, args);
949 pmf_put_function(func);
950 spin_lock_irqsave(&pmf_lock, flags);
951 }
952 pmf_put_device(dev);
953 spin_unlock_irqrestore(&pmf_lock, flags);
954
955 return rc;
956}
957EXPORT_SYMBOL_GPL(pmf_do_functions);
958
959
960struct pmf_function *pmf_find_function(struct device_node *target,
961 const char *name)
962{
963 struct pmf_function *func;
964 unsigned long flags;
965
966 spin_lock_irqsave(&pmf_lock, flags);
967 func = __pmf_find_function(target, name, PMF_FLAGS_ON_DEMAND);
968 if (func)
969 func = pmf_get_function(func);
970 spin_unlock_irqrestore(&pmf_lock, flags);
971 return func;
972}
973EXPORT_SYMBOL_GPL(pmf_find_function);
974
975int pmf_call_function(struct device_node *target, const char *name,
976 struct pmf_args *args)
977{
978 struct pmf_function *func = pmf_find_function(target, name);
979 int rc;
980
981 if (func == NULL)
982 return -ENODEV;
983
984 rc = pmf_call_one(func, args);
985 pmf_put_function(func);
986 return rc;
987}
988EXPORT_SYMBOL_GPL(pmf_call_function);
989
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 90040c49494d..18bf3011d1e3 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -5,8 +5,8 @@
5 * in a separate file 5 * in a separate file
6 * 6 *
7 * Copyright (C) 1997 Paul Mackerras (paulus@samba.org) 7 * Copyright (C) 1997 Paul Mackerras (paulus@samba.org)
8 * 8 * Copyright (C) 2005 Benjamin Herrenschmidt (benh@kernel.crashing.org)
9 * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org) 9 * IBM, Corp.
10 * 10 *
11 * This program is free software; you can redistribute it and/or 11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License 12 * modify it under the terms of the GNU General Public License
@@ -54,12 +54,7 @@ struct pmac_irq_hw {
54}; 54};
55 55
56/* Default addresses */ 56/* Default addresses */
57static volatile struct pmac_irq_hw *pmac_irq_hw[4] = { 57static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4];
58 (struct pmac_irq_hw *) 0xf3000020,
59 (struct pmac_irq_hw *) 0xf3000010,
60 (struct pmac_irq_hw *) 0xf4000020,
61 (struct pmac_irq_hw *) 0xf4000010,
62};
63 58
64#define GC_LEVEL_MASK 0x3ff00000 59#define GC_LEVEL_MASK 0x3ff00000
65#define OHARE_LEVEL_MASK 0x1ff00000 60#define OHARE_LEVEL_MASK 0x1ff00000
@@ -82,8 +77,7 @@ static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
82 * since it can lose interrupts (see pmac_set_irq_mask). 77 * since it can lose interrupts (see pmac_set_irq_mask).
83 * -- Cort 78 * -- Cort
84 */ 79 */
85void 80void __set_lost(unsigned long irq_nr, int nokick)
86__set_lost(unsigned long irq_nr, int nokick)
87{ 81{
88 if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) { 82 if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) {
89 atomic_inc(&ppc_n_lost_interrupts); 83 atomic_inc(&ppc_n_lost_interrupts);
@@ -92,8 +86,7 @@ __set_lost(unsigned long irq_nr, int nokick)
92 } 86 }
93} 87}
94 88
95static void 89static void pmac_mask_and_ack_irq(unsigned int irq_nr)
96pmac_mask_and_ack_irq(unsigned int irq_nr)
97{ 90{
98 unsigned long bit = 1UL << (irq_nr & 0x1f); 91 unsigned long bit = 1UL << (irq_nr & 0x1f);
99 int i = irq_nr >> 5; 92 int i = irq_nr >> 5;
@@ -224,8 +217,7 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
224 return IRQ_NONE; 217 return IRQ_NONE;
225} 218}
226 219
227int 220static int pmac_get_irq(struct pt_regs *regs)
228pmac_get_irq(struct pt_regs *regs)
229{ 221{
230 int irq; 222 int irq;
231 unsigned long bits = 0; 223 unsigned long bits = 0;
@@ -256,34 +248,40 @@ pmac_get_irq(struct pt_regs *regs)
256 248
257/* This routine will fix some missing interrupt values in the device tree 249/* This routine will fix some missing interrupt values in the device tree
258 * on the gatwick mac-io controller used by some PowerBooks 250 * on the gatwick mac-io controller used by some PowerBooks
251 *
252 * Walking of OF nodes could use a bit more fixing up here, but it's not
253 * very important as this is all boot time code on static portions of the
254 * device-tree.
255 *
256 * However, the modifications done to "intrs" will have to be removed and
257 * replaced with proper updates of the "interrupts" properties or
258 * AAPL,interrupts, yet to be decided, once the dynamic parsing is there.
259 */ 259 */
260static void __init 260static void __init pmac_fix_gatwick_interrupts(struct device_node *gw,
261pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base) 261 int irq_base)
262{ 262{
263 struct device_node *node; 263 struct device_node *node;
264 int count; 264 int count;
265 265
266 memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool)); 266 memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool));
267 node = gw->child;
268 count = 0; 267 count = 0;
269 while(node) 268 for (node = NULL; (node = of_get_next_child(gw, node)) != NULL;) {
270 {
271 /* Fix SCC */ 269 /* Fix SCC */
272 if (strcasecmp(node->name, "escc") == 0) 270 if ((strcasecmp(node->name, "escc") == 0) && node->child) {
273 if (node->child) { 271 if (node->child->n_intrs < 3) {
274 if (node->child->n_intrs < 3) { 272 node->child->intrs = &gatwick_int_pool[count];
275 node->child->intrs = &gatwick_int_pool[count]; 273 count += 3;
276 count += 3;
277 }
278 node->child->n_intrs = 3;
279 node->child->intrs[0].line = 15+irq_base;
280 node->child->intrs[1].line = 4+irq_base;
281 node->child->intrs[2].line = 5+irq_base;
282 printk(KERN_INFO "irq: fixed SCC on second controller (%d,%d,%d)\n",
283 node->child->intrs[0].line,
284 node->child->intrs[1].line,
285 node->child->intrs[2].line);
286 } 274 }
275 node->child->n_intrs = 3;
276 node->child->intrs[0].line = 15+irq_base;
277 node->child->intrs[1].line = 4+irq_base;
278 node->child->intrs[2].line = 5+irq_base;
279 printk(KERN_INFO "irq: fixed SCC on gatwick"
280 " (%d,%d,%d)\n",
281 node->child->intrs[0].line,
282 node->child->intrs[1].line,
283 node->child->intrs[2].line);
284 }
287 /* Fix media-bay & left SWIM */ 285 /* Fix media-bay & left SWIM */
288 if (strcasecmp(node->name, "media-bay") == 0) { 286 if (strcasecmp(node->name, "media-bay") == 0) {
289 struct device_node* ya_node; 287 struct device_node* ya_node;
@@ -292,12 +290,11 @@ pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base)
292 node->intrs = &gatwick_int_pool[count++]; 290 node->intrs = &gatwick_int_pool[count++];
293 node->n_intrs = 1; 291 node->n_intrs = 1;
294 node->intrs[0].line = 29+irq_base; 292 node->intrs[0].line = 29+irq_base;
295 printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n", 293 printk(KERN_INFO "irq: fixed media-bay on gatwick"
296 node->intrs[0].line); 294 " (%d)\n", node->intrs[0].line);
297 295
298 ya_node = node->child; 296 ya_node = node->child;
299 while(ya_node) 297 while(ya_node) {
300 {
301 if (strcasecmp(ya_node->name, "floppy") == 0) { 298 if (strcasecmp(ya_node->name, "floppy") == 0) {
302 if (ya_node->n_intrs < 2) { 299 if (ya_node->n_intrs < 2) {
303 ya_node->intrs = &gatwick_int_pool[count]; 300 ya_node->intrs = &gatwick_int_pool[count];
@@ -323,7 +320,6 @@ pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base)
323 ya_node = ya_node->sibling; 320 ya_node = ya_node->sibling;
324 } 321 }
325 } 322 }
326 node = node->sibling;
327 } 323 }
328 if (count > 10) { 324 if (count > 10) {
329 printk("WARNING !! Gatwick interrupt pool overflow\n"); 325 printk("WARNING !! Gatwick interrupt pool overflow\n");
@@ -338,45 +334,41 @@ pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base)
338 * controller. If we find this second ohare, set it up and fix the 334 * controller. If we find this second ohare, set it up and fix the
339 * interrupt value in the device tree for the ethernet chip. 335 * interrupt value in the device tree for the ethernet chip.
340 */ 336 */
341static int __init enable_second_ohare(void) 337static void __init enable_second_ohare(struct device_node *np)
342{ 338{
343 unsigned char bus, devfn; 339 unsigned char bus, devfn;
344 unsigned short cmd; 340 unsigned short cmd;
345 unsigned long addr;
346 struct device_node *irqctrler = find_devices("pci106b,7");
347 struct device_node *ether; 341 struct device_node *ether;
348 342
349 if (irqctrler == NULL || irqctrler->n_addrs <= 0) 343 /* This code doesn't strictly belong here, it could be part of
350 return -1; 344 * either the PCI initialisation or the feature code. It's kept
351 addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40); 345 * here for historical reasons.
352 pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20); 346 */
353 max_irqs = 64; 347 if (pci_device_from_OF_node(np, &bus, &devfn) == 0) {
354 if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) { 348 struct pci_controller* hose =
355 struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler); 349 pci_find_hose_for_OF_device(np);
356 if (!hose) 350 if (!hose) {
357 printk(KERN_ERR "Can't find PCI hose for OHare2 !\n"); 351 printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
358 else { 352 return;
359 early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
360 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
361 cmd &= ~PCI_COMMAND_IO;
362 early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
363 } 353 }
354 early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
355 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
356 cmd &= ~PCI_COMMAND_IO;
357 early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
364 } 358 }
365 359
366 /* Fix interrupt for the modem/ethernet combo controller. The number 360 /* Fix interrupt for the modem/ethernet combo controller. The number
367 in the device tree (27) is bogus (correct for the ethernet-only 361 * in the device tree (27) is bogus (correct for the ethernet-only
368 board but not the combo ethernet/modem board). 362 * board but not the combo ethernet/modem board).
369 The real interrupt is 28 on the second controller -> 28+32 = 60. 363 * The real interrupt is 28 on the second controller -> 28+32 = 60.
370 */ 364 */
371 ether = find_devices("pci1011,14"); 365 ether = of_find_node_by_name(NULL, "pci1011,14");
372 if (ether && ether->n_intrs > 0) { 366 if (ether && ether->n_intrs > 0) {
373 ether->intrs[0].line = 60; 367 ether->intrs[0].line = 60;
374 printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n", 368 printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n",
375 ether->intrs[0].line); 369 ether->intrs[0].line);
376 } 370 }
377 371 of_node_put(ether);
378 /* Return the interrupt number of the cascade */
379 return irqctrler->intrs[0].line;
380} 372}
381 373
382#ifdef CONFIG_XMON 374#ifdef CONFIG_XMON
@@ -394,189 +386,251 @@ static struct irqaction gatwick_cascade_action = {
394 .mask = CPU_MASK_NONE, 386 .mask = CPU_MASK_NONE,
395 .name = "cascade", 387 .name = "cascade",
396}; 388};
397#endif /* CONFIG_PPC32 */
398 389
399static int pmac_u3_cascade(struct pt_regs *regs, void *data) 390static void __init pmac_pic_probe_oldstyle(void)
400{ 391{
401 return mpic_get_one_irq((struct mpic *)data, regs);
402}
403
404void __init pmac_pic_init(void)
405{
406 struct device_node *irqctrler = NULL;
407 struct device_node *irqctrler2 = NULL;
408 struct device_node *np;
409#ifdef CONFIG_PPC32
410 int i; 392 int i;
411 unsigned long addr;
412 int irq_cascade = -1; 393 int irq_cascade = -1;
413#endif 394 struct device_node *master = NULL;
414 struct mpic *mpic1, *mpic2; 395 struct device_node *slave = NULL;
396 u8 __iomem *addr;
397 struct resource r;
415 398
416 /* We first try to detect Apple's new Core99 chipset, since mac-io 399 /* Set our get_irq function */
417 * is quite different on those machines and contains an IBM MPIC2. 400 ppc_md.get_irq = pmac_get_irq;
418 */
419 np = find_type_devices("open-pic");
420 while (np) {
421 if (np->parent && !strcmp(np->parent->name, "u3"))
422 irqctrler2 = np;
423 else
424 irqctrler = np;
425 np = np->next;
426 }
427 if (irqctrler != NULL && irqctrler->n_addrs > 0) {
428 unsigned char senses[128];
429
430 printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n",
431 (unsigned int)irqctrler->addrs[0].address);
432 pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0);
433
434 prom_get_irq_senses(senses, 0, 128);
435 mpic1 = mpic_alloc(irqctrler->addrs[0].address,
436 MPIC_PRIMARY | MPIC_WANTS_RESET,
437 0, 0, 128, 252, senses, 128, " OpenPIC ");
438 BUG_ON(mpic1 == NULL);
439 mpic_init(mpic1);
440
441 if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 &&
442 irqctrler2->n_addrs > 0) {
443 printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n",
444 (u32)irqctrler2->addrs[0].address,
445 irqctrler2->intrs[0].line);
446
447 pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0);
448 prom_get_irq_senses(senses, 128, 128 + 124);
449
450 /* We don't need to set MPIC_BROKEN_U3 here since we don't have
451 * hypertransport interrupts routed to it
452 */
453 mpic2 = mpic_alloc(irqctrler2->addrs[0].address,
454 MPIC_BIG_ENDIAN | MPIC_WANTS_RESET,
455 0, 128, 124, 0, senses, 124,
456 " U3-MPIC ");
457 BUG_ON(mpic2 == NULL);
458 mpic_init(mpic2);
459 mpic_setup_cascade(irqctrler2->intrs[0].line,
460 pmac_u3_cascade, mpic2);
461 }
462#if defined(CONFIG_XMON) && defined(CONFIG_PPC32)
463 {
464 struct device_node* pswitch;
465 int nmi_irq;
466
467 pswitch = find_devices("programmer-switch");
468 if (pswitch && pswitch->n_intrs) {
469 nmi_irq = pswitch->intrs[0].line;
470 mpic_irq_set_priority(nmi_irq, 9);
471 setup_irq(nmi_irq, &xmon_action);
472 }
473 }
474#endif /* CONFIG_XMON */
475 return;
476 }
477 irqctrler = NULL;
478 401
479#ifdef CONFIG_PPC32 402 /*
480 /* Get the level/edge settings, assume if it's not 403 * Find the interrupt controller type & node
481 * a Grand Central nor an OHare, then it's an Heathrow
482 * (or Paddington).
483 */ 404 */
484 ppc_md.get_irq = pmac_get_irq; 405
485 if (find_devices("gc")) 406 if ((master = of_find_node_by_name(NULL, "gc")) != NULL) {
407 max_irqs = max_real_irqs = 32;
486 level_mask[0] = GC_LEVEL_MASK; 408 level_mask[0] = GC_LEVEL_MASK;
487 else if (find_devices("ohare")) { 409 } else if ((master = of_find_node_by_name(NULL, "ohare")) != NULL) {
410 max_irqs = max_real_irqs = 32;
488 level_mask[0] = OHARE_LEVEL_MASK; 411 level_mask[0] = OHARE_LEVEL_MASK;
412
489 /* We might have a second cascaded ohare */ 413 /* We might have a second cascaded ohare */
490 level_mask[1] = OHARE_LEVEL_MASK; 414 slave = of_find_node_by_name(NULL, "pci106b,7");
491 } else { 415 if (slave) {
416 max_irqs = 64;
417 level_mask[1] = OHARE_LEVEL_MASK;
418 enable_second_ohare(slave);
419 }
420 } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) {
421 max_irqs = max_real_irqs = 64;
492 level_mask[0] = HEATHROW_LEVEL_MASK; 422 level_mask[0] = HEATHROW_LEVEL_MASK;
493 level_mask[1] = 0; 423 level_mask[1] = 0;
424
494 /* We might have a second cascaded heathrow */ 425 /* We might have a second cascaded heathrow */
495 level_mask[2] = HEATHROW_LEVEL_MASK; 426 slave = of_find_node_by_name(master, "mac-io");
496 level_mask[3] = 0; 427
497 } 428 /* Check ordering of master & slave */
429 if (device_is_compatible(master, "gatwick")) {
430 struct device_node *tmp;
431 BUG_ON(slave == NULL);
432 tmp = master;
433 master = slave;
434 slave = tmp;
435 }
498 436
499 /* 437 /* We found a slave */
500 * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts, 438 if (slave) {
501 * 1998 G3 Series PowerBooks have 128,
502 * other powermacs have 32.
503 * The combo ethernet/modem card for the Powerstar powerbooks
504 * (2400/3400/3500, ohare based) has a second ohare chip
505 * effectively making a total of 64.
506 */
507 max_irqs = max_real_irqs = 32;
508 irqctrler = find_devices("mac-io");
509 if (irqctrler)
510 {
511 max_real_irqs = 64;
512 if (irqctrler->next)
513 max_irqs = 128; 439 max_irqs = 128;
514 else 440 level_mask[2] = HEATHROW_LEVEL_MASK;
515 max_irqs = 64; 441 level_mask[3] = 0;
442 pmac_fix_gatwick_interrupts(slave, max_real_irqs);
443 }
516 } 444 }
445 BUG_ON(master == NULL);
446
447 /* Set the handler for the main PIC */
517 for ( i = 0; i < max_real_irqs ; i++ ) 448 for ( i = 0; i < max_real_irqs ; i++ )
518 irq_desc[i].handler = &pmac_pic; 449 irq_desc[i].handler = &pmac_pic;
519 450
520 /* get addresses of first controller */ 451 /* Get addresses of first controller if we have a node for it */
521 if (irqctrler) { 452 BUG_ON(of_address_to_resource(master, 0, &r));
522 if (irqctrler->n_addrs > 0) {
523 addr = (unsigned long)
524 ioremap(irqctrler->addrs[0].address, 0x40);
525 for (i = 0; i < 2; ++i)
526 pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
527 (addr + (2 - i) * 0x10);
528 }
529 453
530 /* get addresses of second controller */ 454 /* Map interrupts of primary controller */
531 irqctrler = irqctrler->next; 455 addr = (u8 __iomem *) ioremap(r.start, 0x40);
532 if (irqctrler && irqctrler->n_addrs > 0) { 456 i = 0;
533 addr = (unsigned long) 457 pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)
534 ioremap(irqctrler->addrs[0].address, 0x40); 458 (addr + 0x20);
535 for (i = 2; i < 4; ++i) 459 if (max_real_irqs > 32)
536 pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) 460 pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)
537 (addr + (4 - i) * 0x10); 461 (addr + 0x10);
538 irq_cascade = irqctrler->intrs[0].line; 462 of_node_put(master);
539 if (device_is_compatible(irqctrler, "gatwick")) 463
540 pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs); 464 printk(KERN_INFO "irq: Found primary Apple PIC %s for %d irqs\n",
541 } 465 master->full_name, max_real_irqs);
542 } else { 466
543 /* older powermacs have a GC (grand central) or ohare at 467 /* Map interrupts of cascaded controller */
544 f3000000, with interrupt control registers at f3000020. */ 468 if (slave && !of_address_to_resource(slave, 0, &r)) {
545 addr = (unsigned long) ioremap(0xf3000000, 0x40); 469 addr = (u8 __iomem *)ioremap(r.start, 0x40);
546 pmac_irq_hw[0] = (volatile struct pmac_irq_hw *) (addr + 0x20); 470 pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)
471 (addr + 0x20);
472 if (max_irqs > 64)
473 pmac_irq_hw[i++] =
474 (volatile struct pmac_irq_hw __iomem *)
475 (addr + 0x10);
476 irq_cascade = slave->intrs[0].line;
477
478 printk(KERN_INFO "irq: Found slave Apple PIC %s for %d irqs"
479 " cascade: %d\n", slave->full_name,
480 max_irqs - max_real_irqs, irq_cascade);
547 } 481 }
548 482 of_node_put(slave);
549 /* PowerBooks 3400 and 3500 can have a second controller in a second
550 ohare chip, on the combo ethernet/modem card */
551 if (machine_is_compatible("AAPL,3400/2400")
552 || machine_is_compatible("AAPL,3500"))
553 irq_cascade = enable_second_ohare();
554 483
555 /* disable all interrupts in all controllers */ 484 /* disable all interrupts in all controllers */
556 for (i = 0; i * 32 < max_irqs; ++i) 485 for (i = 0; i * 32 < max_irqs; ++i)
557 out_le32(&pmac_irq_hw[i]->enable, 0); 486 out_le32(&pmac_irq_hw[i]->enable, 0);
487
558 /* mark level interrupts */ 488 /* mark level interrupts */
559 for (i = 0; i < max_irqs; i++) 489 for (i = 0; i < max_irqs; i++)
560 if (level_mask[i >> 5] & (1UL << (i & 0x1f))) 490 if (level_mask[i >> 5] & (1UL << (i & 0x1f)))
561 irq_desc[i].status = IRQ_LEVEL; 491 irq_desc[i].status = IRQ_LEVEL;
562 492
563 /* get interrupt line of secondary interrupt controller */ 493 /* Setup handlers for secondary controller and hook cascade irq*/
564 if (irq_cascade >= 0) { 494 if (slave) {
565 printk(KERN_INFO "irq: secondary controller on irq %d\n",
566 (int)irq_cascade);
567 for ( i = max_real_irqs ; i < max_irqs ; i++ ) 495 for ( i = max_real_irqs ; i < max_irqs ; i++ )
568 irq_desc[i].handler = &gatwick_pic; 496 irq_desc[i].handler = &gatwick_pic;
569 setup_irq(irq_cascade, &gatwick_cascade_action); 497 setup_irq(irq_cascade, &gatwick_cascade_action);
570 } 498 }
571 printk("System has %d possible interrupts\n", max_irqs); 499 printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs);
572 if (max_irqs != max_real_irqs)
573 printk(KERN_DEBUG "%d interrupts on main controller\n",
574 max_real_irqs);
575
576#ifdef CONFIG_XMON 500#ifdef CONFIG_XMON
577 setup_irq(20, &xmon_action); 501 setup_irq(20, &xmon_action);
578#endif /* CONFIG_XMON */ 502#endif
579#endif /* CONFIG_PPC32 */ 503}
504#endif /* CONFIG_PPC32 */
505
506static int pmac_u3_cascade(struct pt_regs *regs, void *data)
507{
508 return mpic_get_one_irq((struct mpic *)data, regs);
509}
510
511static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic)
512{
513#if defined(CONFIG_XMON) && defined(CONFIG_PPC32)
514 struct device_node* pswitch;
515 int nmi_irq;
516
517 pswitch = of_find_node_by_name(NULL, "programmer-switch");
518 if (pswitch && pswitch->n_intrs) {
519 nmi_irq = pswitch->intrs[0].line;
520 mpic_irq_set_priority(nmi_irq, 9);
521 setup_irq(nmi_irq, &xmon_action);
522 }
523 of_node_put(pswitch);
524#endif /* defined(CONFIG_XMON) && defined(CONFIG_PPC32) */
525}
526
527static struct mpic * __init pmac_setup_one_mpic(struct device_node *np,
528 int master)
529{
530 unsigned char senses[128];
531 int offset = master ? 0 : 128;
532 int count = master ? 128 : 124;
533 const char *name = master ? " MPIC 1 " : " MPIC 2 ";
534 struct resource r;
535 struct mpic *mpic;
536 unsigned int flags = master ? MPIC_PRIMARY : 0;
537 int rc;
538
539 rc = of_address_to_resource(np, 0, &r);
540 if (rc)
541 return NULL;
542
543 pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0);
544
545 prom_get_irq_senses(senses, offset, offset + count);
546
547 flags |= MPIC_WANTS_RESET;
548 if (get_property(np, "big-endian", NULL))
549 flags |= MPIC_BIG_ENDIAN;
550
551 /* Primary Big Endian means HT interrupts. This is quite dodgy
552 * but works until I find a better way
553 */
554 if (master && (flags & MPIC_BIG_ENDIAN))
555 flags |= MPIC_BROKEN_U3;
556
557 mpic = mpic_alloc(r.start, flags, 0, offset, count, master ? 252 : 0,
558 senses, count, name);
559 if (mpic == NULL)
560 return NULL;
561
562 mpic_init(mpic);
563
564 return mpic;
565 }
566
567static int __init pmac_pic_probe_mpic(void)
568{
569 struct mpic *mpic1, *mpic2;
570 struct device_node *np, *master = NULL, *slave = NULL;
571
572 /* We can have up to 2 MPICs cascaded */
573 for (np = NULL; (np = of_find_node_by_type(np, "open-pic"))
574 != NULL;) {
575 if (master == NULL &&
576 get_property(np, "interrupts", NULL) == NULL)
577 master = of_node_get(np);
578 else if (slave == NULL)
579 slave = of_node_get(np);
580 if (master && slave)
581 break;
582 }
583
584 /* Check for bogus setups */
585 if (master == NULL && slave != NULL) {
586 master = slave;
587 slave = NULL;
588 }
589
590 /* Not found, default to good old pmac pic */
591 if (master == NULL)
592 return -ENODEV;
593
594 /* Set master handler */
595 ppc_md.get_irq = mpic_get_irq;
596
597 /* Setup master */
598 mpic1 = pmac_setup_one_mpic(master, 1);
599 BUG_ON(mpic1 == NULL);
600
601 /* Install NMI if any */
602 pmac_pic_setup_mpic_nmi(mpic1);
603
604 of_node_put(master);
605
606 /* No slave, let's go out */
607 if (slave == NULL || slave->n_intrs < 1)
608 return 0;
609
610 mpic2 = pmac_setup_one_mpic(slave, 0);
611 if (mpic2 == NULL) {
612 printk(KERN_ERR "Failed to setup slave MPIC\n");
613 of_node_put(slave);
614 return 0;
615 }
616 mpic_setup_cascade(slave->intrs[0].line, pmac_u3_cascade, mpic2);
617
618 of_node_put(slave);
619 return 0;
620}
621
622
623void __init pmac_pic_init(void)
624{
625 /* We first try to detect Apple's new Core99 chipset, since mac-io
626 * is quite different on those machines and contains an IBM MPIC2.
627 */
628 if (pmac_pic_probe_mpic() == 0)
629 return;
630
631#ifdef CONFIG_PPC32
632 pmac_pic_probe_oldstyle();
633#endif
580} 634}
581 635
582#if defined(CONFIG_PM) && defined(CONFIG_PPC32) 636#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h
index 2ad25e13423e..21c7b0f8f329 100644
--- a/arch/powerpc/platforms/powermac/pmac.h
+++ b/arch/powerpc/platforms/powermac/pmac.h
@@ -42,10 +42,6 @@ extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
42 unsigned long data_port, unsigned long ctrl_port, int *irq); 42 unsigned long data_port, unsigned long ctrl_port, int *irq);
43 43
44extern int pmac_nvram_init(void); 44extern int pmac_nvram_init(void);
45 45extern void pmac_pic_init(void);
46extern struct hw_interrupt_type pmac_pic;
47
48void pmac_pic_init(void);
49int pmac_get_irq(struct pt_regs *regs);
50 46
51#endif /* __PMAC_H__ */ 47#endif /* __PMAC_H__ */
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 7acb0546671f..3b1a9d4fcbc6 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -60,6 +60,7 @@
60#include <asm/system.h> 60#include <asm/system.h>
61#include <asm/pgtable.h> 61#include <asm/pgtable.h>
62#include <asm/io.h> 62#include <asm/io.h>
63#include <asm/kexec.h>
63#include <asm/pci-bridge.h> 64#include <asm/pci-bridge.h>
64#include <asm/ohare.h> 65#include <asm/ohare.h>
65#include <asm/mediabay.h> 66#include <asm/mediabay.h>
@@ -74,8 +75,8 @@
74#include <asm/iommu.h> 75#include <asm/iommu.h>
75#include <asm/smu.h> 76#include <asm/smu.h>
76#include <asm/pmc.h> 77#include <asm/pmc.h>
77#include <asm/mpic.h>
78#include <asm/lmb.h> 78#include <asm/lmb.h>
79#include <asm/udbg.h>
79 80
80#include "pmac.h" 81#include "pmac.h"
81 82
@@ -321,16 +322,6 @@ void __init pmac_setup_arch(void)
321 l2cr_init(); 322 l2cr_init();
322#endif /* CONFIG_PPC32 */ 323#endif /* CONFIG_PPC32 */
323 324
324#ifdef CONFIG_PPC64
325 /* Probe motherboard chipset */
326 /* this is done earlier in setup_arch for 32-bit */
327 pmac_feature_init();
328
329 /* We can NAP */
330 powersave_nap = 1;
331 printk(KERN_INFO "Using native/NAP idle loop\n");
332#endif
333
334#ifdef CONFIG_KGDB 325#ifdef CONFIG_KGDB
335 zs_kgdb_hook(0); 326 zs_kgdb_hook(0);
336#endif 327#endif
@@ -354,7 +345,7 @@ void __init pmac_setup_arch(void)
354 345
355#ifdef CONFIG_SMP 346#ifdef CONFIG_SMP
356 /* Check for Core99 */ 347 /* Check for Core99 */
357 if (find_devices("uni-n") || find_devices("u3")) 348 if (find_devices("uni-n") || find_devices("u3") || find_devices("u4"))
358 smp_ops = &core99_smp_ops; 349 smp_ops = &core99_smp_ops;
359#ifdef CONFIG_PPC32 350#ifdef CONFIG_PPC32
360 else 351 else
@@ -621,35 +612,31 @@ static void __init pmac_init_early(void)
621 * and call ioremap 612 * and call ioremap
622 */ 613 */
623 hpte_init_native(); 614 hpte_init_native();
615#endif
624 616
625 /* Init SCC */ 617 /* Enable early btext debug if requested */
626 if (strstr(cmd_line, "sccdbg")) { 618 if (strstr(cmd_line, "btextdbg")) {
627 sccdbg = 1; 619 udbg_adb_init_early();
628 udbg_init_scc(NULL); 620 register_early_udbg_console();
629 } 621 }
630 622
631 /* Setup interrupt mapping options */ 623 /* Probe motherboard chipset */
632 ppc64_interrupt_controller = IC_OPEN_PIC; 624 pmac_feature_init();
633 625
634 iommu_init_early_u3(); 626 /* We can NAP */
635#endif 627 powersave_nap = 1;
636} 628 printk(KERN_INFO "Using native/NAP idle loop\n");
629
630 /* Initialize debug stuff */
631 udbg_scc_init(!!strstr(cmd_line, "sccdbg"));
632 udbg_adb_init(!!strstr(cmd_line, "btextdbg"));
637 633
638static void __init pmac_progress(char *s, unsigned short hex)
639{
640#ifdef CONFIG_PPC64 634#ifdef CONFIG_PPC64
641 if (sccdbg) { 635 /* Setup interrupt mapping options */
642 udbg_puts(s); 636 ppc64_interrupt_controller = IC_OPEN_PIC;
643 udbg_puts("\n"); 637
644 return; 638 iommu_init_early_dart();
645 }
646#endif 639#endif
647#ifdef CONFIG_BOOTX_TEXT
648 if (boot_text_mapped) {
649 btext_drawstring(s);
650 btext_drawchar('\n');
651 }
652#endif /* CONFIG_BOOTX_TEXT */
653} 640}
654 641
655/* 642/*
@@ -663,35 +650,14 @@ static int pmac_check_legacy_ioport(unsigned int baseport)
663 650
664static int __init pmac_declare_of_platform_devices(void) 651static int __init pmac_declare_of_platform_devices(void)
665{ 652{
666 struct device_node *np, *npp; 653 struct device_node *np;
667 654
668 np = find_devices("uni-n"); 655 np = of_find_node_by_name(NULL, "valkyrie");
669 if (np) {
670 for (np = np->child; np != NULL; np = np->sibling)
671 if (strncmp(np->name, "i2c", 3) == 0) {
672 of_platform_device_create(np, "uni-n-i2c",
673 NULL);
674 break;
675 }
676 }
677 np = find_devices("valkyrie");
678 if (np) 656 if (np)
679 of_platform_device_create(np, "valkyrie", NULL); 657 of_platform_device_create(np, "valkyrie", NULL);
680 np = find_devices("platinum"); 658 np = of_find_node_by_name(NULL, "platinum");
681 if (np) 659 if (np)
682 of_platform_device_create(np, "platinum", NULL); 660 of_platform_device_create(np, "platinum", NULL);
683
684 npp = of_find_node_by_name(NULL, "u3");
685 if (npp) {
686 for (np = NULL; (np = of_get_next_child(npp, np)) != NULL;) {
687 if (strncmp(np->name, "i2c", 3) == 0) {
688 of_platform_device_create(np, "u3-i2c", NULL);
689 of_node_put(np);
690 break;
691 }
692 }
693 of_node_put(npp);
694 }
695 np = of_find_node_by_type(NULL, "smu"); 661 np = of_find_node_by_type(NULL, "smu");
696 if (np) { 662 if (np) {
697 of_platform_device_create(np, "smu", NULL); 663 of_platform_device_create(np, "smu", NULL);
@@ -718,7 +684,7 @@ static int __init pmac_probe(int platform)
718 * occupies having to be broken up so the DART itself is not 684 * occupies having to be broken up so the DART itself is not
719 * part of the cacheable linar mapping 685 * part of the cacheable linar mapping
720 */ 686 */
721 alloc_u3_dart_table(); 687 alloc_dart_table();
722#endif 688#endif
723 689
724#ifdef CONFIG_PMAC_SMU 690#ifdef CONFIG_PMAC_SMU
@@ -734,15 +700,17 @@ static int __init pmac_probe(int platform)
734} 700}
735 701
736#ifdef CONFIG_PPC64 702#ifdef CONFIG_PPC64
737static int pmac_probe_mode(struct pci_bus *bus) 703/* Move that to pci.c */
704static int pmac_pci_probe_mode(struct pci_bus *bus)
738{ 705{
739 struct device_node *node = bus->sysdata; 706 struct device_node *node = bus->sysdata;
740 707
741 /* We need to use normal PCI probing for the AGP bus, 708 /* We need to use normal PCI probing for the AGP bus,
742 since the device for the AGP bridge isn't in the tree. */ 709 * since the device for the AGP bridge isn't in the tree.
743 if (bus->self == NULL && device_is_compatible(node, "u3-agp")) 710 */
711 if (bus->self == NULL && (device_is_compatible(node, "u3-agp") ||
712 device_is_compatible(node, "u4-pcie")))
744 return PCI_PROBE_NORMAL; 713 return PCI_PROBE_NORMAL;
745
746 return PCI_PROBE_DEVTREE; 714 return PCI_PROBE_DEVTREE;
747} 715}
748#endif 716#endif
@@ -756,7 +724,7 @@ struct machdep_calls __initdata pmac_md = {
756 .init_early = pmac_init_early, 724 .init_early = pmac_init_early,
757 .show_cpuinfo = pmac_show_cpuinfo, 725 .show_cpuinfo = pmac_show_cpuinfo,
758 .init_IRQ = pmac_pic_init, 726 .init_IRQ = pmac_pic_init,
759 .get_irq = mpic_get_irq, /* changed later */ 727 .get_irq = NULL, /* changed later */
760 .pcibios_fixup = pmac_pcibios_fixup, 728 .pcibios_fixup = pmac_pcibios_fixup,
761 .restart = pmac_restart, 729 .restart = pmac_restart,
762 .power_off = pmac_power_off, 730 .power_off = pmac_power_off,
@@ -768,12 +736,17 @@ struct machdep_calls __initdata pmac_md = {
768 .calibrate_decr = pmac_calibrate_decr, 736 .calibrate_decr = pmac_calibrate_decr,
769 .feature_call = pmac_do_feature_call, 737 .feature_call = pmac_do_feature_call,
770 .check_legacy_ioport = pmac_check_legacy_ioport, 738 .check_legacy_ioport = pmac_check_legacy_ioport,
771 .progress = pmac_progress, 739 .progress = udbg_progress,
772#ifdef CONFIG_PPC64 740#ifdef CONFIG_PPC64
773 .pci_probe_mode = pmac_probe_mode, 741 .pci_probe_mode = pmac_pci_probe_mode,
774 .idle_loop = native_idle, 742 .idle_loop = native_idle,
775 .enable_pmcs = power4_enable_pmcs, 743 .enable_pmcs = power4_enable_pmcs,
744#ifdef CONFIG_KEXEC
745 .machine_kexec = default_machine_kexec,
746 .machine_kexec_prepare = default_machine_kexec_prepare,
747 .machine_crash_shutdown = default_machine_crash_shutdown,
776#endif 748#endif
749#endif /* CONFIG_PPC64 */
777#ifdef CONFIG_PPC32 750#ifdef CONFIG_PPC32
778 .pcibios_enable_device_hook = pmac_pci_enable_device_hook, 751 .pcibios_enable_device_hook = pmac_pci_enable_device_hook,
779 .pcibios_after_init = pmac_pcibios_after_init, 752 .pcibios_after_init = pmac_pcibios_after_init,
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index fb2a7c798e82..0df2cdcd805c 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -52,8 +52,9 @@
52#include <asm/cacheflush.h> 52#include <asm/cacheflush.h>
53#include <asm/keylargo.h> 53#include <asm/keylargo.h>
54#include <asm/pmac_low_i2c.h> 54#include <asm/pmac_low_i2c.h>
55#include <asm/pmac_pfunc.h>
55 56
56#undef DEBUG 57#define DEBUG
57 58
58#ifdef DEBUG 59#ifdef DEBUG
59#define DBG(fmt...) udbg_printf(fmt) 60#define DBG(fmt...) udbg_printf(fmt)
@@ -62,6 +63,7 @@
62#endif 63#endif
63 64
64extern void __secondary_start_pmac_0(void); 65extern void __secondary_start_pmac_0(void);
66extern int pmac_pfunc_base_install(void);
65 67
66#ifdef CONFIG_PPC32 68#ifdef CONFIG_PPC32
67 69
@@ -361,7 +363,6 @@ static void __init psurge_dual_sync_tb(int cpu_nr)
361 set_dec(tb_ticks_per_jiffy); 363 set_dec(tb_ticks_per_jiffy);
362 /* XXX fixme */ 364 /* XXX fixme */
363 set_tb(0, 0); 365 set_tb(0, 0);
364 last_jiffy_stamp(cpu_nr) = 0;
365 366
366 if (cpu_nr > 0) { 367 if (cpu_nr > 0) {
367 mb(); 368 mb();
@@ -429,15 +430,62 @@ struct smp_ops_t psurge_smp_ops = {
429}; 430};
430#endif /* CONFIG_PPC32 - actually powersurge support */ 431#endif /* CONFIG_PPC32 - actually powersurge support */
431 432
433/*
434 * Core 99 and later support
435 */
436
437static void (*pmac_tb_freeze)(int freeze);
438static unsigned long timebase;
439static int tb_req;
440
441static void smp_core99_give_timebase(void)
442{
443 unsigned long flags;
444
445 local_irq_save(flags);
446
447 while(!tb_req)
448 barrier();
449 tb_req = 0;
450 (*pmac_tb_freeze)(1);
451 mb();
452 timebase = get_tb();
453 mb();
454 while (timebase)
455 barrier();
456 mb();
457 (*pmac_tb_freeze)(0);
458 mb();
459
460 local_irq_restore(flags);
461}
462
463
464static void __devinit smp_core99_take_timebase(void)
465{
466 unsigned long flags;
467
468 local_irq_save(flags);
469
470 tb_req = 1;
471 mb();
472 while (!timebase)
473 barrier();
474 mb();
475 set_tb(timebase >> 32, timebase & 0xffffffff);
476 timebase = 0;
477 mb();
478 set_dec(tb_ticks_per_jiffy/2);
479
480 local_irq_restore(flags);
481}
482
432#ifdef CONFIG_PPC64 483#ifdef CONFIG_PPC64
433/* 484/*
434 * G5s enable/disable the timebase via an i2c-connected clock chip. 485 * G5s enable/disable the timebase via an i2c-connected clock chip.
435 */ 486 */
436static struct device_node *pmac_tb_clock_chip_host; 487static struct pmac_i2c_bus *pmac_tb_clock_chip_host;
437static u8 pmac_tb_pulsar_addr; 488static u8 pmac_tb_pulsar_addr;
438static void (*pmac_tb_freeze)(int freeze);
439static DEFINE_SPINLOCK(timebase_lock);
440static unsigned long timebase;
441 489
442static void smp_core99_cypress_tb_freeze(int freeze) 490static void smp_core99_cypress_tb_freeze(int freeze)
443{ 491{
@@ -447,19 +495,20 @@ static void smp_core99_cypress_tb_freeze(int freeze)
447 /* Strangely, the device-tree says address is 0xd2, but darwin 495 /* Strangely, the device-tree says address is 0xd2, but darwin
448 * accesses 0xd0 ... 496 * accesses 0xd0 ...
449 */ 497 */
450 pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined); 498 pmac_i2c_setmode(pmac_tb_clock_chip_host,
451 rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, 499 pmac_i2c_mode_combined);
452 0xd0 | pmac_low_i2c_read, 500 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
453 0x81, &data, 1); 501 0xd0 | pmac_i2c_read,
502 1, 0x81, &data, 1);
454 if (rc != 0) 503 if (rc != 0)
455 goto bail; 504 goto bail;
456 505
457 data = (data & 0xf3) | (freeze ? 0x00 : 0x0c); 506 data = (data & 0xf3) | (freeze ? 0x00 : 0x0c);
458 507
459 pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub); 508 pmac_i2c_setmode(pmac_tb_clock_chip_host, pmac_i2c_mode_stdsub);
460 rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, 509 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
461 0xd0 | pmac_low_i2c_write, 510 0xd0 | pmac_i2c_write,
462 0x81, &data, 1); 511 1, 0x81, &data, 1);
463 512
464 bail: 513 bail:
465 if (rc != 0) { 514 if (rc != 0) {
@@ -475,19 +524,20 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
475 u8 data; 524 u8 data;
476 int rc; 525 int rc;
477 526
478 pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined); 527 pmac_i2c_setmode(pmac_tb_clock_chip_host,
479 rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, 528 pmac_i2c_mode_combined);
480 pmac_tb_pulsar_addr | pmac_low_i2c_read, 529 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
481 0x2e, &data, 1); 530 pmac_tb_pulsar_addr | pmac_i2c_read,
531 1, 0x2e, &data, 1);
482 if (rc != 0) 532 if (rc != 0)
483 goto bail; 533 goto bail;
484 534
485 data = (data & 0x88) | (freeze ? 0x11 : 0x22); 535 data = (data & 0x88) | (freeze ? 0x11 : 0x22);
486 536
487 pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub); 537 pmac_i2c_setmode(pmac_tb_clock_chip_host, pmac_i2c_mode_stdsub);
488 rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, 538 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
489 pmac_tb_pulsar_addr | pmac_low_i2c_write, 539 pmac_tb_pulsar_addr | pmac_i2c_write,
490 0x2e, &data, 1); 540 1, 0x2e, &data, 1);
491 bail: 541 bail:
492 if (rc != 0) { 542 if (rc != 0) {
493 printk(KERN_ERR "Pulsar Timebase %s rc: %d\n", 543 printk(KERN_ERR "Pulsar Timebase %s rc: %d\n",
@@ -496,54 +546,14 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
496 } 546 }
497} 547}
498 548
499 549static void __init smp_core99_setup_i2c_hwsync(int ncpus)
500static void smp_core99_give_timebase(void)
501{
502 /* Open i2c bus for synchronous access */
503 if (pmac_low_i2c_open(pmac_tb_clock_chip_host, 0))
504 panic("Can't open i2c for TB sync !\n");
505
506 spin_lock(&timebase_lock);
507 (*pmac_tb_freeze)(1);
508 mb();
509 timebase = get_tb();
510 spin_unlock(&timebase_lock);
511
512 while (timebase)
513 barrier();
514
515 spin_lock(&timebase_lock);
516 (*pmac_tb_freeze)(0);
517 spin_unlock(&timebase_lock);
518
519 /* Close i2c bus */
520 pmac_low_i2c_close(pmac_tb_clock_chip_host);
521}
522
523
524static void __devinit smp_core99_take_timebase(void)
525{
526 while (!timebase)
527 barrier();
528 spin_lock(&timebase_lock);
529 set_tb(timebase >> 32, timebase & 0xffffffff);
530 timebase = 0;
531 spin_unlock(&timebase_lock);
532}
533
534static void __init smp_core99_setup(int ncpus)
535{ 550{
536 struct device_node *cc = NULL; 551 struct device_node *cc = NULL;
537 struct device_node *p; 552 struct device_node *p;
553 const char *name = NULL;
538 u32 *reg; 554 u32 *reg;
539 int ok; 555 int ok;
540 556
541 /* HW sync only on these platforms */
542 if (!machine_is_compatible("PowerMac7,2") &&
543 !machine_is_compatible("PowerMac7,3") &&
544 !machine_is_compatible("RackMac3,1"))
545 return;
546
547 /* Look for the clock chip */ 557 /* Look for the clock chip */
548 while ((cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL) { 558 while ((cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL) {
549 p = of_get_parent(cc); 559 p = of_get_parent(cc);
@@ -552,124 +562,86 @@ static void __init smp_core99_setup(int ncpus)
552 if (!ok) 562 if (!ok)
553 continue; 563 continue;
554 564
565 pmac_tb_clock_chip_host = pmac_i2c_find_bus(cc);
566 if (pmac_tb_clock_chip_host == NULL)
567 continue;
555 reg = (u32 *)get_property(cc, "reg", NULL); 568 reg = (u32 *)get_property(cc, "reg", NULL);
556 if (reg == NULL) 569 if (reg == NULL)
557 continue; 570 continue;
558
559 switch (*reg) { 571 switch (*reg) {
560 case 0xd2: 572 case 0xd2:
561 if (device_is_compatible(cc, "pulsar-legacy-slewing")) { 573 if (device_is_compatible(cc,"pulsar-legacy-slewing")) {
562 pmac_tb_freeze = smp_core99_pulsar_tb_freeze; 574 pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
563 pmac_tb_pulsar_addr = 0xd2; 575 pmac_tb_pulsar_addr = 0xd2;
564 printk(KERN_INFO "Timebase clock is Pulsar chip\n"); 576 name = "Pulsar";
565 } else if (device_is_compatible(cc, "cy28508")) { 577 } else if (device_is_compatible(cc, "cy28508")) {
566 pmac_tb_freeze = smp_core99_cypress_tb_freeze; 578 pmac_tb_freeze = smp_core99_cypress_tb_freeze;
567 printk(KERN_INFO "Timebase clock is Cypress chip\n"); 579 name = "Cypress";
568 } 580 }
569 break; 581 break;
570 case 0xd4: 582 case 0xd4:
571 pmac_tb_freeze = smp_core99_pulsar_tb_freeze; 583 pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
572 pmac_tb_pulsar_addr = 0xd4; 584 pmac_tb_pulsar_addr = 0xd4;
573 printk(KERN_INFO "Timebase clock is Pulsar chip\n"); 585 name = "Pulsar";
574 break; 586 break;
575 } 587 }
576 if (pmac_tb_freeze != NULL) { 588 if (pmac_tb_freeze != NULL)
577 pmac_tb_clock_chip_host = of_get_parent(cc);
578 of_node_put(cc);
579 break; 589 break;
580 }
581 } 590 }
582 if (pmac_tb_freeze == NULL) { 591 if (pmac_tb_freeze != NULL) {
583 smp_ops->give_timebase = smp_generic_give_timebase; 592 /* Open i2c bus for synchronous access */
584 smp_ops->take_timebase = smp_generic_take_timebase; 593 if (pmac_i2c_open(pmac_tb_clock_chip_host, 1)) {
594 printk(KERN_ERR "Failed top open i2c bus for clock"
595 " sync, fallback to software sync !\n");
596 goto no_i2c_sync;
597 }
598 printk(KERN_INFO "Processor timebase sync using %s i2c clock\n",
599 name);
600 return;
585 } 601 }
602 no_i2c_sync:
603 pmac_tb_freeze = NULL;
604 pmac_tb_clock_chip_host = NULL;
586} 605}
587 606
588/* nothing to do here, caches are already set up by service processor */ 607
589static inline void __devinit core99_init_caches(int cpu) 608
609/*
610 * Newer G5s uses a platform function
611 */
612
613static void smp_core99_pfunc_tb_freeze(int freeze)
590{ 614{
615 struct device_node *cpus;
616 struct pmf_args args;
617
618 cpus = of_find_node_by_path("/cpus");
619 BUG_ON(cpus == NULL);
620 args.count = 1;
621 args.u[0].v = !freeze;
622 pmf_call_function(cpus, "cpu-timebase", &args);
623 of_node_put(cpus);
591} 624}
592 625
593#else /* CONFIG_PPC64 */ 626#else /* CONFIG_PPC64 */
594 627
595/* 628/*
596 * SMP G4 powermacs use a GPIO to enable/disable the timebase. 629 * SMP G4 use a GPIO to enable/disable the timebase.
597 */ 630 */
598 631
599static unsigned int core99_tb_gpio; /* Timebase freeze GPIO */ 632static unsigned int core99_tb_gpio; /* Timebase freeze GPIO */
600 633
601static unsigned int pri_tb_hi, pri_tb_lo; 634static void smp_core99_gpio_tb_freeze(int freeze)
602static unsigned int pri_tb_stamp;
603
604/* not __init, called in sleep/wakeup code */
605void smp_core99_give_timebase(void)
606{ 635{
607 unsigned long flags; 636 if (freeze)
608 unsigned int t; 637 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4);
609 638 else
610 /* wait for the secondary to be in take_timebase */ 639 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);
611 for (t = 100000; t > 0 && !sec_tb_reset; --t)
612 udelay(10);
613 if (!sec_tb_reset) {
614 printk(KERN_WARNING "Timeout waiting sync on second CPU\n");
615 return;
616 }
617
618 /* freeze the timebase and read it */
619 /* disable interrupts so the timebase is disabled for the
620 shortest possible time */
621 local_irq_save(flags);
622 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4);
623 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); 640 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
624 mb();
625 pri_tb_hi = get_tbu();
626 pri_tb_lo = get_tbl();
627 pri_tb_stamp = last_jiffy_stamp(smp_processor_id());
628 mb();
629
630 /* tell the secondary we're ready */
631 sec_tb_reset = 2;
632 mb();
633
634 /* wait for the secondary to have taken it */
635 /* note: can't use udelay here, since it needs the timebase running */
636 for (t = 10000000; t > 0 && sec_tb_reset; --t)
637 barrier();
638 if (sec_tb_reset)
639 /* XXX BUG_ON here? */
640 printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
641
642 /* Now, restart the timebase by leaving the GPIO to an open collector */
643 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);
644 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
645 local_irq_restore(flags);
646} 641}
647 642
648/* not __init, called in sleep/wakeup code */
649void smp_core99_take_timebase(void)
650{
651 unsigned long flags;
652
653 /* tell the primary we're here */
654 sec_tb_reset = 1;
655 mb();
656
657 /* wait for the primary to set pri_tb_hi/lo */
658 while (sec_tb_reset < 2)
659 mb();
660
661 /* set our stuff the same as the primary */
662 local_irq_save(flags);
663 set_dec(1);
664 set_tb(pri_tb_hi, pri_tb_lo);
665 last_jiffy_stamp(smp_processor_id()) = pri_tb_stamp;
666 mb();
667 643
668 /* tell the primary we're done */ 644#endif /* !CONFIG_PPC64 */
669 sec_tb_reset = 0;
670 mb();
671 local_irq_restore(flags);
672}
673 645
674/* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */ 646/* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */
675volatile static long int core99_l2_cache; 647volatile static long int core99_l2_cache;
@@ -677,6 +649,7 @@ volatile static long int core99_l3_cache;
677 649
678static void __devinit core99_init_caches(int cpu) 650static void __devinit core99_init_caches(int cpu)
679{ 651{
652#ifndef CONFIG_PPC64
680 if (!cpu_has_feature(CPU_FTR_L2CR)) 653 if (!cpu_has_feature(CPU_FTR_L2CR))
681 return; 654 return;
682 655
@@ -702,30 +675,76 @@ static void __devinit core99_init_caches(int cpu)
702 _set_L3CR(core99_l3_cache); 675 _set_L3CR(core99_l3_cache);
703 printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache); 676 printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache);
704 } 677 }
678#endif /* !CONFIG_PPC64 */
705} 679}
706 680
707static void __init smp_core99_setup(int ncpus) 681static void __init smp_core99_setup(int ncpus)
708{ 682{
709 struct device_node *cpu; 683#ifdef CONFIG_PPC64
710 u32 *tbprop = NULL; 684
711 int i; 685 /* i2c based HW sync on some G5s */
686 if (machine_is_compatible("PowerMac7,2") ||
687 machine_is_compatible("PowerMac7,3") ||
688 machine_is_compatible("RackMac3,1"))
689 smp_core99_setup_i2c_hwsync(ncpus);
712 690
713 core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */ 691 /* pfunc based HW sync on recent G5s */
714 cpu = of_find_node_by_type(NULL, "cpu"); 692 if (pmac_tb_freeze == NULL) {
715 if (cpu != NULL) { 693 struct device_node *cpus =
716 tbprop = (u32 *)get_property(cpu, "timebase-enable", NULL); 694 of_find_node_by_path("/cpus");
717 if (tbprop) 695 if (cpus &&
718 core99_tb_gpio = *tbprop; 696 get_property(cpus, "platform-cpu-timebase", NULL)) {
719 of_node_put(cpu); 697 pmac_tb_freeze = smp_core99_pfunc_tb_freeze;
698 printk(KERN_INFO "Processor timebase sync using"
699 " platform function\n");
700 }
720 } 701 }
721 702
722 /* XXX should get this from reg properties */ 703#else /* CONFIG_PPC64 */
723 for (i = 1; i < ncpus; ++i) 704
724 smp_hw_index[i] = i; 705 /* GPIO based HW sync on ppc32 Core99 */
725 powersave_nap = 0; 706 if (pmac_tb_freeze == NULL && !machine_is_compatible("MacRISC4")) {
726} 707 struct device_node *cpu;
708 u32 *tbprop = NULL;
709
710 core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */
711 cpu = of_find_node_by_type(NULL, "cpu");
712 if (cpu != NULL) {
713 tbprop = (u32 *)get_property(cpu, "timebase-enable",
714 NULL);
715 if (tbprop)
716 core99_tb_gpio = *tbprop;
717 of_node_put(cpu);
718 }
719 pmac_tb_freeze = smp_core99_gpio_tb_freeze;
720 printk(KERN_INFO "Processor timebase sync using"
721 " GPIO 0x%02x\n", core99_tb_gpio);
722 }
723
724#endif /* CONFIG_PPC64 */
725
726 /* No timebase sync, fallback to software */
727 if (pmac_tb_freeze == NULL) {
728 smp_ops->give_timebase = smp_generic_give_timebase;
729 smp_ops->take_timebase = smp_generic_take_timebase;
730 printk(KERN_INFO "Processor timebase sync using software\n");
731 }
732
733#ifndef CONFIG_PPC64
734 {
735 int i;
736
737 /* XXX should get this from reg properties */
738 for (i = 1; i < ncpus; ++i)
739 smp_hw_index[i] = i;
740 }
727#endif 741#endif
728 742
743 /* 32 bits SMP can't NAP */
744 if (!machine_is_compatible("MacRISC4"))
745 powersave_nap = 0;
746}
747
729static int __init smp_core99_probe(void) 748static int __init smp_core99_probe(void)
730{ 749{
731 struct device_node *cpus; 750 struct device_node *cpus;
@@ -743,8 +762,19 @@ static int __init smp_core99_probe(void)
743 if (ncpus <= 1) 762 if (ncpus <= 1)
744 return 1; 763 return 1;
745 764
765 /* We need to perform some early initialisations before we can start
766 * setting up SMP as we are running before initcalls
767 */
768 pmac_pfunc_base_install();
769 pmac_i2c_init();
770
771 /* Setup various bits like timebase sync method, ability to nap, ... */
746 smp_core99_setup(ncpus); 772 smp_core99_setup(ncpus);
773
774 /* Install IPIs */
747 mpic_request_ipis(); 775 mpic_request_ipis();
776
777 /* Collect l2cr and l3cr values from CPU 0 */
748 core99_init_caches(0); 778 core99_init_caches(0);
749 779
750 return ncpus; 780 return ncpus;
@@ -753,14 +783,15 @@ static int __init smp_core99_probe(void)
753static void __devinit smp_core99_kick_cpu(int nr) 783static void __devinit smp_core99_kick_cpu(int nr)
754{ 784{
755 unsigned int save_vector; 785 unsigned int save_vector;
756 unsigned long new_vector; 786 unsigned long target, flags;
757 unsigned long flags;
758 volatile unsigned int *vector 787 volatile unsigned int *vector
759 = ((volatile unsigned int *)(KERNELBASE+0x100)); 788 = ((volatile unsigned int *)(KERNELBASE+0x100));
760 789
761 if (nr < 0 || nr > 3) 790 if (nr < 0 || nr > 3)
762 return; 791 return;
763 if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346); 792
793 if (ppc_md.progress)
794 ppc_md.progress("smp_core99_kick_cpu", 0x346);
764 795
765 local_irq_save(flags); 796 local_irq_save(flags);
766 local_irq_disable(); 797 local_irq_disable();
@@ -768,14 +799,11 @@ static void __devinit smp_core99_kick_cpu(int nr)
768 /* Save reset vector */ 799 /* Save reset vector */
769 save_vector = *vector; 800 save_vector = *vector;
770 801
771 /* Setup fake reset vector that does 802 /* Setup fake reset vector that does
772 * b __secondary_start_pmac_0 + nr*8 - KERNELBASE 803 * b __secondary_start_pmac_0 + nr*8 - KERNELBASE
773 */ 804 */
774 new_vector = (unsigned long) __secondary_start_pmac_0 + nr * 8; 805 target = (unsigned long) __secondary_start_pmac_0 + nr * 8;
775 *vector = 0x48000002 + new_vector - KERNELBASE; 806 create_branch((unsigned long)vector, target, BRANCH_SET_LINK);
776
777 /* flush data cache and inval instruction cache */
778 flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
779 807
780 /* Put some life in our friend */ 808 /* Put some life in our friend */
781 pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0); 809 pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
@@ -805,17 +833,25 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr)
805 mpic_setup_this_cpu(); 833 mpic_setup_this_cpu();
806 834
807 if (cpu_nr == 0) { 835 if (cpu_nr == 0) {
808#ifdef CONFIG_POWER4 836#ifdef CONFIG_PPC64
809 extern void g5_phy_disable_cpu1(void); 837 extern void g5_phy_disable_cpu1(void);
810 838
839 /* Close i2c bus if it was used for tb sync */
840 if (pmac_tb_clock_chip_host) {
841 pmac_i2c_close(pmac_tb_clock_chip_host);
842 pmac_tb_clock_chip_host = NULL;
843 }
844
811 /* If we didn't start the second CPU, we must take 845 /* If we didn't start the second CPU, we must take
812 * it off the bus 846 * it off the bus
813 */ 847 */
814 if (machine_is_compatible("MacRISC4") && 848 if (machine_is_compatible("MacRISC4") &&
815 num_online_cpus() < 2) 849 num_online_cpus() < 2)
816 g5_phy_disable_cpu1(); 850 g5_phy_disable_cpu1();
817#endif /* CONFIG_POWER4 */ 851#endif /* CONFIG_PPC64 */
818 if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349); 852
853 if (ppc_md.progress)
854 ppc_md.progress("core99_setup_cpu 0 done", 0x349);
819 } 855 }
820} 856}
821 857
diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c
index feb0a94e7819..5d9afa1fa02d 100644
--- a/arch/powerpc/platforms/powermac/time.c
+++ b/arch/powerpc/platforms/powermac/time.c
@@ -258,15 +258,20 @@ int __init via_calibrate_decr(void)
258 volatile unsigned char __iomem *via; 258 volatile unsigned char __iomem *via;
259 int count = VIA_TIMER_FREQ_6 / 100; 259 int count = VIA_TIMER_FREQ_6 / 100;
260 unsigned int dstart, dend; 260 unsigned int dstart, dend;
261 struct resource rsrc;
261 262
262 vias = find_devices("via-cuda"); 263 vias = of_find_node_by_name(NULL, "via-cuda");
263 if (vias == 0) 264 if (vias == 0)
264 vias = find_devices("via-pmu"); 265 vias = of_find_node_by_name(NULL, "via-pmu");
265 if (vias == 0) 266 if (vias == 0)
266 vias = find_devices("via"); 267 vias = of_find_node_by_name(NULL, "via");
267 if (vias == 0 || vias->n_addrs == 0) 268 if (vias == 0 || of_address_to_resource(vias, 0, &rsrc))
268 return 0; 269 return 0;
269 via = ioremap(vias->addrs[0].address, vias->addrs[0].size); 270 via = ioremap(rsrc.start, rsrc.end - rsrc.start + 1);
271 if (via == NULL) {
272 printk(KERN_ERR "Failed to map VIA for timer calibration !\n");
273 return 0;
274 }
270 275
271 /* set timer 1 for continuous interrupts */ 276 /* set timer 1 for continuous interrupts */
272 out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT); 277 out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT);
diff --git a/arch/powerpc/platforms/powermac/udbg_adb.c b/arch/powerpc/platforms/powermac/udbg_adb.c
new file mode 100644
index 000000000000..06c8265c2baf
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/udbg_adb.c
@@ -0,0 +1,221 @@
1#include <linux/config.h>
2#include <linux/string.h>
3#include <linux/kernel.h>
4#include <linux/errno.h>
5#include <linux/bitops.h>
6#include <linux/ptrace.h>
7#include <linux/adb.h>
8#include <linux/pmu.h>
9#include <linux/cuda.h>
10#include <asm/machdep.h>
11#include <asm/io.h>
12#include <asm/page.h>
13#include <asm/xmon.h>
14#include <asm/prom.h>
15#include <asm/bootx.h>
16#include <asm/machdep.h>
17#include <asm/errno.h>
18#include <asm/pmac_feature.h>
19#include <asm/processor.h>
20#include <asm/delay.h>
21#include <asm/btext.h>
22#include <asm/time.h>
23#include <asm/udbg.h>
24
25/*
26 * This implementation is "special", it can "patch" the current
27 * udbg implementation and work on top of it. It must thus be
28 * initialized last
29 */
30
31static void (*udbg_adb_old_putc)(char c);
32static int (*udbg_adb_old_getc)(void);
33static int (*udbg_adb_old_getc_poll)(void);
34
35static enum {
36 input_adb_none,
37 input_adb_pmu,
38 input_adb_cuda,
39} input_type = input_adb_none;
40
41int xmon_wants_key, xmon_adb_keycode;
42
43static inline void udbg_adb_poll(void)
44{
45#ifdef CONFIG_ADB_PMU
46 if (input_type == input_adb_pmu)
47 pmu_poll_adb();
48#endif /* CONFIG_ADB_PMU */
49#ifdef CONFIG_ADB_CUDA
50 if (input_type == input_adb_cuda)
51 cuda_poll();
52#endif /* CONFIG_ADB_CUDA */
53}
54
55#ifdef CONFIG_BOOTX_TEXT
56
57static int udbg_adb_use_btext;
58static int xmon_adb_shiftstate;
59
60static unsigned char xmon_keytab[128] =
61 "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */
62 "yt123465=97-80]o" /* 0x10 - 0x1f */
63 "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */
64 "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
65 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
66 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
67
68static unsigned char xmon_shift_keytab[128] =
69 "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */
70 "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */
71 "U{IP\rLJ\"K:|<?NM>" /* 0x20 - 0x2f */
72 "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
73 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
74 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
75
76static int udbg_adb_local_getc(void)
77{
78 int k, t, on;
79
80 xmon_wants_key = 1;
81 for (;;) {
82 xmon_adb_keycode = -1;
83 t = 0;
84 on = 0;
85 k = -1;
86 do {
87 if (--t < 0) {
88 on = 1 - on;
89 btext_drawchar(on? 0xdb: 0x20);
90 btext_drawchar('\b');
91 t = 200000;
92 }
93 udbg_adb_poll();
94 if (udbg_adb_old_getc_poll)
95 k = udbg_adb_old_getc_poll();
96 } while (k == -1 && xmon_adb_keycode == -1);
97 if (on)
98 btext_drawstring(" \b");
99 if (k != -1)
100 return k;
101 k = xmon_adb_keycode;
102
103 /* test for shift keys */
104 if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
105 xmon_adb_shiftstate = (k & 0x80) == 0;
106 continue;
107 }
108 if (k >= 0x80)
109 continue; /* ignore up transitions */
110 k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
111 if (k != 0)
112 break;
113 }
114 xmon_wants_key = 0;
115 return k;
116}
117#endif /* CONFIG_BOOTX_TEXT */
118
119static int udbg_adb_getc(void)
120{
121#ifdef CONFIG_BOOTX_TEXT
122 if (udbg_adb_use_btext && input_type != input_adb_none)
123 return udbg_adb_local_getc();
124#endif
125 if (udbg_adb_old_getc)
126 return udbg_adb_old_getc();
127 return -1;
128}
129
130/* getc_poll() is not really used, unless you have the xmon-over modem
131 * hack that doesn't quite concern us here, thus we just poll the low level
132 * ADB driver to prevent it from timing out and call back the original poll
133 * routine.
134 */
135static int udbg_adb_getc_poll(void)
136{
137 udbg_adb_poll();
138
139 if (udbg_adb_old_getc_poll)
140 return udbg_adb_old_getc_poll();
141 return -1;
142}
143
144static void udbg_adb_putc(char c)
145{
146#ifdef CONFIG_BOOTX_TEXT
147 if (udbg_adb_use_btext)
148 btext_drawchar(c);
149#endif
150 if (udbg_adb_old_putc)
151 return udbg_adb_old_putc(c);
152}
153
154void udbg_adb_init_early(void)
155{
156#ifdef CONFIG_BOOTX_TEXT
157 if (btext_find_display(1) == 0) {
158 udbg_adb_use_btext = 1;
159 udbg_putc = udbg_adb_putc;
160 }
161#endif
162}
163
164int udbg_adb_init(int force_btext)
165{
166 struct device_node *np;
167
168 /* Capture existing callbacks */
169 udbg_adb_old_putc = udbg_putc;
170 udbg_adb_old_getc = udbg_getc;
171 udbg_adb_old_getc_poll = udbg_getc_poll;
172
173 /* Check if our early init was already called */
174 if (udbg_adb_old_putc == udbg_adb_putc)
175 udbg_adb_old_putc = NULL;
176#ifdef CONFIG_BOOTX_TEXT
177 if (udbg_adb_old_putc == btext_drawchar)
178 udbg_adb_old_putc = NULL;
179#endif
180
181 /* Set ours as output */
182 udbg_putc = udbg_adb_putc;
183 udbg_getc = udbg_adb_getc;
184 udbg_getc_poll = udbg_adb_getc_poll;
185
186#ifdef CONFIG_BOOTX_TEXT
187 /* Check if we should use btext output */
188 if (btext_find_display(force_btext) == 0)
189 udbg_adb_use_btext = 1;
190#endif
191
192 /* See if there is a keyboard in the device tree with a parent
193 * of type "adb". If not, we return a failure, but we keep the
194 * bext output set for now
195 */
196 for (np = NULL; (np = of_find_node_by_name(np, "keyboard")) != NULL;) {
197 struct device_node *parent = of_get_parent(np);
198 int found = (parent && strcmp(parent->type, "adb") == 0);
199 of_node_put(parent);
200 if (found)
201 break;
202 }
203 if (np == NULL)
204 return -ENODEV;
205 of_node_put(np);
206
207#ifdef CONFIG_ADB_PMU
208 if (find_via_pmu())
209 input_type = input_adb_pmu;
210#endif
211#ifdef CONFIG_ADB_CUDA
212 if (find_via_cuda())
213 input_type = input_adb_cuda;
214#endif
215
216 /* Same as above: nothing found, keep btext set for output */
217 if (input_type == input_adb_none)
218 return -ENODEV;
219
220 return 0;
221}
diff --git a/arch/powerpc/kernel/udbg_scc.c b/arch/powerpc/platforms/powermac/udbg_scc.c
index 820c53551507..e87d53acfb61 100644
--- a/arch/powerpc/kernel/udbg_scc.c
+++ b/arch/powerpc/platforms/powermac/udbg_scc.c
@@ -25,7 +25,7 @@ extern void real_writeb(u8 data, volatile u8 __iomem *addr);
25static volatile u8 __iomem *sccc; 25static volatile u8 __iomem *sccc;
26static volatile u8 __iomem *sccd; 26static volatile u8 __iomem *sccd;
27 27
28static void udbg_scc_putc(unsigned char c) 28static void udbg_scc_putc(char c)
29{ 29{
30 if (sccc) { 30 if (sccc) {
31 while ((in_8(sccc) & SCC_TXRDY) == 0) 31 while ((in_8(sccc) & SCC_TXRDY) == 0)
@@ -47,14 +47,14 @@ static int udbg_scc_getc_poll(void)
47 return -1; 47 return -1;
48} 48}
49 49
50static unsigned char udbg_scc_getc(void) 50static int udbg_scc_getc(void)
51{ 51{
52 if (sccc) { 52 if (sccc) {
53 while ((in_8(sccc) & SCC_RXRDY) == 0) 53 while ((in_8(sccc) & SCC_RXRDY) == 0)
54 ; 54 ;
55 return in_8(sccd); 55 return in_8(sccd);
56 } 56 }
57 return 0; 57 return -1;
58} 58}
59 59
60static unsigned char scc_inittab[] = { 60static unsigned char scc_inittab[] = {
@@ -67,38 +67,59 @@ static unsigned char scc_inittab[] = {
67 3, 0xc1, /* rx enable, 8 bits */ 67 3, 0xc1, /* rx enable, 8 bits */
68}; 68};
69 69
70void udbg_init_scc(struct device_node *np) 70void udbg_scc_init(int force_scc)
71{ 71{
72 u32 *reg; 72 u32 *reg;
73 unsigned long addr; 73 unsigned long addr;
74 struct device_node *stdout = NULL, *escc = NULL, *macio = NULL;
75 struct device_node *ch, *ch_def = NULL, *ch_a = NULL;
76 char *path;
74 int i, x; 77 int i, x;
75 78
76 if (np == NULL) 79 escc = of_find_node_by_name(NULL, "escc");
77 np = of_find_node_by_name(NULL, "escc"); 80 if (escc == NULL)
78 if (np == NULL || np->parent == NULL) 81 goto bail;
79 return; 82 macio = of_get_parent(escc);
83 if (macio == NULL)
84 goto bail;
85 path = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
86 if (path != NULL)
87 stdout = of_find_node_by_path(path);
88 for (ch = NULL; (ch = of_get_next_child(escc, ch)) != NULL;) {
89 if (ch == stdout)
90 ch_def = of_node_get(ch);
91 if (strcmp(ch->name, "ch-a") == 0)
92 ch_a = of_node_get(ch);
93 }
94 if (ch_def == NULL && !force_scc)
95 goto bail;
96
97 ch = ch_def ? ch_def : ch_a;
80 98
81 udbg_printf("found SCC...\n");
82 /* Get address within mac-io ASIC */ 99 /* Get address within mac-io ASIC */
83 reg = (u32 *)get_property(np, "reg", NULL); 100 reg = (u32 *)get_property(escc, "reg", NULL);
84 if (reg == NULL) 101 if (reg == NULL)
85 return; 102 goto bail;
86 addr = reg[0]; 103 addr = reg[0];
87 udbg_printf("local addr: %lx\n", addr); 104
88 /* Get address of mac-io PCI itself */ 105 /* Get address of mac-io PCI itself */
89 reg = (u32 *)get_property(np->parent, "assigned-addresses", NULL); 106 reg = (u32 *)get_property(macio, "assigned-addresses", NULL);
90 if (reg == NULL) 107 if (reg == NULL)
91 return; 108 goto bail;
92 addr += reg[2]; 109 addr += reg[2];
93 udbg_printf("final addr: %lx\n", addr); 110
111 /* Lock the serial port */
112 pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch,
113 PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
114
94 115
95 /* Setup for 57600 8N1 */ 116 /* Setup for 57600 8N1 */
96 addr += 0x20; 117 if (ch == ch_a)
118 addr += 0x20;
97 sccc = (volatile u8 * __iomem) ioremap(addr & PAGE_MASK, PAGE_SIZE) ; 119 sccc = (volatile u8 * __iomem) ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
98 sccc += addr & ~PAGE_MASK; 120 sccc += addr & ~PAGE_MASK;
99 sccd = sccc + 0x10; 121 sccd = sccc + 0x10;
100 122
101 udbg_printf("ioremap result sccc: %p\n", sccc);
102 mb(); 123 mb();
103 124
104 for (i = 20000; i != 0; --i) 125 for (i = 20000; i != 0; --i)
@@ -113,9 +134,17 @@ void udbg_init_scc(struct device_node *np)
113 udbg_getc_poll = udbg_scc_getc_poll; 134 udbg_getc_poll = udbg_scc_getc_poll;
114 135
115 udbg_puts("Hello World !\n"); 136 udbg_puts("Hello World !\n");
137
138 bail:
139 of_node_put(macio);
140 of_node_put(escc);
141 of_node_put(stdout);
142 of_node_put(ch_def);
143 of_node_put(ch_a);
116} 144}
117 145
118static void udbg_real_scc_putc(unsigned char c) 146#ifdef CONFIG_PPC64
147static void udbg_real_scc_putc(char c)
119{ 148{
120 while ((real_readb(sccc) & SCC_TXRDY) == 0) 149 while ((real_readb(sccc) & SCC_TXRDY) == 0)
121 ; 150 ;
@@ -133,3 +162,4 @@ void udbg_init_pmac_realmode(void)
133 udbg_getc = NULL; 162 udbg_getc = NULL;
134 udbg_getc_poll = NULL; 163 udbg_getc_poll = NULL;
135} 164}
165#endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 06d5ef501218..6accdd155505 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -1,5 +1,5 @@
1obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ 1obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \
2 setup.o iommu.o ras.o rtasd.o 2 setup.o iommu.o ras.o rtasd.o pci_dlpar.o
3obj-$(CONFIG_SMP) += smp.o 3obj-$(CONFIG_SMP) += smp.o
4obj-$(CONFIG_IBMVIO) += vio.o 4obj-$(CONFIG_IBMVIO) += vio.o
5obj-$(CONFIG_XICS) += xics.o 5obj-$(CONFIG_XICS) += xics.o
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index c8d2a40dc5b4..7fbfd16d72b7 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -1093,6 +1093,15 @@ void eeh_add_device_early(struct device_node *dn)
1093} 1093}
1094EXPORT_SYMBOL_GPL(eeh_add_device_early); 1094EXPORT_SYMBOL_GPL(eeh_add_device_early);
1095 1095
1096void eeh_add_device_tree_early(struct device_node *dn)
1097{
1098 struct device_node *sib;
1099 for (sib = dn->child; sib; sib = sib->sibling)
1100 eeh_add_device_tree_early(sib);
1101 eeh_add_device_early(dn);
1102}
1103EXPORT_SYMBOL_GPL(eeh_add_device_tree_early);
1104
1096/** 1105/**
1097 * eeh_add_device_late - perform EEH initialization for the indicated pci device 1106 * eeh_add_device_late - perform EEH initialization for the indicated pci device
1098 * @dev: pci device for which to set up EEH 1107 * @dev: pci device for which to set up EEH
@@ -1147,6 +1156,23 @@ void eeh_remove_device(struct pci_dev *dev)
1147} 1156}
1148EXPORT_SYMBOL_GPL(eeh_remove_device); 1157EXPORT_SYMBOL_GPL(eeh_remove_device);
1149 1158
1159void eeh_remove_bus_device(struct pci_dev *dev)
1160{
1161 eeh_remove_device(dev);
1162 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
1163 struct pci_bus *bus = dev->subordinate;
1164 struct list_head *ln;
1165 if (!bus)
1166 return;
1167 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
1168 struct pci_dev *pdev = pci_dev_b(ln);
1169 if (pdev)
1170 eeh_remove_bus_device(pdev);
1171 }
1172 }
1173}
1174EXPORT_SYMBOL_GPL(eeh_remove_bus_device);
1175
1150static int proc_eeh_show(struct seq_file *m, void *v) 1176static int proc_eeh_show(struct seq_file *m, void *v)
1151{ 1177{
1152 unsigned int cpu; 1178 unsigned int cpu;
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 2043659ea7b1..169f9148789c 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -436,7 +436,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
436 return; 436 return;
437 } 437 }
438 438
439 ppci = pdn->data; 439 ppci = PCI_DN(pdn);
440 if (!ppci->iommu_table) { 440 if (!ppci->iommu_table) {
441 /* Bussubno hasn't been copied yet. 441 /* Bussubno hasn't been copied yet.
442 * Do it now because iommu_table_setparms_lpar needs it. 442 * Do it now because iommu_table_setparms_lpar needs it.
@@ -483,10 +483,10 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev)
483 * an already allocated iommu table is found and use that. 483 * an already allocated iommu table is found and use that.
484 */ 484 */
485 485
486 while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL) 486 while (dn && PCI_DN(dn) && PCI_DN(dn)->iommu_table == NULL)
487 dn = dn->parent; 487 dn = dn->parent;
488 488
489 if (dn && dn->data) { 489 if (dn && PCI_DN(dn)) {
490 PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table; 490 PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table;
491 } else { 491 } else {
492 DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev)); 492 DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev));
@@ -497,7 +497,7 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
497{ 497{
498 int err = NOTIFY_OK; 498 int err = NOTIFY_OK;
499 struct device_node *np = node; 499 struct device_node *np = node;
500 struct pci_dn *pci = np->data; 500 struct pci_dn *pci = PCI_DN(np);
501 501
502 switch (action) { 502 switch (action) {
503 case PSERIES_RECONFIG_REMOVE: 503 case PSERIES_RECONFIG_REMOVE:
@@ -533,7 +533,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
533 */ 533 */
534 dn = pci_device_to_OF_node(dev); 534 dn = pci_device_to_OF_node(dev);
535 535
536 for (pdn = dn; pdn && pdn->data && !PCI_DN(pdn)->iommu_table; 536 for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
537 pdn = pdn->parent) { 537 pdn = pdn->parent) {
538 dma_window = (unsigned int *) 538 dma_window = (unsigned int *)
539 get_property(pdn, "ibm,dma-window", NULL); 539 get_property(pdn, "ibm,dma-window", NULL);
@@ -552,7 +552,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
552 DBG("Found DMA window, allocating table\n"); 552 DBG("Found DMA window, allocating table\n");
553 } 553 }
554 554
555 pci = pdn->data; 555 pci = PCI_DN(pdn);
556 if (!pci->iommu_table) { 556 if (!pci->iommu_table) {
557 /* iommu_table_setparms_lpar needs bussubno. */ 557 /* iommu_table_setparms_lpar needs bussubno. */
558 pci->bussubno = pci->phb->bus->number; 558 pci->bussubno = pci->phb->bus->number;
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index cf1bc11b3346..1fe445ab78a6 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -24,6 +24,7 @@
24#include <linux/config.h> 24#include <linux/config.h>
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/dma-mapping.h> 26#include <linux/dma-mapping.h>
27#include <linux/console.h>
27#include <asm/processor.h> 28#include <asm/processor.h>
28#include <asm/mmu.h> 29#include <asm/mmu.h>
29#include <asm/page.h> 30#include <asm/page.h>
@@ -60,7 +61,7 @@ extern void pSeries_find_serial_port(void);
60int vtermno; /* virtual terminal# for udbg */ 61int vtermno; /* virtual terminal# for udbg */
61 62
62#define __ALIGNED__ __attribute__((__aligned__(sizeof(long)))) 63#define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
63static void udbg_hvsi_putc(unsigned char c) 64static void udbg_hvsi_putc(char c)
64{ 65{
65 /* packet's seqno isn't used anyways */ 66 /* packet's seqno isn't used anyways */
66 uint8_t packet[] __ALIGNED__ = { 0xff, 5, 0, 0, c }; 67 uint8_t packet[] __ALIGNED__ = { 0xff, 5, 0, 0, c };
@@ -111,7 +112,7 @@ static int udbg_hvsi_getc_poll(void)
111 return ch; 112 return ch;
112} 113}
113 114
114static unsigned char udbg_hvsi_getc(void) 115static int udbg_hvsi_getc(void)
115{ 116{
116 int ch; 117 int ch;
117 for (;;) { 118 for (;;) {
@@ -127,7 +128,7 @@ static unsigned char udbg_hvsi_getc(void)
127 } 128 }
128} 129}
129 130
130static void udbg_putcLP(unsigned char c) 131static void udbg_putcLP(char c)
131{ 132{
132 char buf[16]; 133 char buf[16];
133 unsigned long rc; 134 unsigned long rc;
@@ -172,7 +173,7 @@ static int udbg_getc_pollLP(void)
172 return ch; 173 return ch;
173} 174}
174 175
175static unsigned char udbg_getcLP(void) 176static int udbg_getcLP(void)
176{ 177{
177 int ch; 178 int ch;
178 for (;;) { 179 for (;;) {
@@ -191,7 +192,7 @@ static unsigned char udbg_getcLP(void)
191/* call this from early_init() for a working debug console on 192/* call this from early_init() for a working debug console on
192 * vterm capable LPAR machines 193 * vterm capable LPAR machines
193 */ 194 */
194void udbg_init_debug_lpar(void) 195void __init udbg_init_debug_lpar(void)
195{ 196{
196 vtermno = 0; 197 vtermno = 0;
197 udbg_putc = udbg_putcLP; 198 udbg_putc = udbg_putcLP;
@@ -200,63 +201,54 @@ void udbg_init_debug_lpar(void)
200} 201}
201 202
202/* returns 0 if couldn't find or use /chosen/stdout as console */ 203/* returns 0 if couldn't find or use /chosen/stdout as console */
203int find_udbg_vterm(void) 204void __init find_udbg_vterm(void)
204{ 205{
205 struct device_node *stdout_node; 206 struct device_node *stdout_node;
206 u32 *termno; 207 u32 *termno;
207 char *name; 208 char *name;
208 int found = 0; 209 int add_console;
209 210
210 /* find the boot console from /chosen/stdout */ 211 /* find the boot console from /chosen/stdout */
211 if (!of_chosen) 212 if (!of_chosen)
212 return 0; 213 return;
213 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 214 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
214 if (name == NULL) 215 if (name == NULL)
215 return 0; 216 return;
216 stdout_node = of_find_node_by_path(name); 217 stdout_node = of_find_node_by_path(name);
217 if (!stdout_node) 218 if (!stdout_node)
218 return 0; 219 return;
219
220 /* now we have the stdout node; figure out what type of device it is. */
221 name = (char *)get_property(stdout_node, "name", NULL); 220 name = (char *)get_property(stdout_node, "name", NULL);
222 if (!name) { 221 if (!name) {
223 printk(KERN_WARNING "stdout node missing 'name' property!\n"); 222 printk(KERN_WARNING "stdout node missing 'name' property!\n");
224 goto out; 223 goto out;
225 } 224 }
225 /* The user has requested a console so this is already set up. */
226 add_console = !strstr(cmd_line, "console=");
226 227
227 if (strncmp(name, "vty", 3) == 0) { 228 /* Check if it's a virtual terminal */
228 if (device_is_compatible(stdout_node, "hvterm1")) { 229 if (strncmp(name, "vty", 3) != 0)
229 termno = (u32 *)get_property(stdout_node, "reg", NULL); 230 goto out;
230 if (termno) { 231 termno = (u32 *)get_property(stdout_node, "reg", NULL);
231 vtermno = termno[0]; 232 if (termno == NULL)
232 udbg_putc = udbg_putcLP; 233 goto out;
233 udbg_getc = udbg_getcLP; 234 vtermno = termno[0];
234 udbg_getc_poll = udbg_getc_pollLP; 235
235 found = 1; 236 if (device_is_compatible(stdout_node, "hvterm1")) {
236 } 237 udbg_putc = udbg_putcLP;
237 } else if (device_is_compatible(stdout_node, "hvterm-protocol")) { 238 udbg_getc = udbg_getcLP;
238 termno = (u32 *)get_property(stdout_node, "reg", NULL); 239 udbg_getc_poll = udbg_getc_pollLP;
239 if (termno) { 240 if (add_console)
240 vtermno = termno[0]; 241 add_preferred_console("hvc", termno[0] & 0xff, NULL);
241 udbg_putc = udbg_hvsi_putc; 242 } else if (device_is_compatible(stdout_node, "hvterm-protocol")) {
242 udbg_getc = udbg_hvsi_getc; 243 vtermno = termno[0];
243 udbg_getc_poll = udbg_hvsi_getc_poll; 244 udbg_putc = udbg_hvsi_putc;
244 found = 1; 245 udbg_getc = udbg_hvsi_getc;
245 } 246 udbg_getc_poll = udbg_hvsi_getc_poll;
246 } 247 if (add_console)
247 } else if (strncmp(name, "serial", 6)) { 248 add_preferred_console("hvsi", termno[0] & 0xff, NULL);
248 /* XXX fix ISA serial console */
249 printk(KERN_WARNING "serial stdout on LPAR ('%s')! "
250 "can't print udbg messages\n",
251 stdout_node->full_name);
252 } else {
253 printk(KERN_WARNING "don't know how to print to stdout '%s'\n",
254 stdout_node->full_name);
255 } 249 }
256
257out: 250out:
258 of_node_put(stdout_node); 251 of_node_put(stdout_node);
259 return found;
260} 252}
261 253
262void vpa_init(int cpu) 254void vpa_init(int cpu)
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
new file mode 100644
index 000000000000..21934784f936
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -0,0 +1,174 @@
1/*
2 * PCI Dynamic LPAR, PCI Hot Plug and PCI EEH recovery code
3 * for RPA-compliant PPC64 platform.
4 * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
5 * Copyright (C) 2005 International Business Machines
6 *
7 * Updates, 2005, John Rose <johnrose@austin.ibm.com>
8 * Updates, 2005, Linas Vepstas <linas@austin.ibm.com>
9 *
10 * All rights reserved.
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 as published by
14 * the Free Software Foundation; either version 2 of the License, or (at
15 * your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
20 * NON INFRINGEMENT. See the GNU General Public License for more
21 * details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#include <linux/pci.h>
29#include <asm/pci-bridge.h>
30
31static struct pci_bus *
32find_bus_among_children(struct pci_bus *bus,
33 struct device_node *dn)
34{
35 struct pci_bus *child = NULL;
36 struct list_head *tmp;
37 struct device_node *busdn;
38
39 busdn = pci_bus_to_OF_node(bus);
40 if (busdn == dn)
41 return bus;
42
43 list_for_each(tmp, &bus->children) {
44 child = find_bus_among_children(pci_bus_b(tmp), dn);
45 if (child)
46 break;
47 };
48 return child;
49}
50
51struct pci_bus *
52pcibios_find_pci_bus(struct device_node *dn)
53{
54 struct pci_dn *pdn = dn->data;
55
56 if (!pdn || !pdn->phb || !pdn->phb->bus)
57 return NULL;
58
59 return find_bus_among_children(pdn->phb->bus, dn);
60}
61
62/**
63 * pcibios_remove_pci_devices - remove all devices under this bus
64 *
65 * Remove all of the PCI devices under this bus both from the
66 * linux pci device tree, and from the powerpc EEH address cache.
67 */
68void
69pcibios_remove_pci_devices(struct pci_bus *bus)
70{
71 struct pci_dev *dev, *tmp;
72
73 list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
74 eeh_remove_bus_device(dev);
75 pci_remove_bus_device(dev);
76 }
77}
78
79/* Must be called before pci_bus_add_devices */
80void
81pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
82{
83 struct pci_dev *dev;
84
85 list_for_each_entry(dev, &bus->devices, bus_list) {
86 /*
87 * Skip already-present devices (which are on the
88 * global device list.)
89 */
90 if (list_empty(&dev->global_list)) {
91 int i;
92
93 /* Need to setup IOMMU tables */
94 ppc_md.iommu_dev_setup(dev);
95
96 if(fix_bus)
97 pcibios_fixup_device_resources(dev, bus);
98 pci_read_irq_line(dev);
99 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
100 struct resource *r = &dev->resource[i];
101
102 if (r->parent || !r->start || !r->flags)
103 continue;
104 pci_claim_resource(dev, i);
105 }
106 }
107 }
108}
109
110static int
111pcibios_pci_config_bridge(struct pci_dev *dev)
112{
113 u8 sec_busno;
114 struct pci_bus *child_bus;
115 struct pci_dev *child_dev;
116
117 /* Get busno of downstream bus */
118 pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno);
119
120 /* Add to children of PCI bridge dev->bus */
121 child_bus = pci_add_new_bus(dev->bus, dev, sec_busno);
122 if (!child_bus) {
123 printk (KERN_ERR "%s: could not add second bus\n", __FUNCTION__);
124 return -EIO;
125 }
126 sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number);
127
128 pci_scan_child_bus(child_bus);
129
130 list_for_each_entry(child_dev, &child_bus->devices, bus_list) {
131 eeh_add_device_late(child_dev);
132 }
133
134 /* Fixup new pci devices without touching bus struct */
135 pcibios_fixup_new_pci_devices(child_bus, 0);
136
137 /* Make the discovered devices available */
138 pci_bus_add_devices(child_bus);
139 return 0;
140}
141
142/**
143 * pcibios_add_pci_devices - adds new pci devices to bus
144 *
145 * This routine will find and fixup new pci devices under
146 * the indicated bus. This routine presumes that there
147 * might already be some devices under this bridge, so
148 * it carefully tries to add only new devices. (And that
149 * is how this routine differs from other, similar pcibios
150 * routines.)
151 */
152void
153pcibios_add_pci_devices(struct pci_bus * bus)
154{
155 int slotno, num;
156 struct pci_dev *dev;
157 struct device_node *dn = pci_bus_to_OF_node(bus);
158
159 eeh_add_device_tree_early(dn);
160
161 /* pci_scan_slot should find all children */
162 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
163 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
164 if (num) {
165 pcibios_fixup_new_pci_devices(bus, 1);
166 pci_bus_add_devices(bus);
167 }
168
169 list_for_each_entry(dev, &bus->devices, bus_list) {
170 eeh_add_device_late (dev);
171 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
172 pcibios_pci_config_bridge(dev);
173 }
174}
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index fbd214d68b07..b046bcf7443d 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -49,14 +49,14 @@
49#include <asm/machdep.h> 49#include <asm/machdep.h>
50#include <asm/rtas.h> 50#include <asm/rtas.h>
51#include <asm/udbg.h> 51#include <asm/udbg.h>
52#include <asm/firmware.h>
53
54#include "ras.h"
52 55
53static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX]; 56static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX];
54static DEFINE_SPINLOCK(ras_log_buf_lock); 57static DEFINE_SPINLOCK(ras_log_buf_lock);
55 58
56char mce_data_buf[RTAS_ERROR_LOG_MAX] 59char mce_data_buf[RTAS_ERROR_LOG_MAX];
57;
58/* This is true if we are using the firmware NMI handler (typically LPAR) */
59extern int fwnmi_active;
60 60
61static int ras_get_sensor_state_token; 61static int ras_get_sensor_state_token;
62static int ras_check_exception_token; 62static int ras_check_exception_token;
@@ -280,7 +280,7 @@ static void fwnmi_release_errinfo(void)
280 printk("FWNMI: nmi-interlock failed: %d\n", ret); 280 printk("FWNMI: nmi-interlock failed: %d\n", ret);
281} 281}
282 282
283void pSeries_system_reset_exception(struct pt_regs *regs) 283int pSeries_system_reset_exception(struct pt_regs *regs)
284{ 284{
285 if (fwnmi_active) { 285 if (fwnmi_active) {
286 struct rtas_error_log *errhdr = fwnmi_get_errinfo(regs); 286 struct rtas_error_log *errhdr = fwnmi_get_errinfo(regs);
@@ -289,6 +289,7 @@ void pSeries_system_reset_exception(struct pt_regs *regs)
289 } 289 }
290 fwnmi_release_errinfo(); 290 fwnmi_release_errinfo();
291 } 291 }
292 return 0; /* need to perform reset */
292} 293}
293 294
294/* 295/*
diff --git a/arch/powerpc/platforms/pseries/ras.h b/arch/powerpc/platforms/pseries/ras.h
new file mode 100644
index 000000000000..0e66b0da55e2
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/ras.h
@@ -0,0 +1,9 @@
1#ifndef _PSERIES_RAS_H
2#define _PSERIES_RAS_H
3
4struct pt_regs;
5
6extern int pSeries_system_reset_exception(struct pt_regs *regs);
7extern int pSeries_machine_check_exception(struct pt_regs *regs);
8
9#endif /* _PSERIES_RAS_H */
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 4a465f067ede..8903cf63236a 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -56,6 +56,7 @@
56#include <asm/dma.h> 56#include <asm/dma.h>
57#include <asm/machdep.h> 57#include <asm/machdep.h>
58#include <asm/irq.h> 58#include <asm/irq.h>
59#include <asm/kexec.h>
59#include <asm/time.h> 60#include <asm/time.h>
60#include <asm/nvram.h> 61#include <asm/nvram.h>
61#include "xics.h" 62#include "xics.h"
@@ -68,6 +69,7 @@
68#include <asm/smp.h> 69#include <asm/smp.h>
69 70
70#include "plpar_wrappers.h" 71#include "plpar_wrappers.h"
72#include "ras.h"
71 73
72#ifdef DEBUG 74#ifdef DEBUG
73#define DBG(fmt...) udbg_printf(fmt) 75#define DBG(fmt...) udbg_printf(fmt)
@@ -76,16 +78,9 @@
76#endif 78#endif
77 79
78extern void find_udbg_vterm(void); 80extern void find_udbg_vterm(void);
79extern void system_reset_fwnmi(void); /* from head.S */
80extern void machine_check_fwnmi(void); /* from head.S */
81extern void generic_find_legacy_serial_ports(u64 *physport,
82 unsigned int *default_speed);
83 81
84int fwnmi_active; /* TRUE if an FWNMI handler is present */ 82int fwnmi_active; /* TRUE if an FWNMI handler is present */
85 83
86extern void pSeries_system_reset_exception(struct pt_regs *regs);
87extern int pSeries_machine_check_exception(struct pt_regs *regs);
88
89static void pseries_shared_idle(void); 84static void pseries_shared_idle(void);
90static void pseries_dedicated_idle(void); 85static void pseries_dedicated_idle(void);
91 86
@@ -105,18 +100,22 @@ void pSeries_show_cpuinfo(struct seq_file *m)
105 100
106/* Initialize firmware assisted non-maskable interrupts if 101/* Initialize firmware assisted non-maskable interrupts if
107 * the firmware supports this feature. 102 * the firmware supports this feature.
108 *
109 */ 103 */
110static void __init fwnmi_init(void) 104static void __init fwnmi_init(void)
111{ 105{
112 int ret; 106 unsigned long system_reset_addr, machine_check_addr;
107
113 int ibm_nmi_register = rtas_token("ibm,nmi-register"); 108 int ibm_nmi_register = rtas_token("ibm,nmi-register");
114 if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE) 109 if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE)
115 return; 110 return;
116 ret = rtas_call(ibm_nmi_register, 2, 1, NULL, 111
117 __pa((unsigned long)system_reset_fwnmi), 112 /* If the kernel's not linked at zero we point the firmware at low
118 __pa((unsigned long)machine_check_fwnmi)); 113 * addresses anyway, and use a trampoline to get to the real code. */
119 if (ret == 0) 114 system_reset_addr = __pa(system_reset_fwnmi) - PHYSICAL_START;
115 machine_check_addr = __pa(machine_check_fwnmi) - PHYSICAL_START;
116
117 if (0 == rtas_call(ibm_nmi_register, 2, 1, NULL, system_reset_addr,
118 machine_check_addr))
120 fwnmi_active = 1; 119 fwnmi_active = 1;
121} 120}
122 121
@@ -323,15 +322,18 @@ static void __init pSeries_discover_pic(void)
323 ppc64_interrupt_controller = IC_INVALID; 322 ppc64_interrupt_controller = IC_INVALID;
324 for (np = NULL; (np = of_find_node_by_name(np, "interrupt-controller"));) { 323 for (np = NULL; (np = of_find_node_by_name(np, "interrupt-controller"));) {
325 typep = (char *)get_property(np, "compatible", NULL); 324 typep = (char *)get_property(np, "compatible", NULL);
326 if (strstr(typep, "open-pic")) 325 if (strstr(typep, "open-pic")) {
327 ppc64_interrupt_controller = IC_OPEN_PIC; 326 ppc64_interrupt_controller = IC_OPEN_PIC;
328 else if (strstr(typep, "ppc-xicp")) 327 break;
328 } else if (strstr(typep, "ppc-xicp")) {
329 ppc64_interrupt_controller = IC_PPC_XIC; 329 ppc64_interrupt_controller = IC_PPC_XIC;
330 else 330 break;
331 printk("pSeries_discover_pic: failed to recognize" 331 }
332 " interrupt-controller\n");
333 break;
334 } 332 }
333 if (ppc64_interrupt_controller == IC_INVALID)
334 printk("pSeries_discover_pic: failed to recognize"
335 " interrupt-controller\n");
336
335} 337}
336 338
337static void pSeries_mach_cpu_die(void) 339static void pSeries_mach_cpu_die(void)
@@ -365,10 +367,7 @@ static int pseries_set_xdabr(unsigned long dabr)
365 */ 367 */
366static void __init pSeries_init_early(void) 368static void __init pSeries_init_early(void)
367{ 369{
368 void *comport;
369 int iommu_off = 0; 370 int iommu_off = 0;
370 unsigned int default_speed;
371 u64 physport;
372 371
373 DBG(" -> pSeries_init_early()\n"); 372 DBG(" -> pSeries_init_early()\n");
374 373
@@ -382,17 +381,8 @@ static void __init pSeries_init_early(void)
382 get_property(of_chosen, "linux,iommu-off", NULL)); 381 get_property(of_chosen, "linux,iommu-off", NULL));
383 } 382 }
384 383
385 generic_find_legacy_serial_ports(&physport, &default_speed);
386
387 if (platform_is_lpar()) 384 if (platform_is_lpar())
388 find_udbg_vterm(); 385 find_udbg_vterm();
389 else if (physport) {
390 /* Map the uart for udbg. */
391 comport = (void *)ioremap(physport, 16);
392 udbg_init_uart(comport, default_speed);
393
394 DBG("Hello World !\n");
395 }
396 386
397 if (firmware_has_feature(FW_FEATURE_DABR)) 387 if (firmware_has_feature(FW_FEATURE_DABR))
398 ppc_md.set_dabr = pseries_set_dabr; 388 ppc_md.set_dabr = pseries_set_dabr;
@@ -638,5 +628,8 @@ struct machdep_calls __initdata pSeries_md = {
638 .machine_check_exception = pSeries_machine_check_exception, 628 .machine_check_exception = pSeries_machine_check_exception,
639#ifdef CONFIG_KEXEC 629#ifdef CONFIG_KEXEC
640 .kexec_cpu_down = pseries_kexec_cpu_down, 630 .kexec_cpu_down = pseries_kexec_cpu_down,
631 .machine_kexec = default_machine_kexec,
632 .machine_kexec_prepare = default_machine_kexec_prepare,
633 .machine_crash_shutdown = default_machine_crash_shutdown,
641#endif 634#endif
642}; 635};
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 0377decc0719..0c0cfa32eb58 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -407,7 +407,7 @@ irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
407 smp_message_recv(PPC_MSG_MIGRATE_TASK, regs); 407 smp_message_recv(PPC_MSG_MIGRATE_TASK, regs);
408 } 408 }
409#endif 409#endif
410#ifdef CONFIG_DEBUGGER 410#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
411 if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, 411 if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
412 &xics_ipi_message[cpu].value)) { 412 &xics_ipi_message[cpu].value)) {
413 mb(); 413 mb();
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 6b7efcfc352a..14b9abde2d27 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -4,5 +4,6 @@ obj-$(CONFIG_PPC_I8259) += i8259.o
4obj-$(CONFIG_PPC_MPC106) += grackle.o 4obj-$(CONFIG_PPC_MPC106) += grackle.o
5obj-$(CONFIG_BOOKE) += dcr.o 5obj-$(CONFIG_BOOKE) += dcr.o
6obj-$(CONFIG_40x) += dcr.o 6obj-$(CONFIG_40x) += dcr.o
7obj-$(CONFIG_U3_DART) += u3_iommu.o 7obj-$(CONFIG_U3_DART) += dart_iommu.o
8obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o 8obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
9obj-$(CONFIG_83xx) += ipic.o
diff --git a/arch/powerpc/sysdev/dart.h b/arch/powerpc/sysdev/dart.h
index 33ed9ed7fc1e..c2d05763ccbe 100644
--- a/arch/powerpc/sysdev/dart.h
+++ b/arch/powerpc/sysdev/dart.h
@@ -20,29 +20,44 @@
20#define _POWERPC_SYSDEV_DART_H 20#define _POWERPC_SYSDEV_DART_H
21 21
22 22
23/* physical base of DART registers */
24#define DART_BASE 0xf8033000UL
25
26/* Offset from base to control register */ 23/* Offset from base to control register */
27#define DARTCNTL 0 24#define DART_CNTL 0
25
28/* Offset from base to exception register */ 26/* Offset from base to exception register */
29#define DARTEXCP 0x10 27#define DART_EXCP_U3 0x10
30/* Offset from base to TLB tag registers */ 28/* Offset from base to TLB tag registers */
31#define DARTTAG 0x1000 29#define DART_TAGS_U3 0x1000
32 30
31/* U4 registers */
32#define DART_BASE_U4 0x10
33#define DART_SIZE_U4 0x20
34#define DART_EXCP_U4 0x30
35#define DART_TAGS_U4 0x1000
33 36
34/* Control Register fields */ 37/* Control Register fields */
35 38
36/* base address of table (pfn) */ 39/* U3 registers */
37#define DARTCNTL_BASE_MASK 0xfffff 40#define DART_CNTL_U3_BASE_MASK 0xfffff
38#define DARTCNTL_BASE_SHIFT 12 41#define DART_CNTL_U3_BASE_SHIFT 12
42#define DART_CNTL_U3_FLUSHTLB 0x400
43#define DART_CNTL_U3_ENABLE 0x200
44#define DART_CNTL_U3_SIZE_MASK 0x1ff
45#define DART_CNTL_U3_SIZE_SHIFT 0
46
47/* U4 registers */
48#define DART_BASE_U4_BASE_MASK 0xffffff
49#define DART_BASE_U4_BASE_SHIFT 0
50#define DART_CNTL_U4_FLUSHTLB 0x20000000
51#define DART_CNTL_U4_ENABLE 0x80000000
52#define DART_SIZE_U4_SIZE_MASK 0x1fff
53#define DART_SIZE_U4_SIZE_SHIFT 0
54
55#define DART_REG(r) (dart + ((r) >> 2))
56#define DART_IN(r) (in_be32(DART_REG(r)))
57#define DART_OUT(r,v) (out_be32(DART_REG(r), (v)))
39 58
40#define DARTCNTL_FLUSHTLB 0x400
41#define DARTCNTL_ENABLE 0x200
42 59
43/* size of table in pages */ 60/* size of table in pages */
44#define DARTCNTL_SIZE_MASK 0x1ff
45#define DARTCNTL_SIZE_SHIFT 0
46 61
47 62
48/* DART table fields */ 63/* DART table fields */
diff --git a/arch/powerpc/sysdev/u3_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 5c1a26a6d00c..e00b46b9514e 100644
--- a/arch/powerpc/sysdev/u3_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -1,25 +1,27 @@
1/* 1/*
2 * arch/powerpc/sysdev/u3_iommu.c 2 * arch/powerpc/sysdev/dart_iommu.c
3 * 3 *
4 * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation 4 * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
5 * Copyright (C) 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>,
6 * IBM Corporation
5 * 7 *
6 * Based on pSeries_iommu.c: 8 * Based on pSeries_iommu.c:
7 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation 9 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
8 * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation 10 * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
9 * 11 *
10 * Dynamic DMA mapping support, Apple U3 & IBM CPC925 "DART" iommu. 12 * Dynamic DMA mapping support, Apple U3, U4 & IBM CPC925 "DART" iommu.
13 *
11 * 14 *
12 *
13 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by 16 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or 17 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version. 18 * (at your option) any later version.
17 * 19 *
18 * This program is distributed in the hope that it will be useful, 20 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details. 23 * GNU General Public License for more details.
22 * 24 *
23 * You should have received a copy of the GNU General Public License 25 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software 26 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -57,21 +59,22 @@ static unsigned long dart_tablesize;
57static u32 *dart_vbase; 59static u32 *dart_vbase;
58 60
59/* Mapped base address for the dart */ 61/* Mapped base address for the dart */
60static unsigned int *dart; 62static unsigned int *__iomem dart;
61 63
62/* Dummy val that entries are set to when unused */ 64/* Dummy val that entries are set to when unused */
63static unsigned int dart_emptyval; 65static unsigned int dart_emptyval;
64 66
65static struct iommu_table iommu_table_u3; 67static struct iommu_table iommu_table_dart;
66static int iommu_table_u3_inited; 68static int iommu_table_dart_inited;
67static int dart_dirty; 69static int dart_dirty;
70static int dart_is_u4;
68 71
69#define DBG(...) 72#define DBG(...)
70 73
71static inline void dart_tlb_invalidate_all(void) 74static inline void dart_tlb_invalidate_all(void)
72{ 75{
73 unsigned long l = 0; 76 unsigned long l = 0;
74 unsigned int reg; 77 unsigned int reg, inv_bit;
75 unsigned long limit; 78 unsigned long limit;
76 79
77 DBG("dart: flush\n"); 80 DBG("dart: flush\n");
@@ -81,29 +84,28 @@ static inline void dart_tlb_invalidate_all(void)
81 * 84 *
82 * Gotcha: Sometimes, the DART won't detect that the bit gets 85 * Gotcha: Sometimes, the DART won't detect that the bit gets
83 * set. If so, clear it and set it again. 86 * set. If so, clear it and set it again.
84 */ 87 */
85 88
86 limit = 0; 89 limit = 0;
87 90
91 inv_bit = dart_is_u4 ? DART_CNTL_U4_FLUSHTLB : DART_CNTL_U3_FLUSHTLB;
88retry: 92retry:
89 reg = in_be32((unsigned int *)dart+DARTCNTL);
90 reg |= DARTCNTL_FLUSHTLB;
91 out_be32((unsigned int *)dart+DARTCNTL, reg);
92
93 l = 0; 93 l = 0;
94 while ((in_be32((unsigned int *)dart+DARTCNTL) & DARTCNTL_FLUSHTLB) && 94 reg = DART_IN(DART_CNTL);
95 l < (1L<<limit)) { 95 reg |= inv_bit;
96 DART_OUT(DART_CNTL, reg);
97
98 while ((DART_IN(DART_CNTL) & inv_bit) && l < (1L << limit))
96 l++; 99 l++;
97 } 100 if (l == (1L << limit)) {
98 if (l == (1L<<limit)) {
99 if (limit < 4) { 101 if (limit < 4) {
100 limit++; 102 limit++;
101 reg = in_be32((unsigned int *)dart+DARTCNTL); 103 reg = DART_IN(DART_CNTL);
102 reg &= ~DARTCNTL_FLUSHTLB; 104 reg &= ~inv_bit;
103 out_be32((unsigned int *)dart+DARTCNTL, reg); 105 DART_OUT(DART_CNTL, reg);
104 goto retry; 106 goto retry;
105 } else 107 } else
106 panic("U3-DART: TLB did not flush after waiting a long " 108 panic("DART: TLB did not flush after waiting a long "
107 "time. Buggy U3 ?"); 109 "time. Buggy U3 ?");
108 } 110 }
109} 111}
@@ -115,7 +117,7 @@ static void dart_flush(struct iommu_table *tbl)
115 dart_dirty = 0; 117 dart_dirty = 0;
116} 118}
117 119
118static void dart_build(struct iommu_table *tbl, long index, 120static void dart_build(struct iommu_table *tbl, long index,
119 long npages, unsigned long uaddr, 121 long npages, unsigned long uaddr,
120 enum dma_data_direction direction) 122 enum dma_data_direction direction)
121{ 123{
@@ -128,7 +130,7 @@ static void dart_build(struct iommu_table *tbl, long index,
128 npages <<= DART_PAGE_FACTOR; 130 npages <<= DART_PAGE_FACTOR;
129 131
130 dp = ((unsigned int*)tbl->it_base) + index; 132 dp = ((unsigned int*)tbl->it_base) + index;
131 133
132 /* On U3, all memory is contigous, so we can move this 134 /* On U3, all memory is contigous, so we can move this
133 * out of the loop. 135 * out of the loop.
134 */ 136 */
@@ -148,7 +150,7 @@ static void dart_build(struct iommu_table *tbl, long index,
148static void dart_free(struct iommu_table *tbl, long index, long npages) 150static void dart_free(struct iommu_table *tbl, long index, long npages)
149{ 151{
150 unsigned int *dp; 152 unsigned int *dp;
151 153
152 /* We don't worry about flushing the TLB cache. The only drawback of 154 /* We don't worry about flushing the TLB cache. The only drawback of
153 * not doing it is that we won't catch buggy device drivers doing 155 * not doing it is that we won't catch buggy device drivers doing
154 * bad DMAs, but then no 32-bit architecture ever does either. 156 * bad DMAs, but then no 32-bit architecture ever does either.
@@ -160,7 +162,7 @@ static void dart_free(struct iommu_table *tbl, long index, long npages)
160 npages <<= DART_PAGE_FACTOR; 162 npages <<= DART_PAGE_FACTOR;
161 163
162 dp = ((unsigned int *)tbl->it_base) + index; 164 dp = ((unsigned int *)tbl->it_base) + index;
163 165
164 while (npages--) 166 while (npages--)
165 *(dp++) = dart_emptyval; 167 *(dp++) = dart_emptyval;
166} 168}
@@ -168,20 +170,25 @@ static void dart_free(struct iommu_table *tbl, long index, long npages)
168 170
169static int dart_init(struct device_node *dart_node) 171static int dart_init(struct device_node *dart_node)
170{ 172{
171 unsigned int regword;
172 unsigned int i; 173 unsigned int i;
173 unsigned long tmp; 174 unsigned long tmp, base, size;
175 struct resource r;
174 176
175 if (dart_tablebase == 0 || dart_tablesize == 0) { 177 if (dart_tablebase == 0 || dart_tablesize == 0) {
176 printk(KERN_INFO "U3-DART: table not allocated, using direct DMA\n"); 178 printk(KERN_INFO "DART: table not allocated, using "
179 "direct DMA\n");
177 return -ENODEV; 180 return -ENODEV;
178 } 181 }
179 182
183 if (of_address_to_resource(dart_node, 0, &r))
184 panic("DART: can't get register base ! ");
185
180 /* Make sure nothing from the DART range remains in the CPU cache 186 /* Make sure nothing from the DART range remains in the CPU cache
181 * from a previous mapping that existed before the kernel took 187 * from a previous mapping that existed before the kernel took
182 * over 188 * over
183 */ 189 */
184 flush_dcache_phys_range(dart_tablebase, dart_tablebase + dart_tablesize); 190 flush_dcache_phys_range(dart_tablebase,
191 dart_tablebase + dart_tablesize);
185 192
186 /* Allocate a spare page to map all invalid DART pages. We need to do 193 /* Allocate a spare page to map all invalid DART pages. We need to do
187 * that to work around what looks like a problem with the HT bridge 194 * that to work around what looks like a problem with the HT bridge
@@ -189,21 +196,16 @@ static int dart_init(struct device_node *dart_node)
189 */ 196 */
190 tmp = lmb_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE); 197 tmp = lmb_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE);
191 if (!tmp) 198 if (!tmp)
192 panic("U3-DART: Cannot allocate spare page!"); 199 panic("DART: Cannot allocate spare page!");
193 dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) & DARTMAP_RPNMASK); 200 dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) &
201 DARTMAP_RPNMASK);
194 202
195 /* Map in DART registers. FIXME: Use device node to get base address */ 203 /* Map in DART registers */
196 dart = ioremap(DART_BASE, 0x7000); 204 dart = ioremap(r.start, r.end - r.start + 1);
197 if (dart == NULL) 205 if (dart == NULL)
198 panic("U3-DART: Cannot map registers!"); 206 panic("DART: Cannot map registers!");
199 207
200 /* Set initial control register contents: table base, 208 /* Map in DART table */
201 * table size and enable bit
202 */
203 regword = DARTCNTL_ENABLE |
204 ((dart_tablebase >> DART_PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) |
205 (((dart_tablesize >> DART_PAGE_SHIFT) & DARTCNTL_SIZE_MASK)
206 << DARTCNTL_SIZE_SHIFT);
207 dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize); 209 dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize);
208 210
209 /* Fill initial table */ 211 /* Fill initial table */
@@ -211,36 +213,50 @@ static int dart_init(struct device_node *dart_node)
211 dart_vbase[i] = dart_emptyval; 213 dart_vbase[i] = dart_emptyval;
212 214
213 /* Initialize DART with table base and enable it. */ 215 /* Initialize DART with table base and enable it. */
214 out_be32((unsigned int *)dart, regword); 216 base = dart_tablebase >> DART_PAGE_SHIFT;
217 size = dart_tablesize >> DART_PAGE_SHIFT;
218 if (dart_is_u4) {
219 size &= DART_SIZE_U4_SIZE_MASK;
220 DART_OUT(DART_BASE_U4, base);
221 DART_OUT(DART_SIZE_U4, size);
222 DART_OUT(DART_CNTL, DART_CNTL_U4_ENABLE);
223 } else {
224 size &= DART_CNTL_U3_SIZE_MASK;
225 DART_OUT(DART_CNTL,
226 DART_CNTL_U3_ENABLE |
227 (base << DART_CNTL_U3_BASE_SHIFT) |
228 (size << DART_CNTL_U3_SIZE_SHIFT));
229 }
215 230
216 /* Invalidate DART to get rid of possible stale TLBs */ 231 /* Invalidate DART to get rid of possible stale TLBs */
217 dart_tlb_invalidate_all(); 232 dart_tlb_invalidate_all();
218 233
219 printk(KERN_INFO "U3/CPC925 DART IOMMU initialized\n"); 234 printk(KERN_INFO "DART IOMMU initialized for %s type chipset\n",
235 dart_is_u4 ? "U4" : "U3");
220 236
221 return 0; 237 return 0;
222} 238}
223 239
224static void iommu_table_u3_setup(void) 240static void iommu_table_dart_setup(void)
225{ 241{
226 iommu_table_u3.it_busno = 0; 242 iommu_table_dart.it_busno = 0;
227 iommu_table_u3.it_offset = 0; 243 iommu_table_dart.it_offset = 0;
228 /* it_size is in number of entries */ 244 /* it_size is in number of entries */
229 iommu_table_u3.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR; 245 iommu_table_dart.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR;
230 246
231 /* Initialize the common IOMMU code */ 247 /* Initialize the common IOMMU code */
232 iommu_table_u3.it_base = (unsigned long)dart_vbase; 248 iommu_table_dart.it_base = (unsigned long)dart_vbase;
233 iommu_table_u3.it_index = 0; 249 iommu_table_dart.it_index = 0;
234 iommu_table_u3.it_blocksize = 1; 250 iommu_table_dart.it_blocksize = 1;
235 iommu_init_table(&iommu_table_u3); 251 iommu_init_table(&iommu_table_dart);
236 252
237 /* Reserve the last page of the DART to avoid possible prefetch 253 /* Reserve the last page of the DART to avoid possible prefetch
238 * past the DART mapped area 254 * past the DART mapped area
239 */ 255 */
240 set_bit(iommu_table_u3.it_size - 1, iommu_table_u3.it_map); 256 set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map);
241} 257}
242 258
243static void iommu_dev_setup_u3(struct pci_dev *dev) 259static void iommu_dev_setup_dart(struct pci_dev *dev)
244{ 260{
245 struct device_node *dn; 261 struct device_node *dn;
246 262
@@ -254,35 +270,39 @@ static void iommu_dev_setup_u3(struct pci_dev *dev)
254 dn = pci_device_to_OF_node(dev); 270 dn = pci_device_to_OF_node(dev);
255 271
256 if (dn) 272 if (dn)
257 PCI_DN(dn)->iommu_table = &iommu_table_u3; 273 PCI_DN(dn)->iommu_table = &iommu_table_dart;
258} 274}
259 275
260static void iommu_bus_setup_u3(struct pci_bus *bus) 276static void iommu_bus_setup_dart(struct pci_bus *bus)
261{ 277{
262 struct device_node *dn; 278 struct device_node *dn;
263 279
264 if (!iommu_table_u3_inited) { 280 if (!iommu_table_dart_inited) {
265 iommu_table_u3_inited = 1; 281 iommu_table_dart_inited = 1;
266 iommu_table_u3_setup(); 282 iommu_table_dart_setup();
267 } 283 }
268 284
269 dn = pci_bus_to_OF_node(bus); 285 dn = pci_bus_to_OF_node(bus);
270 286
271 if (dn) 287 if (dn)
272 PCI_DN(dn)->iommu_table = &iommu_table_u3; 288 PCI_DN(dn)->iommu_table = &iommu_table_dart;
273} 289}
274 290
275static void iommu_dev_setup_null(struct pci_dev *dev) { } 291static void iommu_dev_setup_null(struct pci_dev *dev) { }
276static void iommu_bus_setup_null(struct pci_bus *bus) { } 292static void iommu_bus_setup_null(struct pci_bus *bus) { }
277 293
278void iommu_init_early_u3(void) 294void iommu_init_early_dart(void)
279{ 295{
280 struct device_node *dn; 296 struct device_node *dn;
281 297
282 /* Find the DART in the device-tree */ 298 /* Find the DART in the device-tree */
283 dn = of_find_compatible_node(NULL, "dart", "u3-dart"); 299 dn = of_find_compatible_node(NULL, "dart", "u3-dart");
284 if (dn == NULL) 300 if (dn == NULL) {
285 return; 301 dn = of_find_compatible_node(NULL, "dart", "u4-dart");
302 if (dn == NULL)
303 goto bail;
304 dart_is_u4 = 1;
305 }
286 306
287 /* Setup low level TCE operations for the core IOMMU code */ 307 /* Setup low level TCE operations for the core IOMMU code */
288 ppc_md.tce_build = dart_build; 308 ppc_md.tce_build = dart_build;
@@ -290,24 +310,27 @@ void iommu_init_early_u3(void)
290 ppc_md.tce_flush = dart_flush; 310 ppc_md.tce_flush = dart_flush;
291 311
292 /* Initialize the DART HW */ 312 /* Initialize the DART HW */
293 if (dart_init(dn)) { 313 if (dart_init(dn) == 0) {
294 /* If init failed, use direct iommu and null setup functions */ 314 ppc_md.iommu_dev_setup = iommu_dev_setup_dart;
295 ppc_md.iommu_dev_setup = iommu_dev_setup_null; 315 ppc_md.iommu_bus_setup = iommu_bus_setup_dart;
296 ppc_md.iommu_bus_setup = iommu_bus_setup_null;
297
298 /* Setup pci_dma ops */
299 pci_direct_iommu_init();
300 } else {
301 ppc_md.iommu_dev_setup = iommu_dev_setup_u3;
302 ppc_md.iommu_bus_setup = iommu_bus_setup_u3;
303 316
304 /* Setup pci_dma ops */ 317 /* Setup pci_dma ops */
305 pci_iommu_init(); 318 pci_iommu_init();
319
320 return;
306 } 321 }
322
323 bail:
324 /* If init failed, use direct iommu and null setup functions */
325 ppc_md.iommu_dev_setup = iommu_dev_setup_null;
326 ppc_md.iommu_bus_setup = iommu_bus_setup_null;
327
328 /* Setup pci_dma ops */
329 pci_direct_iommu_init();
307} 330}
308 331
309 332
310void __init alloc_u3_dart_table(void) 333void __init alloc_dart_table(void)
311{ 334{
312 /* Only reserve DART space if machine has more than 2GB of RAM 335 /* Only reserve DART space if machine has more than 2GB of RAM
313 * or if requested with iommu=on on cmdline. 336 * or if requested with iommu=on on cmdline.
@@ -323,5 +346,5 @@ void __init alloc_u3_dart_table(void)
323 dart_tablebase = (unsigned long) 346 dart_tablebase = (unsigned long)
324 abs_to_virt(lmb_alloc_base(1UL<<24, 1UL<<24, 0x80000000L)); 347 abs_to_virt(lmb_alloc_base(1UL<<24, 1UL<<24, 0x80000000L));
325 348
326 printk(KERN_INFO "U3-DART allocated at: %lx\n", dart_tablebase); 349 printk(KERN_INFO "DART table allocated at: %lx\n", dart_tablebase);
327} 350}
diff --git a/arch/ppc/syslib/ipic.c b/arch/powerpc/sysdev/ipic.c
index 8f01e0f1d847..8f01e0f1d847 100644
--- a/arch/ppc/syslib/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
diff --git a/arch/ppc/syslib/ipic.h b/arch/powerpc/sysdev/ipic.h
index a7ce7da8785c..a7ce7da8785c 100644
--- a/arch/ppc/syslib/ipic.h
+++ b/arch/powerpc/sysdev/ipic.h
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 58d1cc2023c8..4f26304d0263 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -13,6 +13,9 @@
13 */ 13 */
14 14
15#undef DEBUG 15#undef DEBUG
16#undef DEBUG_IPI
17#undef DEBUG_IRQ
18#undef DEBUG_LOW
16 19
17#include <linux/config.h> 20#include <linux/config.h>
18#include <linux/types.h> 21#include <linux/types.h>
@@ -45,7 +48,11 @@ static struct mpic *mpic_primary;
45static DEFINE_SPINLOCK(mpic_lock); 48static DEFINE_SPINLOCK(mpic_lock);
46 49
47#ifdef CONFIG_PPC32 /* XXX for now */ 50#ifdef CONFIG_PPC32 /* XXX for now */
48#define distribute_irqs CONFIG_IRQ_ALL_CPUS 51#ifdef CONFIG_IRQ_ALL_CPUS
52#define distribute_irqs (1)
53#else
54#define distribute_irqs (0)
55#endif
49#endif 56#endif
50 57
51/* 58/*
@@ -164,70 +171,129 @@ static void __init mpic_test_broken_ipi(struct mpic *mpic)
164/* Test if an interrupt is sourced from HyperTransport (used on broken U3s) 171/* Test if an interrupt is sourced from HyperTransport (used on broken U3s)
165 * to force the edge setting on the MPIC and do the ack workaround. 172 * to force the edge setting on the MPIC and do the ack workaround.
166 */ 173 */
167static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source_no) 174static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source)
168{ 175{
169 if (source_no >= 128 || !mpic->fixups) 176 if (source >= 128 || !mpic->fixups)
170 return 0; 177 return 0;
171 return mpic->fixups[source_no].base != NULL; 178 return mpic->fixups[source].base != NULL;
172} 179}
173 180
174static inline void mpic_apic_end_irq(struct mpic *mpic, unsigned int source_no) 181
182static inline void mpic_ht_end_irq(struct mpic *mpic, unsigned int source)
175{ 183{
176 struct mpic_irq_fixup *fixup = &mpic->fixups[source_no]; 184 struct mpic_irq_fixup *fixup = &mpic->fixups[source];
177 u32 tmp;
178 185
179 spin_lock(&mpic->fixup_lock); 186 if (fixup->applebase) {
180 writeb(0x11 + 2 * fixup->irq, fixup->base); 187 unsigned int soff = (fixup->index >> 3) & ~3;
181 tmp = readl(fixup->base + 2); 188 unsigned int mask = 1U << (fixup->index & 0x1f);
182 writel(tmp | 0x80000000ul, fixup->base + 2); 189 writel(mask, fixup->applebase + soff);
183 /* config writes shouldn't be posted but let's be safe ... */ 190 } else {
184 (void)readl(fixup->base + 2); 191 spin_lock(&mpic->fixup_lock);
185 spin_unlock(&mpic->fixup_lock); 192 writeb(0x11 + 2 * fixup->index, fixup->base + 2);
193 writel(fixup->data, fixup->base + 4);
194 spin_unlock(&mpic->fixup_lock);
195 }
186} 196}
187 197
198static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
199 unsigned int irqflags)
200{
201 struct mpic_irq_fixup *fixup = &mpic->fixups[source];
202 unsigned long flags;
203 u32 tmp;
188 204
189static void __init mpic_amd8111_read_irq(struct mpic *mpic, u8 __iomem *devbase) 205 if (fixup->base == NULL)
206 return;
207
208 DBG("startup_ht_interrupt(%u, %u) index: %d\n",
209 source, irqflags, fixup->index);
210 spin_lock_irqsave(&mpic->fixup_lock, flags);
211 /* Enable and configure */
212 writeb(0x10 + 2 * fixup->index, fixup->base + 2);
213 tmp = readl(fixup->base + 4);
214 tmp &= ~(0x23U);
215 if (irqflags & IRQ_LEVEL)
216 tmp |= 0x22;
217 writel(tmp, fixup->base + 4);
218 spin_unlock_irqrestore(&mpic->fixup_lock, flags);
219}
220
221static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
222 unsigned int irqflags)
190{ 223{
191 int i, irq; 224 struct mpic_irq_fixup *fixup = &mpic->fixups[source];
225 unsigned long flags;
192 u32 tmp; 226 u32 tmp;
193 227
194 printk(KERN_INFO "mpic: - Workarounds on AMD 8111 @ %p\n", devbase); 228 if (fixup->base == NULL)
229 return;
195 230
196 for (i=0; i < 24; i++) { 231 DBG("shutdown_ht_interrupt(%u, %u)\n", source, irqflags);
197 writeb(0x10 + 2*i, devbase + 0xf2); 232
198 tmp = readl(devbase + 0xf4); 233 /* Disable */
199 if ((tmp & 0x1) || !(tmp & 0x20)) 234 spin_lock_irqsave(&mpic->fixup_lock, flags);
200 continue; 235 writeb(0x10 + 2 * fixup->index, fixup->base + 2);
201 irq = (tmp >> 16) & 0xff; 236 tmp = readl(fixup->base + 4);
202 mpic->fixups[irq].irq = i; 237 tmp &= ~1U;
203 mpic->fixups[irq].base = devbase + 0xf2; 238 writel(tmp, fixup->base + 4);
204 } 239 spin_unlock_irqrestore(&mpic->fixup_lock, flags);
205} 240}
206 241
207static void __init mpic_amd8131_read_irq(struct mpic *mpic, u8 __iomem *devbase) 242static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
243 unsigned int devfn, u32 vdid)
208{ 244{
209 int i, irq; 245 int i, irq, n;
246 u8 __iomem *base;
210 u32 tmp; 247 u32 tmp;
248 u8 pos;
249
250 for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0;
251 pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) {
252 u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
253 if (id == PCI_CAP_ID_HT_IRQCONF) {
254 id = readb(devbase + pos + 3);
255 if (id == 0x80)
256 break;
257 }
258 }
259 if (pos == 0)
260 return;
211 261
212 printk(KERN_INFO "mpic: - Workarounds on AMD 8131 @ %p\n", devbase); 262 base = devbase + pos;
263 writeb(0x01, base + 2);
264 n = (readl(base + 4) >> 16) & 0xff;
213 265
214 for (i=0; i < 4; i++) { 266 printk(KERN_INFO "mpic: - HT:%02x.%x [0x%02x] vendor %04x device %04x"
215 writeb(0x10 + 2*i, devbase + 0xba); 267 " has %d irqs\n",
216 tmp = readl(devbase + 0xbc); 268 devfn >> 3, devfn & 0x7, pos, vdid & 0xffff, vdid >> 16, n + 1);
217 if ((tmp & 0x1) || !(tmp & 0x20)) 269
218 continue; 270 for (i = 0; i <= n; i++) {
271 writeb(0x10 + 2 * i, base + 2);
272 tmp = readl(base + 4);
219 irq = (tmp >> 16) & 0xff; 273 irq = (tmp >> 16) & 0xff;
220 mpic->fixups[irq].irq = i; 274 DBG("HT PIC index 0x%x, irq 0x%x, tmp: %08x\n", i, irq, tmp);
221 mpic->fixups[irq].base = devbase + 0xba; 275 /* mask it , will be unmasked later */
276 tmp |= 0x1;
277 writel(tmp, base + 4);
278 mpic->fixups[irq].index = i;
279 mpic->fixups[irq].base = base;
280 /* Apple HT PIC has a non-standard way of doing EOIs */
281 if ((vdid & 0xffff) == 0x106b)
282 mpic->fixups[irq].applebase = devbase + 0x60;
283 else
284 mpic->fixups[irq].applebase = NULL;
285 writeb(0x11 + 2 * i, base + 2);
286 mpic->fixups[irq].data = readl(base + 4) | 0x80000000;
222 } 287 }
223} 288}
224 289
225static void __init mpic_scan_ioapics(struct mpic *mpic) 290
291static void __init mpic_scan_ht_pics(struct mpic *mpic)
226{ 292{
227 unsigned int devfn; 293 unsigned int devfn;
228 u8 __iomem *cfgspace; 294 u8 __iomem *cfgspace;
229 295
230 printk(KERN_INFO "mpic: Setting up IO-APICs workarounds for U3\n"); 296 printk(KERN_INFO "mpic: Setting up HT PICs workarounds for U3/U4\n");
231 297
232 /* Allocate fixups array */ 298 /* Allocate fixups array */
233 mpic->fixups = alloc_bootmem(128 * sizeof(struct mpic_irq_fixup)); 299 mpic->fixups = alloc_bootmem(128 * sizeof(struct mpic_irq_fixup));
@@ -237,21 +303,20 @@ static void __init mpic_scan_ioapics(struct mpic *mpic)
237 /* Init spinlock */ 303 /* Init spinlock */
238 spin_lock_init(&mpic->fixup_lock); 304 spin_lock_init(&mpic->fixup_lock);
239 305
240 /* Map u3 config space. We assume all IO-APICs are on the primary bus 306 /* Map U3 config space. We assume all IO-APICs are on the primary bus
241 * and slot will never be above "0xf" so we only need to map 32k 307 * so we only need to map 64kB.
242 */ 308 */
243 cfgspace = (unsigned char __iomem *)ioremap(0xf2000000, 0x8000); 309 cfgspace = ioremap(0xf2000000, 0x10000);
244 BUG_ON(cfgspace == NULL); 310 BUG_ON(cfgspace == NULL);
245 311
246 /* Now we scan all slots. We do a very quick scan, we read the header type, 312 /* Now we scan all slots. We do a very quick scan, we read the header
247 * vendor ID and device ID only, that's plenty enough 313 * type, vendor ID and device ID only, that's plenty enough
248 */ 314 */
249 for (devfn = 0; devfn < PCI_DEVFN(0x10,0); devfn ++) { 315 for (devfn = 0; devfn < 0x100; devfn++) {
250 u8 __iomem *devbase = cfgspace + (devfn << 8); 316 u8 __iomem *devbase = cfgspace + (devfn << 8);
251 u8 hdr_type = readb(devbase + PCI_HEADER_TYPE); 317 u8 hdr_type = readb(devbase + PCI_HEADER_TYPE);
252 u32 l = readl(devbase + PCI_VENDOR_ID); 318 u32 l = readl(devbase + PCI_VENDOR_ID);
253 u16 vendor_id, device_id; 319 u16 s;
254 int multifunc = 0;
255 320
256 DBG("devfn %x, l: %x\n", devfn, l); 321 DBG("devfn %x, l: %x\n", devfn, l);
257 322
@@ -259,22 +324,16 @@ static void __init mpic_scan_ioapics(struct mpic *mpic)
259 if (l == 0xffffffff || l == 0x00000000 || 324 if (l == 0xffffffff || l == 0x00000000 ||
260 l == 0x0000ffff || l == 0xffff0000) 325 l == 0x0000ffff || l == 0xffff0000)
261 goto next; 326 goto next;
327 /* Check if is supports capability lists */
328 s = readw(devbase + PCI_STATUS);
329 if (!(s & PCI_STATUS_CAP_LIST))
330 goto next;
331
332 mpic_scan_ht_pic(mpic, devbase, devfn, l);
262 333
263 /* Check if it's a multifunction device (only really used
264 * to function 0 though
265 */
266 multifunc = !!(hdr_type & 0x80);
267 vendor_id = l & 0xffff;
268 device_id = (l >> 16) & 0xffff;
269
270 /* If a known device, go to fixup setup code */
271 if (vendor_id == PCI_VENDOR_ID_AMD && device_id == 0x7460)
272 mpic_amd8111_read_irq(mpic, devbase);
273 if (vendor_id == PCI_VENDOR_ID_AMD && device_id == 0x7450)
274 mpic_amd8131_read_irq(mpic, devbase);
275 next: 334 next:
276 /* next device, if function 0 */ 335 /* next device, if function 0 */
277 if ((PCI_FUNC(devfn) == 0) && !multifunc) 336 if (PCI_FUNC(devfn) == 0 && (hdr_type & 0x80) == 0)
278 devfn += 7; 337 devfn += 7;
279 } 338 }
280} 339}
@@ -371,6 +430,31 @@ static void mpic_enable_irq(unsigned int irq)
371 break; 430 break;
372 } 431 }
373 } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK); 432 } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK);
433
434#ifdef CONFIG_MPIC_BROKEN_U3
435 if (mpic->flags & MPIC_BROKEN_U3) {
436 unsigned int src = irq - mpic->irq_offset;
437 if (mpic_is_ht_interrupt(mpic, src) &&
438 (irq_desc[irq].status & IRQ_LEVEL))
439 mpic_ht_end_irq(mpic, src);
440 }
441#endif /* CONFIG_MPIC_BROKEN_U3 */
442}
443
444static unsigned int mpic_startup_irq(unsigned int irq)
445{
446#ifdef CONFIG_MPIC_BROKEN_U3
447 struct mpic *mpic = mpic_from_irq(irq);
448 unsigned int src = irq - mpic->irq_offset;
449
450 if (mpic_is_ht_interrupt(mpic, src))
451 mpic_startup_ht_interrupt(mpic, src, irq_desc[irq].status);
452
453#endif /* CONFIG_MPIC_BROKEN_U3 */
454
455 mpic_enable_irq(irq);
456
457 return 0;
374} 458}
375 459
376static void mpic_disable_irq(unsigned int irq) 460static void mpic_disable_irq(unsigned int irq)
@@ -394,12 +478,27 @@ static void mpic_disable_irq(unsigned int irq)
394 } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK)); 478 } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK));
395} 479}
396 480
481static void mpic_shutdown_irq(unsigned int irq)
482{
483#ifdef CONFIG_MPIC_BROKEN_U3
484 struct mpic *mpic = mpic_from_irq(irq);
485 unsigned int src = irq - mpic->irq_offset;
486
487 if (mpic_is_ht_interrupt(mpic, src))
488 mpic_shutdown_ht_interrupt(mpic, src, irq_desc[irq].status);
489
490#endif /* CONFIG_MPIC_BROKEN_U3 */
491
492 mpic_disable_irq(irq);
493}
494
397static void mpic_end_irq(unsigned int irq) 495static void mpic_end_irq(unsigned int irq)
398{ 496{
399 struct mpic *mpic = mpic_from_irq(irq); 497 struct mpic *mpic = mpic_from_irq(irq);
400 498
499#ifdef DEBUG_IRQ
401 DBG("%s: end_irq: %d\n", mpic->name, irq); 500 DBG("%s: end_irq: %d\n", mpic->name, irq);
402 501#endif
403 /* We always EOI on end_irq() even for edge interrupts since that 502 /* We always EOI on end_irq() even for edge interrupts since that
404 * should only lower the priority, the MPIC should have properly 503 * should only lower the priority, the MPIC should have properly
405 * latched another edge interrupt coming in anyway 504 * latched another edge interrupt coming in anyway
@@ -408,8 +507,9 @@ static void mpic_end_irq(unsigned int irq)
408#ifdef CONFIG_MPIC_BROKEN_U3 507#ifdef CONFIG_MPIC_BROKEN_U3
409 if (mpic->flags & MPIC_BROKEN_U3) { 508 if (mpic->flags & MPIC_BROKEN_U3) {
410 unsigned int src = irq - mpic->irq_offset; 509 unsigned int src = irq - mpic->irq_offset;
411 if (mpic_is_ht_interrupt(mpic, src)) 510 if (mpic_is_ht_interrupt(mpic, src) &&
412 mpic_apic_end_irq(mpic, src); 511 (irq_desc[irq].status & IRQ_LEVEL))
512 mpic_ht_end_irq(mpic, src);
413 } 513 }
414#endif /* CONFIG_MPIC_BROKEN_U3 */ 514#endif /* CONFIG_MPIC_BROKEN_U3 */
415 515
@@ -490,6 +590,8 @@ struct mpic * __init mpic_alloc(unsigned long phys_addr,
490 mpic->name = name; 590 mpic->name = name;
491 591
492 mpic->hc_irq.typename = name; 592 mpic->hc_irq.typename = name;
593 mpic->hc_irq.startup = mpic_startup_irq;
594 mpic->hc_irq.shutdown = mpic_shutdown_irq;
493 mpic->hc_irq.enable = mpic_enable_irq; 595 mpic->hc_irq.enable = mpic_enable_irq;
494 mpic->hc_irq.disable = mpic_disable_irq; 596 mpic->hc_irq.disable = mpic_disable_irq;
495 mpic->hc_irq.end = mpic_end_irq; 597 mpic->hc_irq.end = mpic_end_irq;
@@ -658,10 +760,10 @@ void __init mpic_init(struct mpic *mpic)
658 mpic->irq_count = mpic->num_sources; 760 mpic->irq_count = mpic->num_sources;
659 761
660#ifdef CONFIG_MPIC_BROKEN_U3 762#ifdef CONFIG_MPIC_BROKEN_U3
661 /* Do the ioapic fixups on U3 broken mpic */ 763 /* Do the HT PIC fixups on U3 broken mpic */
662 DBG("MPIC flags: %x\n", mpic->flags); 764 DBG("MPIC flags: %x\n", mpic->flags);
663 if ((mpic->flags & MPIC_BROKEN_U3) && (mpic->flags & MPIC_PRIMARY)) 765 if ((mpic->flags & MPIC_BROKEN_U3) && (mpic->flags & MPIC_PRIMARY))
664 mpic_scan_ioapics(mpic); 766 mpic_scan_ht_pics(mpic);
665#endif /* CONFIG_MPIC_BROKEN_U3 */ 767#endif /* CONFIG_MPIC_BROKEN_U3 */
666 768
667 for (i = 0; i < mpic->num_sources; i++) { 769 for (i = 0; i < mpic->num_sources; i++) {
@@ -848,7 +950,9 @@ void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask)
848 950
849 BUG_ON(mpic == NULL); 951 BUG_ON(mpic == NULL);
850 952
953#ifdef DEBUG_IPI
851 DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no); 954 DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
955#endif
852 956
853 mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10, 957 mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
854 mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0])); 958 mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
@@ -859,19 +963,28 @@ int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs)
859 u32 irq; 963 u32 irq;
860 964
861 irq = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK; 965 irq = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK;
966#ifdef DEBUG_LOW
862 DBG("%s: get_one_irq(): %d\n", mpic->name, irq); 967 DBG("%s: get_one_irq(): %d\n", mpic->name, irq);
863 968#endif
864 if (mpic->cascade && irq == mpic->cascade_vec) { 969 if (mpic->cascade && irq == mpic->cascade_vec) {
970#ifdef DEBUG_LOW
865 DBG("%s: cascading ...\n", mpic->name); 971 DBG("%s: cascading ...\n", mpic->name);
972#endif
866 irq = mpic->cascade(regs, mpic->cascade_data); 973 irq = mpic->cascade(regs, mpic->cascade_data);
867 mpic_eoi(mpic); 974 mpic_eoi(mpic);
868 return irq; 975 return irq;
869 } 976 }
870 if (unlikely(irq == MPIC_VEC_SPURRIOUS)) 977 if (unlikely(irq == MPIC_VEC_SPURRIOUS))
871 return -1; 978 return -1;
872 if (irq < MPIC_VEC_IPI_0) 979 if (irq < MPIC_VEC_IPI_0) {
980#ifdef DEBUG_IRQ
981 DBG("%s: irq %d\n", mpic->name, irq + mpic->irq_offset);
982#endif
873 return irq + mpic->irq_offset; 983 return irq + mpic->irq_offset;
984 }
985#ifdef DEBUG_IPI
874 DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0); 986 DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0);
987#endif
875 return irq - MPIC_VEC_IPI_0 + mpic->ipi_offset; 988 return irq - MPIC_VEC_IPI_0 + mpic->ipi_offset;
876} 989}
877 990
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
index b20312e5ed27..109d874ecfbe 100644
--- a/arch/powerpc/xmon/Makefile
+++ b/arch/powerpc/xmon/Makefile
@@ -3,9 +3,5 @@
3ifdef CONFIG_PPC64 3ifdef CONFIG_PPC64
4EXTRA_CFLAGS += -mno-minimal-toc 4EXTRA_CFLAGS += -mno-minimal-toc
5endif 5endif
6 6obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o start.o \
7obj-$(CONFIG_8xx) += start_8xx.o 7 nonstdio.o
8obj-$(CONFIG_6xx) += start_32.o
9obj-$(CONFIG_4xx) += start_32.o
10obj-$(CONFIG_PPC64) += start_64.o
11obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o nonstdio.o
diff --git a/arch/powerpc/xmon/start_64.c b/arch/powerpc/xmon/start.c
index 712552c4f242..712552c4f242 100644
--- a/arch/powerpc/xmon/start_64.c
+++ b/arch/powerpc/xmon/start.c
diff --git a/arch/powerpc/xmon/start_32.c b/arch/powerpc/xmon/start_32.c
deleted file mode 100644
index c2464df4217e..000000000000
--- a/arch/powerpc/xmon/start_32.c
+++ /dev/null
@@ -1,441 +0,0 @@
1/*
2 * Copyright (C) 1996 Paul Mackerras.
3 */
4#include <linux/config.h>
5#include <linux/string.h>
6#include <asm/machdep.h>
7#include <asm/io.h>
8#include <asm/page.h>
9#include <linux/adb.h>
10#include <linux/pmu.h>
11#include <linux/cuda.h>
12#include <linux/kernel.h>
13#include <linux/errno.h>
14#include <linux/bitops.h>
15#include <asm/xmon.h>
16#include <asm/prom.h>
17#include <asm/bootx.h>
18#include <asm/machdep.h>
19#include <asm/errno.h>
20#include <asm/pmac_feature.h>
21#include <asm/processor.h>
22#include <asm/delay.h>
23#include <asm/btext.h>
24#include <asm/time.h>
25#include "nonstdio.h"
26
27static volatile unsigned char __iomem *sccc, *sccd;
28unsigned int TXRDY, RXRDY, DLAB;
29
30static int use_serial;
31static int use_screen;
32static int via_modem;
33static int xmon_use_sccb;
34static struct device_node *channel_node;
35
36void buf_access(void)
37{
38 if (DLAB)
39 sccd[3] &= ~DLAB; /* reset DLAB */
40}
41
42extern int adb_init(void);
43
44#ifdef CONFIG_PPC_CHRP
45/*
46 * This looks in the "ranges" property for the primary PCI host bridge
47 * to find the physical address of the start of PCI/ISA I/O space.
48 * It is basically a cut-down version of pci_process_bridge_OF_ranges.
49 */
50static unsigned long chrp_find_phys_io_base(void)
51{
52 struct device_node *node;
53 unsigned int *ranges;
54 unsigned long base = CHRP_ISA_IO_BASE;
55 int rlen = 0;
56 int np;
57
58 node = find_devices("isa");
59 if (node != NULL) {
60 node = node->parent;
61 if (node == NULL || node->type == NULL
62 || strcmp(node->type, "pci") != 0)
63 node = NULL;
64 }
65 if (node == NULL)
66 node = find_devices("pci");
67 if (node == NULL)
68 return base;
69
70 ranges = (unsigned int *) get_property(node, "ranges", &rlen);
71 np = prom_n_addr_cells(node) + 5;
72 while ((rlen -= np * sizeof(unsigned int)) >= 0) {
73 if ((ranges[0] >> 24) == 1 && ranges[2] == 0) {
74 /* I/O space starting at 0, grab the phys base */
75 base = ranges[np - 3];
76 break;
77 }
78 ranges += np;
79 }
80 return base;
81}
82#endif /* CONFIG_PPC_CHRP */
83
84void xmon_map_scc(void)
85{
86#ifdef CONFIG_PPC_MULTIPLATFORM
87 volatile unsigned char __iomem *base;
88
89 if (_machine == _MACH_Pmac) {
90 struct device_node *np;
91 unsigned long addr;
92#ifdef CONFIG_BOOTX_TEXT
93 if (!use_screen && !use_serial
94 && !machine_is_compatible("iMac")) {
95 /* see if there is a keyboard in the device tree
96 with a parent of type "adb" */
97 for (np = find_devices("keyboard"); np; np = np->next)
98 if (np->parent && np->parent->type
99 && strcmp(np->parent->type, "adb") == 0)
100 break;
101
102 /* needs to be hacked if xmon_printk is to be used
103 from within find_via_pmu() */
104#ifdef CONFIG_ADB_PMU
105 if (np != NULL && boot_text_mapped && find_via_pmu())
106 use_screen = 1;
107#endif
108#ifdef CONFIG_ADB_CUDA
109 if (np != NULL && boot_text_mapped && find_via_cuda())
110 use_screen = 1;
111#endif
112 }
113 if (!use_screen && (np = find_devices("escc")) != NULL) {
114 /*
115 * look for the device node for the serial port
116 * we're using and see if it says it has a modem
117 */
118 char *name = xmon_use_sccb? "ch-b": "ch-a";
119 char *slots;
120 int l;
121
122 np = np->child;
123 while (np != NULL && strcmp(np->name, name) != 0)
124 np = np->sibling;
125 if (np != NULL) {
126 /* XXX should parse this properly */
127 channel_node = np;
128 slots = get_property(np, "slot-names", &l);
129 if (slots != NULL && l >= 10
130 && strcmp(slots+4, "Modem") == 0)
131 via_modem = 1;
132 }
133 }
134 btext_drawstring("xmon uses ");
135 if (use_screen)
136 btext_drawstring("screen and keyboard\n");
137 else {
138 if (via_modem)
139 btext_drawstring("modem on ");
140 btext_drawstring(xmon_use_sccb? "printer": "modem");
141 btext_drawstring(" port\n");
142 }
143
144#endif /* CONFIG_BOOTX_TEXT */
145
146#ifdef CHRP_ESCC
147 addr = 0xc1013020;
148#else
149 addr = 0xf3013020;
150#endif
151 TXRDY = 4;
152 RXRDY = 1;
153
154 np = find_devices("mac-io");
155 if (np && np->n_addrs)
156 addr = np->addrs[0].address + 0x13020;
157 base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
158 sccc = base + (addr & ~PAGE_MASK);
159 sccd = sccc + 0x10;
160
161 } else {
162 base = (volatile unsigned char *) isa_io_base;
163
164#ifdef CONFIG_PPC_CHRP
165 if (_machine == _MACH_chrp)
166 base = (volatile unsigned char __iomem *)
167 ioremap(chrp_find_phys_io_base(), 0x1000);
168#endif
169
170 sccc = base + 0x3fd;
171 sccd = base + 0x3f8;
172 if (xmon_use_sccb) {
173 sccc -= 0x100;
174 sccd -= 0x100;
175 }
176 TXRDY = 0x20;
177 RXRDY = 1;
178 DLAB = 0x80;
179 }
180#elif defined(CONFIG_GEMINI)
181 /* should already be mapped by the kernel boot */
182 sccc = (volatile unsigned char __iomem *) 0xffeffb0d;
183 sccd = (volatile unsigned char __iomem *) 0xffeffb08;
184 TXRDY = 0x20;
185 RXRDY = 1;
186 DLAB = 0x80;
187#elif defined(CONFIG_405GP)
188 sccc = (volatile unsigned char __iomem *)0xef600305;
189 sccd = (volatile unsigned char __iomem *)0xef600300;
190 TXRDY = 0x20;
191 RXRDY = 1;
192 DLAB = 0x80;
193#endif /* platform */
194}
195
196static int scc_initialized = 0;
197
198void xmon_init_scc(void);
199extern void cuda_poll(void);
200
201static inline void do_poll_adb(void)
202{
203#ifdef CONFIG_ADB_PMU
204 if (sys_ctrler == SYS_CTRLER_PMU)
205 pmu_poll_adb();
206#endif /* CONFIG_ADB_PMU */
207#ifdef CONFIG_ADB_CUDA
208 if (sys_ctrler == SYS_CTRLER_CUDA)
209 cuda_poll();
210#endif /* CONFIG_ADB_CUDA */
211}
212
213int xmon_write(void *ptr, int nb)
214{
215 char *p = ptr;
216 int i, c, ct;
217
218#ifdef CONFIG_SMP
219 static unsigned long xmon_write_lock;
220 int lock_wait = 1000000;
221 int locked;
222
223 while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
224 if (--lock_wait == 0)
225 break;
226#endif
227
228#ifdef CONFIG_BOOTX_TEXT
229 if (use_screen) {
230 /* write it on the screen */
231 for (i = 0; i < nb; ++i)
232 btext_drawchar(*p++);
233 goto out;
234 }
235#endif
236 if (!scc_initialized)
237 xmon_init_scc();
238 ct = 0;
239 for (i = 0; i < nb; ++i) {
240 while ((*sccc & TXRDY) == 0)
241 do_poll_adb();
242 c = p[i];
243 if (c == '\n' && !ct) {
244 c = '\r';
245 ct = 1;
246 --i;
247 } else {
248 ct = 0;
249 }
250 buf_access();
251 *sccd = c;
252 eieio();
253 }
254
255 out:
256#ifdef CONFIG_SMP
257 if (!locked)
258 clear_bit(0, &xmon_write_lock);
259#endif
260 return nb;
261}
262
263int xmon_wants_key;
264int xmon_adb_keycode;
265
266#ifdef CONFIG_BOOTX_TEXT
267static int xmon_adb_shiftstate;
268
269static unsigned char xmon_keytab[128] =
270 "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */
271 "yt123465=97-80]o" /* 0x10 - 0x1f */
272 "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */
273 "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
274 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
275 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
276
277static unsigned char xmon_shift_keytab[128] =
278 "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */
279 "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */
280 "U{IP\rLJ\"K:|<?NM>" /* 0x20 - 0x2f */
281 "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
282 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
283 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
284
285static int xmon_get_adb_key(void)
286{
287 int k, t, on;
288
289 xmon_wants_key = 1;
290 for (;;) {
291 xmon_adb_keycode = -1;
292 t = 0;
293 on = 0;
294 do {
295 if (--t < 0) {
296 on = 1 - on;
297 btext_drawchar(on? 0xdb: 0x20);
298 btext_drawchar('\b');
299 t = 200000;
300 }
301 do_poll_adb();
302 } while (xmon_adb_keycode == -1);
303 k = xmon_adb_keycode;
304 if (on)
305 btext_drawstring(" \b");
306
307 /* test for shift keys */
308 if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
309 xmon_adb_shiftstate = (k & 0x80) == 0;
310 continue;
311 }
312 if (k >= 0x80)
313 continue; /* ignore up transitions */
314 k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
315 if (k != 0)
316 break;
317 }
318 xmon_wants_key = 0;
319 return k;
320}
321#endif /* CONFIG_BOOTX_TEXT */
322
323int xmon_readchar(void)
324{
325#ifdef CONFIG_BOOTX_TEXT
326 if (use_screen)
327 return xmon_get_adb_key();
328#endif
329 if (!scc_initialized)
330 xmon_init_scc();
331 while ((*sccc & RXRDY) == 0)
332 do_poll_adb();
333 buf_access();
334 return *sccd;
335}
336
337int xmon_read_poll(void)
338{
339 if ((*sccc & RXRDY) == 0) {
340 do_poll_adb();
341 return -1;
342 }
343 buf_access();
344 return *sccd;
345}
346
347static unsigned char scc_inittab[] = {
348 13, 0, /* set baud rate divisor */
349 12, 1,
350 14, 1, /* baud rate gen enable, src=rtxc */
351 11, 0x50, /* clocks = br gen */
352 5, 0xea, /* tx 8 bits, assert DTR & RTS */
353 4, 0x46, /* x16 clock, 1 stop */
354 3, 0xc1, /* rx enable, 8 bits */
355};
356
357void xmon_init_scc(void)
358{
359 if ( _machine == _MACH_chrp )
360 {
361 sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */
362 sccd[0] = 12; eieio(); /* DLL = 9600 baud */
363 sccd[1] = 0; eieio();
364 sccd[2] = 0; eieio(); /* FCR = 0 */
365 sccd[3] = 3; eieio(); /* LCR = 8N1 */
366 sccd[1] = 0; eieio(); /* IER = 0 */
367 }
368 else if ( _machine == _MACH_Pmac )
369 {
370 int i, x;
371 unsigned long timeout;
372
373 if (channel_node != 0)
374 pmac_call_feature(
375 PMAC_FTR_SCC_ENABLE,
376 channel_node,
377 PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
378 printk(KERN_INFO "Serial port locked ON by debugger !\n");
379 if (via_modem && channel_node != 0) {
380 unsigned int t0;
381
382 pmac_call_feature(
383 PMAC_FTR_MODEM_ENABLE,
384 channel_node, 0, 1);
385 printk(KERN_INFO "Modem powered up by debugger !\n");
386 t0 = get_tbl();
387 timeout = 3 * tb_ticks_per_sec;
388 if (timeout == 0)
389 /* assume 25MHz if tb_ticks_per_sec not set */
390 timeout = 75000000;
391 while (get_tbl() - t0 < timeout)
392 eieio();
393 }
394 /* use the B channel if requested */
395 if (xmon_use_sccb) {
396 sccc = (volatile unsigned char *)
397 ((unsigned long)sccc & ~0x20);
398 sccd = sccc + 0x10;
399 }
400 for (i = 20000; i != 0; --i) {
401 x = *sccc; eieio();
402 }
403 *sccc = 9; eieio(); /* reset A or B side */
404 *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio();
405 for (i = 0; i < sizeof(scc_inittab); ++i) {
406 *sccc = scc_inittab[i];
407 eieio();
408 }
409 }
410 scc_initialized = 1;
411 if (via_modem) {
412 for (;;) {
413 xmon_write("ATE1V1\r", 7);
414 if (xmon_expect("OK", 5)) {
415 xmon_write("ATA\r", 4);
416 if (xmon_expect("CONNECT", 40))
417 break;
418 }
419 xmon_write("+++", 3);
420 xmon_expect("OK", 3);
421 }
422 }
423}
424
425void xmon_enter(void)
426{
427#ifdef CONFIG_ADB_PMU
428 if (_machine == _MACH_Pmac) {
429 pmu_suspend();
430 }
431#endif
432}
433
434void xmon_leave(void)
435{
436#ifdef CONFIG_ADB_PMU
437 if (_machine == _MACH_Pmac) {
438 pmu_resume();
439 }
440#endif
441}
diff --git a/arch/powerpc/xmon/start_8xx.c b/arch/powerpc/xmon/start_8xx.c
deleted file mode 100644
index 4c17b0486ad5..000000000000
--- a/arch/powerpc/xmon/start_8xx.c
+++ /dev/null
@@ -1,44 +0,0 @@
1/*
2 * Copyright (C) 1996 Paul Mackerras.
3 * Copyright (C) 2000 Dan Malek.
4 * Quick hack of Paul's code to make XMON work on 8xx processors. Lots
5 * of assumptions, like the SMC1 is used, it has been initialized by the
6 * loader at some point, and we can just stuff and suck bytes.
7 * We rely upon the 8xx uart driver to support us, as the interface
8 * changes between boot up and operational phases of the kernel.
9 */
10#include <linux/string.h>
11#include <asm/machdep.h>
12#include <asm/io.h>
13#include <asm/page.h>
14#include <linux/kernel.h>
15#include <asm/8xx_immap.h>
16#include <asm/mpc8xx.h>
17#include <asm/commproc.h>
18#include "nonstdio.h"
19
20extern int xmon_8xx_write(char *str, int nb);
21extern int xmon_8xx_read_poll(void);
22extern int xmon_8xx_read_char(void);
23
24void xmon_map_scc(void)
25{
26 cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
27}
28
29void xmon_init_scc(void);
30
31int xmon_write(void *ptr, int nb)
32{
33 return(xmon_8xx_write(ptr, nb));
34}
35
36int xmon_readchar(void)
37{
38 return xmon_8xx_read_char();
39}
40
41int xmon_read_poll(void)
42{
43 return(xmon_8xx_read_poll());
44}
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index c45a6ad5f3b7..22612ed5379c 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -450,7 +450,6 @@ int xmon_core(struct pt_regs *regs, int fromipi)
450 leave: 450 leave:
451 cpu_clear(cpu, cpus_in_xmon); 451 cpu_clear(cpu, cpus_in_xmon);
452 xmon_fault_jmp[cpu] = NULL; 452 xmon_fault_jmp[cpu] = NULL;
453
454#else 453#else
455 /* UP is simple... */ 454 /* UP is simple... */
456 if (in_xmon) { 455 if (in_xmon) {
@@ -805,7 +804,10 @@ cmds(struct pt_regs *excp)
805 break; 804 break;
806 case 'x': 805 case 'x':
807 case 'X': 806 case 'X':
807 return cmd;
808 case EOF: 808 case EOF:
809 printf(" <no input ...>\n");
810 mdelay(2000);
809 return cmd; 811 return cmd;
810 case '?': 812 case '?':
811 printf(help_string); 813 printf(help_string);
@@ -1011,7 +1013,7 @@ static long check_bp_loc(unsigned long addr)
1011 unsigned int instr; 1013 unsigned int instr;
1012 1014
1013 addr &= ~3; 1015 addr &= ~3;
1014 if (addr < KERNELBASE) { 1016 if (!is_kernel_addr(addr)) {
1015 printf("Breakpoints may only be placed at kernel addresses\n"); 1017 printf("Breakpoints may only be placed at kernel addresses\n");
1016 return 0; 1018 return 0;
1017 } 1019 }
@@ -1062,7 +1064,7 @@ bpt_cmds(void)
1062 dabr.address = 0; 1064 dabr.address = 0;
1063 dabr.enabled = 0; 1065 dabr.enabled = 0;
1064 if (scanhex(&dabr.address)) { 1066 if (scanhex(&dabr.address)) {
1065 if (dabr.address < KERNELBASE) { 1067 if (!is_kernel_addr(dabr.address)) {
1066 printf(badaddr); 1068 printf(badaddr);
1067 break; 1069 break;
1068 } 1070 }
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index cc3f64c084c5..e396f4591d59 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -8,9 +8,6 @@ config MMU
8 bool 8 bool
9 default y 9 default y
10 10
11config UID16
12 bool
13
14config GENERIC_HARDIRQS 11config GENERIC_HARDIRQS
15 bool 12 bool
16 default y 13 default y
diff --git a/arch/ppc/boot/common/util.S b/arch/ppc/boot/common/util.S
index c96c9f80521e..368ec035e6cd 100644
--- a/arch/ppc/boot/common/util.S
+++ b/arch/ppc/boot/common/util.S
@@ -234,7 +234,8 @@ udelay:
234 * First, flush the data cache in case it was enabled and may be 234 * First, flush the data cache in case it was enabled and may be
235 * holding instructions for copy back. 235 * holding instructions for copy back.
236 */ 236 */
237_GLOBAL(flush_instruction_cache) 237 .globl flush_instruction_cache
238flush_instruction_cache:
238 mflr r6 239 mflr r6
239 bl flush_data_cache 240 bl flush_data_cache
240 241
@@ -279,7 +280,8 @@ _GLOBAL(flush_instruction_cache)
279 * Flush data cache 280 * Flush data cache
280 * Do this by just reading lots of stuff into the cache. 281 * Do this by just reading lots of stuff into the cache.
281 */ 282 */
282_GLOBAL(flush_data_cache) 283 .globl flush_data_cache
284flush_data_cache:
283 lis r3,cache_flush_buffer@h 285 lis r3,cache_flush_buffer@h
284 ori r3,r3,cache_flush_buffer@l 286 ori r3,r3,cache_flush_buffer@l
285 li r4,NUM_CACHE_LINES 287 li r4,NUM_CACHE_LINES
diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile
index 532e7ef1edb6..58415d5718e3 100644
--- a/arch/ppc/boot/images/Makefile
+++ b/arch/ppc/boot/images/Makefile
@@ -26,7 +26,7 @@ quiet_cmd_uimage = UIMAGE $@
26targets += uImage 26targets += uImage
27$(obj)/uImage: $(obj)/vmlinux.gz 27$(obj)/uImage: $(obj)/vmlinux.gz
28 $(Q)rm -f $@ 28 $(Q)rm -f $@
29 $(call if_changed,uimage) 29 $(call cmd,uimage)
30 @echo -n ' Image: $@ ' 30 @echo -n ' Image: $@ '
31 @if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi 31 @if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi
32 32
diff --git a/arch/ppc/configs/TQM8540_defconfig b/arch/ppc/configs/TQM8540_defconfig
new file mode 100644
index 000000000000..99bf3b7a2762
--- /dev/null
+++ b/arch/ppc/configs/TQM8540_defconfig
@@ -0,0 +1,973 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.15-rc2
4# Fri Nov 25 17:26:50 2005
5#
6CONFIG_MMU=y
7CONFIG_GENERIC_HARDIRQS=y
8CONFIG_RWSEM_XCHGADD_ALGORITHM=y
9CONFIG_GENERIC_CALIBRATE_DELAY=y
10CONFIG_PPC=y
11CONFIG_PPC32=y
12CONFIG_GENERIC_NVRAM=y
13CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
14CONFIG_ARCH_MAY_HAVE_PC_FDC=y
15
16#
17# Code maturity level options
18#
19CONFIG_EXPERIMENTAL=y
20CONFIG_CLEAN_COMPILE=y
21CONFIG_BROKEN_ON_SMP=y
22CONFIG_INIT_ENV_ARG_LIMIT=32
23
24#
25# General setup
26#
27CONFIG_LOCALVERSION=""
28CONFIG_LOCALVERSION_AUTO=y
29CONFIG_SWAP=y
30CONFIG_SYSVIPC=y
31# CONFIG_POSIX_MQUEUE is not set
32# CONFIG_BSD_PROCESS_ACCT is not set
33CONFIG_SYSCTL=y
34# CONFIG_AUDIT is not set
35# CONFIG_HOTPLUG is not set
36CONFIG_KOBJECT_UEVENT=y
37# CONFIG_IKCONFIG is not set
38CONFIG_INITRAMFS_SOURCE=""
39CONFIG_EMBEDDED=y
40# CONFIG_KALLSYMS is not set
41CONFIG_PRINTK=y
42CONFIG_BUG=y
43CONFIG_BASE_FULL=y
44CONFIG_FUTEX=y
45# CONFIG_EPOLL is not set
46# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
47CONFIG_SHMEM=y
48CONFIG_CC_ALIGN_FUNCTIONS=0
49CONFIG_CC_ALIGN_LABELS=0
50CONFIG_CC_ALIGN_LOOPS=0
51CONFIG_CC_ALIGN_JUMPS=0
52# CONFIG_TINY_SHMEM is not set
53CONFIG_BASE_SMALL=0
54
55#
56# Loadable module support
57#
58# CONFIG_MODULES is not set
59
60#
61# Block layer
62#
63# CONFIG_LBD is not set
64
65#
66# IO Schedulers
67#
68CONFIG_IOSCHED_NOOP=y
69CONFIG_IOSCHED_AS=y
70CONFIG_IOSCHED_DEADLINE=y
71CONFIG_IOSCHED_CFQ=y
72CONFIG_DEFAULT_AS=y
73# CONFIG_DEFAULT_DEADLINE is not set
74# CONFIG_DEFAULT_CFQ is not set
75# CONFIG_DEFAULT_NOOP is not set
76CONFIG_DEFAULT_IOSCHED="anticipatory"
77
78#
79# Processor
80#
81# CONFIG_6xx is not set
82# CONFIG_40x is not set
83# CONFIG_44x is not set
84# CONFIG_POWER3 is not set
85# CONFIG_POWER4 is not set
86# CONFIG_8xx is not set
87# CONFIG_E200 is not set
88CONFIG_E500=y
89CONFIG_BOOKE=y
90CONFIG_FSL_BOOKE=y
91# CONFIG_PHYS_64BIT is not set
92CONFIG_SPE=y
93CONFIG_MATH_EMULATION=y
94# CONFIG_KEXEC is not set
95# CONFIG_CPU_FREQ is not set
96# CONFIG_WANT_EARLY_SERIAL is not set
97CONFIG_PPC_GEN550=y
98CONFIG_85xx=y
99CONFIG_PPC_INDIRECT_PCI_BE=y
100
101#
102# Freescale 85xx options
103#
104# CONFIG_MPC8540_ADS is not set
105# CONFIG_MPC8548_CDS is not set
106# CONFIG_MPC8555_CDS is not set
107# CONFIG_MPC8560_ADS is not set
108# CONFIG_SBC8560 is not set
109# CONFIG_STX_GP3 is not set
110CONFIG_TQM8540=y
111# CONFIG_TQM8541 is not set
112# CONFIG_TQM8555 is not set
113# CONFIG_TQM8560 is not set
114CONFIG_MPC8540=y
115
116#
117# Platform options
118#
119# CONFIG_HIGHMEM is not set
120# CONFIG_HZ_100 is not set
121CONFIG_HZ_250=y
122# CONFIG_HZ_1000 is not set
123CONFIG_HZ=250
124CONFIG_PREEMPT_NONE=y
125# CONFIG_PREEMPT_VOLUNTARY is not set
126# CONFIG_PREEMPT is not set
127CONFIG_SELECT_MEMORY_MODEL=y
128CONFIG_FLATMEM_MANUAL=y
129# CONFIG_DISCONTIGMEM_MANUAL is not set
130# CONFIG_SPARSEMEM_MANUAL is not set
131CONFIG_FLATMEM=y
132CONFIG_FLAT_NODE_MEM_MAP=y
133# CONFIG_SPARSEMEM_STATIC is not set
134CONFIG_SPLIT_PTLOCK_CPUS=4
135CONFIG_BINFMT_ELF=y
136# CONFIG_BINFMT_MISC is not set
137# CONFIG_CMDLINE_BOOL is not set
138# CONFIG_PM is not set
139# CONFIG_SOFTWARE_SUSPEND is not set
140CONFIG_SECCOMP=y
141CONFIG_ISA_DMA_API=y
142
143#
144# Bus options
145#
146CONFIG_PPC_I8259=y
147CONFIG_PPC_INDIRECT_PCI=y
148CONFIG_PCI=y
149CONFIG_PCI_DOMAINS=y
150# CONFIG_PCI_LEGACY_PROC is not set
151
152#
153# PCCARD (PCMCIA/CardBus) support
154#
155# CONFIG_PCCARD is not set
156# CONFIG_RAPIDIO is not set
157
158#
159# Advanced setup
160#
161# CONFIG_ADVANCED_OPTIONS is not set
162
163#
164# Default settings for advanced configuration options are used
165#
166CONFIG_HIGHMEM_START=0xfe000000
167CONFIG_LOWMEM_SIZE=0x30000000
168CONFIG_KERNEL_START=0xc0000000
169CONFIG_TASK_SIZE=0x80000000
170CONFIG_BOOT_LOAD=0x00800000
171
172#
173# Networking
174#
175CONFIG_NET=y
176
177#
178# Networking options
179#
180CONFIG_PACKET=y
181# CONFIG_PACKET_MMAP is not set
182CONFIG_UNIX=y
183# CONFIG_NET_KEY is not set
184CONFIG_INET=y
185CONFIG_IP_MULTICAST=y
186# CONFIG_IP_ADVANCED_ROUTER is not set
187CONFIG_IP_FIB_HASH=y
188CONFIG_IP_PNP=y
189CONFIG_IP_PNP_DHCP=y
190CONFIG_IP_PNP_BOOTP=y
191# CONFIG_IP_PNP_RARP is not set
192# CONFIG_NET_IPIP is not set
193# CONFIG_NET_IPGRE is not set
194# CONFIG_IP_MROUTE is not set
195# CONFIG_ARPD is not set
196CONFIG_SYN_COOKIES=y
197# CONFIG_INET_AH is not set
198# CONFIG_INET_ESP is not set
199# CONFIG_INET_IPCOMP is not set
200# CONFIG_INET_TUNNEL is not set
201CONFIG_INET_DIAG=y
202CONFIG_INET_TCP_DIAG=y
203# CONFIG_TCP_CONG_ADVANCED is not set
204CONFIG_TCP_CONG_BIC=y
205# CONFIG_IPV6 is not set
206# CONFIG_NETFILTER is not set
207
208#
209# DCCP Configuration (EXPERIMENTAL)
210#
211# CONFIG_IP_DCCP is not set
212
213#
214# SCTP Configuration (EXPERIMENTAL)
215#
216# CONFIG_IP_SCTP is not set
217# CONFIG_ATM is not set
218# CONFIG_BRIDGE is not set
219# CONFIG_VLAN_8021Q is not set
220# CONFIG_DECNET is not set
221# CONFIG_LLC2 is not set
222# CONFIG_IPX is not set
223# CONFIG_ATALK is not set
224# CONFIG_X25 is not set
225# CONFIG_LAPB is not set
226# CONFIG_NET_DIVERT is not set
227# CONFIG_ECONET is not set
228# CONFIG_WAN_ROUTER is not set
229
230#
231# QoS and/or fair queueing
232#
233# CONFIG_NET_SCHED is not set
234
235#
236# Network testing
237#
238# CONFIG_NET_PKTGEN is not set
239# CONFIG_HAMRADIO is not set
240# CONFIG_IRDA is not set
241# CONFIG_BT is not set
242# CONFIG_IEEE80211 is not set
243
244#
245# Device Drivers
246#
247
248#
249# Generic Driver Options
250#
251CONFIG_STANDALONE=y
252CONFIG_PREVENT_FIRMWARE_BUILD=y
253# CONFIG_FW_LOADER is not set
254
255#
256# Connector - unified userspace <-> kernelspace linker
257#
258# CONFIG_CONNECTOR is not set
259
260#
261# Memory Technology Devices (MTD)
262#
263CONFIG_MTD=y
264# CONFIG_MTD_DEBUG is not set
265CONFIG_MTD_CONCAT=y
266CONFIG_MTD_PARTITIONS=y
267# CONFIG_MTD_REDBOOT_PARTS is not set
268CONFIG_MTD_CMDLINE_PARTS=y
269
270#
271# User Modules And Translation Layers
272#
273CONFIG_MTD_CHAR=y
274CONFIG_MTD_BLOCK=y
275# CONFIG_FTL is not set
276# CONFIG_NFTL is not set
277# CONFIG_INFTL is not set
278# CONFIG_RFD_FTL is not set
279
280#
281# RAM/ROM/Flash chip drivers
282#
283CONFIG_MTD_CFI=y
284# CONFIG_MTD_JEDECPROBE is not set
285CONFIG_MTD_GEN_PROBE=y
286# CONFIG_MTD_CFI_ADV_OPTIONS is not set
287CONFIG_MTD_MAP_BANK_WIDTH_1=y
288CONFIG_MTD_MAP_BANK_WIDTH_2=y
289CONFIG_MTD_MAP_BANK_WIDTH_4=y
290# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
291# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
292# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
293CONFIG_MTD_CFI_I1=y
294CONFIG_MTD_CFI_I2=y
295# CONFIG_MTD_CFI_I4 is not set
296# CONFIG_MTD_CFI_I8 is not set
297# CONFIG_MTD_CFI_INTELEXT is not set
298CONFIG_MTD_CFI_AMDSTD=y
299CONFIG_MTD_CFI_AMDSTD_RETRY=0
300# CONFIG_MTD_CFI_STAA is not set
301CONFIG_MTD_CFI_UTIL=y
302# CONFIG_MTD_RAM is not set
303# CONFIG_MTD_ROM is not set
304# CONFIG_MTD_ABSENT is not set
305
306#
307# Mapping drivers for chip access
308#
309# CONFIG_MTD_COMPLEX_MAPPINGS is not set
310# CONFIG_MTD_PHYSMAP is not set
311CONFIG_MTD_TQM85xx=y
312# CONFIG_MTD_PLATRAM is not set
313
314#
315# Self-contained MTD device drivers
316#
317# CONFIG_MTD_PMC551 is not set
318# CONFIG_MTD_SLRAM is not set
319# CONFIG_MTD_PHRAM is not set
320# CONFIG_MTD_MTDRAM is not set
321# CONFIG_MTD_BLKMTD is not set
322# CONFIG_MTD_BLOCK2MTD is not set
323
324#
325# Disk-On-Chip Device Drivers
326#
327# CONFIG_MTD_DOC2000 is not set
328# CONFIG_MTD_DOC2001 is not set
329# CONFIG_MTD_DOC2001PLUS is not set
330
331#
332# NAND Flash Device Drivers
333#
334# CONFIG_MTD_NAND is not set
335
336#
337# OneNAND Flash Device Drivers
338#
339# CONFIG_MTD_ONENAND is not set
340
341#
342# Parallel port support
343#
344# CONFIG_PARPORT is not set
345
346#
347# Plug and Play support
348#
349
350#
351# Block devices
352#
353# CONFIG_BLK_DEV_FD is not set
354# CONFIG_BLK_CPQ_DA is not set
355# CONFIG_BLK_CPQ_CISS_DA is not set
356# CONFIG_BLK_DEV_DAC960 is not set
357# CONFIG_BLK_DEV_UMEM is not set
358# CONFIG_BLK_DEV_COW_COMMON is not set
359CONFIG_BLK_DEV_LOOP=y
360# CONFIG_BLK_DEV_CRYPTOLOOP is not set
361# CONFIG_BLK_DEV_NBD is not set
362# CONFIG_BLK_DEV_SX8 is not set
363CONFIG_BLK_DEV_RAM=y
364CONFIG_BLK_DEV_RAM_COUNT=16
365CONFIG_BLK_DEV_RAM_SIZE=32768
366CONFIG_BLK_DEV_INITRD=y
367# CONFIG_CDROM_PKTCDVD is not set
368# CONFIG_ATA_OVER_ETH is not set
369
370#
371# ATA/ATAPI/MFM/RLL support
372#
373CONFIG_IDE=y
374CONFIG_BLK_DEV_IDE=y
375
376#
377# Please see Documentation/ide.txt for help/info on IDE drives
378#
379# CONFIG_BLK_DEV_IDE_SATA is not set
380CONFIG_BLK_DEV_IDEDISK=y
381# CONFIG_IDEDISK_MULTI_MODE is not set
382# CONFIG_BLK_DEV_IDECD is not set
383# CONFIG_BLK_DEV_IDETAPE is not set
384# CONFIG_BLK_DEV_IDEFLOPPY is not set
385# CONFIG_IDE_TASK_IOCTL is not set
386
387#
388# IDE chipset support/bugfixes
389#
390CONFIG_IDE_GENERIC=y
391CONFIG_BLK_DEV_IDEPCI=y
392CONFIG_IDEPCI_SHARE_IRQ=y
393# CONFIG_BLK_DEV_OFFBOARD is not set
394CONFIG_BLK_DEV_GENERIC=y
395# CONFIG_BLK_DEV_OPTI621 is not set
396# CONFIG_BLK_DEV_SL82C105 is not set
397CONFIG_BLK_DEV_IDEDMA_PCI=y
398# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
399CONFIG_IDEDMA_PCI_AUTO=y
400# CONFIG_IDEDMA_ONLYDISK is not set
401# CONFIG_BLK_DEV_AEC62XX is not set
402# CONFIG_BLK_DEV_ALI15X3 is not set
403# CONFIG_BLK_DEV_AMD74XX is not set
404# CONFIG_BLK_DEV_CMD64X is not set
405# CONFIG_BLK_DEV_TRIFLEX is not set
406# CONFIG_BLK_DEV_CY82C693 is not set
407# CONFIG_BLK_DEV_CS5520 is not set
408# CONFIG_BLK_DEV_CS5530 is not set
409# CONFIG_BLK_DEV_HPT34X is not set
410# CONFIG_BLK_DEV_HPT366 is not set
411# CONFIG_BLK_DEV_SC1200 is not set
412# CONFIG_BLK_DEV_PIIX is not set
413# CONFIG_BLK_DEV_IT821X is not set
414# CONFIG_BLK_DEV_NS87415 is not set
415# CONFIG_BLK_DEV_PDC202XX_OLD is not set
416# CONFIG_BLK_DEV_PDC202XX_NEW is not set
417# CONFIG_BLK_DEV_SVWKS is not set
418# CONFIG_BLK_DEV_SIIMAGE is not set
419# CONFIG_BLK_DEV_SLC90E66 is not set
420# CONFIG_BLK_DEV_TRM290 is not set
421CONFIG_BLK_DEV_VIA82CXXX=y
422# CONFIG_IDE_ARM is not set
423CONFIG_BLK_DEV_IDEDMA=y
424# CONFIG_IDEDMA_IVB is not set
425CONFIG_IDEDMA_AUTO=y
426# CONFIG_BLK_DEV_HD is not set
427
428#
429# SCSI device support
430#
431# CONFIG_RAID_ATTRS is not set
432# CONFIG_SCSI is not set
433
434#
435# Multi-device support (RAID and LVM)
436#
437# CONFIG_MD is not set
438
439#
440# Fusion MPT device support
441#
442# CONFIG_FUSION is not set
443
444#
445# IEEE 1394 (FireWire) support
446#
447# CONFIG_IEEE1394 is not set
448
449#
450# I2O device support
451#
452# CONFIG_I2O is not set
453
454#
455# Macintosh device drivers
456#
457# CONFIG_WINDFARM is not set
458
459#
460# Network device support
461#
462CONFIG_NETDEVICES=y
463# CONFIG_DUMMY is not set
464# CONFIG_BONDING is not set
465# CONFIG_EQUALIZER is not set
466# CONFIG_TUN is not set
467
468#
469# ARCnet devices
470#
471# CONFIG_ARCNET is not set
472
473#
474# PHY device support
475#
476CONFIG_PHYLIB=y
477
478#
479# MII PHY device drivers
480#
481# CONFIG_MARVELL_PHY is not set
482# CONFIG_DAVICOM_PHY is not set
483# CONFIG_QSEMI_PHY is not set
484# CONFIG_LXT_PHY is not set
485# CONFIG_CICADA_PHY is not set
486
487#
488# Ethernet (10 or 100Mbit)
489#
490CONFIG_NET_ETHERNET=y
491CONFIG_MII=y
492# CONFIG_HAPPYMEAL is not set
493# CONFIG_SUNGEM is not set
494# CONFIG_CASSINI is not set
495# CONFIG_NET_VENDOR_3COM is not set
496
497#
498# Tulip family network device support
499#
500# CONFIG_NET_TULIP is not set
501# CONFIG_HP100 is not set
502CONFIG_NET_PCI=y
503# CONFIG_PCNET32 is not set
504# CONFIG_AMD8111_ETH is not set
505# CONFIG_ADAPTEC_STARFIRE is not set
506# CONFIG_B44 is not set
507# CONFIG_FORCEDETH is not set
508# CONFIG_DGRS is not set
509# CONFIG_EEPRO100 is not set
510CONFIG_E100=y
511# CONFIG_FEALNX is not set
512# CONFIG_NATSEMI is not set
513# CONFIG_NE2K_PCI is not set
514# CONFIG_8139CP is not set
515# CONFIG_8139TOO is not set
516# CONFIG_SIS900 is not set
517# CONFIG_EPIC100 is not set
518# CONFIG_SUNDANCE is not set
519# CONFIG_TLAN is not set
520# CONFIG_VIA_RHINE is not set
521
522#
523# Ethernet (1000 Mbit)
524#
525# CONFIG_ACENIC is not set
526# CONFIG_DL2K is not set
527# CONFIG_E1000 is not set
528# CONFIG_NS83820 is not set
529# CONFIG_HAMACHI is not set
530# CONFIG_YELLOWFIN is not set
531# CONFIG_R8169 is not set
532# CONFIG_SIS190 is not set
533# CONFIG_SKGE is not set
534# CONFIG_SK98LIN is not set
535# CONFIG_VIA_VELOCITY is not set
536# CONFIG_TIGON3 is not set
537# CONFIG_BNX2 is not set
538CONFIG_GIANFAR=y
539CONFIG_GFAR_NAPI=y
540
541#
542# Ethernet (10000 Mbit)
543#
544# CONFIG_CHELSIO_T1 is not set
545# CONFIG_IXGB is not set
546# CONFIG_S2IO is not set
547
548#
549# Token Ring devices
550#
551# CONFIG_TR is not set
552
553#
554# Wireless LAN (non-hamradio)
555#
556# CONFIG_NET_RADIO is not set
557
558#
559# Wan interfaces
560#
561# CONFIG_WAN is not set
562# CONFIG_FDDI is not set
563# CONFIG_HIPPI is not set
564# CONFIG_PPP is not set
565# CONFIG_SLIP is not set
566# CONFIG_SHAPER is not set
567# CONFIG_NETCONSOLE is not set
568# CONFIG_NETPOLL is not set
569# CONFIG_NET_POLL_CONTROLLER is not set
570
571#
572# ISDN subsystem
573#
574# CONFIG_ISDN is not set
575
576#
577# Telephony Support
578#
579# CONFIG_PHONE is not set
580
581#
582# Input device support
583#
584CONFIG_INPUT=y
585
586#
587# Userland interfaces
588#
589# CONFIG_INPUT_MOUSEDEV is not set
590# CONFIG_INPUT_JOYDEV is not set
591# CONFIG_INPUT_TSDEV is not set
592# CONFIG_INPUT_EVDEV is not set
593# CONFIG_INPUT_EVBUG is not set
594
595#
596# Input Device Drivers
597#
598# CONFIG_INPUT_KEYBOARD is not set
599# CONFIG_INPUT_MOUSE is not set
600# CONFIG_INPUT_JOYSTICK is not set
601# CONFIG_INPUT_TOUCHSCREEN is not set
602# CONFIG_INPUT_MISC is not set
603
604#
605# Hardware I/O ports
606#
607# CONFIG_SERIO is not set
608# CONFIG_GAMEPORT is not set
609
610#
611# Character devices
612#
613# CONFIG_VT is not set
614# CONFIG_SERIAL_NONSTANDARD is not set
615
616#
617# Serial drivers
618#
619CONFIG_SERIAL_8250=y
620CONFIG_SERIAL_8250_CONSOLE=y
621CONFIG_SERIAL_8250_NR_UARTS=4
622# CONFIG_SERIAL_8250_EXTENDED is not set
623
624#
625# Non-8250 serial port support
626#
627CONFIG_SERIAL_CORE=y
628CONFIG_SERIAL_CORE_CONSOLE=y
629# CONFIG_SERIAL_JSM is not set
630CONFIG_UNIX98_PTYS=y
631CONFIG_LEGACY_PTYS=y
632CONFIG_LEGACY_PTY_COUNT=256
633
634#
635# IPMI
636#
637# CONFIG_IPMI_HANDLER is not set
638
639#
640# Watchdog Cards
641#
642# CONFIG_WATCHDOG is not set
643# CONFIG_NVRAM is not set
644CONFIG_GEN_RTC=y
645# CONFIG_GEN_RTC_X is not set
646# CONFIG_DTLK is not set
647# CONFIG_R3964 is not set
648# CONFIG_APPLICOM is not set
649
650#
651# Ftape, the floppy tape device driver
652#
653# CONFIG_AGP is not set
654# CONFIG_DRM is not set
655# CONFIG_RAW_DRIVER is not set
656
657#
658# TPM devices
659#
660# CONFIG_TCG_TPM is not set
661# CONFIG_TELCLOCK is not set
662
663#
664# I2C support
665#
666CONFIG_I2C=y
667CONFIG_I2C_CHARDEV=y
668
669#
670# I2C Algorithms
671#
672# CONFIG_I2C_ALGOBIT is not set
673# CONFIG_I2C_ALGOPCF is not set
674# CONFIG_I2C_ALGOPCA is not set
675
676#
677# I2C Hardware Bus support
678#
679# CONFIG_I2C_ALI1535 is not set
680# CONFIG_I2C_ALI1563 is not set
681# CONFIG_I2C_ALI15X3 is not set
682# CONFIG_I2C_AMD756 is not set
683# CONFIG_I2C_AMD8111 is not set
684# CONFIG_I2C_I801 is not set
685# CONFIG_I2C_I810 is not set
686# CONFIG_I2C_PIIX4 is not set
687CONFIG_I2C_MPC=y
688# CONFIG_I2C_NFORCE2 is not set
689# CONFIG_I2C_PARPORT_LIGHT is not set
690# CONFIG_I2C_PROSAVAGE is not set
691# CONFIG_I2C_SAVAGE4 is not set
692# CONFIG_SCx200_ACB is not set
693# CONFIG_I2C_SIS5595 is not set
694# CONFIG_I2C_SIS630 is not set
695# CONFIG_I2C_SIS96X is not set
696# CONFIG_I2C_VIA is not set
697# CONFIG_I2C_VIAPRO is not set
698# CONFIG_I2C_VOODOO3 is not set
699# CONFIG_I2C_PCA_ISA is not set
700
701#
702# Miscellaneous I2C Chip support
703#
704CONFIG_SENSORS_DS1337=y
705# CONFIG_SENSORS_DS1374 is not set
706# CONFIG_SENSORS_EEPROM is not set
707# CONFIG_SENSORS_PCF8574 is not set
708# CONFIG_SENSORS_PCA9539 is not set
709# CONFIG_SENSORS_PCF8591 is not set
710# CONFIG_SENSORS_RTC8564 is not set
711# CONFIG_SENSORS_M41T00 is not set
712# CONFIG_SENSORS_MAX6875 is not set
713# CONFIG_RTC_X1205_I2C is not set
714# CONFIG_I2C_DEBUG_CORE is not set
715# CONFIG_I2C_DEBUG_ALGO is not set
716# CONFIG_I2C_DEBUG_BUS is not set
717# CONFIG_I2C_DEBUG_CHIP is not set
718
719#
720# Dallas's 1-wire bus
721#
722# CONFIG_W1 is not set
723
724#
725# Hardware Monitoring support
726#
727CONFIG_HWMON=y
728# CONFIG_HWMON_VID is not set
729# CONFIG_SENSORS_ADM1021 is not set
730# CONFIG_SENSORS_ADM1025 is not set
731# CONFIG_SENSORS_ADM1026 is not set
732# CONFIG_SENSORS_ADM1031 is not set
733# CONFIG_SENSORS_ADM9240 is not set
734# CONFIG_SENSORS_ASB100 is not set
735# CONFIG_SENSORS_ATXP1 is not set
736# CONFIG_SENSORS_DS1621 is not set
737# CONFIG_SENSORS_FSCHER is not set
738# CONFIG_SENSORS_FSCPOS is not set
739# CONFIG_SENSORS_GL518SM is not set
740# CONFIG_SENSORS_GL520SM is not set
741# CONFIG_SENSORS_IT87 is not set
742# CONFIG_SENSORS_LM63 is not set
743CONFIG_SENSORS_LM75=y
744# CONFIG_SENSORS_LM77 is not set
745# CONFIG_SENSORS_LM78 is not set
746# CONFIG_SENSORS_LM80 is not set
747# CONFIG_SENSORS_LM83 is not set
748# CONFIG_SENSORS_LM85 is not set
749# CONFIG_SENSORS_LM87 is not set
750# CONFIG_SENSORS_LM90 is not set
751# CONFIG_SENSORS_LM92 is not set
752# CONFIG_SENSORS_MAX1619 is not set
753# CONFIG_SENSORS_PC87360 is not set
754# CONFIG_SENSORS_SIS5595 is not set
755# CONFIG_SENSORS_SMSC47M1 is not set
756# CONFIG_SENSORS_SMSC47B397 is not set
757# CONFIG_SENSORS_VIA686A is not set
758# CONFIG_SENSORS_W83781D is not set
759# CONFIG_SENSORS_W83792D is not set
760# CONFIG_SENSORS_W83L785TS is not set
761# CONFIG_SENSORS_W83627HF is not set
762# CONFIG_SENSORS_W83627EHF is not set
763CONFIG_HWMON_DEBUG_CHIP=y
764
765#
766# Misc devices
767#
768
769#
770# Multimedia Capabilities Port drivers
771#
772
773#
774# Multimedia devices
775#
776# CONFIG_VIDEO_DEV is not set
777
778#
779# Digital Video Broadcasting Devices
780#
781# CONFIG_DVB is not set
782
783#
784# Graphics support
785#
786# CONFIG_FB is not set
787
788#
789# Sound
790#
791# CONFIG_SOUND is not set
792
793#
794# USB support
795#
796CONFIG_USB_ARCH_HAS_HCD=y
797CONFIG_USB_ARCH_HAS_OHCI=y
798# CONFIG_USB is not set
799
800#
801# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
802#
803
804#
805# USB Gadget Support
806#
807# CONFIG_USB_GADGET is not set
808
809#
810# MMC/SD Card support
811#
812# CONFIG_MMC is not set
813
814#
815# InfiniBand support
816#
817# CONFIG_INFINIBAND is not set
818
819#
820# SN Devices
821#
822
823#
824# File systems
825#
826CONFIG_EXT2_FS=y
827# CONFIG_EXT2_FS_XATTR is not set
828# CONFIG_EXT2_FS_XIP is not set
829CONFIG_EXT3_FS=y
830CONFIG_EXT3_FS_XATTR=y
831# CONFIG_EXT3_FS_POSIX_ACL is not set
832# CONFIG_EXT3_FS_SECURITY is not set
833CONFIG_JBD=y
834# CONFIG_JBD_DEBUG is not set
835CONFIG_FS_MBCACHE=y
836# CONFIG_REISERFS_FS is not set
837# CONFIG_JFS_FS is not set
838# CONFIG_FS_POSIX_ACL is not set
839# CONFIG_XFS_FS is not set
840# CONFIG_MINIX_FS is not set
841# CONFIG_ROMFS_FS is not set
842CONFIG_INOTIFY=y
843# CONFIG_QUOTA is not set
844CONFIG_DNOTIFY=y
845# CONFIG_AUTOFS_FS is not set
846# CONFIG_AUTOFS4_FS is not set
847# CONFIG_FUSE_FS is not set
848
849#
850# CD-ROM/DVD Filesystems
851#
852# CONFIG_ISO9660_FS is not set
853# CONFIG_UDF_FS is not set
854
855#
856# DOS/FAT/NT Filesystems
857#
858# CONFIG_MSDOS_FS is not set
859# CONFIG_VFAT_FS is not set
860# CONFIG_NTFS_FS is not set
861
862#
863# Pseudo filesystems
864#
865CONFIG_PROC_FS=y
866CONFIG_PROC_KCORE=y
867CONFIG_SYSFS=y
868CONFIG_TMPFS=y
869# CONFIG_HUGETLB_PAGE is not set
870CONFIG_RAMFS=y
871# CONFIG_RELAYFS_FS is not set
872
873#
874# Miscellaneous filesystems
875#
876# CONFIG_ADFS_FS is not set
877# CONFIG_AFFS_FS is not set
878# CONFIG_HFS_FS is not set
879# CONFIG_HFSPLUS_FS is not set
880# CONFIG_BEFS_FS is not set
881# CONFIG_BFS_FS is not set
882# CONFIG_EFS_FS is not set
883# CONFIG_JFFS_FS is not set
884CONFIG_JFFS2_FS=y
885CONFIG_JFFS2_FS_DEBUG=0
886CONFIG_JFFS2_FS_WRITEBUFFER=y
887# CONFIG_JFFS2_SUMMARY is not set
888# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
889CONFIG_JFFS2_ZLIB=y
890CONFIG_JFFS2_RTIME=y
891# CONFIG_JFFS2_RUBIN is not set
892CONFIG_CRAMFS=y
893# CONFIG_VXFS_FS is not set
894# CONFIG_HPFS_FS is not set
895# CONFIG_QNX4FS_FS is not set
896# CONFIG_SYSV_FS is not set
897# CONFIG_UFS_FS is not set
898
899#
900# Network File Systems
901#
902CONFIG_NFS_FS=y
903# CONFIG_NFS_V3 is not set
904# CONFIG_NFS_V4 is not set
905# CONFIG_NFS_DIRECTIO is not set
906# CONFIG_NFSD is not set
907CONFIG_ROOT_NFS=y
908CONFIG_LOCKD=y
909CONFIG_NFS_COMMON=y
910CONFIG_SUNRPC=y
911# CONFIG_RPCSEC_GSS_KRB5 is not set
912# CONFIG_RPCSEC_GSS_SPKM3 is not set
913# CONFIG_SMB_FS is not set
914# CONFIG_CIFS is not set
915# CONFIG_NCP_FS is not set
916# CONFIG_CODA_FS is not set
917# CONFIG_AFS_FS is not set
918# CONFIG_9P_FS is not set
919
920#
921# Partition Types
922#
923CONFIG_PARTITION_ADVANCED=y
924# CONFIG_ACORN_PARTITION is not set
925# CONFIG_OSF_PARTITION is not set
926# CONFIG_AMIGA_PARTITION is not set
927# CONFIG_ATARI_PARTITION is not set
928# CONFIG_MAC_PARTITION is not set
929# CONFIG_MSDOS_PARTITION is not set
930# CONFIG_LDM_PARTITION is not set
931# CONFIG_SGI_PARTITION is not set
932# CONFIG_ULTRIX_PARTITION is not set
933# CONFIG_SUN_PARTITION is not set
934# CONFIG_EFI_PARTITION is not set
935
936#
937# Native Language Support
938#
939# CONFIG_NLS is not set
940
941#
942# Library routines
943#
944# CONFIG_CRC_CCITT is not set
945# CONFIG_CRC16 is not set
946CONFIG_CRC32=y
947# CONFIG_LIBCRC32C is not set
948CONFIG_ZLIB_INFLATE=y
949CONFIG_ZLIB_DEFLATE=y
950# CONFIG_PROFILING is not set
951
952#
953# Kernel hacking
954#
955# CONFIG_PRINTK_TIME is not set
956# CONFIG_DEBUG_KERNEL is not set
957CONFIG_LOG_BUF_SHIFT=14
958# CONFIG_SERIAL_TEXT_DEBUG is not set
959
960#
961# Security options
962#
963# CONFIG_KEYS is not set
964# CONFIG_SECURITY is not set
965
966#
967# Cryptographic options
968#
969# CONFIG_CRYPTO is not set
970
971#
972# Hardware crypto devices
973#
diff --git a/arch/ppc/configs/TQM8541_defconfig b/arch/ppc/configs/TQM8541_defconfig
new file mode 100644
index 000000000000..0ff56695d349
--- /dev/null
+++ b/arch/ppc/configs/TQM8541_defconfig
@@ -0,0 +1,986 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.15-rc2
4# Wed Nov 30 13:36:28 2005
5#
6CONFIG_MMU=y
7CONFIG_GENERIC_HARDIRQS=y
8CONFIG_RWSEM_XCHGADD_ALGORITHM=y
9CONFIG_GENERIC_CALIBRATE_DELAY=y
10CONFIG_PPC=y
11CONFIG_PPC32=y
12CONFIG_GENERIC_NVRAM=y
13CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
14CONFIG_ARCH_MAY_HAVE_PC_FDC=y
15
16#
17# Code maturity level options
18#
19CONFIG_EXPERIMENTAL=y
20CONFIG_CLEAN_COMPILE=y
21CONFIG_BROKEN_ON_SMP=y
22CONFIG_INIT_ENV_ARG_LIMIT=32
23
24#
25# General setup
26#
27CONFIG_LOCALVERSION=""
28CONFIG_LOCALVERSION_AUTO=y
29CONFIG_SWAP=y
30CONFIG_SYSVIPC=y
31# CONFIG_POSIX_MQUEUE is not set
32# CONFIG_BSD_PROCESS_ACCT is not set
33CONFIG_SYSCTL=y
34# CONFIG_AUDIT is not set
35# CONFIG_HOTPLUG is not set
36CONFIG_KOBJECT_UEVENT=y
37# CONFIG_IKCONFIG is not set
38CONFIG_INITRAMFS_SOURCE=""
39CONFIG_EMBEDDED=y
40# CONFIG_KALLSYMS is not set
41CONFIG_PRINTK=y
42CONFIG_BUG=y
43CONFIG_BASE_FULL=y
44CONFIG_FUTEX=y
45# CONFIG_EPOLL is not set
46# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
47CONFIG_SHMEM=y
48CONFIG_CC_ALIGN_FUNCTIONS=0
49CONFIG_CC_ALIGN_LABELS=0
50CONFIG_CC_ALIGN_LOOPS=0
51CONFIG_CC_ALIGN_JUMPS=0
52# CONFIG_TINY_SHMEM is not set
53CONFIG_BASE_SMALL=0
54
55#
56# Loadable module support
57#
58# CONFIG_MODULES is not set
59
60#
61# Block layer
62#
63# CONFIG_LBD is not set
64
65#
66# IO Schedulers
67#
68CONFIG_IOSCHED_NOOP=y
69CONFIG_IOSCHED_AS=y
70CONFIG_IOSCHED_DEADLINE=y
71CONFIG_IOSCHED_CFQ=y
72CONFIG_DEFAULT_AS=y
73# CONFIG_DEFAULT_DEADLINE is not set
74# CONFIG_DEFAULT_CFQ is not set
75# CONFIG_DEFAULT_NOOP is not set
76CONFIG_DEFAULT_IOSCHED="anticipatory"
77
78#
79# Processor
80#
81# CONFIG_6xx is not set
82# CONFIG_40x is not set
83# CONFIG_44x is not set
84# CONFIG_POWER3 is not set
85# CONFIG_POWER4 is not set
86# CONFIG_8xx is not set
87# CONFIG_E200 is not set
88CONFIG_E500=y
89CONFIG_BOOKE=y
90CONFIG_FSL_BOOKE=y
91# CONFIG_PHYS_64BIT is not set
92CONFIG_SPE=y
93CONFIG_MATH_EMULATION=y
94# CONFIG_KEXEC is not set
95# CONFIG_CPU_FREQ is not set
96# CONFIG_WANT_EARLY_SERIAL is not set
97CONFIG_PPC_GEN550=y
98CONFIG_85xx=y
99CONFIG_PPC_INDIRECT_PCI_BE=y
100
101#
102# Freescale 85xx options
103#
104# CONFIG_MPC8540_ADS is not set
105# CONFIG_MPC8548_CDS is not set
106# CONFIG_MPC8555_CDS is not set
107# CONFIG_MPC8560_ADS is not set
108# CONFIG_SBC8560 is not set
109# CONFIG_STX_GP3 is not set
110# CONFIG_TQM8540 is not set
111CONFIG_TQM8541=y
112# CONFIG_TQM8555 is not set
113# CONFIG_TQM8560 is not set
114CONFIG_MPC8555=y
115
116#
117# Platform options
118#
119CONFIG_CPM2=y
120# CONFIG_PC_KEYBOARD is not set
121# CONFIG_HIGHMEM is not set
122# CONFIG_HZ_100 is not set
123CONFIG_HZ_250=y
124# CONFIG_HZ_1000 is not set
125CONFIG_HZ=250
126CONFIG_PREEMPT_NONE=y
127# CONFIG_PREEMPT_VOLUNTARY is not set
128# CONFIG_PREEMPT is not set
129CONFIG_SELECT_MEMORY_MODEL=y
130CONFIG_FLATMEM_MANUAL=y
131# CONFIG_DISCONTIGMEM_MANUAL is not set
132# CONFIG_SPARSEMEM_MANUAL is not set
133CONFIG_FLATMEM=y
134CONFIG_FLAT_NODE_MEM_MAP=y
135# CONFIG_SPARSEMEM_STATIC is not set
136CONFIG_SPLIT_PTLOCK_CPUS=4
137CONFIG_BINFMT_ELF=y
138# CONFIG_BINFMT_MISC is not set
139# CONFIG_CMDLINE_BOOL is not set
140# CONFIG_PM is not set
141# CONFIG_SOFTWARE_SUSPEND is not set
142CONFIG_SECCOMP=y
143CONFIG_ISA_DMA_API=y
144
145#
146# Bus options
147#
148CONFIG_PPC_I8259=y
149CONFIG_PPC_INDIRECT_PCI=y
150CONFIG_PCI=y
151CONFIG_PCI_DOMAINS=y
152# CONFIG_PCI_LEGACY_PROC is not set
153
154#
155# PCCARD (PCMCIA/CardBus) support
156#
157# CONFIG_PCCARD is not set
158
159#
160# Advanced setup
161#
162# CONFIG_ADVANCED_OPTIONS is not set
163
164#
165# Default settings for advanced configuration options are used
166#
167CONFIG_HIGHMEM_START=0xfe000000
168CONFIG_LOWMEM_SIZE=0x30000000
169CONFIG_KERNEL_START=0xc0000000
170CONFIG_TASK_SIZE=0x80000000
171CONFIG_BOOT_LOAD=0x00800000
172
173#
174# Networking
175#
176CONFIG_NET=y
177
178#
179# Networking options
180#
181CONFIG_PACKET=y
182# CONFIG_PACKET_MMAP is not set
183CONFIG_UNIX=y
184# CONFIG_NET_KEY is not set
185CONFIG_INET=y
186CONFIG_IP_MULTICAST=y
187# CONFIG_IP_ADVANCED_ROUTER is not set
188CONFIG_IP_FIB_HASH=y
189CONFIG_IP_PNP=y
190CONFIG_IP_PNP_DHCP=y
191CONFIG_IP_PNP_BOOTP=y
192# CONFIG_IP_PNP_RARP is not set
193# CONFIG_NET_IPIP is not set
194# CONFIG_NET_IPGRE is not set
195# CONFIG_IP_MROUTE is not set
196# CONFIG_ARPD is not set
197CONFIG_SYN_COOKIES=y
198# CONFIG_INET_AH is not set
199# CONFIG_INET_ESP is not set
200# CONFIG_INET_IPCOMP is not set
201# CONFIG_INET_TUNNEL is not set
202CONFIG_INET_DIAG=y
203CONFIG_INET_TCP_DIAG=y
204# CONFIG_TCP_CONG_ADVANCED is not set
205CONFIG_TCP_CONG_BIC=y
206# CONFIG_IPV6 is not set
207# CONFIG_NETFILTER is not set
208
209#
210# DCCP Configuration (EXPERIMENTAL)
211#
212# CONFIG_IP_DCCP is not set
213
214#
215# SCTP Configuration (EXPERIMENTAL)
216#
217# CONFIG_IP_SCTP is not set
218# CONFIG_ATM is not set
219# CONFIG_BRIDGE is not set
220# CONFIG_VLAN_8021Q is not set
221# CONFIG_DECNET is not set
222# CONFIG_LLC2 is not set
223# CONFIG_IPX is not set
224# CONFIG_ATALK is not set
225# CONFIG_X25 is not set
226# CONFIG_LAPB is not set
227# CONFIG_NET_DIVERT is not set
228# CONFIG_ECONET is not set
229# CONFIG_WAN_ROUTER is not set
230
231#
232# QoS and/or fair queueing
233#
234# CONFIG_NET_SCHED is not set
235
236#
237# Network testing
238#
239# CONFIG_NET_PKTGEN is not set
240# CONFIG_HAMRADIO is not set
241# CONFIG_IRDA is not set
242# CONFIG_BT is not set
243# CONFIG_IEEE80211 is not set
244
245#
246# Device Drivers
247#
248
249#
250# Generic Driver Options
251#
252CONFIG_STANDALONE=y
253CONFIG_PREVENT_FIRMWARE_BUILD=y
254# CONFIG_FW_LOADER is not set
255
256#
257# Connector - unified userspace <-> kernelspace linker
258#
259# CONFIG_CONNECTOR is not set
260
261#
262# Memory Technology Devices (MTD)
263#
264CONFIG_MTD=y
265# CONFIG_MTD_DEBUG is not set
266CONFIG_MTD_CONCAT=y
267CONFIG_MTD_PARTITIONS=y
268# CONFIG_MTD_REDBOOT_PARTS is not set
269CONFIG_MTD_CMDLINE_PARTS=y
270
271#
272# User Modules And Translation Layers
273#
274CONFIG_MTD_CHAR=y
275CONFIG_MTD_BLOCK=y
276# CONFIG_FTL is not set
277# CONFIG_NFTL is not set
278# CONFIG_INFTL is not set
279# CONFIG_RFD_FTL is not set
280
281#
282# RAM/ROM/Flash chip drivers
283#
284CONFIG_MTD_CFI=y
285# CONFIG_MTD_JEDECPROBE is not set
286CONFIG_MTD_GEN_PROBE=y
287# CONFIG_MTD_CFI_ADV_OPTIONS is not set
288CONFIG_MTD_MAP_BANK_WIDTH_1=y
289CONFIG_MTD_MAP_BANK_WIDTH_2=y
290CONFIG_MTD_MAP_BANK_WIDTH_4=y
291# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
292# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
293# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
294CONFIG_MTD_CFI_I1=y
295CONFIG_MTD_CFI_I2=y
296# CONFIG_MTD_CFI_I4 is not set
297# CONFIG_MTD_CFI_I8 is not set
298# CONFIG_MTD_CFI_INTELEXT is not set
299CONFIG_MTD_CFI_AMDSTD=y
300CONFIG_MTD_CFI_AMDSTD_RETRY=0
301# CONFIG_MTD_CFI_STAA is not set
302CONFIG_MTD_CFI_UTIL=y
303# CONFIG_MTD_RAM is not set
304# CONFIG_MTD_ROM is not set
305# CONFIG_MTD_ABSENT is not set
306
307#
308# Mapping drivers for chip access
309#
310# CONFIG_MTD_COMPLEX_MAPPINGS is not set
311# CONFIG_MTD_PHYSMAP is not set
312CONFIG_MTD_TQM85xx=y
313# CONFIG_MTD_PLATRAM is not set
314
315#
316# Self-contained MTD device drivers
317#
318# CONFIG_MTD_PMC551 is not set
319# CONFIG_MTD_SLRAM is not set
320# CONFIG_MTD_PHRAM is not set
321# CONFIG_MTD_MTDRAM is not set
322# CONFIG_MTD_BLKMTD is not set
323# CONFIG_MTD_BLOCK2MTD is not set
324
325#
326# Disk-On-Chip Device Drivers
327#
328# CONFIG_MTD_DOC2000 is not set
329# CONFIG_MTD_DOC2001 is not set
330# CONFIG_MTD_DOC2001PLUS is not set
331
332#
333# NAND Flash Device Drivers
334#
335# CONFIG_MTD_NAND is not set
336
337#
338# OneNAND Flash Device Drivers
339#
340# CONFIG_MTD_ONENAND is not set
341
342#
343# Parallel port support
344#
345# CONFIG_PARPORT is not set
346
347#
348# Plug and Play support
349#
350
351#
352# Block devices
353#
354# CONFIG_BLK_DEV_FD is not set
355# CONFIG_BLK_CPQ_DA is not set
356# CONFIG_BLK_CPQ_CISS_DA is not set
357# CONFIG_BLK_DEV_DAC960 is not set
358# CONFIG_BLK_DEV_UMEM is not set
359# CONFIG_BLK_DEV_COW_COMMON is not set
360CONFIG_BLK_DEV_LOOP=y
361# CONFIG_BLK_DEV_CRYPTOLOOP is not set
362# CONFIG_BLK_DEV_NBD is not set
363# CONFIG_BLK_DEV_SX8 is not set
364CONFIG_BLK_DEV_RAM=y
365CONFIG_BLK_DEV_RAM_COUNT=16
366CONFIG_BLK_DEV_RAM_SIZE=32768
367CONFIG_BLK_DEV_INITRD=y
368# CONFIG_CDROM_PKTCDVD is not set
369# CONFIG_ATA_OVER_ETH is not set
370
371#
372# ATA/ATAPI/MFM/RLL support
373#
374CONFIG_IDE=y
375CONFIG_BLK_DEV_IDE=y
376
377#
378# Please see Documentation/ide.txt for help/info on IDE drives
379#
380# CONFIG_BLK_DEV_IDE_SATA is not set
381CONFIG_BLK_DEV_IDEDISK=y
382# CONFIG_IDEDISK_MULTI_MODE is not set
383# CONFIG_BLK_DEV_IDECD is not set
384# CONFIG_BLK_DEV_IDETAPE is not set
385# CONFIG_BLK_DEV_IDEFLOPPY is not set
386# CONFIG_IDE_TASK_IOCTL is not set
387
388#
389# IDE chipset support/bugfixes
390#
391CONFIG_IDE_GENERIC=y
392CONFIG_BLK_DEV_IDEPCI=y
393CONFIG_IDEPCI_SHARE_IRQ=y
394# CONFIG_BLK_DEV_OFFBOARD is not set
395CONFIG_BLK_DEV_GENERIC=y
396# CONFIG_BLK_DEV_OPTI621 is not set
397# CONFIG_BLK_DEV_SL82C105 is not set
398CONFIG_BLK_DEV_IDEDMA_PCI=y
399# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
400CONFIG_IDEDMA_PCI_AUTO=y
401# CONFIG_IDEDMA_ONLYDISK is not set
402# CONFIG_BLK_DEV_AEC62XX is not set
403# CONFIG_BLK_DEV_ALI15X3 is not set
404# CONFIG_BLK_DEV_AMD74XX is not set
405# CONFIG_BLK_DEV_CMD64X is not set
406# CONFIG_BLK_DEV_TRIFLEX is not set
407# CONFIG_BLK_DEV_CY82C693 is not set
408# CONFIG_BLK_DEV_CS5520 is not set
409# CONFIG_BLK_DEV_CS5530 is not set
410# CONFIG_BLK_DEV_HPT34X is not set
411# CONFIG_BLK_DEV_HPT366 is not set
412# CONFIG_BLK_DEV_SC1200 is not set
413# CONFIG_BLK_DEV_PIIX is not set
414# CONFIG_BLK_DEV_IT821X is not set
415# CONFIG_BLK_DEV_NS87415 is not set
416# CONFIG_BLK_DEV_PDC202XX_OLD is not set
417# CONFIG_BLK_DEV_PDC202XX_NEW is not set
418# CONFIG_BLK_DEV_SVWKS is not set
419# CONFIG_BLK_DEV_SIIMAGE is not set
420# CONFIG_BLK_DEV_SLC90E66 is not set
421# CONFIG_BLK_DEV_TRM290 is not set
422CONFIG_BLK_DEV_VIA82CXXX=y
423# CONFIG_IDE_ARM is not set
424CONFIG_BLK_DEV_IDEDMA=y
425# CONFIG_IDEDMA_IVB is not set
426CONFIG_IDEDMA_AUTO=y
427# CONFIG_BLK_DEV_HD is not set
428
429#
430# SCSI device support
431#
432# CONFIG_RAID_ATTRS is not set
433# CONFIG_SCSI is not set
434
435#
436# Multi-device support (RAID and LVM)
437#
438# CONFIG_MD is not set
439
440#
441# Fusion MPT device support
442#
443# CONFIG_FUSION is not set
444
445#
446# IEEE 1394 (FireWire) support
447#
448# CONFIG_IEEE1394 is not set
449
450#
451# I2O device support
452#
453# CONFIG_I2O is not set
454
455#
456# Macintosh device drivers
457#
458# CONFIG_WINDFARM is not set
459
460#
461# Network device support
462#
463CONFIG_NETDEVICES=y
464# CONFIG_DUMMY is not set
465# CONFIG_BONDING is not set
466# CONFIG_EQUALIZER is not set
467# CONFIG_TUN is not set
468
469#
470# ARCnet devices
471#
472# CONFIG_ARCNET is not set
473
474#
475# PHY device support
476#
477CONFIG_PHYLIB=y
478
479#
480# MII PHY device drivers
481#
482# CONFIG_MARVELL_PHY is not set
483# CONFIG_DAVICOM_PHY is not set
484# CONFIG_QSEMI_PHY is not set
485# CONFIG_LXT_PHY is not set
486# CONFIG_CICADA_PHY is not set
487
488#
489# Ethernet (10 or 100Mbit)
490#
491CONFIG_NET_ETHERNET=y
492CONFIG_MII=y
493# CONFIG_HAPPYMEAL is not set
494# CONFIG_SUNGEM is not set
495# CONFIG_CASSINI is not set
496# CONFIG_NET_VENDOR_3COM is not set
497
498#
499# Tulip family network device support
500#
501# CONFIG_NET_TULIP is not set
502# CONFIG_HP100 is not set
503CONFIG_NET_PCI=y
504# CONFIG_PCNET32 is not set
505# CONFIG_AMD8111_ETH is not set
506# CONFIG_ADAPTEC_STARFIRE is not set
507# CONFIG_B44 is not set
508# CONFIG_FORCEDETH is not set
509# CONFIG_DGRS is not set
510# CONFIG_EEPRO100 is not set
511CONFIG_E100=y
512# CONFIG_FEALNX is not set
513# CONFIG_NATSEMI is not set
514# CONFIG_NE2K_PCI is not set
515# CONFIG_8139CP is not set
516# CONFIG_8139TOO is not set
517# CONFIG_SIS900 is not set
518# CONFIG_EPIC100 is not set
519# CONFIG_SUNDANCE is not set
520# CONFIG_TLAN is not set
521# CONFIG_VIA_RHINE is not set
522# CONFIG_FS_ENET is not set
523
524#
525# Ethernet (1000 Mbit)
526#
527# CONFIG_ACENIC is not set
528# CONFIG_DL2K is not set
529# CONFIG_E1000 is not set
530# CONFIG_NS83820 is not set
531# CONFIG_HAMACHI is not set
532# CONFIG_YELLOWFIN is not set
533# CONFIG_R8169 is not set
534# CONFIG_SIS190 is not set
535# CONFIG_SKGE is not set
536# CONFIG_SK98LIN is not set
537# CONFIG_VIA_VELOCITY is not set
538# CONFIG_TIGON3 is not set
539# CONFIG_BNX2 is not set
540CONFIG_GIANFAR=y
541CONFIG_GFAR_NAPI=y
542
543#
544# Ethernet (10000 Mbit)
545#
546# CONFIG_CHELSIO_T1 is not set
547# CONFIG_IXGB is not set
548# CONFIG_S2IO is not set
549
550#
551# Token Ring devices
552#
553# CONFIG_TR is not set
554
555#
556# Wireless LAN (non-hamradio)
557#
558# CONFIG_NET_RADIO is not set
559
560#
561# Wan interfaces
562#
563# CONFIG_WAN is not set
564# CONFIG_FDDI is not set
565# CONFIG_HIPPI is not set
566# CONFIG_PPP is not set
567# CONFIG_SLIP is not set
568# CONFIG_SHAPER is not set
569# CONFIG_NETCONSOLE is not set
570# CONFIG_NETPOLL is not set
571# CONFIG_NET_POLL_CONTROLLER is not set
572
573#
574# ISDN subsystem
575#
576# CONFIG_ISDN is not set
577
578#
579# Telephony Support
580#
581# CONFIG_PHONE is not set
582
583#
584# Input device support
585#
586CONFIG_INPUT=y
587
588#
589# Userland interfaces
590#
591# CONFIG_INPUT_MOUSEDEV is not set
592# CONFIG_INPUT_JOYDEV is not set
593# CONFIG_INPUT_TSDEV is not set
594# CONFIG_INPUT_EVDEV is not set
595# CONFIG_INPUT_EVBUG is not set
596
597#
598# Input Device Drivers
599#
600# CONFIG_INPUT_KEYBOARD is not set
601# CONFIG_INPUT_MOUSE is not set
602# CONFIG_INPUT_JOYSTICK is not set
603# CONFIG_INPUT_TOUCHSCREEN is not set
604# CONFIG_INPUT_MISC is not set
605
606#
607# Hardware I/O ports
608#
609# CONFIG_SERIO is not set
610# CONFIG_GAMEPORT is not set
611
612#
613# Character devices
614#
615# CONFIG_VT is not set
616# CONFIG_SERIAL_NONSTANDARD is not set
617
618#
619# Serial drivers
620#
621CONFIG_SERIAL_8250=y
622CONFIG_SERIAL_8250_CONSOLE=y
623CONFIG_SERIAL_8250_NR_UARTS=4
624# CONFIG_SERIAL_8250_EXTENDED is not set
625
626#
627# Non-8250 serial port support
628#
629CONFIG_SERIAL_CORE=y
630CONFIG_SERIAL_CORE_CONSOLE=y
631# CONFIG_SERIAL_CPM is not set
632# CONFIG_SERIAL_JSM is not set
633CONFIG_UNIX98_PTYS=y
634CONFIG_LEGACY_PTYS=y
635CONFIG_LEGACY_PTY_COUNT=256
636
637#
638# IPMI
639#
640# CONFIG_IPMI_HANDLER is not set
641
642#
643# Watchdog Cards
644#
645# CONFIG_WATCHDOG is not set
646# CONFIG_NVRAM is not set
647CONFIG_GEN_RTC=y
648# CONFIG_GEN_RTC_X is not set
649# CONFIG_DTLK is not set
650# CONFIG_R3964 is not set
651# CONFIG_APPLICOM is not set
652
653#
654# Ftape, the floppy tape device driver
655#
656# CONFIG_AGP is not set
657# CONFIG_DRM is not set
658# CONFIG_RAW_DRIVER is not set
659
660#
661# TPM devices
662#
663# CONFIG_TCG_TPM is not set
664# CONFIG_TELCLOCK is not set
665
666#
667# I2C support
668#
669CONFIG_I2C=y
670CONFIG_I2C_CHARDEV=y
671
672#
673# I2C Algorithms
674#
675# CONFIG_I2C_ALGOBIT is not set
676# CONFIG_I2C_ALGOPCF is not set
677# CONFIG_I2C_ALGOPCA is not set
678
679#
680# I2C Hardware Bus support
681#
682# CONFIG_I2C_ALI1535 is not set
683# CONFIG_I2C_ALI1563 is not set
684# CONFIG_I2C_ALI15X3 is not set
685# CONFIG_I2C_AMD756 is not set
686# CONFIG_I2C_AMD8111 is not set
687# CONFIG_I2C_I801 is not set
688# CONFIG_I2C_I810 is not set
689# CONFIG_I2C_PIIX4 is not set
690CONFIG_I2C_MPC=y
691# CONFIG_I2C_MPC8260 is not set
692# CONFIG_I2C_NFORCE2 is not set
693# CONFIG_I2C_PARPORT_LIGHT is not set
694# CONFIG_I2C_PROSAVAGE is not set
695# CONFIG_I2C_SAVAGE4 is not set
696# CONFIG_SCx200_ACB is not set
697# CONFIG_I2C_SIS5595 is not set
698# CONFIG_I2C_SIS630 is not set
699# CONFIG_I2C_SIS96X is not set
700# CONFIG_I2C_VIA is not set
701# CONFIG_I2C_VIAPRO is not set
702# CONFIG_I2C_VOODOO3 is not set
703# CONFIG_I2C_PCA_ISA is not set
704
705#
706# Miscellaneous I2C Chip support
707#
708CONFIG_SENSORS_DS1337=y
709# CONFIG_SENSORS_DS1374 is not set
710# CONFIG_SENSORS_EEPROM is not set
711# CONFIG_SENSORS_MAX6900 is not set
712# CONFIG_SENSORS_PCF8574 is not set
713# CONFIG_SENSORS_PCF8563 is not set
714# CONFIG_SENSORS_PCA9539 is not set
715# CONFIG_SENSORS_PCF8591 is not set
716# CONFIG_SENSORS_RTC8564 is not set
717# CONFIG_SENSORS_M41T00 is not set
718# CONFIG_SENSORS_MAX6875 is not set
719# CONFIG_RTC_X1205_I2C is not set
720# CONFIG_I2C_DEBUG_CORE is not set
721# CONFIG_I2C_DEBUG_ALGO is not set
722# CONFIG_I2C_DEBUG_BUS is not set
723# CONFIG_I2C_DEBUG_CHIP is not set
724
725#
726# Dallas's 1-wire bus
727#
728# CONFIG_W1 is not set
729
730#
731# Hardware Monitoring support
732#
733CONFIG_HWMON=y
734# CONFIG_HWMON_VID is not set
735# CONFIG_SENSORS_ADM1021 is not set
736# CONFIG_SENSORS_ADM1025 is not set
737# CONFIG_SENSORS_ADM1026 is not set
738# CONFIG_SENSORS_ADM1031 is not set
739# CONFIG_SENSORS_ADM9240 is not set
740# CONFIG_SENSORS_ASB100 is not set
741# CONFIG_SENSORS_ATXP1 is not set
742# CONFIG_SENSORS_DS1621 is not set
743# CONFIG_SENSORS_FSCHER is not set
744# CONFIG_SENSORS_FSCPOS is not set
745# CONFIG_SENSORS_GL518SM is not set
746# CONFIG_SENSORS_GL520SM is not set
747# CONFIG_SENSORS_IT87 is not set
748# CONFIG_SENSORS_LM63 is not set
749CONFIG_SENSORS_LM75=y
750# CONFIG_SENSORS_LM77 is not set
751# CONFIG_SENSORS_LM78 is not set
752# CONFIG_SENSORS_LM80 is not set
753# CONFIG_SENSORS_LM83 is not set
754# CONFIG_SENSORS_LM85 is not set
755# CONFIG_SENSORS_LM87 is not set
756# CONFIG_SENSORS_LM90 is not set
757# CONFIG_SENSORS_LM92 is not set
758# CONFIG_SENSORS_MAX1619 is not set
759# CONFIG_SENSORS_PC87360 is not set
760# CONFIG_SENSORS_SIS5595 is not set
761# CONFIG_SENSORS_SMSC47M1 is not set
762# CONFIG_SENSORS_SMSC47B397 is not set
763# CONFIG_SENSORS_VIA686A is not set
764# CONFIG_SENSORS_W83781D is not set
765# CONFIG_SENSORS_W83792D is not set
766# CONFIG_SENSORS_W83L785TS is not set
767# CONFIG_SENSORS_W83627HF is not set
768# CONFIG_SENSORS_W83627EHF is not set
769CONFIG_HWMON_DEBUG_CHIP=y
770
771#
772# Misc devices
773#
774
775#
776# Multimedia Capabilities Port drivers
777#
778
779#
780# Multimedia devices
781#
782# CONFIG_VIDEO_DEV is not set
783
784#
785# Digital Video Broadcasting Devices
786#
787# CONFIG_DVB is not set
788
789#
790# Graphics support
791#
792# CONFIG_FB is not set
793
794#
795# Sound
796#
797# CONFIG_SOUND is not set
798
799#
800# USB support
801#
802CONFIG_USB_ARCH_HAS_HCD=y
803CONFIG_USB_ARCH_HAS_OHCI=y
804# CONFIG_USB is not set
805
806#
807# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
808#
809
810#
811# USB Gadget Support
812#
813# CONFIG_USB_GADGET is not set
814
815#
816# MMC/SD Card support
817#
818# CONFIG_MMC is not set
819
820#
821# InfiniBand support
822#
823# CONFIG_INFINIBAND is not set
824
825#
826# SN Devices
827#
828
829#
830# File systems
831#
832CONFIG_EXT2_FS=y
833# CONFIG_EXT2_FS_XATTR is not set
834# CONFIG_EXT2_FS_XIP is not set
835CONFIG_EXT3_FS=y
836CONFIG_EXT3_FS_XATTR=y
837# CONFIG_EXT3_FS_POSIX_ACL is not set
838# CONFIG_EXT3_FS_SECURITY is not set
839CONFIG_JBD=y
840# CONFIG_JBD_DEBUG is not set
841CONFIG_FS_MBCACHE=y
842# CONFIG_REISERFS_FS is not set
843# CONFIG_JFS_FS is not set
844# CONFIG_FS_POSIX_ACL is not set
845# CONFIG_XFS_FS is not set
846# CONFIG_MINIX_FS is not set
847# CONFIG_ROMFS_FS is not set
848CONFIG_INOTIFY=y
849# CONFIG_QUOTA is not set
850CONFIG_DNOTIFY=y
851# CONFIG_AUTOFS_FS is not set
852# CONFIG_AUTOFS4_FS is not set
853# CONFIG_FUSE_FS is not set
854
855#
856# CD-ROM/DVD Filesystems
857#
858# CONFIG_ISO9660_FS is not set
859# CONFIG_UDF_FS is not set
860
861#
862# DOS/FAT/NT Filesystems
863#
864# CONFIG_MSDOS_FS is not set
865# CONFIG_VFAT_FS is not set
866# CONFIG_NTFS_FS is not set
867
868#
869# Pseudo filesystems
870#
871CONFIG_PROC_FS=y
872CONFIG_PROC_KCORE=y
873CONFIG_SYSFS=y
874CONFIG_TMPFS=y
875# CONFIG_HUGETLB_PAGE is not set
876CONFIG_RAMFS=y
877# CONFIG_RELAYFS_FS is not set
878
879#
880# Miscellaneous filesystems
881#
882# CONFIG_ADFS_FS is not set
883# CONFIG_AFFS_FS is not set
884# CONFIG_HFS_FS is not set
885# CONFIG_HFSPLUS_FS is not set
886# CONFIG_BEFS_FS is not set
887# CONFIG_BFS_FS is not set
888# CONFIG_EFS_FS is not set
889# CONFIG_JFFS_FS is not set
890CONFIG_JFFS2_FS=y
891CONFIG_JFFS2_FS_DEBUG=0
892CONFIG_JFFS2_FS_WRITEBUFFER=y
893# CONFIG_JFFS2_SUMMARY is not set
894# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
895CONFIG_JFFS2_ZLIB=y
896CONFIG_JFFS2_RTIME=y
897# CONFIG_JFFS2_RUBIN is not set
898CONFIG_CRAMFS=y
899# CONFIG_VXFS_FS is not set
900# CONFIG_HPFS_FS is not set
901# CONFIG_QNX4FS_FS is not set
902# CONFIG_SYSV_FS is not set
903# CONFIG_UFS_FS is not set
904
905#
906# Network File Systems
907#
908CONFIG_NFS_FS=y
909# CONFIG_NFS_V3 is not set
910# CONFIG_NFS_V4 is not set
911# CONFIG_NFS_DIRECTIO is not set
912# CONFIG_NFSD is not set
913CONFIG_ROOT_NFS=y
914CONFIG_LOCKD=y
915CONFIG_NFS_COMMON=y
916CONFIG_SUNRPC=y
917# CONFIG_RPCSEC_GSS_KRB5 is not set
918# CONFIG_RPCSEC_GSS_SPKM3 is not set
919# CONFIG_SMB_FS is not set
920# CONFIG_CIFS is not set
921# CONFIG_NCP_FS is not set
922# CONFIG_CODA_FS is not set
923# CONFIG_AFS_FS is not set
924# CONFIG_9P_FS is not set
925
926#
927# Partition Types
928#
929CONFIG_PARTITION_ADVANCED=y
930# CONFIG_ACORN_PARTITION is not set
931# CONFIG_OSF_PARTITION is not set
932# CONFIG_AMIGA_PARTITION is not set
933# CONFIG_ATARI_PARTITION is not set
934# CONFIG_MAC_PARTITION is not set
935# CONFIG_MSDOS_PARTITION is not set
936# CONFIG_LDM_PARTITION is not set
937# CONFIG_SGI_PARTITION is not set
938# CONFIG_ULTRIX_PARTITION is not set
939# CONFIG_SUN_PARTITION is not set
940# CONFIG_EFI_PARTITION is not set
941
942#
943# Native Language Support
944#
945# CONFIG_NLS is not set
946# CONFIG_SCC_ENET is not set
947# CONFIG_FEC_ENET is not set
948
949#
950# CPM2 Options
951#
952
953#
954# Library routines
955#
956# CONFIG_CRC_CCITT is not set
957# CONFIG_CRC16 is not set
958CONFIG_CRC32=y
959# CONFIG_LIBCRC32C is not set
960CONFIG_ZLIB_INFLATE=y
961CONFIG_ZLIB_DEFLATE=y
962# CONFIG_PROFILING is not set
963
964#
965# Kernel hacking
966#
967# CONFIG_PRINTK_TIME is not set
968# CONFIG_DEBUG_KERNEL is not set
969CONFIG_LOG_BUF_SHIFT=14
970# CONFIG_KGDB_CONSOLE is not set
971# CONFIG_SERIAL_TEXT_DEBUG is not set
972
973#
974# Security options
975#
976# CONFIG_KEYS is not set
977# CONFIG_SECURITY is not set
978
979#
980# Cryptographic options
981#
982# CONFIG_CRYPTO is not set
983
984#
985# Hardware crypto devices
986#
diff --git a/arch/ppc/configs/TQM8555_defconfig b/arch/ppc/configs/TQM8555_defconfig
new file mode 100644
index 000000000000..730b3db2e47a
--- /dev/null
+++ b/arch/ppc/configs/TQM8555_defconfig
@@ -0,0 +1,983 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.15-rc2
4# Thu Nov 24 17:10:52 2005
5#
6CONFIG_MMU=y
7CONFIG_GENERIC_HARDIRQS=y
8CONFIG_RWSEM_XCHGADD_ALGORITHM=y
9CONFIG_GENERIC_CALIBRATE_DELAY=y
10CONFIG_PPC=y
11CONFIG_PPC32=y
12CONFIG_GENERIC_NVRAM=y
13CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
14CONFIG_ARCH_MAY_HAVE_PC_FDC=y
15
16#
17# Code maturity level options
18#
19CONFIG_EXPERIMENTAL=y
20CONFIG_CLEAN_COMPILE=y
21CONFIG_BROKEN_ON_SMP=y
22CONFIG_INIT_ENV_ARG_LIMIT=32
23
24#
25# General setup
26#
27CONFIG_LOCALVERSION=""
28CONFIG_LOCALVERSION_AUTO=y
29CONFIG_SWAP=y
30CONFIG_SYSVIPC=y
31# CONFIG_POSIX_MQUEUE is not set
32# CONFIG_BSD_PROCESS_ACCT is not set
33CONFIG_SYSCTL=y
34# CONFIG_AUDIT is not set
35# CONFIG_HOTPLUG is not set
36CONFIG_KOBJECT_UEVENT=y
37# CONFIG_IKCONFIG is not set
38CONFIG_INITRAMFS_SOURCE=""
39CONFIG_EMBEDDED=y
40# CONFIG_KALLSYMS is not set
41CONFIG_PRINTK=y
42CONFIG_BUG=y
43CONFIG_BASE_FULL=y
44CONFIG_FUTEX=y
45# CONFIG_EPOLL is not set
46# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
47CONFIG_SHMEM=y
48CONFIG_CC_ALIGN_FUNCTIONS=0
49CONFIG_CC_ALIGN_LABELS=0
50CONFIG_CC_ALIGN_LOOPS=0
51CONFIG_CC_ALIGN_JUMPS=0
52# CONFIG_TINY_SHMEM is not set
53CONFIG_BASE_SMALL=0
54
55#
56# Loadable module support
57#
58# CONFIG_MODULES is not set
59
60#
61# Block layer
62#
63# CONFIG_LBD is not set
64
65#
66# IO Schedulers
67#
68CONFIG_IOSCHED_NOOP=y
69CONFIG_IOSCHED_AS=y
70CONFIG_IOSCHED_DEADLINE=y
71CONFIG_IOSCHED_CFQ=y
72CONFIG_DEFAULT_AS=y
73# CONFIG_DEFAULT_DEADLINE is not set
74# CONFIG_DEFAULT_CFQ is not set
75# CONFIG_DEFAULT_NOOP is not set
76CONFIG_DEFAULT_IOSCHED="anticipatory"
77
78#
79# Processor
80#
81# CONFIG_6xx is not set
82# CONFIG_40x is not set
83# CONFIG_44x is not set
84# CONFIG_POWER3 is not set
85# CONFIG_POWER4 is not set
86# CONFIG_8xx is not set
87# CONFIG_E200 is not set
88CONFIG_E500=y
89CONFIG_BOOKE=y
90CONFIG_FSL_BOOKE=y
91# CONFIG_PHYS_64BIT is not set
92CONFIG_SPE=y
93CONFIG_MATH_EMULATION=y
94# CONFIG_KEXEC is not set
95# CONFIG_CPU_FREQ is not set
96# CONFIG_WANT_EARLY_SERIAL is not set
97CONFIG_PPC_GEN550=y
98CONFIG_85xx=y
99CONFIG_PPC_INDIRECT_PCI_BE=y
100
101#
102# Freescale 85xx options
103#
104# CONFIG_MPC8540_ADS is not set
105# CONFIG_MPC8548_CDS is not set
106# CONFIG_MPC8555_CDS is not set
107# CONFIG_MPC8560_ADS is not set
108# CONFIG_SBC8560 is not set
109# CONFIG_STX_GP3 is not set
110# CONFIG_TQM8540 is not set
111# CONFIG_TQM8541 is not set
112CONFIG_TQM8555=y
113# CONFIG_TQM8560 is not set
114CONFIG_MPC8555=y
115
116#
117# Platform options
118#
119CONFIG_CPM2=y
120# CONFIG_PC_KEYBOARD is not set
121# CONFIG_HIGHMEM is not set
122# CONFIG_HZ_100 is not set
123CONFIG_HZ_250=y
124# CONFIG_HZ_1000 is not set
125CONFIG_HZ=250
126CONFIG_PREEMPT_NONE=y
127# CONFIG_PREEMPT_VOLUNTARY is not set
128# CONFIG_PREEMPT is not set
129CONFIG_SELECT_MEMORY_MODEL=y
130CONFIG_FLATMEM_MANUAL=y
131# CONFIG_DISCONTIGMEM_MANUAL is not set
132# CONFIG_SPARSEMEM_MANUAL is not set
133CONFIG_FLATMEM=y
134CONFIG_FLAT_NODE_MEM_MAP=y
135# CONFIG_SPARSEMEM_STATIC is not set
136CONFIG_SPLIT_PTLOCK_CPUS=4
137CONFIG_BINFMT_ELF=y
138# CONFIG_BINFMT_MISC is not set
139# CONFIG_CMDLINE_BOOL is not set
140# CONFIG_PM is not set
141# CONFIG_SOFTWARE_SUSPEND is not set
142CONFIG_SECCOMP=y
143CONFIG_ISA_DMA_API=y
144
145#
146# Bus options
147#
148CONFIG_PPC_I8259=y
149CONFIG_PPC_INDIRECT_PCI=y
150CONFIG_PCI=y
151CONFIG_PCI_DOMAINS=y
152# CONFIG_PCI_LEGACY_PROC is not set
153
154#
155# PCCARD (PCMCIA/CardBus) support
156#
157# CONFIG_PCCARD is not set
158
159#
160# Advanced setup
161#
162# CONFIG_ADVANCED_OPTIONS is not set
163
164#
165# Default settings for advanced configuration options are used
166#
167CONFIG_HIGHMEM_START=0xfe000000
168CONFIG_LOWMEM_SIZE=0x30000000
169CONFIG_KERNEL_START=0xc0000000
170CONFIG_TASK_SIZE=0x80000000
171CONFIG_BOOT_LOAD=0x00800000
172
173#
174# Networking
175#
176CONFIG_NET=y
177
178#
179# Networking options
180#
181CONFIG_PACKET=y
182# CONFIG_PACKET_MMAP is not set
183CONFIG_UNIX=y
184# CONFIG_NET_KEY is not set
185CONFIG_INET=y
186CONFIG_IP_MULTICAST=y
187# CONFIG_IP_ADVANCED_ROUTER is not set
188CONFIG_IP_FIB_HASH=y
189CONFIG_IP_PNP=y
190CONFIG_IP_PNP_DHCP=y
191CONFIG_IP_PNP_BOOTP=y
192# CONFIG_IP_PNP_RARP is not set
193# CONFIG_NET_IPIP is not set
194# CONFIG_NET_IPGRE is not set
195# CONFIG_IP_MROUTE is not set
196# CONFIG_ARPD is not set
197CONFIG_SYN_COOKIES=y
198# CONFIG_INET_AH is not set
199# CONFIG_INET_ESP is not set
200# CONFIG_INET_IPCOMP is not set
201# CONFIG_INET_TUNNEL is not set
202CONFIG_INET_DIAG=y
203CONFIG_INET_TCP_DIAG=y
204# CONFIG_TCP_CONG_ADVANCED is not set
205CONFIG_TCP_CONG_BIC=y
206# CONFIG_IPV6 is not set
207# CONFIG_NETFILTER is not set
208
209#
210# DCCP Configuration (EXPERIMENTAL)
211#
212# CONFIG_IP_DCCP is not set
213
214#
215# SCTP Configuration (EXPERIMENTAL)
216#
217# CONFIG_IP_SCTP is not set
218# CONFIG_ATM is not set
219# CONFIG_BRIDGE is not set
220# CONFIG_VLAN_8021Q is not set
221# CONFIG_DECNET is not set
222# CONFIG_LLC2 is not set
223# CONFIG_IPX is not set
224# CONFIG_ATALK is not set
225# CONFIG_X25 is not set
226# CONFIG_LAPB is not set
227# CONFIG_NET_DIVERT is not set
228# CONFIG_ECONET is not set
229# CONFIG_WAN_ROUTER is not set
230
231#
232# QoS and/or fair queueing
233#
234# CONFIG_NET_SCHED is not set
235
236#
237# Network testing
238#
239# CONFIG_NET_PKTGEN is not set
240# CONFIG_HAMRADIO is not set
241# CONFIG_IRDA is not set
242# CONFIG_BT is not set
243# CONFIG_IEEE80211 is not set
244
245#
246# Device Drivers
247#
248
249#
250# Generic Driver Options
251#
252CONFIG_STANDALONE=y
253CONFIG_PREVENT_FIRMWARE_BUILD=y
254# CONFIG_FW_LOADER is not set
255
256#
257# Connector - unified userspace <-> kernelspace linker
258#
259# CONFIG_CONNECTOR is not set
260
261#
262# Memory Technology Devices (MTD)
263#
264CONFIG_MTD=y
265# CONFIG_MTD_DEBUG is not set
266CONFIG_MTD_CONCAT=y
267CONFIG_MTD_PARTITIONS=y
268# CONFIG_MTD_REDBOOT_PARTS is not set
269CONFIG_MTD_CMDLINE_PARTS=y
270
271#
272# User Modules And Translation Layers
273#
274CONFIG_MTD_CHAR=y
275CONFIG_MTD_BLOCK=y
276# CONFIG_FTL is not set
277# CONFIG_NFTL is not set
278# CONFIG_INFTL is not set
279# CONFIG_RFD_FTL is not set
280
281#
282# RAM/ROM/Flash chip drivers
283#
284CONFIG_MTD_CFI=y
285# CONFIG_MTD_JEDECPROBE is not set
286CONFIG_MTD_GEN_PROBE=y
287# CONFIG_MTD_CFI_ADV_OPTIONS is not set
288CONFIG_MTD_MAP_BANK_WIDTH_1=y
289CONFIG_MTD_MAP_BANK_WIDTH_2=y
290CONFIG_MTD_MAP_BANK_WIDTH_4=y
291# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
292# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
293# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
294CONFIG_MTD_CFI_I1=y
295CONFIG_MTD_CFI_I2=y
296# CONFIG_MTD_CFI_I4 is not set
297# CONFIG_MTD_CFI_I8 is not set
298# CONFIG_MTD_CFI_INTELEXT is not set
299CONFIG_MTD_CFI_AMDSTD=y
300CONFIG_MTD_CFI_AMDSTD_RETRY=0
301# CONFIG_MTD_CFI_STAA is not set
302CONFIG_MTD_CFI_UTIL=y
303# CONFIG_MTD_RAM is not set
304# CONFIG_MTD_ROM is not set
305# CONFIG_MTD_ABSENT is not set
306
307#
308# Mapping drivers for chip access
309#
310# CONFIG_MTD_COMPLEX_MAPPINGS is not set
311# CONFIG_MTD_PHYSMAP is not set
312CONFIG_MTD_TQM85xx=y
313# CONFIG_MTD_PLATRAM is not set
314
315#
316# Self-contained MTD device drivers
317#
318# CONFIG_MTD_PMC551 is not set
319# CONFIG_MTD_SLRAM is not set
320# CONFIG_MTD_PHRAM is not set
321# CONFIG_MTD_MTDRAM is not set
322# CONFIG_MTD_BLKMTD is not set
323# CONFIG_MTD_BLOCK2MTD is not set
324
325#
326# Disk-On-Chip Device Drivers
327#
328# CONFIG_MTD_DOC2000 is not set
329# CONFIG_MTD_DOC2001 is not set
330# CONFIG_MTD_DOC2001PLUS is not set
331
332#
333# NAND Flash Device Drivers
334#
335# CONFIG_MTD_NAND is not set
336
337#
338# OneNAND Flash Device Drivers
339#
340# CONFIG_MTD_ONENAND is not set
341
342#
343# Parallel port support
344#
345# CONFIG_PARPORT is not set
346
347#
348# Plug and Play support
349#
350
351#
352# Block devices
353#
354# CONFIG_BLK_DEV_FD is not set
355# CONFIG_BLK_CPQ_DA is not set
356# CONFIG_BLK_CPQ_CISS_DA is not set
357# CONFIG_BLK_DEV_DAC960 is not set
358# CONFIG_BLK_DEV_UMEM is not set
359# CONFIG_BLK_DEV_COW_COMMON is not set
360CONFIG_BLK_DEV_LOOP=y
361# CONFIG_BLK_DEV_CRYPTOLOOP is not set
362# CONFIG_BLK_DEV_NBD is not set
363# CONFIG_BLK_DEV_SX8 is not set
364CONFIG_BLK_DEV_RAM=y
365CONFIG_BLK_DEV_RAM_COUNT=16
366CONFIG_BLK_DEV_RAM_SIZE=32768
367CONFIG_BLK_DEV_INITRD=y
368# CONFIG_CDROM_PKTCDVD is not set
369# CONFIG_ATA_OVER_ETH is not set
370
371#
372# ATA/ATAPI/MFM/RLL support
373#
374CONFIG_IDE=y
375CONFIG_BLK_DEV_IDE=y
376
377#
378# Please see Documentation/ide.txt for help/info on IDE drives
379#
380# CONFIG_BLK_DEV_IDE_SATA is not set
381CONFIG_BLK_DEV_IDEDISK=y
382# CONFIG_IDEDISK_MULTI_MODE is not set
383# CONFIG_BLK_DEV_IDECD is not set
384# CONFIG_BLK_DEV_IDETAPE is not set
385# CONFIG_BLK_DEV_IDEFLOPPY is not set
386# CONFIG_IDE_TASK_IOCTL is not set
387
388#
389# IDE chipset support/bugfixes
390#
391CONFIG_IDE_GENERIC=y
392CONFIG_BLK_DEV_IDEPCI=y
393CONFIG_IDEPCI_SHARE_IRQ=y
394# CONFIG_BLK_DEV_OFFBOARD is not set
395CONFIG_BLK_DEV_GENERIC=y
396# CONFIG_BLK_DEV_OPTI621 is not set
397# CONFIG_BLK_DEV_SL82C105 is not set
398CONFIG_BLK_DEV_IDEDMA_PCI=y
399# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
400CONFIG_IDEDMA_PCI_AUTO=y
401# CONFIG_IDEDMA_ONLYDISK is not set
402# CONFIG_BLK_DEV_AEC62XX is not set
403# CONFIG_BLK_DEV_ALI15X3 is not set
404# CONFIG_BLK_DEV_AMD74XX is not set
405# CONFIG_BLK_DEV_CMD64X is not set
406# CONFIG_BLK_DEV_TRIFLEX is not set
407# CONFIG_BLK_DEV_CY82C693 is not set
408# CONFIG_BLK_DEV_CS5520 is not set
409# CONFIG_BLK_DEV_CS5530 is not set
410# CONFIG_BLK_DEV_HPT34X is not set
411# CONFIG_BLK_DEV_HPT366 is not set
412# CONFIG_BLK_DEV_SC1200 is not set
413# CONFIG_BLK_DEV_PIIX is not set
414# CONFIG_BLK_DEV_IT821X is not set
415# CONFIG_BLK_DEV_NS87415 is not set
416# CONFIG_BLK_DEV_PDC202XX_OLD is not set
417# CONFIG_BLK_DEV_PDC202XX_NEW is not set
418# CONFIG_BLK_DEV_SVWKS is not set
419# CONFIG_BLK_DEV_SIIMAGE is not set
420# CONFIG_BLK_DEV_SLC90E66 is not set
421# CONFIG_BLK_DEV_TRM290 is not set
422CONFIG_BLK_DEV_VIA82CXXX=y
423# CONFIG_IDE_ARM is not set
424CONFIG_BLK_DEV_IDEDMA=y
425# CONFIG_IDEDMA_IVB is not set
426CONFIG_IDEDMA_AUTO=y
427# CONFIG_BLK_DEV_HD is not set
428
429#
430# SCSI device support
431#
432# CONFIG_RAID_ATTRS is not set
433# CONFIG_SCSI is not set
434
435#
436# Multi-device support (RAID and LVM)
437#
438# CONFIG_MD is not set
439
440#
441# Fusion MPT device support
442#
443# CONFIG_FUSION is not set
444
445#
446# IEEE 1394 (FireWire) support
447#
448# CONFIG_IEEE1394 is not set
449
450#
451# I2O device support
452#
453# CONFIG_I2O is not set
454
455#
456# Macintosh device drivers
457#
458# CONFIG_WINDFARM is not set
459
460#
461# Network device support
462#
463CONFIG_NETDEVICES=y
464# CONFIG_DUMMY is not set
465# CONFIG_BONDING is not set
466# CONFIG_EQUALIZER is not set
467# CONFIG_TUN is not set
468
469#
470# ARCnet devices
471#
472# CONFIG_ARCNET is not set
473
474#
475# PHY device support
476#
477CONFIG_PHYLIB=y
478
479#
480# MII PHY device drivers
481#
482# CONFIG_MARVELL_PHY is not set
483# CONFIG_DAVICOM_PHY is not set
484# CONFIG_QSEMI_PHY is not set
485# CONFIG_LXT_PHY is not set
486# CONFIG_CICADA_PHY is not set
487
488#
489# Ethernet (10 or 100Mbit)
490#
491CONFIG_NET_ETHERNET=y
492CONFIG_MII=y
493# CONFIG_HAPPYMEAL is not set
494# CONFIG_SUNGEM is not set
495# CONFIG_CASSINI is not set
496# CONFIG_NET_VENDOR_3COM is not set
497
498#
499# Tulip family network device support
500#
501# CONFIG_NET_TULIP is not set
502# CONFIG_HP100 is not set
503CONFIG_NET_PCI=y
504# CONFIG_PCNET32 is not set
505# CONFIG_AMD8111_ETH is not set
506# CONFIG_ADAPTEC_STARFIRE is not set
507# CONFIG_B44 is not set
508# CONFIG_FORCEDETH is not set
509# CONFIG_DGRS is not set
510# CONFIG_EEPRO100 is not set
511CONFIG_E100=y
512# CONFIG_FEALNX is not set
513# CONFIG_NATSEMI is not set
514# CONFIG_NE2K_PCI is not set
515# CONFIG_8139CP is not set
516# CONFIG_8139TOO is not set
517# CONFIG_SIS900 is not set
518# CONFIG_EPIC100 is not set
519# CONFIG_SUNDANCE is not set
520# CONFIG_TLAN is not set
521# CONFIG_VIA_RHINE is not set
522# CONFIG_FS_ENET is not set
523
524#
525# Ethernet (1000 Mbit)
526#
527# CONFIG_ACENIC is not set
528# CONFIG_DL2K is not set
529# CONFIG_E1000 is not set
530# CONFIG_NS83820 is not set
531# CONFIG_HAMACHI is not set
532# CONFIG_YELLOWFIN is not set
533# CONFIG_R8169 is not set
534# CONFIG_SIS190 is not set
535# CONFIG_SKGE is not set
536# CONFIG_SK98LIN is not set
537# CONFIG_VIA_VELOCITY is not set
538# CONFIG_TIGON3 is not set
539# CONFIG_BNX2 is not set
540CONFIG_GIANFAR=y
541CONFIG_GFAR_NAPI=y
542
543#
544# Ethernet (10000 Mbit)
545#
546# CONFIG_CHELSIO_T1 is not set
547# CONFIG_IXGB is not set
548# CONFIG_S2IO is not set
549
550#
551# Token Ring devices
552#
553# CONFIG_TR is not set
554
555#
556# Wireless LAN (non-hamradio)
557#
558# CONFIG_NET_RADIO is not set
559
560#
561# Wan interfaces
562#
563# CONFIG_WAN is not set
564# CONFIG_FDDI is not set
565# CONFIG_HIPPI is not set
566# CONFIG_PPP is not set
567# CONFIG_SLIP is not set
568# CONFIG_SHAPER is not set
569# CONFIG_NETCONSOLE is not set
570# CONFIG_NETPOLL is not set
571# CONFIG_NET_POLL_CONTROLLER is not set
572
573#
574# ISDN subsystem
575#
576# CONFIG_ISDN is not set
577
578#
579# Telephony Support
580#
581# CONFIG_PHONE is not set
582
583#
584# Input device support
585#
586CONFIG_INPUT=y
587
588#
589# Userland interfaces
590#
591# CONFIG_INPUT_MOUSEDEV is not set
592# CONFIG_INPUT_JOYDEV is not set
593# CONFIG_INPUT_TSDEV is not set
594# CONFIG_INPUT_EVDEV is not set
595# CONFIG_INPUT_EVBUG is not set
596
597#
598# Input Device Drivers
599#
600# CONFIG_INPUT_KEYBOARD is not set
601# CONFIG_INPUT_MOUSE is not set
602# CONFIG_INPUT_JOYSTICK is not set
603# CONFIG_INPUT_TOUCHSCREEN is not set
604# CONFIG_INPUT_MISC is not set
605
606#
607# Hardware I/O ports
608#
609# CONFIG_SERIO is not set
610# CONFIG_GAMEPORT is not set
611
612#
613# Character devices
614#
615# CONFIG_VT is not set
616# CONFIG_SERIAL_NONSTANDARD is not set
617
618#
619# Serial drivers
620#
621CONFIG_SERIAL_8250=y
622CONFIG_SERIAL_8250_CONSOLE=y
623CONFIG_SERIAL_8250_NR_UARTS=4
624# CONFIG_SERIAL_8250_EXTENDED is not set
625
626#
627# Non-8250 serial port support
628#
629CONFIG_SERIAL_CORE=y
630CONFIG_SERIAL_CORE_CONSOLE=y
631# CONFIG_SERIAL_CPM is not set
632# CONFIG_SERIAL_JSM is not set
633CONFIG_UNIX98_PTYS=y
634CONFIG_LEGACY_PTYS=y
635CONFIG_LEGACY_PTY_COUNT=256
636
637#
638# IPMI
639#
640# CONFIG_IPMI_HANDLER is not set
641
642#
643# Watchdog Cards
644#
645# CONFIG_WATCHDOG is not set
646# CONFIG_NVRAM is not set
647CONFIG_GEN_RTC=y
648# CONFIG_GEN_RTC_X is not set
649# CONFIG_DTLK is not set
650# CONFIG_R3964 is not set
651# CONFIG_APPLICOM is not set
652
653#
654# Ftape, the floppy tape device driver
655#
656# CONFIG_AGP is not set
657# CONFIG_DRM is not set
658# CONFIG_RAW_DRIVER is not set
659
660#
661# TPM devices
662#
663# CONFIG_TCG_TPM is not set
664# CONFIG_TELCLOCK is not set
665
666#
667# I2C support
668#
669CONFIG_I2C=y
670CONFIG_I2C_CHARDEV=y
671
672#
673# I2C Algorithms
674#
675# CONFIG_I2C_ALGOBIT is not set
676# CONFIG_I2C_ALGOPCF is not set
677# CONFIG_I2C_ALGOPCA is not set
678
679#
680# I2C Hardware Bus support
681#
682# CONFIG_I2C_ALI1535 is not set
683# CONFIG_I2C_ALI1563 is not set
684# CONFIG_I2C_ALI15X3 is not set
685# CONFIG_I2C_AMD756 is not set
686# CONFIG_I2C_AMD8111 is not set
687# CONFIG_I2C_I801 is not set
688# CONFIG_I2C_I810 is not set
689# CONFIG_I2C_PIIX4 is not set
690CONFIG_I2C_MPC=y
691# CONFIG_I2C_NFORCE2 is not set
692# CONFIG_I2C_PARPORT_LIGHT is not set
693# CONFIG_I2C_PROSAVAGE is not set
694# CONFIG_I2C_SAVAGE4 is not set
695# CONFIG_SCx200_ACB is not set
696# CONFIG_I2C_SIS5595 is not set
697# CONFIG_I2C_SIS630 is not set
698# CONFIG_I2C_SIS96X is not set
699# CONFIG_I2C_VIA is not set
700# CONFIG_I2C_VIAPRO is not set
701# CONFIG_I2C_VOODOO3 is not set
702# CONFIG_I2C_PCA_ISA is not set
703
704#
705# Miscellaneous I2C Chip support
706#
707CONFIG_SENSORS_DS1337=y
708# CONFIG_SENSORS_DS1374 is not set
709# CONFIG_SENSORS_EEPROM is not set
710# CONFIG_SENSORS_PCF8574 is not set
711# CONFIG_SENSORS_PCA9539 is not set
712# CONFIG_SENSORS_PCF8591 is not set
713# CONFIG_SENSORS_RTC8564 is not set
714# CONFIG_SENSORS_M41T00 is not set
715# CONFIG_SENSORS_MAX6875 is not set
716# CONFIG_RTC_X1205_I2C is not set
717# CONFIG_I2C_DEBUG_CORE is not set
718# CONFIG_I2C_DEBUG_ALGO is not set
719# CONFIG_I2C_DEBUG_BUS is not set
720# CONFIG_I2C_DEBUG_CHIP is not set
721
722#
723# Dallas's 1-wire bus
724#
725# CONFIG_W1 is not set
726
727#
728# Hardware Monitoring support
729#
730CONFIG_HWMON=y
731# CONFIG_HWMON_VID is not set
732# CONFIG_SENSORS_ADM1021 is not set
733# CONFIG_SENSORS_ADM1025 is not set
734# CONFIG_SENSORS_ADM1026 is not set
735# CONFIG_SENSORS_ADM1031 is not set
736# CONFIG_SENSORS_ADM9240 is not set
737# CONFIG_SENSORS_ASB100 is not set
738# CONFIG_SENSORS_ATXP1 is not set
739# CONFIG_SENSORS_DS1621 is not set
740# CONFIG_SENSORS_FSCHER is not set
741# CONFIG_SENSORS_FSCPOS is not set
742# CONFIG_SENSORS_GL518SM is not set
743# CONFIG_SENSORS_GL520SM is not set
744# CONFIG_SENSORS_IT87 is not set
745# CONFIG_SENSORS_LM63 is not set
746CONFIG_SENSORS_LM75=y
747# CONFIG_SENSORS_LM77 is not set
748# CONFIG_SENSORS_LM78 is not set
749# CONFIG_SENSORS_LM80 is not set
750# CONFIG_SENSORS_LM83 is not set
751# CONFIG_SENSORS_LM85 is not set
752# CONFIG_SENSORS_LM87 is not set
753# CONFIG_SENSORS_LM90 is not set
754# CONFIG_SENSORS_LM92 is not set
755# CONFIG_SENSORS_MAX1619 is not set
756# CONFIG_SENSORS_PC87360 is not set
757# CONFIG_SENSORS_SIS5595 is not set
758# CONFIG_SENSORS_SMSC47M1 is not set
759# CONFIG_SENSORS_SMSC47B397 is not set
760# CONFIG_SENSORS_VIA686A is not set
761# CONFIG_SENSORS_W83781D is not set
762# CONFIG_SENSORS_W83792D is not set
763# CONFIG_SENSORS_W83L785TS is not set
764# CONFIG_SENSORS_W83627HF is not set
765# CONFIG_SENSORS_W83627EHF is not set
766CONFIG_HWMON_DEBUG_CHIP=y
767
768#
769# Misc devices
770#
771
772#
773# Multimedia Capabilities Port drivers
774#
775
776#
777# Multimedia devices
778#
779# CONFIG_VIDEO_DEV is not set
780
781#
782# Digital Video Broadcasting Devices
783#
784# CONFIG_DVB is not set
785
786#
787# Graphics support
788#
789# CONFIG_FB is not set
790
791#
792# Sound
793#
794# CONFIG_SOUND is not set
795
796#
797# USB support
798#
799CONFIG_USB_ARCH_HAS_HCD=y
800CONFIG_USB_ARCH_HAS_OHCI=y
801# CONFIG_USB is not set
802
803#
804# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
805#
806
807#
808# USB Gadget Support
809#
810# CONFIG_USB_GADGET is not set
811
812#
813# MMC/SD Card support
814#
815# CONFIG_MMC is not set
816
817#
818# InfiniBand support
819#
820# CONFIG_INFINIBAND is not set
821
822#
823# SN Devices
824#
825
826#
827# File systems
828#
829CONFIG_EXT2_FS=y
830# CONFIG_EXT2_FS_XATTR is not set
831# CONFIG_EXT2_FS_XIP is not set
832CONFIG_EXT3_FS=y
833CONFIG_EXT3_FS_XATTR=y
834# CONFIG_EXT3_FS_POSIX_ACL is not set
835# CONFIG_EXT3_FS_SECURITY is not set
836CONFIG_JBD=y
837# CONFIG_JBD_DEBUG is not set
838CONFIG_FS_MBCACHE=y
839# CONFIG_REISERFS_FS is not set
840# CONFIG_JFS_FS is not set
841# CONFIG_FS_POSIX_ACL is not set
842# CONFIG_XFS_FS is not set
843# CONFIG_MINIX_FS is not set
844# CONFIG_ROMFS_FS is not set
845CONFIG_INOTIFY=y
846# CONFIG_QUOTA is not set
847CONFIG_DNOTIFY=y
848# CONFIG_AUTOFS_FS is not set
849# CONFIG_AUTOFS4_FS is not set
850# CONFIG_FUSE_FS is not set
851
852#
853# CD-ROM/DVD Filesystems
854#
855# CONFIG_ISO9660_FS is not set
856# CONFIG_UDF_FS is not set
857
858#
859# DOS/FAT/NT Filesystems
860#
861# CONFIG_MSDOS_FS is not set
862# CONFIG_VFAT_FS is not set
863# CONFIG_NTFS_FS is not set
864
865#
866# Pseudo filesystems
867#
868CONFIG_PROC_FS=y
869CONFIG_PROC_KCORE=y
870CONFIG_SYSFS=y
871CONFIG_TMPFS=y
872# CONFIG_HUGETLB_PAGE is not set
873CONFIG_RAMFS=y
874# CONFIG_RELAYFS_FS is not set
875
876#
877# Miscellaneous filesystems
878#
879# CONFIG_ADFS_FS is not set
880# CONFIG_AFFS_FS is not set
881# CONFIG_HFS_FS is not set
882# CONFIG_HFSPLUS_FS is not set
883# CONFIG_BEFS_FS is not set
884# CONFIG_BFS_FS is not set
885# CONFIG_EFS_FS is not set
886# CONFIG_JFFS_FS is not set
887CONFIG_JFFS2_FS=y
888CONFIG_JFFS2_FS_DEBUG=0
889CONFIG_JFFS2_FS_WRITEBUFFER=y
890# CONFIG_JFFS2_SUMMARY is not set
891# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
892CONFIG_JFFS2_ZLIB=y
893CONFIG_JFFS2_RTIME=y
894# CONFIG_JFFS2_RUBIN is not set
895CONFIG_CRAMFS=y
896# CONFIG_VXFS_FS is not set
897# CONFIG_HPFS_FS is not set
898# CONFIG_QNX4FS_FS is not set
899# CONFIG_SYSV_FS is not set
900# CONFIG_UFS_FS is not set
901
902#
903# Network File Systems
904#
905CONFIG_NFS_FS=y
906# CONFIG_NFS_V3 is not set
907# CONFIG_NFS_V4 is not set
908# CONFIG_NFS_DIRECTIO is not set
909# CONFIG_NFSD is not set
910CONFIG_ROOT_NFS=y
911CONFIG_LOCKD=y
912CONFIG_NFS_COMMON=y
913CONFIG_SUNRPC=y
914# CONFIG_RPCSEC_GSS_KRB5 is not set
915# CONFIG_RPCSEC_GSS_SPKM3 is not set
916# CONFIG_SMB_FS is not set
917# CONFIG_CIFS is not set
918# CONFIG_NCP_FS is not set
919# CONFIG_CODA_FS is not set
920# CONFIG_AFS_FS is not set
921# CONFIG_9P_FS is not set
922
923#
924# Partition Types
925#
926CONFIG_PARTITION_ADVANCED=y
927# CONFIG_ACORN_PARTITION is not set
928# CONFIG_OSF_PARTITION is not set
929# CONFIG_AMIGA_PARTITION is not set
930# CONFIG_ATARI_PARTITION is not set
931# CONFIG_MAC_PARTITION is not set
932# CONFIG_MSDOS_PARTITION is not set
933# CONFIG_LDM_PARTITION is not set
934# CONFIG_SGI_PARTITION is not set
935# CONFIG_ULTRIX_PARTITION is not set
936# CONFIG_SUN_PARTITION is not set
937# CONFIG_EFI_PARTITION is not set
938
939#
940# Native Language Support
941#
942# CONFIG_NLS is not set
943# CONFIG_SCC_ENET is not set
944# CONFIG_FEC_ENET is not set
945
946#
947# CPM2 Options
948#
949
950#
951# Library routines
952#
953# CONFIG_CRC_CCITT is not set
954# CONFIG_CRC16 is not set
955CONFIG_CRC32=y
956# CONFIG_LIBCRC32C is not set
957CONFIG_ZLIB_INFLATE=y
958CONFIG_ZLIB_DEFLATE=y
959# CONFIG_PROFILING is not set
960
961#
962# Kernel hacking
963#
964# CONFIG_PRINTK_TIME is not set
965# CONFIG_DEBUG_KERNEL is not set
966CONFIG_LOG_BUF_SHIFT=14
967# CONFIG_KGDB_CONSOLE is not set
968# CONFIG_SERIAL_TEXT_DEBUG is not set
969
970#
971# Security options
972#
973# CONFIG_KEYS is not set
974# CONFIG_SECURITY is not set
975
976#
977# Cryptographic options
978#
979# CONFIG_CRYPTO is not set
980
981#
982# Hardware crypto devices
983#
diff --git a/arch/ppc/configs/TQM8560_defconfig b/arch/ppc/configs/TQM8560_defconfig
new file mode 100644
index 000000000000..1d902072825e
--- /dev/null
+++ b/arch/ppc/configs/TQM8560_defconfig
@@ -0,0 +1,992 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.15-rc2
4# Wed Nov 30 16:47:53 2005
5#
6CONFIG_MMU=y
7CONFIG_GENERIC_HARDIRQS=y
8CONFIG_RWSEM_XCHGADD_ALGORITHM=y
9CONFIG_GENERIC_CALIBRATE_DELAY=y
10CONFIG_PPC=y
11CONFIG_PPC32=y
12CONFIG_GENERIC_NVRAM=y
13CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
14CONFIG_ARCH_MAY_HAVE_PC_FDC=y
15
16#
17# Code maturity level options
18#
19CONFIG_EXPERIMENTAL=y
20CONFIG_CLEAN_COMPILE=y
21CONFIG_BROKEN_ON_SMP=y
22CONFIG_INIT_ENV_ARG_LIMIT=32
23
24#
25# General setup
26#
27CONFIG_LOCALVERSION=""
28CONFIG_LOCALVERSION_AUTO=y
29CONFIG_SWAP=y
30CONFIG_SYSVIPC=y
31# CONFIG_POSIX_MQUEUE is not set
32# CONFIG_BSD_PROCESS_ACCT is not set
33CONFIG_SYSCTL=y
34# CONFIG_AUDIT is not set
35# CONFIG_HOTPLUG is not set
36CONFIG_KOBJECT_UEVENT=y
37# CONFIG_IKCONFIG is not set
38CONFIG_INITRAMFS_SOURCE=""
39CONFIG_EMBEDDED=y
40# CONFIG_KALLSYMS is not set
41CONFIG_PRINTK=y
42CONFIG_BUG=y
43CONFIG_BASE_FULL=y
44CONFIG_FUTEX=y
45# CONFIG_EPOLL is not set
46# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
47CONFIG_SHMEM=y
48CONFIG_CC_ALIGN_FUNCTIONS=0
49CONFIG_CC_ALIGN_LABELS=0
50CONFIG_CC_ALIGN_LOOPS=0
51CONFIG_CC_ALIGN_JUMPS=0
52# CONFIG_TINY_SHMEM is not set
53CONFIG_BASE_SMALL=0
54
55#
56# Loadable module support
57#
58# CONFIG_MODULES is not set
59
60#
61# Block layer
62#
63# CONFIG_LBD is not set
64
65#
66# IO Schedulers
67#
68CONFIG_IOSCHED_NOOP=y
69CONFIG_IOSCHED_AS=y
70CONFIG_IOSCHED_DEADLINE=y
71CONFIG_IOSCHED_CFQ=y
72CONFIG_DEFAULT_AS=y
73# CONFIG_DEFAULT_DEADLINE is not set
74# CONFIG_DEFAULT_CFQ is not set
75# CONFIG_DEFAULT_NOOP is not set
76CONFIG_DEFAULT_IOSCHED="anticipatory"
77
78#
79# Processor
80#
81# CONFIG_6xx is not set
82# CONFIG_40x is not set
83# CONFIG_44x is not set
84# CONFIG_POWER3 is not set
85# CONFIG_POWER4 is not set
86# CONFIG_8xx is not set
87# CONFIG_E200 is not set
88CONFIG_E500=y
89CONFIG_BOOKE=y
90CONFIG_FSL_BOOKE=y
91# CONFIG_PHYS_64BIT is not set
92CONFIG_SPE=y
93CONFIG_MATH_EMULATION=y
94# CONFIG_KEXEC is not set
95# CONFIG_CPU_FREQ is not set
96# CONFIG_WANT_EARLY_SERIAL is not set
97CONFIG_85xx=y
98CONFIG_PPC_INDIRECT_PCI_BE=y
99
100#
101# Freescale 85xx options
102#
103# CONFIG_MPC8540_ADS is not set
104# CONFIG_MPC8548_CDS is not set
105# CONFIG_MPC8555_CDS is not set
106# CONFIG_MPC8560_ADS is not set
107# CONFIG_SBC8560 is not set
108# CONFIG_STX_GP3 is not set
109# CONFIG_TQM8540 is not set
110# CONFIG_TQM8541 is not set
111# CONFIG_TQM8555 is not set
112CONFIG_TQM8560=y
113CONFIG_MPC8560=y
114
115#
116# Platform options
117#
118CONFIG_CPM2=y
119# CONFIG_PC_KEYBOARD is not set
120# CONFIG_HIGHMEM is not set
121# CONFIG_HZ_100 is not set
122CONFIG_HZ_250=y
123# CONFIG_HZ_1000 is not set
124CONFIG_HZ=250
125CONFIG_PREEMPT_NONE=y
126# CONFIG_PREEMPT_VOLUNTARY is not set
127# CONFIG_PREEMPT is not set
128CONFIG_SELECT_MEMORY_MODEL=y
129CONFIG_FLATMEM_MANUAL=y
130# CONFIG_DISCONTIGMEM_MANUAL is not set
131# CONFIG_SPARSEMEM_MANUAL is not set
132CONFIG_FLATMEM=y
133CONFIG_FLAT_NODE_MEM_MAP=y
134# CONFIG_SPARSEMEM_STATIC is not set
135CONFIG_SPLIT_PTLOCK_CPUS=4
136CONFIG_BINFMT_ELF=y
137# CONFIG_BINFMT_MISC is not set
138# CONFIG_CMDLINE_BOOL is not set
139# CONFIG_PM is not set
140# CONFIG_SOFTWARE_SUSPEND is not set
141CONFIG_SECCOMP=y
142CONFIG_ISA_DMA_API=y
143
144#
145# Bus options
146#
147CONFIG_PPC_I8259=y
148CONFIG_PPC_INDIRECT_PCI=y
149CONFIG_PCI=y
150CONFIG_PCI_DOMAINS=y
151# CONFIG_PCI_LEGACY_PROC is not set
152
153#
154# PCCARD (PCMCIA/CardBus) support
155#
156# CONFIG_PCCARD is not set
157# CONFIG_RAPIDIO is not set
158
159#
160# Advanced setup
161#
162# CONFIG_ADVANCED_OPTIONS is not set
163
164#
165# Default settings for advanced configuration options are used
166#
167CONFIG_HIGHMEM_START=0xfe000000
168CONFIG_LOWMEM_SIZE=0x30000000
169CONFIG_KERNEL_START=0xc0000000
170CONFIG_TASK_SIZE=0x80000000
171CONFIG_BOOT_LOAD=0x00800000
172
173#
174# Networking
175#
176CONFIG_NET=y
177
178#
179# Networking options
180#
181CONFIG_PACKET=y
182# CONFIG_PACKET_MMAP is not set
183CONFIG_UNIX=y
184# CONFIG_NET_KEY is not set
185CONFIG_INET=y
186CONFIG_IP_MULTICAST=y
187# CONFIG_IP_ADVANCED_ROUTER is not set
188CONFIG_IP_FIB_HASH=y
189CONFIG_IP_PNP=y
190CONFIG_IP_PNP_DHCP=y
191CONFIG_IP_PNP_BOOTP=y
192# CONFIG_IP_PNP_RARP is not set
193# CONFIG_NET_IPIP is not set
194# CONFIG_NET_IPGRE is not set
195# CONFIG_IP_MROUTE is not set
196# CONFIG_ARPD is not set
197CONFIG_SYN_COOKIES=y
198# CONFIG_INET_AH is not set
199# CONFIG_INET_ESP is not set
200# CONFIG_INET_IPCOMP is not set
201# CONFIG_INET_TUNNEL is not set
202CONFIG_INET_DIAG=y
203CONFIG_INET_TCP_DIAG=y
204# CONFIG_TCP_CONG_ADVANCED is not set
205CONFIG_TCP_CONG_BIC=y
206# CONFIG_IPV6 is not set
207# CONFIG_NETFILTER is not set
208
209#
210# DCCP Configuration (EXPERIMENTAL)
211#
212# CONFIG_IP_DCCP is not set
213
214#
215# SCTP Configuration (EXPERIMENTAL)
216#
217# CONFIG_IP_SCTP is not set
218# CONFIG_ATM is not set
219# CONFIG_BRIDGE is not set
220# CONFIG_VLAN_8021Q is not set
221# CONFIG_DECNET is not set
222# CONFIG_LLC2 is not set
223# CONFIG_IPX is not set
224# CONFIG_ATALK is not set
225# CONFIG_X25 is not set
226# CONFIG_LAPB is not set
227# CONFIG_NET_DIVERT is not set
228# CONFIG_ECONET is not set
229# CONFIG_WAN_ROUTER is not set
230
231#
232# QoS and/or fair queueing
233#
234# CONFIG_NET_SCHED is not set
235
236#
237# Network testing
238#
239# CONFIG_NET_PKTGEN is not set
240# CONFIG_HAMRADIO is not set
241# CONFIG_IRDA is not set
242# CONFIG_BT is not set
243# CONFIG_IEEE80211 is not set
244
245#
246# Device Drivers
247#
248
249#
250# Generic Driver Options
251#
252CONFIG_STANDALONE=y
253CONFIG_PREVENT_FIRMWARE_BUILD=y
254# CONFIG_FW_LOADER is not set
255
256#
257# Connector - unified userspace <-> kernelspace linker
258#
259# CONFIG_CONNECTOR is not set
260
261#
262# Memory Technology Devices (MTD)
263#
264CONFIG_MTD=y
265# CONFIG_MTD_DEBUG is not set
266CONFIG_MTD_CONCAT=y
267CONFIG_MTD_PARTITIONS=y
268# CONFIG_MTD_REDBOOT_PARTS is not set
269CONFIG_MTD_CMDLINE_PARTS=y
270
271#
272# User Modules And Translation Layers
273#
274CONFIG_MTD_CHAR=y
275CONFIG_MTD_BLOCK=y
276# CONFIG_FTL is not set
277# CONFIG_NFTL is not set
278# CONFIG_INFTL is not set
279# CONFIG_RFD_FTL is not set
280
281#
282# RAM/ROM/Flash chip drivers
283#
284CONFIG_MTD_CFI=y
285# CONFIG_MTD_JEDECPROBE is not set
286CONFIG_MTD_GEN_PROBE=y
287# CONFIG_MTD_CFI_ADV_OPTIONS is not set
288CONFIG_MTD_MAP_BANK_WIDTH_1=y
289CONFIG_MTD_MAP_BANK_WIDTH_2=y
290CONFIG_MTD_MAP_BANK_WIDTH_4=y
291# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
292# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
293# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
294CONFIG_MTD_CFI_I1=y
295CONFIG_MTD_CFI_I2=y
296# CONFIG_MTD_CFI_I4 is not set
297# CONFIG_MTD_CFI_I8 is not set
298# CONFIG_MTD_CFI_INTELEXT is not set
299CONFIG_MTD_CFI_AMDSTD=y
300CONFIG_MTD_CFI_AMDSTD_RETRY=0
301# CONFIG_MTD_CFI_STAA is not set
302CONFIG_MTD_CFI_UTIL=y
303# CONFIG_MTD_RAM is not set
304# CONFIG_MTD_ROM is not set
305# CONFIG_MTD_ABSENT is not set
306
307#
308# Mapping drivers for chip access
309#
310# CONFIG_MTD_COMPLEX_MAPPINGS is not set
311# CONFIG_MTD_PHYSMAP is not set
312CONFIG_MTD_TQM85xx=y
313# CONFIG_MTD_PLATRAM is not set
314
315#
316# Self-contained MTD device drivers
317#
318# CONFIG_MTD_PMC551 is not set
319# CONFIG_MTD_SLRAM is not set
320# CONFIG_MTD_PHRAM is not set
321# CONFIG_MTD_MTDRAM is not set
322# CONFIG_MTD_BLKMTD is not set
323# CONFIG_MTD_BLOCK2MTD is not set
324
325#
326# Disk-On-Chip Device Drivers
327#
328# CONFIG_MTD_DOC2000 is not set
329# CONFIG_MTD_DOC2001 is not set
330# CONFIG_MTD_DOC2001PLUS is not set
331
332#
333# NAND Flash Device Drivers
334#
335# CONFIG_MTD_NAND is not set
336
337#
338# OneNAND Flash Device Drivers
339#
340# CONFIG_MTD_ONENAND is not set
341
342#
343# Parallel port support
344#
345# CONFIG_PARPORT is not set
346
347#
348# Plug and Play support
349#
350
351#
352# Block devices
353#
354# CONFIG_BLK_DEV_FD is not set
355# CONFIG_BLK_CPQ_DA is not set
356# CONFIG_BLK_CPQ_CISS_DA is not set
357# CONFIG_BLK_DEV_DAC960 is not set
358# CONFIG_BLK_DEV_UMEM is not set
359# CONFIG_BLK_DEV_COW_COMMON is not set
360CONFIG_BLK_DEV_LOOP=y
361# CONFIG_BLK_DEV_CRYPTOLOOP is not set
362# CONFIG_BLK_DEV_NBD is not set
363# CONFIG_BLK_DEV_SX8 is not set
364CONFIG_BLK_DEV_RAM=y
365CONFIG_BLK_DEV_RAM_COUNT=16
366CONFIG_BLK_DEV_RAM_SIZE=32768
367CONFIG_BLK_DEV_INITRD=y
368# CONFIG_CDROM_PKTCDVD is not set
369# CONFIG_ATA_OVER_ETH is not set
370
371#
372# ATA/ATAPI/MFM/RLL support
373#
374CONFIG_IDE=y
375CONFIG_BLK_DEV_IDE=y
376
377#
378# Please see Documentation/ide.txt for help/info on IDE drives
379#
380# CONFIG_BLK_DEV_IDE_SATA is not set
381CONFIG_BLK_DEV_IDEDISK=y
382# CONFIG_IDEDISK_MULTI_MODE is not set
383# CONFIG_BLK_DEV_IDECD is not set
384# CONFIG_BLK_DEV_IDETAPE is not set
385# CONFIG_BLK_DEV_IDEFLOPPY is not set
386# CONFIG_IDE_TASK_IOCTL is not set
387
388#
389# IDE chipset support/bugfixes
390#
391CONFIG_IDE_GENERIC=y
392CONFIG_BLK_DEV_IDEPCI=y
393CONFIG_IDEPCI_SHARE_IRQ=y
394# CONFIG_BLK_DEV_OFFBOARD is not set
395CONFIG_BLK_DEV_GENERIC=y
396# CONFIG_BLK_DEV_OPTI621 is not set
397# CONFIG_BLK_DEV_SL82C105 is not set
398CONFIG_BLK_DEV_IDEDMA_PCI=y
399# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
400CONFIG_IDEDMA_PCI_AUTO=y
401# CONFIG_IDEDMA_ONLYDISK is not set
402# CONFIG_BLK_DEV_AEC62XX is not set
403# CONFIG_BLK_DEV_ALI15X3 is not set
404# CONFIG_BLK_DEV_AMD74XX is not set
405# CONFIG_BLK_DEV_CMD64X is not set
406# CONFIG_BLK_DEV_TRIFLEX is not set
407# CONFIG_BLK_DEV_CY82C693 is not set
408# CONFIG_BLK_DEV_CS5520 is not set
409# CONFIG_BLK_DEV_CS5530 is not set
410# CONFIG_BLK_DEV_HPT34X is not set
411# CONFIG_BLK_DEV_HPT366 is not set
412# CONFIG_BLK_DEV_SC1200 is not set
413# CONFIG_BLK_DEV_PIIX is not set
414# CONFIG_BLK_DEV_IT821X is not set
415# CONFIG_BLK_DEV_NS87415 is not set
416# CONFIG_BLK_DEV_PDC202XX_OLD is not set
417# CONFIG_BLK_DEV_PDC202XX_NEW is not set
418# CONFIG_BLK_DEV_SVWKS is not set
419# CONFIG_BLK_DEV_SIIMAGE is not set
420# CONFIG_BLK_DEV_SLC90E66 is not set
421# CONFIG_BLK_DEV_TRM290 is not set
422CONFIG_BLK_DEV_VIA82CXXX=y
423# CONFIG_IDE_ARM is not set
424CONFIG_BLK_DEV_IDEDMA=y
425# CONFIG_IDEDMA_IVB is not set
426CONFIG_IDEDMA_AUTO=y
427# CONFIG_BLK_DEV_HD is not set
428
429#
430# SCSI device support
431#
432# CONFIG_RAID_ATTRS is not set
433# CONFIG_SCSI is not set
434
435#
436# Multi-device support (RAID and LVM)
437#
438# CONFIG_MD is not set
439
440#
441# Fusion MPT device support
442#
443# CONFIG_FUSION is not set
444
445#
446# IEEE 1394 (FireWire) support
447#
448# CONFIG_IEEE1394 is not set
449
450#
451# I2O device support
452#
453# CONFIG_I2O is not set
454
455#
456# Macintosh device drivers
457#
458# CONFIG_WINDFARM is not set
459
460#
461# Network device support
462#
463CONFIG_NETDEVICES=y
464# CONFIG_DUMMY is not set
465# CONFIG_BONDING is not set
466# CONFIG_EQUALIZER is not set
467# CONFIG_TUN is not set
468
469#
470# ARCnet devices
471#
472# CONFIG_ARCNET is not set
473
474#
475# PHY device support
476#
477CONFIG_PHYLIB=y
478
479#
480# MII PHY device drivers
481#
482# CONFIG_MARVELL_PHY is not set
483# CONFIG_DAVICOM_PHY is not set
484# CONFIG_QSEMI_PHY is not set
485# CONFIG_LXT_PHY is not set
486# CONFIG_CICADA_PHY is not set
487
488#
489# Ethernet (10 or 100Mbit)
490#
491CONFIG_NET_ETHERNET=y
492CONFIG_MII=y
493# CONFIG_HAPPYMEAL is not set
494# CONFIG_SUNGEM is not set
495# CONFIG_CASSINI is not set
496# CONFIG_NET_VENDOR_3COM is not set
497
498#
499# Tulip family network device support
500#
501# CONFIG_NET_TULIP is not set
502# CONFIG_HP100 is not set
503CONFIG_NET_PCI=y
504# CONFIG_PCNET32 is not set
505# CONFIG_AMD8111_ETH is not set
506# CONFIG_ADAPTEC_STARFIRE is not set
507# CONFIG_B44 is not set
508# CONFIG_FORCEDETH is not set
509# CONFIG_DGRS is not set
510# CONFIG_EEPRO100 is not set
511CONFIG_E100=y
512# CONFIG_FEALNX is not set
513# CONFIG_NATSEMI is not set
514# CONFIG_NE2K_PCI is not set
515# CONFIG_8139CP is not set
516# CONFIG_8139TOO is not set
517# CONFIG_SIS900 is not set
518# CONFIG_EPIC100 is not set
519# CONFIG_SUNDANCE is not set
520# CONFIG_TLAN is not set
521# CONFIG_VIA_RHINE is not set
522# CONFIG_FS_ENET is not set
523
524#
525# Ethernet (1000 Mbit)
526#
527# CONFIG_ACENIC is not set
528# CONFIG_DL2K is not set
529# CONFIG_E1000 is not set
530# CONFIG_NS83820 is not set
531# CONFIG_HAMACHI is not set
532# CONFIG_YELLOWFIN is not set
533# CONFIG_R8169 is not set
534# CONFIG_SIS190 is not set
535# CONFIG_SKGE is not set
536# CONFIG_SK98LIN is not set
537# CONFIG_VIA_VELOCITY is not set
538# CONFIG_TIGON3 is not set
539# CONFIG_BNX2 is not set
540CONFIG_GIANFAR=y
541CONFIG_GFAR_NAPI=y
542
543#
544# Ethernet (10000 Mbit)
545#
546# CONFIG_CHELSIO_T1 is not set
547# CONFIG_IXGB is not set
548# CONFIG_S2IO is not set
549
550#
551# Token Ring devices
552#
553# CONFIG_TR is not set
554
555#
556# Wireless LAN (non-hamradio)
557#
558# CONFIG_NET_RADIO is not set
559
560#
561# Wan interfaces
562#
563# CONFIG_WAN is not set
564# CONFIG_FDDI is not set
565# CONFIG_HIPPI is not set
566# CONFIG_PPP is not set
567# CONFIG_SLIP is not set
568# CONFIG_SHAPER is not set
569# CONFIG_NETCONSOLE is not set
570# CONFIG_NETPOLL is not set
571# CONFIG_NET_POLL_CONTROLLER is not set
572
573#
574# ISDN subsystem
575#
576# CONFIG_ISDN is not set
577
578#
579# Telephony Support
580#
581# CONFIG_PHONE is not set
582
583#
584# Input device support
585#
586CONFIG_INPUT=y
587
588#
589# Userland interfaces
590#
591# CONFIG_INPUT_MOUSEDEV is not set
592# CONFIG_INPUT_JOYDEV is not set
593# CONFIG_INPUT_TSDEV is not set
594# CONFIG_INPUT_EVDEV is not set
595# CONFIG_INPUT_EVBUG is not set
596
597#
598# Input Device Drivers
599#
600# CONFIG_INPUT_KEYBOARD is not set
601# CONFIG_INPUT_MOUSE is not set
602# CONFIG_INPUT_JOYSTICK is not set
603# CONFIG_INPUT_TOUCHSCREEN is not set
604# CONFIG_INPUT_MISC is not set
605
606#
607# Hardware I/O ports
608#
609# CONFIG_SERIO is not set
610# CONFIG_GAMEPORT is not set
611
612#
613# Character devices
614#
615# CONFIG_VT is not set
616# CONFIG_SERIAL_NONSTANDARD is not set
617
618#
619# Serial drivers
620#
621CONFIG_SERIAL_8250=y
622CONFIG_SERIAL_8250_CONSOLE=y
623CONFIG_SERIAL_8250_NR_UARTS=4
624# CONFIG_SERIAL_8250_EXTENDED is not set
625
626#
627# Non-8250 serial port support
628#
629CONFIG_SERIAL_CORE=y
630CONFIG_SERIAL_CORE_CONSOLE=y
631CONFIG_SERIAL_CPM=y
632CONFIG_SERIAL_CPM_CONSOLE=y
633CONFIG_SERIAL_CPM_SCC1=y
634# CONFIG_SERIAL_CPM_SCC2 is not set
635# CONFIG_SERIAL_CPM_SCC3 is not set
636# CONFIG_SERIAL_CPM_SCC4 is not set
637# CONFIG_SERIAL_CPM_SMC1 is not set
638# CONFIG_SERIAL_CPM_SMC2 is not set
639# CONFIG_SERIAL_JSM is not set
640CONFIG_UNIX98_PTYS=y
641CONFIG_LEGACY_PTYS=y
642CONFIG_LEGACY_PTY_COUNT=256
643
644#
645# IPMI
646#
647# CONFIG_IPMI_HANDLER is not set
648
649#
650# Watchdog Cards
651#
652# CONFIG_WATCHDOG is not set
653# CONFIG_NVRAM is not set
654CONFIG_GEN_RTC=y
655# CONFIG_GEN_RTC_X is not set
656# CONFIG_DTLK is not set
657# CONFIG_R3964 is not set
658# CONFIG_APPLICOM is not set
659
660#
661# Ftape, the floppy tape device driver
662#
663# CONFIG_AGP is not set
664# CONFIG_DRM is not set
665# CONFIG_RAW_DRIVER is not set
666
667#
668# TPM devices
669#
670# CONFIG_TCG_TPM is not set
671# CONFIG_TELCLOCK is not set
672
673#
674# I2C support
675#
676CONFIG_I2C=y
677CONFIG_I2C_CHARDEV=y
678
679#
680# I2C Algorithms
681#
682# CONFIG_I2C_ALGOBIT is not set
683# CONFIG_I2C_ALGOPCF is not set
684# CONFIG_I2C_ALGOPCA is not set
685
686#
687# I2C Hardware Bus support
688#
689# CONFIG_I2C_ALI1535 is not set
690# CONFIG_I2C_ALI1563 is not set
691# CONFIG_I2C_ALI15X3 is not set
692# CONFIG_I2C_AMD756 is not set
693# CONFIG_I2C_AMD8111 is not set
694# CONFIG_I2C_I801 is not set
695# CONFIG_I2C_I810 is not set
696# CONFIG_I2C_PIIX4 is not set
697CONFIG_I2C_MPC=y
698# CONFIG_I2C_MPC8260 is not set
699# CONFIG_I2C_NFORCE2 is not set
700# CONFIG_I2C_PARPORT_LIGHT is not set
701# CONFIG_I2C_PROSAVAGE is not set
702# CONFIG_I2C_SAVAGE4 is not set
703# CONFIG_SCx200_ACB is not set
704# CONFIG_I2C_SIS5595 is not set
705# CONFIG_I2C_SIS630 is not set
706# CONFIG_I2C_SIS96X is not set
707# CONFIG_I2C_VIA is not set
708# CONFIG_I2C_VIAPRO is not set
709# CONFIG_I2C_VOODOO3 is not set
710# CONFIG_I2C_PCA_ISA is not set
711
712#
713# Miscellaneous I2C Chip support
714#
715CONFIG_SENSORS_DS1337=y
716# CONFIG_SENSORS_DS1374 is not set
717# CONFIG_SENSORS_EEPROM is not set
718# CONFIG_SENSORS_MAX6900 is not set
719# CONFIG_SENSORS_PCF8574 is not set
720# CONFIG_SENSORS_PCF8563 is not set
721# CONFIG_SENSORS_PCA9539 is not set
722# CONFIG_SENSORS_PCF8591 is not set
723# CONFIG_SENSORS_RTC8564 is not set
724# CONFIG_SENSORS_M41T00 is not set
725# CONFIG_SENSORS_MAX6875 is not set
726# CONFIG_RTC_X1205_I2C is not set
727# CONFIG_I2C_DEBUG_CORE is not set
728# CONFIG_I2C_DEBUG_ALGO is not set
729# CONFIG_I2C_DEBUG_BUS is not set
730# CONFIG_I2C_DEBUG_CHIP is not set
731
732#
733# Dallas's 1-wire bus
734#
735# CONFIG_W1 is not set
736
737#
738# Hardware Monitoring support
739#
740CONFIG_HWMON=y
741# CONFIG_HWMON_VID is not set
742# CONFIG_SENSORS_ADM1021 is not set
743# CONFIG_SENSORS_ADM1025 is not set
744# CONFIG_SENSORS_ADM1026 is not set
745# CONFIG_SENSORS_ADM1031 is not set
746# CONFIG_SENSORS_ADM9240 is not set
747# CONFIG_SENSORS_ASB100 is not set
748# CONFIG_SENSORS_ATXP1 is not set
749# CONFIG_SENSORS_DS1621 is not set
750# CONFIG_SENSORS_FSCHER is not set
751# CONFIG_SENSORS_FSCPOS is not set
752# CONFIG_SENSORS_GL518SM is not set
753# CONFIG_SENSORS_GL520SM is not set
754# CONFIG_SENSORS_IT87 is not set
755# CONFIG_SENSORS_LM63 is not set
756CONFIG_SENSORS_LM75=y
757# CONFIG_SENSORS_LM77 is not set
758# CONFIG_SENSORS_LM78 is not set
759# CONFIG_SENSORS_LM80 is not set
760# CONFIG_SENSORS_LM83 is not set
761# CONFIG_SENSORS_LM85 is not set
762# CONFIG_SENSORS_LM87 is not set
763# CONFIG_SENSORS_LM90 is not set
764# CONFIG_SENSORS_LM92 is not set
765# CONFIG_SENSORS_MAX1619 is not set
766# CONFIG_SENSORS_PC87360 is not set
767# CONFIG_SENSORS_SIS5595 is not set
768# CONFIG_SENSORS_SMSC47M1 is not set
769# CONFIG_SENSORS_SMSC47B397 is not set
770# CONFIG_SENSORS_VIA686A is not set
771# CONFIG_SENSORS_W83781D is not set
772# CONFIG_SENSORS_W83792D is not set
773# CONFIG_SENSORS_W83L785TS is not set
774# CONFIG_SENSORS_W83627HF is not set
775# CONFIG_SENSORS_W83627EHF is not set
776CONFIG_HWMON_DEBUG_CHIP=y
777
778#
779# Misc devices
780#
781
782#
783# Multimedia Capabilities Port drivers
784#
785
786#
787# Multimedia devices
788#
789# CONFIG_VIDEO_DEV is not set
790
791#
792# Digital Video Broadcasting Devices
793#
794# CONFIG_DVB is not set
795
796#
797# Graphics support
798#
799# CONFIG_FB is not set
800
801#
802# Sound
803#
804# CONFIG_SOUND is not set
805
806#
807# USB support
808#
809CONFIG_USB_ARCH_HAS_HCD=y
810CONFIG_USB_ARCH_HAS_OHCI=y
811# CONFIG_USB is not set
812
813#
814# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
815#
816
817#
818# USB Gadget Support
819#
820# CONFIG_USB_GADGET is not set
821
822#
823# MMC/SD Card support
824#
825# CONFIG_MMC is not set
826
827#
828# InfiniBand support
829#
830# CONFIG_INFINIBAND is not set
831
832#
833# SN Devices
834#
835
836#
837# File systems
838#
839CONFIG_EXT2_FS=y
840# CONFIG_EXT2_FS_XATTR is not set
841# CONFIG_EXT2_FS_XIP is not set
842CONFIG_EXT3_FS=y
843CONFIG_EXT3_FS_XATTR=y
844# CONFIG_EXT3_FS_POSIX_ACL is not set
845# CONFIG_EXT3_FS_SECURITY is not set
846CONFIG_JBD=y
847# CONFIG_JBD_DEBUG is not set
848CONFIG_FS_MBCACHE=y
849# CONFIG_REISERFS_FS is not set
850# CONFIG_JFS_FS is not set
851# CONFIG_FS_POSIX_ACL is not set
852# CONFIG_XFS_FS is not set
853# CONFIG_MINIX_FS is not set
854# CONFIG_ROMFS_FS is not set
855CONFIG_INOTIFY=y
856# CONFIG_QUOTA is not set
857CONFIG_DNOTIFY=y
858# CONFIG_AUTOFS_FS is not set
859# CONFIG_AUTOFS4_FS is not set
860# CONFIG_FUSE_FS is not set
861
862#
863# CD-ROM/DVD Filesystems
864#
865# CONFIG_ISO9660_FS is not set
866# CONFIG_UDF_FS is not set
867
868#
869# DOS/FAT/NT Filesystems
870#
871# CONFIG_MSDOS_FS is not set
872# CONFIG_VFAT_FS is not set
873# CONFIG_NTFS_FS is not set
874
875#
876# Pseudo filesystems
877#
878CONFIG_PROC_FS=y
879CONFIG_PROC_KCORE=y
880CONFIG_SYSFS=y
881CONFIG_TMPFS=y
882# CONFIG_HUGETLB_PAGE is not set
883CONFIG_RAMFS=y
884# CONFIG_RELAYFS_FS is not set
885
886#
887# Miscellaneous filesystems
888#
889# CONFIG_ADFS_FS is not set
890# CONFIG_AFFS_FS is not set
891# CONFIG_HFS_FS is not set
892# CONFIG_HFSPLUS_FS is not set
893# CONFIG_BEFS_FS is not set
894# CONFIG_BFS_FS is not set
895# CONFIG_EFS_FS is not set
896# CONFIG_JFFS_FS is not set
897CONFIG_JFFS2_FS=y
898CONFIG_JFFS2_FS_DEBUG=0
899CONFIG_JFFS2_FS_WRITEBUFFER=y
900# CONFIG_JFFS2_SUMMARY is not set
901# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
902CONFIG_JFFS2_ZLIB=y
903CONFIG_JFFS2_RTIME=y
904# CONFIG_JFFS2_RUBIN is not set
905CONFIG_CRAMFS=y
906# CONFIG_VXFS_FS is not set
907# CONFIG_HPFS_FS is not set
908# CONFIG_QNX4FS_FS is not set
909# CONFIG_SYSV_FS is not set
910# CONFIG_UFS_FS is not set
911
912#
913# Network File Systems
914#
915CONFIG_NFS_FS=y
916# CONFIG_NFS_V3 is not set
917# CONFIG_NFS_V4 is not set
918# CONFIG_NFS_DIRECTIO is not set
919# CONFIG_NFSD is not set
920CONFIG_ROOT_NFS=y
921CONFIG_LOCKD=y
922CONFIG_NFS_COMMON=y
923CONFIG_SUNRPC=y
924# CONFIG_RPCSEC_GSS_KRB5 is not set
925# CONFIG_RPCSEC_GSS_SPKM3 is not set
926# CONFIG_SMB_FS is not set
927# CONFIG_CIFS is not set
928# CONFIG_NCP_FS is not set
929# CONFIG_CODA_FS is not set
930# CONFIG_AFS_FS is not set
931# CONFIG_9P_FS is not set
932
933#
934# Partition Types
935#
936CONFIG_PARTITION_ADVANCED=y
937# CONFIG_ACORN_PARTITION is not set
938# CONFIG_OSF_PARTITION is not set
939# CONFIG_AMIGA_PARTITION is not set
940# CONFIG_ATARI_PARTITION is not set
941# CONFIG_MAC_PARTITION is not set
942# CONFIG_MSDOS_PARTITION is not set
943# CONFIG_LDM_PARTITION is not set
944# CONFIG_SGI_PARTITION is not set
945# CONFIG_ULTRIX_PARTITION is not set
946# CONFIG_SUN_PARTITION is not set
947# CONFIG_EFI_PARTITION is not set
948
949#
950# Native Language Support
951#
952# CONFIG_NLS is not set
953# CONFIG_SCC_ENET is not set
954# CONFIG_FEC_ENET is not set
955
956#
957# CPM2 Options
958#
959
960#
961# Library routines
962#
963# CONFIG_CRC_CCITT is not set
964# CONFIG_CRC16 is not set
965CONFIG_CRC32=y
966# CONFIG_LIBCRC32C is not set
967CONFIG_ZLIB_INFLATE=y
968CONFIG_ZLIB_DEFLATE=y
969# CONFIG_PROFILING is not set
970
971#
972# Kernel hacking
973#
974# CONFIG_PRINTK_TIME is not set
975# CONFIG_DEBUG_KERNEL is not set
976CONFIG_LOG_BUF_SHIFT=14
977# CONFIG_KGDB_CONSOLE is not set
978
979#
980# Security options
981#
982# CONFIG_KEYS is not set
983# CONFIG_SECURITY is not set
984
985#
986# Cryptographic options
987#
988# CONFIG_CRYPTO is not set
989
990#
991# Hardware crypto devices
992#
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 0bb23fce4293..e6c1d615bb86 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -49,5 +49,4 @@ obj-$(CONFIG_TAU) += temp.o
49ifndef CONFIG_E200 49ifndef CONFIG_E200
50obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o 50obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o
51endif 51endif
52obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
53endif 52endif
diff --git a/arch/ppc/kernel/asm-offsets.c b/arch/ppc/kernel/asm-offsets.c
index fe0e767fb94e..7964bf660e92 100644
--- a/arch/ppc/kernel/asm-offsets.c
+++ b/arch/ppc/kernel/asm-offsets.c
@@ -131,7 +131,7 @@ main(void)
131 DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); 131 DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
132 DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); 132 DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
133 133
134 DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror)); 134 DEFINE(TI_SIGFRAME, offsetof(struct thread_info, nvgprs_frame));
135 DEFINE(TI_TASK, offsetof(struct thread_info, task)); 135 DEFINE(TI_TASK, offsetof(struct thread_info, task));
136 DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); 136 DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
137 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); 137 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index f044edbb454f..a48b950722a1 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -200,8 +200,6 @@ _GLOBAL(DoSyscall)
200 bl do_show_syscall 200 bl do_show_syscall
201#endif /* SHOW_SYSCALLS */ 201#endif /* SHOW_SYSCALLS */
202 rlwinm r10,r1,0,0,18 /* current_thread_info() */ 202 rlwinm r10,r1,0,0,18 /* current_thread_info() */
203 li r11,0
204 stb r11,TI_SC_NOERR(r10)
205 lwz r11,TI_FLAGS(r10) 203 lwz r11,TI_FLAGS(r10)
206 andi. r11,r11,_TIF_SYSCALL_T_OR_A 204 andi. r11,r11,_TIF_SYSCALL_T_OR_A
207 bne- syscall_dotrace 205 bne- syscall_dotrace
@@ -222,25 +220,21 @@ ret_from_syscall:
222 bl do_show_syscall_exit 220 bl do_show_syscall_exit
223#endif 221#endif
224 mr r6,r3 222 mr r6,r3
225 li r11,-_LAST_ERRNO
226 cmplw 0,r3,r11
227 rlwinm r12,r1,0,0,18 /* current_thread_info() */ 223 rlwinm r12,r1,0,0,18 /* current_thread_info() */
228 blt+ 30f
229 lbz r11,TI_SC_NOERR(r12)
230 cmpwi r11,0
231 bne 30f
232 neg r3,r3
233 lwz r10,_CCR(r1) /* Set SO bit in CR */
234 oris r10,r10,0x1000
235 stw r10,_CCR(r1)
236
237 /* disable interrupts so current_thread_info()->flags can't change */ 224 /* disable interrupts so current_thread_info()->flags can't change */
23830: LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ 225 LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
239 SYNC 226 SYNC
240 MTMSRD(r10) 227 MTMSRD(r10)
241 lwz r9,TI_FLAGS(r12) 228 lwz r9,TI_FLAGS(r12)
242 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED) 229 li r8,-_LAST_ERRNO
230 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
243 bne- syscall_exit_work 231 bne- syscall_exit_work
232 cmplw 0,r3,r8
233 blt+ syscall_exit_cont
234 lwz r11,_CCR(r1) /* Load CR */
235 neg r3,r3
236 oris r11,r11,0x1000 /* Set SO bit in CR */
237 stw r11,_CCR(r1)
244syscall_exit_cont: 238syscall_exit_cont:
245#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 239#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
246 /* If the process has its own DBCR0 value, load it up. The single 240 /* If the process has its own DBCR0 value, load it up. The single
@@ -292,46 +286,113 @@ syscall_dotrace:
292 b syscall_dotrace_cont 286 b syscall_dotrace_cont
293 287
294syscall_exit_work: 288syscall_exit_work:
295 stw r6,RESULT(r1) /* Save result */ 289 andi. r0,r9,_TIF_RESTOREALL
290 bne- 2f
291 cmplw 0,r3,r8
292 blt+ 1f
293 andi. r0,r9,_TIF_NOERROR
294 bne- 1f
295 lwz r11,_CCR(r1) /* Load CR */
296 neg r3,r3
297 oris r11,r11,0x1000 /* Set SO bit in CR */
298 stw r11,_CCR(r1)
299
3001: stw r6,RESULT(r1) /* Save result */
296 stw r3,GPR3(r1) /* Update return value */ 301 stw r3,GPR3(r1) /* Update return value */
297 andi. r0,r9,_TIF_SYSCALL_T_OR_A 3022: andi. r0,r9,(_TIF_PERSYSCALL_MASK)
298 beq 5f 303 beq 4f
299 ori r10,r10,MSR_EE 304
300 SYNC 305 /* Clear per-syscall TIF flags if any are set, but _leave_
301 MTMSRD(r10) /* re-enable interrupts */ 306 _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
307 yet. */
308
309 li r11,_TIF_PERSYSCALL_MASK
310 addi r12,r12,TI_FLAGS
3113: lwarx r8,0,r12
312 andc r8,r8,r11
313#ifdef CONFIG_IBM405_ERR77
314 dcbt 0,r12
315#endif
316 stwcx. r8,0,r12
317 bne- 3b
318 subi r12,r12,TI_FLAGS
319
3204: /* Anything which requires enabling interrupts? */
321 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
322 beq 7f
323
324 /* Save NVGPRS if they're not saved already */
302 lwz r4,TRAP(r1) 325 lwz r4,TRAP(r1)
303 andi. r4,r4,1 326 andi. r4,r4,1
304 beq 4f 327 beq 5f
305 SAVE_NVGPRS(r1) 328 SAVE_NVGPRS(r1)
306 li r4,0xc00 329 li r4,0xc00
307 stw r4,TRAP(r1) 330 stw r4,TRAP(r1)
3084: 331
332 /* Re-enable interrupts */
3335: ori r10,r10,MSR_EE
334 SYNC
335 MTMSRD(r10)
336
337 andi. r0,r9,_TIF_SAVE_NVGPRS
338 bne save_user_nvgprs
339
340save_user_nvgprs_cont:
341 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
342 beq 7f
343
309 addi r3,r1,STACK_FRAME_OVERHEAD 344 addi r3,r1,STACK_FRAME_OVERHEAD
310 bl do_syscall_trace_leave 345 bl do_syscall_trace_leave
311 REST_NVGPRS(r1) 346 REST_NVGPRS(r1)
3122: 347
313 lwz r3,GPR3(r1) 3486: lwz r3,GPR3(r1)
314 LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ 349 LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
315 SYNC 350 SYNC
316 MTMSRD(r10) /* disable interrupts again */ 351 MTMSRD(r10) /* disable interrupts again */
317 rlwinm r12,r1,0,0,18 /* current_thread_info() */ 352 rlwinm r12,r1,0,0,18 /* current_thread_info() */
318 lwz r9,TI_FLAGS(r12) 353 lwz r9,TI_FLAGS(r12)
3195: 3547:
320 andi. r0,r9,_TIF_NEED_RESCHED 355 andi. r0,r9,_TIF_NEED_RESCHED
321 bne 1f 356 bne 8f
322 lwz r5,_MSR(r1) 357 lwz r5,_MSR(r1)
323 andi. r5,r5,MSR_PR 358 andi. r5,r5,MSR_PR
324 beq syscall_exit_cont 359 beq ret_from_except
325 andi. r0,r9,_TIF_SIGPENDING 360 andi. r0,r9,_TIF_SIGPENDING
326 beq syscall_exit_cont 361 beq ret_from_except
327 b do_user_signal 362 b do_user_signal
3281: 3638:
329 ori r10,r10,MSR_EE 364 ori r10,r10,MSR_EE
330 SYNC 365 SYNC
331 MTMSRD(r10) /* re-enable interrupts */ 366 MTMSRD(r10) /* re-enable interrupts */
332 bl schedule 367 bl schedule
333 b 2b 368 b 6b
369
370save_user_nvgprs:
371 lwz r8,TI_SIGFRAME(r12)
372
373.macro savewords start, end
374 1: stw \start,4*(\start)(r8)
375 .section __ex_table,"a"
376 .align 2
377 .long 1b,save_user_nvgprs_fault
378 .previous
379 .if \end - \start
380 savewords "(\start+1)",\end
381 .endif
382.endm
383 savewords 14,31
384 b save_user_nvgprs_cont
385
386
387save_user_nvgprs_fault:
388 li r3,11 /* SIGSEGV */
389 lwz r4,TI_TASK(r12)
390 bl force_sigsegv
334 391
392 rlwinm r12,r1,0,0,18 /* current_thread_info() */
393 lwz r9,TI_FLAGS(r12)
394 b save_user_nvgprs_cont
395
335#ifdef SHOW_SYSCALLS 396#ifdef SHOW_SYSCALLS
336do_show_syscall: 397do_show_syscall:
337#ifdef SHOW_SYSCALLS_TASK 398#ifdef SHOW_SYSCALLS_TASK
@@ -401,28 +462,10 @@ show_syscalls_task:
401#endif /* SHOW_SYSCALLS */ 462#endif /* SHOW_SYSCALLS */
402 463
403/* 464/*
404 * The sigsuspend and rt_sigsuspend system calls can call do_signal 465 * The fork/clone functions need to copy the full register set into
405 * and thus put the process into the stopped state where we might 466 * the child process. Therefore we need to save all the nonvolatile
406 * want to examine its user state with ptrace. Therefore we need 467 * registers (r13 - r31) before calling the C code.
407 * to save all the nonvolatile registers (r13 - r31) before calling
408 * the C code.
409 */ 468 */
410 .globl ppc_sigsuspend
411ppc_sigsuspend:
412 SAVE_NVGPRS(r1)
413 lwz r0,TRAP(r1)
414 rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
415 stw r0,TRAP(r1) /* register set saved */
416 b sys_sigsuspend
417
418 .globl ppc_rt_sigsuspend
419ppc_rt_sigsuspend:
420 SAVE_NVGPRS(r1)
421 lwz r0,TRAP(r1)
422 rlwinm r0,r0,0,0,30
423 stw r0,TRAP(r1)
424 b sys_rt_sigsuspend
425
426 .globl ppc_fork 469 .globl ppc_fork
427ppc_fork: 470ppc_fork:
428 SAVE_NVGPRS(r1) 471 SAVE_NVGPRS(r1)
@@ -447,14 +490,6 @@ ppc_clone:
447 stw r0,TRAP(r1) /* register set saved */ 490 stw r0,TRAP(r1) /* register set saved */
448 b sys_clone 491 b sys_clone
449 492
450 .globl ppc_swapcontext
451ppc_swapcontext:
452 SAVE_NVGPRS(r1)
453 lwz r0,TRAP(r1)
454 rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
455 stw r0,TRAP(r1) /* register set saved */
456 b sys_swapcontext
457
458/* 493/*
459 * Top-level page fault handling. 494 * Top-level page fault handling.
460 * This is in assembler because if do_page_fault tells us that 495 * This is in assembler because if do_page_fault tells us that
@@ -626,16 +661,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_601)
626 .long ret_from_except 661 .long ret_from_except
627#endif 662#endif
628 663
629 .globl sigreturn_exit
630sigreturn_exit:
631 subi r1,r3,STACK_FRAME_OVERHEAD
632 rlwinm r12,r1,0,0,18 /* current_thread_info() */
633 lwz r9,TI_FLAGS(r12)
634 andi. r0,r9,_TIF_SYSCALL_T_OR_A
635 beq+ ret_from_except_full
636 bl do_syscall_trace_leave
637 /* fall through */
638
639 .globl ret_from_except_full 664 .globl ret_from_except_full
640ret_from_except_full: 665ret_from_except_full:
641 REST_NVGPRS(r1) 666 REST_NVGPRS(r1)
@@ -658,7 +683,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */
658 /* Check current_thread_info()->flags */ 683 /* Check current_thread_info()->flags */
659 rlwinm r9,r1,0,0,18 684 rlwinm r9,r1,0,0,18
660 lwz r9,TI_FLAGS(r9) 685 lwz r9,TI_FLAGS(r9)
661 andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED) 686 andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
662 bne do_work 687 bne do_work
663 688
664restore_user: 689restore_user:
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 5e61124581d0..fb5658bba285 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -1197,7 +1197,7 @@ _GLOBAL(sys_call_table)
1197 .long sys_ssetmask 1197 .long sys_ssetmask
1198 .long sys_setreuid /* 70 */ 1198 .long sys_setreuid /* 70 */
1199 .long sys_setregid 1199 .long sys_setregid
1200 .long ppc_sigsuspend 1200 .long sys_sigsuspend
1201 .long sys_sigpending 1201 .long sys_sigpending
1202 .long sys_sethostname 1202 .long sys_sethostname
1203 .long sys_setrlimit /* 75 */ 1203 .long sys_setrlimit /* 75 */
@@ -1303,7 +1303,7 @@ _GLOBAL(sys_call_table)
1303 .long sys_rt_sigpending /* 175 */ 1303 .long sys_rt_sigpending /* 175 */
1304 .long sys_rt_sigtimedwait 1304 .long sys_rt_sigtimedwait
1305 .long sys_rt_sigqueueinfo 1305 .long sys_rt_sigqueueinfo
1306 .long ppc_rt_sigsuspend 1306 .long sys_rt_sigsuspend
1307 .long sys_pread64 1307 .long sys_pread64
1308 .long sys_pwrite64 /* 180 */ 1308 .long sys_pwrite64 /* 180 */
1309 .long sys_chown 1309 .long sys_chown
@@ -1374,7 +1374,7 @@ _GLOBAL(sys_call_table)
1374 .long sys_clock_gettime 1374 .long sys_clock_gettime
1375 .long sys_clock_getres 1375 .long sys_clock_getres
1376 .long sys_clock_nanosleep 1376 .long sys_clock_nanosleep
1377 .long ppc_swapcontext 1377 .long sys_swapcontext
1378 .long sys_tgkill /* 250 */ 1378 .long sys_tgkill /* 250 */
1379 .long sys_utimes 1379 .long sys_utimes
1380 .long sys_statfs64 1380 .long sys_statfs64
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index f7fae5f153b2..50c75eec8874 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -815,8 +815,7 @@ EXPORT_SYMBOL(pci_device_to_OF_node);
815 * to set pci_assign_all_buses to 1 and still use RTAS for PCI 815 * to set pci_assign_all_buses to 1 and still use RTAS for PCI
816 * config cycles. 816 * config cycles.
817 */ 817 */
818struct pci_controller* 818struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
819pci_find_hose_for_OF_device(struct device_node* node)
820{ 819{
821 if (!have_of) 820 if (!have_of)
822 return NULL; 821 return NULL;
@@ -942,7 +941,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
942 while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) { 941 while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
943 res = NULL; 942 res = NULL;
944 size = ranges[na+4]; 943 size = ranges[na+4];
945 switch (ranges[0] >> 24) { 944 switch ((ranges[0] >> 24) & 0x3) {
946 case 1: /* I/O space */ 945 case 1: /* I/O space */
947 if (ranges[2] != 0) 946 if (ranges[2] != 0)
948 break; 947 break;
@@ -956,6 +955,8 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
956 res = &hose->io_resource; 955 res = &hose->io_resource;
957 res->flags = IORESOURCE_IO; 956 res->flags = IORESOURCE_IO;
958 res->start = ranges[2]; 957 res->start = ranges[2];
958 DBG("PCI: IO 0x%lx -> 0x%lx\n",
959 res->start, res->start + size - 1);
959 break; 960 break;
960 case 2: /* memory space */ 961 case 2: /* memory space */
961 memno = 0; 962 memno = 0;
@@ -973,7 +974,11 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
973 if (memno < 3) { 974 if (memno < 3) {
974 res = &hose->mem_resources[memno]; 975 res = &hose->mem_resources[memno];
975 res->flags = IORESOURCE_MEM; 976 res->flags = IORESOURCE_MEM;
977 if(ranges[0] & 0x40000000)
978 res->flags |= IORESOURCE_PREFETCH;
976 res->start = ranges[na+2]; 979 res->start = ranges[na+2];
980 DBG("PCI: MEM[%d] 0x%lx -> 0x%lx\n", memno,
981 res->start, res->start + size - 1);
977 } 982 }
978 break; 983 break;
979 } 984 }
@@ -1806,6 +1811,23 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
1806EXPORT_SYMBOL(pci_iomap); 1811EXPORT_SYMBOL(pci_iomap);
1807EXPORT_SYMBOL(pci_iounmap); 1812EXPORT_SYMBOL(pci_iounmap);
1808 1813
1814unsigned long pci_address_to_pio(phys_addr_t address)
1815{
1816 struct pci_controller* hose = hose_head;
1817
1818 for (; hose; hose = hose->next) {
1819 unsigned int size = hose->io_resource.end -
1820 hose->io_resource.start + 1;
1821 if (address >= hose->io_base_phys &&
1822 address < (hose->io_base_phys + size)) {
1823 unsigned long base =
1824 (unsigned long)hose->io_base_virt - _IO_BASE;
1825 return base + (address - hose->io_base_phys);
1826 }
1827 }
1828 return (unsigned int)-1;
1829}
1830EXPORT_SYMBOL(pci_address_to_pio);
1809 1831
1810/* 1832/*
1811 * Null PCI config access functions, for the case when we can't 1833 * Null PCI config access functions, for the case when we can't
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index bb6a5c6a64be..95075f99a6d4 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -82,10 +82,6 @@ EXPORT_SYMBOL(ppc_n_lost_interrupts);
82EXPORT_SYMBOL(ISA_DMA_THRESHOLD); 82EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
83EXPORT_SYMBOL(DMA_MODE_READ); 83EXPORT_SYMBOL(DMA_MODE_READ);
84EXPORT_SYMBOL(DMA_MODE_WRITE); 84EXPORT_SYMBOL(DMA_MODE_WRITE);
85#if defined(CONFIG_PPC_PREP)
86EXPORT_SYMBOL(_prep_type);
87EXPORT_SYMBOL(ucSystemType);
88#endif
89 85
90#if !defined(__INLINE_BITOPS) 86#if !defined(__INLINE_BITOPS)
91EXPORT_SYMBOL(set_bit); 87EXPORT_SYMBOL(set_bit);
@@ -311,7 +307,6 @@ EXPORT_SYMBOL(__res);
311 307
312EXPORT_SYMBOL(next_mmu_context); 308EXPORT_SYMBOL(next_mmu_context);
313EXPORT_SYMBOL(set_context); 309EXPORT_SYMBOL(set_context);
314EXPORT_SYMBOL_GPL(__handle_mm_fault); /* For MOL */
315EXPORT_SYMBOL(disarm_decr); 310EXPORT_SYMBOL(disarm_decr);
316#ifdef CONFIG_PPC_STD_MMU 311#ifdef CONFIG_PPC_STD_MMU
317extern long mol_trampoline; 312extern long mol_trampoline;
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 0eb0b7085e6a..e707c6f6e61b 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -744,6 +744,9 @@ void __init setup_arch(char **cmdline_p)
744 /* so udelay does something sensible, assume <= 1000 bogomips */ 744 /* so udelay does something sensible, assume <= 1000 bogomips */
745 loops_per_jiffy = 500000000 / HZ; 745 loops_per_jiffy = 500000000 / HZ;
746 746
747 if (ppc_md.init_early)
748 ppc_md.init_early();
749
747#ifdef CONFIG_PPC_MULTIPLATFORM 750#ifdef CONFIG_PPC_MULTIPLATFORM
748 /* This could be called "early setup arch", it must be done 751 /* This could be called "early setup arch", it must be done
749 * now because xmon need it 752 * now because xmon need it
diff --git a/arch/ppc/platforms/85xx/Kconfig b/arch/ppc/platforms/85xx/Kconfig
index c5bc2821d991..7ddd331a7145 100644
--- a/arch/ppc/platforms/85xx/Kconfig
+++ b/arch/ppc/platforms/85xx/Kconfig
@@ -39,7 +39,7 @@ config MPC8560_ADS
39config SBC8560 39config SBC8560
40 bool "WindRiver PowerQUICC III SBC8560" 40 bool "WindRiver PowerQUICC III SBC8560"
41 help 41 help
42 This option enables support for the WindRiver PowerQUICC III 42 This option enables support for the WindRiver PowerQUICC III
43 SBC8560 board. 43 SBC8560 board.
44 44
45config STX_GP3 45config STX_GP3
@@ -48,6 +48,26 @@ config STX_GP3
48 This option enables support for the Silicon Turnkey Express GP3 48 This option enables support for the Silicon Turnkey Express GP3
49 board. 49 board.
50 50
51config TQM8540
52 bool "TQ Components TQM8540"
53 help
54 This option enablese support for the TQ Components TQM8540 board.
55
56config TQM8541
57 bool "TQ Components TQM8541"
58 help
59 This option enablese support for the TQ Components TQM8541 board.
60
61config TQM8555
62 bool "TQ Components TQM8555"
63 help
64 This option enablese support for the TQ Components TQM8555 board.
65
66config TQM8560
67 bool "TQ Components TQM8560"
68 help
69 This option enablese support for the TQ Components TQM8560 board.
70
51endchoice 71endchoice
52 72
53# It's often necessary to know the specific 85xx processor type. 73# It's often necessary to know the specific 85xx processor type.
@@ -55,7 +75,7 @@ endchoice
55# don't need to ask more redundant questions. 75# don't need to ask more redundant questions.
56config MPC8540 76config MPC8540
57 bool 77 bool
58 depends on MPC8540_ADS 78 depends on MPC8540_ADS || TQM8540
59 default y 79 default y
60 80
61config MPC8548 81config MPC8548
@@ -65,12 +85,12 @@ config MPC8548
65 85
66config MPC8555 86config MPC8555
67 bool 87 bool
68 depends on MPC8555_CDS 88 depends on MPC8555_CDS || TQM8541 || TQM8555
69 default y 89 default y
70 90
71config MPC8560 91config MPC8560
72 bool 92 bool
73 depends on SBC8560 || MPC8560_ADS || STX_GP3 93 depends on SBC8560 || MPC8560_ADS || STX_GP3 || TQM8560
74 default y 94 default y
75 95
76config 85xx_PCI2 96config 85xx_PCI2
diff --git a/arch/ppc/platforms/85xx/Makefile b/arch/ppc/platforms/85xx/Makefile
index efdf813108f2..6c4753c144d3 100644
--- a/arch/ppc/platforms/85xx/Makefile
+++ b/arch/ppc/platforms/85xx/Makefile
@@ -7,3 +7,7 @@ obj-$(CONFIG_MPC8555_CDS) += mpc85xx_cds_common.o
7obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads_common.o mpc8560_ads.o 7obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads_common.o mpc8560_ads.o
8obj-$(CONFIG_SBC8560) += sbc85xx.o sbc8560.o 8obj-$(CONFIG_SBC8560) += sbc85xx.o sbc8560.o
9obj-$(CONFIG_STX_GP3) += stx_gp3.o 9obj-$(CONFIG_STX_GP3) += stx_gp3.o
10obj-$(CONFIG_TQM8540) += tqm85xx.o
11obj-$(CONFIG_TQM8541) += tqm85xx.o
12obj-$(CONFIG_TQM8555) += tqm85xx.o
13obj-$(CONFIG_TQM8560) += tqm85xx.o
diff --git a/arch/ppc/platforms/85xx/tqm85xx.c b/arch/ppc/platforms/85xx/tqm85xx.c
new file mode 100644
index 000000000000..c6dfd8f0f9df
--- /dev/null
+++ b/arch/ppc/platforms/85xx/tqm85xx.c
@@ -0,0 +1,419 @@
1/*
2 * arch/ppc/platforms/85xx/tqm85xx.c
3 *
4 * TQM85xx (40/41/55/60) board specific routines
5 *
6 * Copyright (c) 2005 DENX Software Engineering
7 * Stefan Roese <sr@denx.de>
8 *
9 * Based on original work by
10 * Kumar Gala <galak@kernel.crashing.org>
11 * Copyright 2004 Freescale Semiconductor Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 */
18
19#include <linux/config.h>
20#include <linux/stddef.h>
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/errno.h>
24#include <linux/reboot.h>
25#include <linux/pci.h>
26#include <linux/kdev_t.h>
27#include <linux/major.h>
28#include <linux/console.h>
29#include <linux/delay.h>
30#include <linux/seq_file.h>
31#include <linux/root_dev.h>
32#include <linux/serial.h>
33#include <linux/tty.h> /* for linux/serial_core.h */
34#include <linux/serial_core.h>
35#include <linux/initrd.h>
36#include <linux/module.h>
37#include <linux/fsl_devices.h>
38
39#include <asm/system.h>
40#include <asm/pgtable.h>
41#include <asm/page.h>
42#include <asm/atomic.h>
43#include <asm/time.h>
44#include <asm/io.h>
45#include <asm/machdep.h>
46#include <asm/open_pic.h>
47#include <asm/bootinfo.h>
48#include <asm/pci-bridge.h>
49#include <asm/mpc85xx.h>
50#include <asm/irq.h>
51#include <asm/immap_85xx.h>
52#include <asm/kgdb.h>
53#include <asm/ppc_sys.h>
54#include <asm/cpm2.h>
55#include <mm/mmu_decl.h>
56
57#include <syslib/ppc85xx_setup.h>
58#include <syslib/cpm2_pic.h>
59#include <syslib/ppc85xx_common.h>
60#include <syslib/ppc85xx_rio.h>
61
62#ifndef CONFIG_PCI
63unsigned long isa_io_base = 0;
64unsigned long isa_mem_base = 0;
65#endif
66
67
68extern unsigned long total_memory; /* in mm/init */
69
70unsigned char __res[sizeof (bd_t)];
71
72/* Internal interrupts are all Level Sensitive, and Positive Polarity */
73static u_char tqm85xx_openpic_initsenses[] __initdata = {
74 MPC85XX_INTERNAL_IRQ_SENSES,
75 0x0, /* External 0: */
76 0x0, /* External 1: */
77#if defined(CONFIG_PCI)
78 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 2: PCI INTA */
79 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 3: PCI INTB */
80#else
81 0x0, /* External 2: */
82 0x0, /* External 3: */
83#endif
84 0x0, /* External 4: */
85 0x0, /* External 5: */
86 0x0, /* External 6: */
87 0x0, /* External 7: */
88 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 8: PHY */
89 0x0, /* External 9: */
90 0x0, /* External 10: */
91 0x0, /* External 11: */
92};
93
94static const char *GFAR_PHY_0 = "phy0:2";
95static const char *GFAR_PHY_1 = "phy0:1";
96#ifdef CONFIG_MPC8540
97static const char *GFAR_PHY_3 = "phy0:3";
98#endif
99
100/* ************************************************************************
101 *
102 * Setup the architecture
103 *
104 */
105static void __init
106tqm85xx_setup_arch(void)
107{
108 bd_t *binfo = (bd_t *) __res;
109 unsigned int freq;
110 struct gianfar_platform_data *pdata;
111 struct gianfar_mdio_data *mdata;
112
113#ifdef CONFIG_MPC8560
114 cpm2_reset();
115#endif
116
117 /* get the core frequency */
118 freq = binfo->bi_intfreq;
119
120 if (ppc_md.progress)
121 ppc_md.progress("tqm85xx_setup_arch()", 0);
122
123 /* Set loops_per_jiffy to a half-way reasonable value,
124 for use until calibrate_delay gets called. */
125 loops_per_jiffy = freq / HZ;
126
127#ifdef CONFIG_PCI
128 /* setup PCI host bridges */
129 mpc85xx_setup_hose();
130#endif
131
132#ifndef CONFIG_MPC8560
133#if defined(CONFIG_SERIAL_8250)
134 mpc85xx_early_serial_map();
135#endif
136
137#ifdef CONFIG_SERIAL_TEXT_DEBUG
138 /* Invalidate the entry we stole earlier the serial ports
139 * should be properly mapped */
140 invalidate_tlbcam_entry(num_tlbcam_entries - 1);
141#endif
142#endif /* CONFIG_MPC8560 */
143
144 /* setup the board related info for the MDIO bus */
145 mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
146
147 mdata->irq[0] = MPC85xx_IRQ_EXT8;
148 mdata->irq[1] = MPC85xx_IRQ_EXT8;
149 mdata->irq[2] = -1;
150 mdata->irq[3] = MPC85xx_IRQ_EXT8;
151 mdata->irq[31] = -1;
152 mdata->paddr += binfo->bi_immr_base;
153
154 /* setup the board related information for the enet controllers */
155 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
156 if (pdata) {
157 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
158 pdata->bus_id = GFAR_PHY_0;
159 memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
160 }
161
162 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
163 if (pdata) {
164 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
165 pdata->bus_id = GFAR_PHY_1;
166 memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
167 }
168
169#ifdef CONFIG_MPC8540
170 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
171 if (pdata) {
172 pdata->board_flags = 0;
173 pdata->bus_id = GFAR_PHY_3;
174 memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6);
175 }
176#endif
177
178#ifdef CONFIG_BLK_DEV_INITRD
179 if (initrd_start)
180 ROOT_DEV = Root_RAM0;
181 else
182#endif
183#ifdef CONFIG_ROOT_NFS
184 ROOT_DEV = Root_NFS;
185#else
186 ROOT_DEV = Root_HDA1;
187#endif
188}
189
190#ifdef CONFIG_MPC8560
191static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
192{
193 while ((irq = cpm2_get_irq(regs)) >= 0)
194 __do_IRQ(irq, regs);
195 return IRQ_HANDLED;
196}
197
198static struct irqaction cpm2_irqaction = {
199 .handler = cpm2_cascade,
200 .flags = SA_INTERRUPT,
201 .mask = CPU_MASK_NONE,
202 .name = "cpm2_cascade",
203};
204#endif /* CONFIG_MPC8560 */
205
206void __init
207tqm85xx_init_IRQ(void)
208{
209 bd_t *binfo = (bd_t *) __res;
210
211 /* Determine the Physical Address of the OpenPIC regs */
212 phys_addr_t OpenPIC_PAddr =
213 binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
214 OpenPIC_Addr = ioremap(OpenPIC_PAddr, MPC85xx_OPENPIC_SIZE);
215 OpenPIC_InitSenses = tqm85xx_openpic_initsenses;
216 OpenPIC_NumInitSenses = sizeof (tqm85xx_openpic_initsenses);
217
218 /* Skip reserved space and internal sources */
219 openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200);
220
221 /* Map PIC IRQs 0-11 */
222 openpic_set_sources(48, 12, OpenPIC_Addr + 0x10000);
223
224 /* we let openpic interrupts starting from an offset, to
225 * leave space for cascading interrupts underneath.
226 */
227 openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
228
229#ifdef CONFIG_MPC8560
230 /* Setup CPM2 PIC */
231 cpm2_init_IRQ();
232
233 setup_irq(MPC85xx_IRQ_CPM, &cpm2_irqaction);
234#endif /* CONFIG_MPC8560 */
235
236 return;
237}
238
239int tqm85xx_show_cpuinfo(struct seq_file *m)
240{
241 uint pvid, svid, phid1;
242 uint memsize = total_memory;
243 bd_t *binfo = (bd_t *) __res;
244 unsigned int freq;
245
246 /* get the core frequency */
247 freq = binfo->bi_intfreq;
248
249 pvid = mfspr(SPRN_PVR);
250 svid = mfspr(SPRN_SVR);
251
252 seq_printf(m, "Vendor\t\t: TQ Components\n");
253 seq_printf(m, "Machine\t\t: TQM%s\n", cur_ppc_sys_spec->ppc_sys_name);
254 seq_printf(m, "clock\t\t: %dMHz\n", freq / 1000000);
255 seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
256 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
257
258 /* Display cpu Pll setting */
259 phid1 = mfspr(SPRN_HID1);
260 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
261
262 /* Display the amount of memory */
263 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
264
265 return 0;
266}
267
268#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_DS1337)
269extern ulong ds1337_get_rtc_time(void);
270extern int ds1337_set_rtc_time(unsigned long nowtime);
271
272static int __init
273tqm85xx_rtc_hookup(void)
274{
275 struct timespec tv;
276
277 ppc_md.set_rtc_time = ds1337_set_rtc_time;
278 ppc_md.get_rtc_time = ds1337_get_rtc_time;
279
280 tv.tv_nsec = 0;
281 tv.tv_sec = (ppc_md.get_rtc_time)();
282 do_settimeofday(&tv);
283
284 return 0;
285}
286late_initcall(tqm85xx_rtc_hookup);
287#endif
288
289#ifdef CONFIG_PCI
290/*
291 * interrupt routing
292 */
293int mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
294{
295 static char pci_irq_table[][4] =
296 /*
297 * PCI IDSEL/INTPIN->INTLINE
298 * A B C D
299 */
300 {
301 {PIRQA, PIRQB, 0, 0},
302 };
303
304 const long min_idsel = 0x1c, max_idsel = 0x1c, irqs_per_slot = 4;
305 return PCI_IRQ_TABLE_LOOKUP;
306}
307
308int mpc85xx_exclude_device(u_char bus, u_char devfn)
309{
310 if (bus == 0 && PCI_SLOT(devfn) == 0)
311 return PCIBIOS_DEVICE_NOT_FOUND;
312 else
313 return PCIBIOS_SUCCESSFUL;
314}
315
316#endif /* CONFIG_PCI */
317
318#ifdef CONFIG_RAPIDIO
319void platform_rio_init(void)
320{
321 /* 512MB RIO LAW at 0xc0000000 */
322 mpc85xx_rio_setup(0xc0000000, 0x20000000);
323}
324#endif /* CONFIG_RAPIDIO */
325
326/* ************************************************************************ */
327void __init
328platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
329 unsigned long r6, unsigned long r7)
330{
331 /* parse_bootinfo must always be called first */
332 parse_bootinfo(find_bootinfo());
333
334 /*
335 * If we were passed in a board information, copy it into the
336 * residual data area.
337 */
338 if (r3) {
339 memcpy((void *) __res, (void *) (r3 + KERNELBASE),
340 sizeof (bd_t));
341 }
342
343#if defined(CONFIG_SERIAL_TEXT_DEBUG) && !defined(CONFIG_MPC8560)
344 {
345 bd_t *binfo = (bd_t *) __res;
346 struct uart_port p;
347
348 /* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */
349 settlbcam(num_tlbcam_entries - 1, binfo->bi_immr_base,
350 binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
351
352 memset(&p, 0, sizeof (p));
353 p.iotype = SERIAL_IO_MEM;
354 p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET;
355 p.uartclk = binfo->bi_busfreq;
356
357 gen550_init(0, &p);
358
359 memset(&p, 0, sizeof (p));
360 p.iotype = SERIAL_IO_MEM;
361 p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET;
362 p.uartclk = binfo->bi_busfreq;
363
364 gen550_init(1, &p);
365 }
366#endif
367
368#if defined(CONFIG_BLK_DEV_INITRD)
369 /*
370 * If the init RAM disk has been configured in, and there's a valid
371 * starting address for it, set it up.
372 */
373 if (r4) {
374 initrd_start = r4 + KERNELBASE;
375 initrd_end = r5 + KERNELBASE;
376 }
377#endif /* CONFIG_BLK_DEV_INITRD */
378
379 /* Copy the kernel command line arguments to a safe place. */
380
381 if (r6) {
382 *(char *) (r7 + KERNELBASE) = 0;
383 strcpy(cmd_line, (char *) (r6 + KERNELBASE));
384 }
385
386 identify_ppc_sys_by_id(mfspr(SPRN_SVR));
387
388 /* setup the PowerPC module struct */
389 ppc_md.setup_arch = tqm85xx_setup_arch;
390 ppc_md.show_cpuinfo = tqm85xx_show_cpuinfo;
391
392 ppc_md.init_IRQ = tqm85xx_init_IRQ;
393 ppc_md.get_irq = openpic_get_irq;
394
395 ppc_md.restart = mpc85xx_restart;
396 ppc_md.power_off = mpc85xx_power_off;
397 ppc_md.halt = mpc85xx_halt;
398
399 ppc_md.find_end_of_memory = mpc85xx_find_end_of_memory;
400
401 ppc_md.time_init = NULL;
402 ppc_md.set_rtc_time = NULL;
403 ppc_md.get_rtc_time = NULL;
404 ppc_md.calibrate_decr = mpc85xx_calibrate_decr;
405
406#ifndef CONFIG_MPC8560
407#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
408 ppc_md.progress = gen550_progress;
409#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
410#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
411 ppc_md.early_serial_map = mpc85xx_early_serial_map;
412#endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */
413#endif /* CONFIG_MPC8560 */
414
415 if (ppc_md.progress)
416 ppc_md.progress("tqm85xx_init(): exit", 0);
417
418 return;
419}
diff --git a/arch/ppc/platforms/85xx/tqm85xx.h b/arch/ppc/platforms/85xx/tqm85xx.h
new file mode 100644
index 000000000000..3775eb363fde
--- /dev/null
+++ b/arch/ppc/platforms/85xx/tqm85xx.h
@@ -0,0 +1,56 @@
1/*
2 * arch/ppc/platforms/85xx/tqm85xx.h
3 *
4 * TQM85xx (40/41/55/60) board definitions
5 *
6 * Copyright (c) 2005 DENX Software Engineering
7 * Stefan Roese <sr@denx.de>
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 */
15
16#ifndef __MACH_TQM85XX_H
17#define __MACH_TQM85XX_H
18
19#include <linux/config.h>
20#include <linux/init.h>
21#include <asm/ppcboot.h>
22
23#define BOARD_CCSRBAR ((uint)0xe0000000)
24#define CCSRBAR_SIZE ((uint)1024*1024)
25
26#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET)
27
28#define PCI_CFG_ADDR_OFFSET (0x8000)
29#define PCI_CFG_DATA_OFFSET (0x8004)
30
31/* PCI interrupt controller */
32#define PIRQA MPC85xx_IRQ_EXT2
33#define PIRQB MPC85xx_IRQ_EXT3
34
35#define MPC85XX_PCI1_LOWER_IO 0x00000000
36#define MPC85XX_PCI1_UPPER_IO 0x00ffffff
37
38#define MPC85XX_PCI1_LOWER_MEM 0x80000000
39#define MPC85XX_PCI1_UPPER_MEM 0x9fffffff
40
41#define MPC85XX_PCI1_IO_BASE 0xe2000000
42#define MPC85XX_PCI1_MEM_OFFSET 0x00000000
43
44#define MPC85XX_PCI1_IO_SIZE 0x01000000
45
46#define BASE_BAUD 115200
47
48extern void mpc85xx_setup_hose(void) __init;
49extern void mpc85xx_restart(char *cmd);
50extern void mpc85xx_power_off(void);
51extern void mpc85xx_halt(void);
52extern void mpc85xx_init_IRQ(void) __init;
53extern unsigned long mpc85xx_find_end_of_memory(void) __init;
54extern void mpc85xx_calibrate_decr(void) __init;
55
56#endif /* __MACH_TQM85XX_H */
diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c
index f1b70ab3c6fd..056ac2a7b5c1 100644
--- a/arch/ppc/platforms/chrp_setup.c
+++ b/arch/ppc/platforms/chrp_setup.c
@@ -404,7 +404,6 @@ static struct irqaction xmon_irqaction = {
404void __init chrp_init_IRQ(void) 404void __init chrp_init_IRQ(void)
405{ 405{
406 struct device_node *np; 406 struct device_node *np;
407 int i;
408 unsigned long chrp_int_ack = 0; 407 unsigned long chrp_int_ack = 0;
409 unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; 408 unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
410#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) 409#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
index 4415748071dc..d06535802003 100644
--- a/arch/ppc/platforms/prep_setup.c
+++ b/arch/ppc/platforms/prep_setup.c
@@ -72,7 +72,6 @@
72 72
73TODC_ALLOC(); 73TODC_ALLOC();
74 74
75unsigned char ucSystemType;
76unsigned char ucBoardRev; 75unsigned char ucBoardRev;
77unsigned char ucBoardRevMaj, ucBoardRevMin; 76unsigned char ucBoardRevMaj, ucBoardRevMin;
78 77
@@ -954,7 +953,6 @@ prep_calibrate_decr(void)
954static void __init 953static void __init
955prep_init_IRQ(void) 954prep_init_IRQ(void)
956{ 955{
957 int i;
958 unsigned int pci_viddid, pci_did; 956 unsigned int pci_viddid, pci_did;
959 957
960 if (OpenPIC_Addr != NULL) { 958 if (OpenPIC_Addr != NULL) {
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index 5b7f2b80e56e..84ef03018d0e 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -96,7 +96,7 @@ ifeq ($(CONFIG_85xx),y)
96obj-$(CONFIG_PCI) += pci_auto.o 96obj-$(CONFIG_PCI) += pci_auto.o
97endif 97endif
98obj-$(CONFIG_RAPIDIO) += ppc85xx_rio.o 98obj-$(CONFIG_RAPIDIO) += ppc85xx_rio.o
99obj-$(CONFIG_83xx) += ipic.o ppc83xx_setup.o ppc_sys.o \ 99obj-$(CONFIG_83xx) += ppc83xx_setup.o ppc_sys.o \
100 mpc83xx_sys.o mpc83xx_devices.o 100 mpc83xx_sys.o mpc83xx_devices.o
101ifeq ($(CONFIG_83xx),y) 101ifeq ($(CONFIG_83xx),y)
102obj-$(CONFIG_PCI) += pci_auto.o 102obj-$(CONFIG_PCI) += pci_auto.o
diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c
index 1cc3abe6fa43..688616de3cde 100644
--- a/arch/ppc/syslib/m8xx_setup.c
+++ b/arch/ppc/syslib/m8xx_setup.c
@@ -135,6 +135,16 @@ static struct irqaction tbint_irqaction = {
135 .name = "tbint", 135 .name = "tbint",
136}; 136};
137 137
138/* per-board overridable init_internal_rtc() function. */
139void __init __attribute__ ((weak))
140init_internal_rtc(void)
141{
142 /* Disable the RTC one second and alarm interrupts. */
143 out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) & ~(RTCSC_SIE | RTCSC_ALE));
144 /* Enable the RTC */
145 out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) | (RTCSC_RTF | RTCSC_RTE));
146}
147
138/* The decrementer counts at the system (internal) clock frequency divided by 148/* The decrementer counts at the system (internal) clock frequency divided by
139 * sixteen, or external oscillator divided by four. We force the processor 149 * sixteen, or external oscillator divided by four. We force the processor
140 * to use system clock divided by sixteen. 150 * to use system clock divided by sixteen.
@@ -183,10 +193,7 @@ void __init m8xx_calibrate_decr(void)
183 out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, KAPWR_KEY); 193 out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, KAPWR_KEY);
184 out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, KAPWR_KEY); 194 out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, KAPWR_KEY);
185 195
186 /* Disable the RTC one second and alarm interrupts. */ 196 init_internal_rtc();
187 out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) & ~(RTCSC_SIE | RTCSC_ALE));
188 /* Enable the RTC */
189 out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) | (RTCSC_RTF | RTCSC_RTE));
190 197
191 /* Enabling the decrementer also enables the timebase interrupts 198 /* Enabling the decrementer also enables the timebase interrupts
192 * (or from the other point of view, to get decrementer interrupts 199 * (or from the other point of view, to get decrementer interrupts
diff --git a/arch/ppc/syslib/m8xx_wdt.c b/arch/ppc/syslib/m8xx_wdt.c
index a21632d37e5a..df6c9557b86a 100644
--- a/arch/ppc/syslib/m8xx_wdt.c
+++ b/arch/ppc/syslib/m8xx_wdt.c
@@ -19,6 +19,7 @@
19#include <syslib/m8xx_wdt.h> 19#include <syslib/m8xx_wdt.h>
20 20
21static int wdt_timeout; 21static int wdt_timeout;
22int m8xx_has_internal_rtc = 0;
22 23
23static irqreturn_t m8xx_wdt_interrupt(int, void *, struct pt_regs *); 24static irqreturn_t m8xx_wdt_interrupt(int, void *, struct pt_regs *);
24static struct irqaction m8xx_wdt_irqaction = { 25static struct irqaction m8xx_wdt_irqaction = {
@@ -45,35 +46,15 @@ static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev, struct pt_regs *regs)
45 return IRQ_HANDLED; 46 return IRQ_HANDLED;
46} 47}
47 48
48void __init m8xx_wdt_handler_install(bd_t * binfo) 49#define SYPCR_SWP 0x1
50#define SYPCR_SWE 0x4
51
52
53void __init m8xx_wdt_install_irq(volatile immap_t *imap, bd_t *binfo)
49{ 54{
50 volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
51 u32 pitc; 55 u32 pitc;
52 u32 sypcr;
53 u32 pitrtclk; 56 u32 pitrtclk;
54 57
55 sypcr = in_be32(&imap->im_siu_conf.sc_sypcr);
56
57 if (!(sypcr & 0x04)) {
58 printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n",
59 sypcr);
60 return;
61 }
62
63 m8xx_wdt_reset();
64
65 printk(KERN_NOTICE
66 "m8xx_wdt: active wdt found (SWTC: 0x%04X, SWP: 0x%01X)\n",
67 (sypcr >> 16), sypcr & 0x01);
68
69 wdt_timeout = (sypcr >> 16) & 0xFFFF;
70
71 if (!wdt_timeout)
72 wdt_timeout = 0xFFFF;
73
74 if (sypcr & 0x01)
75 wdt_timeout *= 2048;
76
77 /* 58 /*
78 * Fire trigger if half of the wdt ticked down 59 * Fire trigger if half of the wdt ticked down
79 */ 60 */
@@ -98,6 +79,67 @@ void __init m8xx_wdt_handler_install(bd_t * binfo)
98 printk(KERN_NOTICE 79 printk(KERN_NOTICE
99 "m8xx_wdt: keep-alive trigger installed (PITC: 0x%04X)\n", pitc); 80 "m8xx_wdt: keep-alive trigger installed (PITC: 0x%04X)\n", pitc);
100 81
82}
83
84static void m8xx_wdt_timer_func(unsigned long data);
85
86static struct timer_list m8xx_wdt_timer =
87 TIMER_INITIALIZER(m8xx_wdt_timer_func, 0, 0);
88
89void m8xx_wdt_stop_timer(void)
90{
91 del_timer(&m8xx_wdt_timer);
92}
93
94void m8xx_wdt_install_timer(void)
95{
96 m8xx_wdt_timer.expires = jiffies + (HZ/2);
97 add_timer(&m8xx_wdt_timer);
98}
99
100static void m8xx_wdt_timer_func(unsigned long data)
101{
102 m8xx_wdt_reset();
103 m8xx_wdt_install_timer();
104}
105
106void __init m8xx_wdt_handler_install(bd_t * binfo)
107{
108 volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
109 u32 sypcr;
110
111 sypcr = in_be32(&imap->im_siu_conf.sc_sypcr);
112
113 if (!(sypcr & SYPCR_SWE)) {
114 printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n",
115 sypcr);
116 return;
117 }
118
119 m8xx_wdt_reset();
120
121 printk(KERN_NOTICE
122 "m8xx_wdt: active wdt found (SWTC: 0x%04X, SWP: 0x%01X)\n",
123 (sypcr >> 16), sypcr & SYPCR_SWP);
124
125 wdt_timeout = (sypcr >> 16) & 0xFFFF;
126
127 if (!wdt_timeout)
128 wdt_timeout = 0xFFFF;
129
130 if (sypcr & SYPCR_SWP)
131 wdt_timeout *= 2048;
132
133 m8xx_has_internal_rtc = in_be16(&imap->im_sit.sit_rtcsc) & RTCSC_RTE;
134
135 /* if the internal RTC is off use a kernel timer */
136 if (!m8xx_has_internal_rtc) {
137 if (wdt_timeout < (binfo->bi_intfreq/HZ))
138 printk(KERN_ERR "m8xx_wdt: timeout too short for ktimer!\n");
139 m8xx_wdt_install_timer();
140 } else
141 m8xx_wdt_install_irq(imap, binfo);
142
101 wdt_timeout /= binfo->bi_intfreq; 143 wdt_timeout /= binfo->bi_intfreq;
102} 144}
103 145
diff --git a/arch/ppc/syslib/m8xx_wdt.h b/arch/ppc/syslib/m8xx_wdt.h
index 0d81a9f8155f..e75835f0012b 100644
--- a/arch/ppc/syslib/m8xx_wdt.h
+++ b/arch/ppc/syslib/m8xx_wdt.h
@@ -9,8 +9,12 @@
9#ifndef _PPC_SYSLIB_M8XX_WDT_H 9#ifndef _PPC_SYSLIB_M8XX_WDT_H
10#define _PPC_SYSLIB_M8XX_WDT_H 10#define _PPC_SYSLIB_M8XX_WDT_H
11 11
12extern int m8xx_has_internal_rtc;
13
12extern void m8xx_wdt_handler_install(bd_t * binfo); 14extern void m8xx_wdt_handler_install(bd_t * binfo);
13extern int m8xx_wdt_get_timeout(void); 15extern int m8xx_wdt_get_timeout(void);
14extern void m8xx_wdt_reset(void); 16extern void m8xx_wdt_reset(void);
17extern void m8xx_wdt_install_timer(void);
18extern void m8xx_wdt_stop_timer(void);
15 19
16#endif /* _PPC_SYSLIB_M8XX_WDT_H */ 20#endif /* _PPC_SYSLIB_M8XX_WDT_H */
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 8ecda6d66de4..cc02232aa96e 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -712,35 +712,18 @@ sys_ptrace(long request, long pid, long addr, long data)
712 int ret; 712 int ret;
713 713
714 lock_kernel(); 714 lock_kernel();
715
716 if (request == PTRACE_TRACEME) { 715 if (request == PTRACE_TRACEME) {
717 /* are we already being traced? */ 716 ret = ptrace_traceme();
718 ret = -EPERM; 717 goto out;
719 if (current->ptrace & PT_PTRACED)
720 goto out;
721 ret = security_ptrace(current->parent, current);
722 if (ret)
723 goto out;
724 /* set the ptrace bit in the process flags. */
725 current->ptrace |= PT_PTRACED;
726 goto out;
727 } 718 }
728 719
729 ret = -EPERM; 720 child = ptrace_get_task_struct(pid);
730 if (pid == 1) /* you may not mess with init */ 721 if (IS_ERR(child)) {
731 goto out; 722 ret = PTR_ERR(child);
732
733 ret = -ESRCH;
734 read_lock(&tasklist_lock);
735 child = find_task_by_pid(pid);
736 if (child)
737 get_task_struct(child);
738 read_unlock(&tasklist_lock);
739 if (!child)
740 goto out; 723 goto out;
724 }
741 725
742 ret = do_ptrace(child, request, addr, data); 726 ret = do_ptrace(child, request, addr, data);
743
744 put_task_struct(child); 727 put_task_struct(child);
745out: 728out:
746 unlock_kernel(); 729 unlock_kernel();
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 64f5ae0ff96d..8cf6d437a630 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -14,10 +14,6 @@ config SUPERH
14 gaming console. The SuperH port has a home page at 14 gaming console. The SuperH port has a home page at
15 <http://www.linux-sh.org/>. 15 <http://www.linux-sh.org/>.
16 16
17config UID16
18 bool
19 default y
20
21config RWSEM_GENERIC_SPINLOCK 17config RWSEM_GENERIC_SPINLOCK
22 bool 18 bool
23 default y 19 default y
diff --git a/arch/sh64/kernel/time.c b/arch/sh64/kernel/time.c
index 870fe5327e09..1195af37ee5a 100644
--- a/arch/sh64/kernel/time.c
+++ b/arch/sh64/kernel/time.c
@@ -417,7 +417,7 @@ static __init unsigned int get_cpu_hz(void)
417 /* 417 /*
418 ** Regardless the toolchain, force the compiler to use the 418 ** Regardless the toolchain, force the compiler to use the
419 ** arbitrary register r3 as a clock tick counter. 419 ** arbitrary register r3 as a clock tick counter.
420 ** NOTE: r3 must be in accordance with rtc_interrupt() 420 ** NOTE: r3 must be in accordance with sh64_rtc_interrupt()
421 */ 421 */
422 register unsigned long long __rtc_irq_flag __asm__ ("r3"); 422 register unsigned long long __rtc_irq_flag __asm__ ("r3");
423 423
@@ -482,7 +482,8 @@ static __init unsigned int get_cpu_hz(void)
482#endif 482#endif
483} 483}
484 484
485static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) 485static irqreturn_t sh64_rtc_interrupt(int irq, void *dev_id,
486 struct pt_regs *regs)
486{ 487{
487 ctrl_outb(0, RCR1); /* Disable Carry Interrupts */ 488 ctrl_outb(0, RCR1); /* Disable Carry Interrupts */
488 regs->regs[3] = 1; /* Using r3 */ 489 regs->regs[3] = 1; /* Using r3 */
@@ -491,7 +492,7 @@ static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
491} 492}
492 493
493static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; 494static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL};
494static struct irqaction irq1 = { rtc_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "rtc", NULL, NULL}; 495static struct irqaction irq1 = { sh64_rtc_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "rtc", NULL, NULL};
495 496
496void __init time_init(void) 497void __init time_init(void)
497{ 498{
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 56c34e7fd4ee..f944b58cdfe7 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -9,10 +9,6 @@ config MMU
9 bool 9 bool
10 default y 10 default y
11 11
12config UID16
13 bool
14 default y
15
16config HIGHMEM 12config HIGHMEM
17 bool 13 bool
18 default y 14 default y
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
index 475c4c13462c..fc470c0e9dc6 100644
--- a/arch/sparc/kernel/ptrace.c
+++ b/arch/sparc/kernel/ptrace.c
@@ -286,40 +286,17 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
286 s, (int) request, (int) pid, addr, data, addr2); 286 s, (int) request, (int) pid, addr, data, addr2);
287 } 287 }
288#endif 288#endif
289 if (request == PTRACE_TRACEME) {
290 int my_ret;
291
292 /* are we already being traced? */
293 if (current->ptrace & PT_PTRACED) {
294 pt_error_return(regs, EPERM);
295 goto out;
296 }
297 my_ret = security_ptrace(current->parent, current);
298 if (my_ret) {
299 pt_error_return(regs, -my_ret);
300 goto out;
301 }
302 289
303 /* set the ptrace bit in the process flags. */ 290 if (request == PTRACE_TRACEME) {
304 current->ptrace |= PT_PTRACED; 291 ret = ptrace_traceme();
305 pt_succ_return(regs, 0); 292 pt_succ_return(regs, 0);
306 goto out; 293 goto out;
307 } 294 }
308#ifndef ALLOW_INIT_TRACING
309 if (pid == 1) {
310 /* Can't dork with init. */
311 pt_error_return(regs, EPERM);
312 goto out;
313 }
314#endif
315 read_lock(&tasklist_lock);
316 child = find_task_by_pid(pid);
317 if (child)
318 get_task_struct(child);
319 read_unlock(&tasklist_lock);
320 295
321 if (!child) { 296 child = ptrace_get_task_struct(pid);
322 pt_error_return(regs, ESRCH); 297 if (IS_ERR(child)) {
298 ret = PTR_ERR(child);
299 pt_error_return(regs, -ret);
323 goto out; 300 goto out;
324 } 301 }
325 302
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index c4b7ad70cd7c..b775ceb4cf98 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -309,11 +309,6 @@ config COMPAT
309 depends on SPARC32_COMPAT 309 depends on SPARC32_COMPAT
310 default y 310 default y
311 311
312config UID16
313 bool
314 depends on SPARC32_COMPAT
315 default y
316
317config BINFMT_ELF32 312config BINFMT_ELF32
318 tristate "Kernel support for 32-bit ELF binaries" 313 tristate "Kernel support for 32-bit ELF binaries"
319 depends on SPARC32_COMPAT 314 depends on SPARC32_COMPAT
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index 774ecbb8a031..84d3df2264cb 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -198,39 +198,15 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
198 } 198 }
199#endif 199#endif
200 if (request == PTRACE_TRACEME) { 200 if (request == PTRACE_TRACEME) {
201 int ret; 201 ret = ptrace_traceme();
202
203 /* are we already being traced? */
204 if (current->ptrace & PT_PTRACED) {
205 pt_error_return(regs, EPERM);
206 goto out;
207 }
208 ret = security_ptrace(current->parent, current);
209 if (ret) {
210 pt_error_return(regs, -ret);
211 goto out;
212 }
213
214 /* set the ptrace bit in the process flags. */
215 current->ptrace |= PT_PTRACED;
216 pt_succ_return(regs, 0); 202 pt_succ_return(regs, 0);
217 goto out; 203 goto out;
218 } 204 }
219#ifndef ALLOW_INIT_TRACING
220 if (pid == 1) {
221 /* Can't dork with init. */
222 pt_error_return(regs, EPERM);
223 goto out;
224 }
225#endif
226 read_lock(&tasklist_lock);
227 child = find_task_by_pid(pid);
228 if (child)
229 get_task_struct(child);
230 read_unlock(&tasklist_lock);
231 205
232 if (!child) { 206 child = ptrace_get_task_struct(pid);
233 pt_error_return(regs, ESRCH); 207 if (IS_ERR(child)) {
208 ret = PTR_ERR(child);
209 pt_error_return(regs, -ret);
234 goto out; 210 goto out;
235 } 211 }
236 212
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 1eb21de9d1b5..b4ff2e576021 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -22,10 +22,6 @@ config SBUS
22config PCI 22config PCI
23 bool 23 bool
24 24
25config UID16
26 bool
27 default y
28
29config GENERIC_CALIBRATE_DELAY 25config GENERIC_CALIBRATE_DELAY
30 bool 26 bool
31 default y 27 default y
@@ -83,7 +79,7 @@ config KERNEL_HALF_GIGS
83 of physical memory. 79 of physical memory.
84 80
85config MODE_SKAS 81config MODE_SKAS
86 bool "Separate Kernel Address Space support" 82 bool "Separate Kernel Address Space support" if MODE_TT
87 default y 83 default y
88 help 84 help
89 This option controls whether skas (separate kernel address space) 85 This option controls whether skas (separate kernel address space)
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 73f9652b2ee9..3a93c6f772fa 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -117,6 +117,7 @@ static int ubd_open(struct inode * inode, struct file * filp);
117static int ubd_release(struct inode * inode, struct file * file); 117static int ubd_release(struct inode * inode, struct file * file);
118static int ubd_ioctl(struct inode * inode, struct file * file, 118static int ubd_ioctl(struct inode * inode, struct file * file,
119 unsigned int cmd, unsigned long arg); 119 unsigned int cmd, unsigned long arg);
120static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
120 121
121#define MAX_DEV (8) 122#define MAX_DEV (8)
122 123
@@ -125,6 +126,7 @@ static struct block_device_operations ubd_blops = {
125 .open = ubd_open, 126 .open = ubd_open,
126 .release = ubd_release, 127 .release = ubd_release,
127 .ioctl = ubd_ioctl, 128 .ioctl = ubd_ioctl,
129 .getgeo = ubd_getgeo,
128}; 130};
129 131
130/* Protected by the queue_lock */ 132/* Protected by the queue_lock */
@@ -1058,6 +1060,16 @@ static void do_ubd_request(request_queue_t *q)
1058 } 1060 }
1059} 1061}
1060 1062
1063static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1064{
1065 struct ubd *dev = bdev->bd_disk->private_data;
1066
1067 geo->heads = 128;
1068 geo->sectors = 32;
1069 geo->cylinders = dev->size / (128 * 32 * 512);
1070 return 0;
1071}
1072
1061static int ubd_ioctl(struct inode * inode, struct file * file, 1073static int ubd_ioctl(struct inode * inode, struct file * file,
1062 unsigned int cmd, unsigned long arg) 1074 unsigned int cmd, unsigned long arg)
1063{ 1075{
@@ -1070,16 +1082,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
1070 }; 1082 };
1071 1083
1072 switch (cmd) { 1084 switch (cmd) {
1073 struct hd_geometry g;
1074 struct cdrom_volctrl volume; 1085 struct cdrom_volctrl volume;
1075 case HDIO_GETGEO:
1076 if(!loc) return(-EINVAL);
1077 g.heads = 128;
1078 g.sectors = 32;
1079 g.cylinders = dev->size / (128 * 32 * 512);
1080 g.start = get_start_sect(inode->i_bdev);
1081 return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
1082
1083 case HDIO_GET_IDENTITY: 1086 case HDIO_GET_IDENTITY:
1084 ubd_id.cyls = dev->size / (128 * 32 * 512); 1087 ubd_id.cyls = dev->size / (128 * 32 * 512);
1085 if(copy_to_user((char __user *) arg, (char *) &ubd_id, 1088 if(copy_to_user((char __user *) arg, (char *) &ubd_id,
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index e5fec5570199..8f4e46d677ab 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -10,6 +10,19 @@
10#include "sysdep/ptrace.h" 10#include "sysdep/ptrace.h"
11#include "sysdep/faultinfo.h" 11#include "sysdep/faultinfo.h"
12 12
13typedef void (*kern_hndl)(int, union uml_pt_regs *);
14
15struct kern_handlers {
16 kern_hndl relay_signal;
17 kern_hndl winch;
18 kern_hndl bus_handler;
19 kern_hndl page_fault;
20 kern_hndl sigio_handler;
21 kern_hndl timer_handler;
22};
23
24extern struct kern_handlers handlinfo_kern;
25
13extern int ncpus; 26extern int ncpus;
14extern char *linux_prog; 27extern char *linux_prog;
15extern char *gdb_init; 28extern char *gdb_init;
@@ -51,8 +64,6 @@ extern void timer_handler(int sig, union uml_pt_regs *regs);
51extern int set_signals(int enable); 64extern int set_signals(int enable);
52extern void force_sigbus(void); 65extern void force_sigbus(void);
53extern int pid_to_processor_id(int pid); 66extern int pid_to_processor_id(int pid);
54extern void block_signals(void);
55extern void unblock_signals(void);
56extern void deliver_signals(void *t); 67extern void deliver_signals(void *t);
57extern int next_syscall_index(int max); 68extern int next_syscall_index(int max);
58extern int next_trap_index(int max); 69extern int next_trap_index(int max);
@@ -111,6 +122,8 @@ extern void arch_switch(void);
111extern void free_irq(unsigned int, void *); 122extern void free_irq(unsigned int, void *);
112extern int um_in_interrupt(void); 123extern int um_in_interrupt(void);
113extern int cpu(void); 124extern int cpu(void);
125extern void segv_handler(int sig, union uml_pt_regs *regs);
126extern void sigio_handler(int sig, union uml_pt_regs *regs);
114 127
115#endif 128#endif
116 129
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index c279ee6d89e4..dd72d66cf0ed 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -9,6 +9,8 @@
9#include "uml-config.h" 9#include "uml-config.h"
10#include "asm/types.h" 10#include "asm/types.h"
11#include "../os/include/file.h" 11#include "../os/include/file.h"
12#include "sysdep/ptrace.h"
13#include "kern_util.h"
12 14
13#define OS_TYPE_FILE 1 15#define OS_TYPE_FILE 1
14#define OS_TYPE_DIR 2 16#define OS_TYPE_DIR 2
@@ -219,4 +221,18 @@ extern int umid_file_name(char *name, char *buf, int len);
219extern int set_umid(char *name); 221extern int set_umid(char *name);
220extern char *get_umid(void); 222extern char *get_umid(void);
221 223
224/* signal.c */
225extern void set_sigstack(void *sig_stack, int size);
226extern void remove_sigstack(void);
227extern void set_handler(int sig, void (*handler)(int), int flags, ...);
228extern int change_sig(int signal, int on);
229extern void block_signals(void);
230extern void unblock_signals(void);
231extern int get_signals(void);
232extern int set_signals(int enable);
233
234/* trap.c */
235extern void os_fill_handlinfo(struct kern_handlers h);
236extern void do_longjmp(void *p, int val);
237
222#endif 238#endif
diff --git a/arch/um/include/signal_user.h b/arch/um/include/signal_user.h
deleted file mode 100644
index b075e543d864..000000000000
--- a/arch/um/include/signal_user.h
+++ /dev/null
@@ -1,28 +0,0 @@
1/*
2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SIGNAL_USER_H__
7#define __SIGNAL_USER_H__
8
9extern int signal_stack_size;
10
11extern int change_sig(int signal, int on);
12extern void set_sigstack(void *stack, int size);
13extern void set_handler(int sig, void (*handler)(int), int flags, ...);
14extern int set_signals(int enable);
15extern int get_signals(void);
16
17#endif
18
19/*
20 * Overrides for Emacs so that we follow Linus's tabbing style.
21 * Emacs will notice this stuff at the end of the file and automatically
22 * adjust the settings for this buffer only. This must remain at the end
23 * of the file.
24 * ---------------------------------------------------------------------------
25 * Local variables:
26 * c-file-style: "linux"
27 * End:
28 */
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index b9984003e603..c1dbd77b073f 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -23,12 +23,7 @@ struct cpu_task {
23 23
24extern struct cpu_task cpu_tasks[]; 24extern struct cpu_task cpu_tasks[];
25 25
26struct signal_info { 26extern void (*sig_info[])(int, union uml_pt_regs *);
27 void (*handler)(int, union uml_pt_regs *);
28 int is_irq;
29};
30
31extern struct signal_info sig_info[];
32 27
33extern unsigned long low_physmem; 28extern unsigned long low_physmem;
34extern unsigned long high_physmem; 29extern unsigned long high_physmem;
@@ -64,7 +59,6 @@ extern void setup_machinename(char *machine_out);
64extern void setup_hostinfo(void); 59extern void setup_hostinfo(void);
65extern void do_exec(int old_pid, int new_pid); 60extern void do_exec(int old_pid, int new_pid);
66extern void tracer_panic(char *msg, ...); 61extern void tracer_panic(char *msg, ...);
67extern void do_longjmp(void *p, int val);
68extern int detach(int pid, int sig); 62extern int detach(int pid, int sig);
69extern int attach(int pid); 63extern int attach(int pid);
70extern void kill_child_dead(int pid); 64extern void kill_child_dead(int pid);
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 6f7700593a6f..193cc2b7448d 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -9,8 +9,8 @@ clean-files :=
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 irq_user.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_user.o sigio_kern.o \
12 signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \ 12 signal_kern.o smp.o syscall_kern.o sysrq.o time.o \
13 time_kern.o tlb.o trap_kern.o trap_user.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 user_util.o 14 user_util.o
15 15
16obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o 16obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
index 50a2aa35cda9..0e32f5f4a887 100644
--- a/arch/um/kernel/irq_user.c
+++ b/arch/um/kernel/irq_user.c
@@ -15,7 +15,6 @@
15#include "kern_util.h" 15#include "kern_util.h"
16#include "user.h" 16#include "user.h"
17#include "process.h" 17#include "process.h"
18#include "signal_user.h"
19#include "sigio.h" 18#include "sigio.h"
20#include "irq_user.h" 19#include "irq_user.h"
21#include "os.h" 20#include "os.h"
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 651abf255bc5..d2d3f256778c 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -36,7 +36,6 @@
36#include "kern_util.h" 36#include "kern_util.h"
37#include "kern.h" 37#include "kern.h"
38#include "signal_kern.h" 38#include "signal_kern.h"
39#include "signal_user.h"
40#include "init.h" 39#include "init.h"
41#include "irq_user.h" 40#include "irq_user.h"
42#include "mem_user.h" 41#include "mem_user.h"
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index a637e885c583..6f1a3a288117 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -12,6 +12,8 @@
12#include "mode.h" 12#include "mode.h"
13#include "choose-mode.h" 13#include "choose-mode.h"
14 14
15void (*pm_power_off)(void);
16
15#ifdef CONFIG_SMP 17#ifdef CONFIG_SMP
16static void kill_idlers(int me) 18static void kill_idlers(int me)
17{ 19{
diff --git a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
index 03618bd13d55..7b0e0e81c161 100644
--- a/arch/um/kernel/signal_kern.c
+++ b/arch/um/kernel/signal_kern.c
@@ -22,7 +22,6 @@
22#include "asm/ucontext.h" 22#include "asm/ucontext.h"
23#include "kern_util.h" 23#include "kern_util.h"
24#include "signal_kern.h" 24#include "signal_kern.h"
25#include "signal_user.h"
26#include "kern.h" 25#include "kern.h"
27#include "frame_kern.h" 26#include "frame_kern.h"
28#include "sigcontext.h" 27#include "sigcontext.h"
diff --git a/arch/um/kernel/signal_user.c b/arch/um/kernel/signal_user.c
deleted file mode 100644
index 62f457835fb1..000000000000
--- a/arch/um/kernel/signal_user.c
+++ /dev/null
@@ -1,157 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdio.h>
7#include <unistd.h>
8#include <stdlib.h>
9#include <signal.h>
10#include <errno.h>
11#include <stdarg.h>
12#include <string.h>
13#include <sys/mman.h>
14#include "user_util.h"
15#include "kern_util.h"
16#include "user.h"
17#include "signal_user.h"
18#include "signal_kern.h"
19#include "sysdep/sigcontext.h"
20#include "sigcontext.h"
21
22void set_sigstack(void *sig_stack, int size)
23{
24 stack_t stack = ((stack_t) { .ss_flags = 0,
25 .ss_sp = (__ptr_t) sig_stack,
26 .ss_size = size - sizeof(void *) });
27
28 if(sigaltstack(&stack, NULL) != 0)
29 panic("enabling signal stack failed, errno = %d\n", errno);
30}
31
32void set_handler(int sig, void (*handler)(int), int flags, ...)
33{
34 struct sigaction action;
35 va_list ap;
36 int mask;
37
38 va_start(ap, flags);
39 action.sa_handler = handler;
40 sigemptyset(&action.sa_mask);
41 while((mask = va_arg(ap, int)) != -1){
42 sigaddset(&action.sa_mask, mask);
43 }
44 va_end(ap);
45 action.sa_flags = flags;
46 action.sa_restorer = NULL;
47 if(sigaction(sig, &action, NULL) < 0)
48 panic("sigaction failed");
49}
50
51int change_sig(int signal, int on)
52{
53 sigset_t sigset, old;
54
55 sigemptyset(&sigset);
56 sigaddset(&sigset, signal);
57 sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
58 return(!sigismember(&old, signal));
59}
60
61/* Both here and in set/get_signal we don't touch SIGPROF, because we must not
62 * disable profiling; it's safe because the profiling code does not interact
63 * with the kernel code at all.*/
64
65static void change_signals(int type)
66{
67 sigset_t mask;
68
69 sigemptyset(&mask);
70 sigaddset(&mask, SIGVTALRM);
71 sigaddset(&mask, SIGALRM);
72 sigaddset(&mask, SIGIO);
73 if(sigprocmask(type, &mask, NULL) < 0)
74 panic("Failed to change signal mask - errno = %d", errno);
75}
76
77void block_signals(void)
78{
79 change_signals(SIG_BLOCK);
80}
81
82void unblock_signals(void)
83{
84 change_signals(SIG_UNBLOCK);
85}
86
87/* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled
88 * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to
89 * be able to profile all of UML, not just the non-critical sections. If
90 * profiling is not thread-safe, then that is not my problem. We can disable
91 * profiling when SMP is enabled in that case.
92 */
93#define SIGIO_BIT 0
94#define SIGVTALRM_BIT 1
95
96static int enable_mask(sigset_t *mask)
97{
98 int sigs;
99
100 sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
101 sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
102 sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
103 return(sigs);
104}
105
106int get_signals(void)
107{
108 sigset_t mask;
109
110 if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
111 panic("Failed to get signal mask");
112 return(enable_mask(&mask));
113}
114
115int set_signals(int enable)
116{
117 sigset_t mask;
118 int ret;
119
120 sigemptyset(&mask);
121 if(enable & (1 << SIGIO_BIT))
122 sigaddset(&mask, SIGIO);
123 if(enable & (1 << SIGVTALRM_BIT)){
124 sigaddset(&mask, SIGVTALRM);
125 sigaddset(&mask, SIGALRM);
126 }
127
128 /* This is safe - sigprocmask is guaranteed to copy locally the
129 * value of new_set, do his work and then, at the end, write to
130 * old_set.
131 */
132 if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
133 panic("Failed to enable signals");
134 ret = enable_mask(&mask);
135 sigemptyset(&mask);
136 if((enable & (1 << SIGIO_BIT)) == 0)
137 sigaddset(&mask, SIGIO);
138 if((enable & (1 << SIGVTALRM_BIT)) == 0){
139 sigaddset(&mask, SIGVTALRM);
140 sigaddset(&mask, SIGALRM);
141 }
142 if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
143 panic("Failed to block signals");
144
145 return(ret);
146}
147
148/*
149 * Overrides for Emacs so that we follow Linus's tabbing style.
150 * Emacs will notice this stuff at the end of the file and automatically
151 * adjust the settings for this buffer only. This must remain at the end
152 * of the file.
153 * ---------------------------------------------------------------------------
154 * Local variables:
155 * c-file-style: "linux"
156 * End:
157 */
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index 8de471b59c1c..7a9fc16d71d4 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -4,7 +4,7 @@
4# 4#
5 5
6obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \ 6obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
7 syscall.o tlb.o trap_user.o uaccess.o 7 syscall.o tlb.o uaccess.o
8 8
9USER_OBJS := process.o clone.o 9USER_OBJS := process.o clone.o
10 10
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
index daa2f85b684c..01d489de3986 100644
--- a/arch/um/kernel/skas/include/skas.h
+++ b/arch/um/kernel/skas/include/skas.h
@@ -22,7 +22,6 @@ extern int start_idle_thread(void *stack, void *switch_buf_ptr,
22extern int user_thread(unsigned long stack, int flags); 22extern int user_thread(unsigned long stack, int flags);
23extern void userspace(union uml_pt_regs *regs); 23extern void userspace(union uml_pt_regs *regs);
24extern void new_thread_proc(void *stack, void (*handler)(int sig)); 24extern void new_thread_proc(void *stack, void (*handler)(int sig));
25extern void remove_sigstack(void);
26extern void new_thread_handler(int sig); 25extern void new_thread_handler(int sig);
27extern void handle_syscall(union uml_pt_regs *regs); 26extern void handle_syscall(union uml_pt_regs *regs);
28extern int map(struct mm_id * mm_idp, unsigned long virt, 27extern int map(struct mm_id * mm_idp, unsigned long virt,
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 599d679bd4fc..9264d4021dfe 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -31,7 +31,6 @@
31#include "proc_mm.h" 31#include "proc_mm.h"
32#include "skas_ptrace.h" 32#include "skas_ptrace.h"
33#include "chan_user.h" 33#include "chan_user.h"
34#include "signal_user.h"
35#include "registers.h" 34#include "registers.h"
36#include "mem.h" 35#include "mem.h"
37#include "uml-config.h" 36#include "uml-config.h"
@@ -514,16 +513,6 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
514 siglongjmp(**switch_buf, 1); 513 siglongjmp(**switch_buf, 1);
515} 514}
516 515
517void remove_sigstack(void)
518{
519 stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE,
520 .ss_sp = NULL,
521 .ss_size = 0 });
522
523 if(sigaltstack(&stack, NULL) != 0)
524 panic("disabling signal stack failed, errno = %d\n", errno);
525}
526
527void initial_thread_cb_skas(void (*proc)(void *), void *arg) 516void initial_thread_cb_skas(void (*proc)(void *), void *arg)
528{ 517{
529 sigjmp_buf here; 518 sigjmp_buf here;
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 9c990253966c..09790ccb161c 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -14,7 +14,6 @@
14#include "asm/atomic.h" 14#include "asm/atomic.h"
15#include "kern_util.h" 15#include "kern_util.h"
16#include "time_user.h" 16#include "time_user.h"
17#include "signal_user.h"
18#include "skas.h" 17#include "skas.h"
19#include "os.h" 18#include "os.h"
20#include "user_util.h" 19#include "user_util.h"
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index c40b611e3d93..11f518a7e156 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -14,9 +14,9 @@
14#include "kern_util.h" 14#include "kern_util.h"
15#include "user.h" 15#include "user.h"
16#include "process.h" 16#include "process.h"
17#include "signal_user.h"
18#include "time_user.h" 17#include "time_user.h"
19#include "kern_constants.h" 18#include "kern_constants.h"
19#include "os.h"
20 20
21/* XXX This really needs to be declared and initialized in a kernel file since 21/* XXX This really needs to be declared and initialized in a kernel file since
22 * it's in <linux/time.h> 22 * it's in <linux/time.h>
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index 0d4c10a73607..d56046c2aba2 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -26,9 +26,13 @@
26#include "mconsole_kern.h" 26#include "mconsole_kern.h"
27#include "mem.h" 27#include "mem.h"
28#include "mem_kern.h" 28#include "mem_kern.h"
29#include "sysdep/sigcontext.h"
30#include "sysdep/ptrace.h"
31#include "os.h"
29#ifdef CONFIG_MODE_SKAS 32#ifdef CONFIG_MODE_SKAS
30#include "skas.h" 33#include "skas.h"
31#endif 34#endif
35#include "os.h"
32 36
33/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */ 37/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */
34int handle_page_fault(unsigned long address, unsigned long ip, 38int handle_page_fault(unsigned long address, unsigned long ip,
@@ -125,6 +129,25 @@ out_of_memory:
125 goto out; 129 goto out;
126} 130}
127 131
132void segv_handler(int sig, union uml_pt_regs *regs)
133{
134 struct faultinfo * fi = UPT_FAULTINFO(regs);
135
136 if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){
137 bad_segv(*fi, UPT_IP(regs));
138 return;
139 }
140 segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs);
141}
142
143struct kern_handlers handlinfo_kern = {
144 .relay_signal = relay_signal,
145 .winch = winch,
146 .bus_handler = relay_signal,
147 .page_fault = segv_handler,
148 .sigio_handler = sigio_handler,
149 .timer_handler = timer_handler
150};
128/* 151/*
129 * We give a *copy* of the faultinfo in the regs to segv. 152 * We give a *copy* of the faultinfo in the regs to segv.
130 * This must be done, since nesting SEGVs could overwrite 153 * This must be done, since nesting SEGVs could overwrite
diff --git a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
deleted file mode 100644
index e9ccd6b8d3c7..000000000000
--- a/arch/um/kernel/trap_user.c
+++ /dev/null
@@ -1,98 +0,0 @@
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 <errno.h>
8#include <setjmp.h>
9#include <signal.h>
10#include <sys/time.h>
11#include <sys/wait.h>
12#include <asm/page.h>
13#include <asm/unistd.h>
14#include <asm/ptrace.h>
15#include "init.h"
16#include "sysdep/ptrace.h"
17#include "sigcontext.h"
18#include "sysdep/sigcontext.h"
19#include "irq_user.h"
20#include "signal_user.h"
21#include "time_user.h"
22#include "task.h"
23#include "mode.h"
24#include "choose-mode.h"
25#include "kern_util.h"
26#include "user_util.h"
27#include "os.h"
28
29void kill_child_dead(int pid)
30{
31 kill(pid, SIGKILL);
32 kill(pid, SIGCONT);
33 do {
34 int n;
35 CATCH_EINTR(n = waitpid(pid, NULL, 0));
36 if (n > 0)
37 kill(pid, SIGCONT);
38 else
39 break;
40 } while(1);
41}
42
43void segv_handler(int sig, union uml_pt_regs *regs)
44{
45 struct faultinfo * fi = UPT_FAULTINFO(regs);
46
47 if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){
48 bad_segv(*fi, UPT_IP(regs));
49 return;
50 }
51 segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs);
52}
53
54void usr2_handler(int sig, union uml_pt_regs *regs)
55{
56 CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
57}
58
59struct signal_info sig_info[] = {
60 [ SIGTRAP ] { .handler = relay_signal,
61 .is_irq = 0 },
62 [ SIGFPE ] { .handler = relay_signal,
63 .is_irq = 0 },
64 [ SIGILL ] { .handler = relay_signal,
65 .is_irq = 0 },
66 [ SIGWINCH ] { .handler = winch,
67 .is_irq = 1 },
68 [ SIGBUS ] { .handler = bus_handler,
69 .is_irq = 0 },
70 [ SIGSEGV] { .handler = segv_handler,
71 .is_irq = 0 },
72 [ SIGIO ] { .handler = sigio_handler,
73 .is_irq = 1 },
74 [ SIGVTALRM ] { .handler = timer_handler,
75 .is_irq = 1 },
76 [ SIGALRM ] { .handler = timer_handler,
77 .is_irq = 1 },
78 [ SIGUSR2 ] { .handler = usr2_handler,
79 .is_irq = 0 },
80};
81
82void do_longjmp(void *b, int val)
83{
84 sigjmp_buf *buf = b;
85
86 siglongjmp(*buf, val);
87}
88
89/*
90 * Overrides for Emacs so that we follow Linus's tabbing style.
91 * Emacs will notice this stuff at the end of the file and automatically
92 * adjust the settings for this buffer only. This must remain at the end
93 * of the file.
94 * ---------------------------------------------------------------------------
95 * Local variables:
96 * c-file-style: "linux"
97 * End:
98 */
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
index 065b504a653b..136e54c47d37 100644
--- a/arch/um/kernel/tt/exec_kern.c
+++ b/arch/um/kernel/tt/exec_kern.c
@@ -14,7 +14,6 @@
14#include "kern_util.h" 14#include "kern_util.h"
15#include "irq_user.h" 15#include "irq_user.h"
16#include "time_user.h" 16#include "time_user.h"
17#include "signal_user.h"
18#include "mem_user.h" 17#include "mem_user.h"
19#include "os.h" 18#include "os.h"
20#include "tlb.h" 19#include "tlb.h"
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index cfaa373a6e77..14d4622a5fb8 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -13,7 +13,6 @@
13#include "asm/ptrace.h" 13#include "asm/ptrace.h"
14#include "asm/tlbflush.h" 14#include "asm/tlbflush.h"
15#include "irq_user.h" 15#include "irq_user.h"
16#include "signal_user.h"
17#include "kern_util.h" 16#include "kern_util.h"
18#include "user_util.h" 17#include "user_util.h"
19#include "os.h" 18#include "os.h"
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
index d11e7399d7a1..71daae24e48a 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -19,7 +19,6 @@
19#include "sigcontext.h" 19#include "sigcontext.h"
20#include "sysdep/sigcontext.h" 20#include "sysdep/sigcontext.h"
21#include "os.h" 21#include "os.h"
22#include "signal_user.h"
23#include "user_util.h" 22#include "user_util.h"
24#include "mem_user.h" 23#include "mem_user.h"
25#include "process.h" 24#include "process.h"
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
index fc108615beaf..a414c529fbcd 100644
--- a/arch/um/kernel/tt/trap_user.c
+++ b/arch/um/kernel/tt/trap_user.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 */
@@ -8,18 +8,18 @@
8#include <signal.h> 8#include <signal.h>
9#include "sysdep/ptrace.h" 9#include "sysdep/ptrace.h"
10#include "sysdep/sigcontext.h" 10#include "sysdep/sigcontext.h"
11#include "signal_user.h"
12#include "user_util.h" 11#include "user_util.h"
13#include "kern_util.h" 12#include "kern_util.h"
14#include "task.h" 13#include "task.h"
15#include "tt.h" 14#include "tt.h"
15#include "os.h"
16 16
17void sig_handler_common_tt(int sig, void *sc_ptr) 17void sig_handler_common_tt(int sig, void *sc_ptr)
18{ 18{
19 struct sigcontext *sc = sc_ptr; 19 struct sigcontext *sc = sc_ptr;
20 struct tt_regs save_regs, *r; 20 struct tt_regs save_regs, *r;
21 struct signal_info *info;
22 int save_errno = errno, is_user; 21 int save_errno = errno, is_user;
22 void (*handler)(int, union uml_pt_regs *);
23 23
24 /* This is done because to allow SIGSEGV to be delivered inside a SEGV 24 /* This is done because to allow SIGSEGV to be delivered inside a SEGV
25 * handler. This can happen in copy_user, and if SEGV is disabled, 25 * handler. This can happen in copy_user, and if SEGV is disabled,
@@ -40,10 +40,14 @@ void sig_handler_common_tt(int sig, void *sc_ptr)
40 if(sig != SIGUSR2) 40 if(sig != SIGUSR2)
41 r->syscall = -1; 41 r->syscall = -1;
42 42
43 info = &sig_info[sig]; 43 handler = sig_info[sig];
44 if(!info->is_irq) unblock_signals(); 44
45 /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */
46 if (sig != SIGIO && sig != SIGWINCH &&
47 sig != SIGVTALRM && sig != SIGALRM)
48 unblock_signals();
45 49
46 (*info->handler)(sig, (union uml_pt_regs *) r); 50 handler(sig, (union uml_pt_regs *) r);
47 51
48 if(is_user){ 52 if(is_user){
49 interrupt_end(); 53 interrupt_end();
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 26626b2b9172..73747ac19774 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -363,6 +363,11 @@ int linux_main(int argc, char **argv)
363 uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0, 363 uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
364 &host_task_size, &task_size); 364 &host_task_size, &task_size);
365 365
366 /*
367 * Setting up handlers to 'sig_info' struct
368 */
369 os_fill_handlinfo(handlinfo_kern);
370
366 brk_start = (unsigned long) sbrk(0); 371 brk_start = (unsigned long) sbrk(0);
367 CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start); 372 CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
368 /* Increase physical memory size for exec-shield users 373 /* Increase physical memory size for exec-shield users
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 11e30b13e318..40c7d6b1df68 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -4,11 +4,13 @@
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 main.o mem.o process.o signal.o \
7 start_up.o time.o tt.o tty.o uaccess.o umid.o user_syms.o drivers/ \ 7 start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o user_syms.o \
8 sys-$(SUBARCH)/ 8 drivers/ sys-$(SUBARCH)/
9
10obj-$(CONFIG_MODE_SKAS) += skas/
9 11
10USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ 12USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
11 start_up.o time.o tt.o tty.o uaccess.o umid.o 13 start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o
12 14
13elf_aux.o: $(ARCH_DIR)/kernel-offsets.h 15elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
14CFLAGS_elf_aux.o += -I$(objtree)/arch/um 16CFLAGS_elf_aux.o += -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 23da27d22569..172c8474453c 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -16,7 +16,6 @@
16#include "user_util.h" 16#include "user_util.h"
17#include "kern_util.h" 17#include "kern_util.h"
18#include "mem_user.h" 18#include "mem_user.h"
19#include "signal_user.h"
20#include "time_user.h" 19#include "time_user.h"
21#include "irq_user.h" 20#include "irq_user.h"
22#include "user.h" 21#include "user.h"
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index d9c52387c4a1..39815c6b5e45 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -15,7 +15,6 @@
15#include "os.h" 15#include "os.h"
16#include "user.h" 16#include "user.h"
17#include "user_util.h" 17#include "user_util.h"
18#include "signal_user.h"
19#include "process.h" 18#include "process.h"
20#include "irq_user.h" 19#include "irq_user.h"
21#include "kern_util.h" 20#include "kern_util.h"
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index c7bfd5ee3925..c1f46a0fef13 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -4,9 +4,22 @@
4 */ 4 */
5 5
6#include <signal.h> 6#include <signal.h>
7#include <stdio.h>
8#include <unistd.h>
9#include <stdlib.h>
10#include <errno.h>
11#include <stdarg.h>
12#include <string.h>
13#include <sys/mman.h>
14#include "user_util.h"
15#include "kern_util.h"
16#include "user.h"
17#include "signal_kern.h"
18#include "sysdep/sigcontext.h"
19#include "sysdep/signal.h"
20#include "sigcontext.h"
7#include "time_user.h" 21#include "time_user.h"
8#include "mode.h" 22#include "mode.h"
9#include "sysdep/signal.h"
10 23
11void sig_handler(ARCH_SIGHDLR_PARAM) 24void sig_handler(ARCH_SIGHDLR_PARAM)
12{ 25{
@@ -36,13 +49,138 @@ void alarm_handler(ARCH_SIGHDLR_PARAM)
36 switch_timers(1); 49 switch_timers(1);
37} 50}
38 51
39/* 52void set_sigstack(void *sig_stack, int size)
40 * Overrides for Emacs so that we follow Linus's tabbing style. 53{
41 * Emacs will notice this stuff at the end of the file and automatically 54 stack_t stack = ((stack_t) { .ss_flags = 0,
42 * adjust the settings for this buffer only. This must remain at the end 55 .ss_sp = (__ptr_t) sig_stack,
43 * of the file. 56 .ss_size = size - sizeof(void *) });
44 * --------------------------------------------------------------------------- 57
45 * Local variables: 58 if(sigaltstack(&stack, NULL) != 0)
46 * c-file-style: "linux" 59 panic("enabling signal stack failed, errno = %d\n", errno);
47 * End: 60}
61
62void remove_sigstack(void)
63{
64 stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE,
65 .ss_sp = NULL,
66 .ss_size = 0 });
67
68 if(sigaltstack(&stack, NULL) != 0)
69 panic("disabling signal stack failed, errno = %d\n", errno);
70}
71
72void set_handler(int sig, void (*handler)(int), int flags, ...)
73{
74 struct sigaction action;
75 va_list ap;
76 int mask;
77
78 va_start(ap, flags);
79 action.sa_handler = handler;
80 sigemptyset(&action.sa_mask);
81 while((mask = va_arg(ap, int)) != -1){
82 sigaddset(&action.sa_mask, mask);
83 }
84 va_end(ap);
85 action.sa_flags = flags;
86 action.sa_restorer = NULL;
87 if(sigaction(sig, &action, NULL) < 0)
88 panic("sigaction failed");
89}
90
91int change_sig(int signal, int on)
92{
93 sigset_t sigset, old;
94
95 sigemptyset(&sigset);
96 sigaddset(&sigset, signal);
97 sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
98 return(!sigismember(&old, signal));
99}
100
101/* Both here and in set/get_signal we don't touch SIGPROF, because we must not
102 * disable profiling; it's safe because the profiling code does not interact
103 * with the kernel code at all.*/
104
105static void change_signals(int type)
106{
107 sigset_t mask;
108
109 sigemptyset(&mask);
110 sigaddset(&mask, SIGVTALRM);
111 sigaddset(&mask, SIGALRM);
112 sigaddset(&mask, SIGIO);
113 if(sigprocmask(type, &mask, NULL) < 0)
114 panic("Failed to change signal mask - errno = %d", errno);
115}
116
117void block_signals(void)
118{
119 change_signals(SIG_BLOCK);
120}
121
122void unblock_signals(void)
123{
124 change_signals(SIG_UNBLOCK);
125}
126
127/* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled
128 * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to
129 * be able to profile all of UML, not just the non-critical sections. If
130 * profiling is not thread-safe, then that is not my problem. We can disable
131 * profiling when SMP is enabled in that case.
48 */ 132 */
133#define SIGIO_BIT 0
134#define SIGVTALRM_BIT 1
135
136static int enable_mask(sigset_t *mask)
137{
138 int sigs;
139
140 sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
141 sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
142 sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
143 return(sigs);
144}
145
146int get_signals(void)
147{
148 sigset_t mask;
149
150 if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
151 panic("Failed to get signal mask");
152 return(enable_mask(&mask));
153}
154
155int set_signals(int enable)
156{
157 sigset_t mask;
158 int ret;
159
160 sigemptyset(&mask);
161 if(enable & (1 << SIGIO_BIT))
162 sigaddset(&mask, SIGIO);
163 if(enable & (1 << SIGVTALRM_BIT)){
164 sigaddset(&mask, SIGVTALRM);
165 sigaddset(&mask, SIGALRM);
166 }
167
168 /* This is safe - sigprocmask is guaranteed to copy locally the
169 * value of new_set, do his work and then, at the end, write to
170 * old_set.
171 */
172 if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
173 panic("Failed to enable signals");
174 ret = enable_mask(&mask);
175 sigemptyset(&mask);
176 if((enable & (1 << SIGIO_BIT)) == 0)
177 sigaddset(&mask, SIGIO);
178 if((enable & (1 << SIGVTALRM_BIT)) == 0){
179 sigaddset(&mask, SIGVTALRM);
180 sigaddset(&mask, SIGALRM);
181 }
182 if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
183 panic("Failed to block signals");
184
185 return(ret);
186}
diff --git a/arch/um/os-Linux/skas/Makefile b/arch/um/os-Linux/skas/Makefile
new file mode 100644
index 000000000000..eab5386d60a7
--- /dev/null
+++ b/arch/um/os-Linux/skas/Makefile
@@ -0,0 +1,10 @@
1#
2# Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com)
3# Licensed under the GPL
4#
5
6obj-y := trap.o
7
8USER_OBJS := trap.o
9
10include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/skas/trap_user.c b/arch/um/os-Linux/skas/trap.c
index 9950a6716fe5..9ad5fbec4593 100644
--- a/arch/um/kernel/skas/trap_user.c
+++ b/arch/um/os-Linux/skas/trap.c
@@ -1,11 +1,10 @@
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 */
5 5
6#include <signal.h> 6#include <signal.h>
7#include <errno.h> 7#include <errno.h>
8#include "signal_user.h"
9#include "user_util.h" 8#include "user_util.h"
10#include "kern_util.h" 9#include "kern_util.h"
11#include "task.h" 10#include "task.h"
@@ -14,12 +13,13 @@
14#include "ptrace_user.h" 13#include "ptrace_user.h"
15#include "sysdep/ptrace.h" 14#include "sysdep/ptrace.h"
16#include "sysdep/ptrace_user.h" 15#include "sysdep/ptrace_user.h"
16#include "os.h"
17 17
18void sig_handler_common_skas(int sig, void *sc_ptr) 18void sig_handler_common_skas(int sig, void *sc_ptr)
19{ 19{
20 struct sigcontext *sc = sc_ptr; 20 struct sigcontext *sc = sc_ptr;
21 struct skas_regs *r; 21 struct skas_regs *r;
22 struct signal_info *info; 22 void (*handler)(int, union uml_pt_regs *);
23 int save_errno = errno; 23 int save_errno = errno;
24 int save_user; 24 int save_user;
25 25
@@ -34,17 +34,22 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
34 r = &TASK_REGS(get_current())->skas; 34 r = &TASK_REGS(get_current())->skas;
35 save_user = r->is_user; 35 save_user = r->is_user;
36 r->is_user = 0; 36 r->is_user = 0;
37 if ( sig == SIGFPE || sig == SIGSEGV || 37 if ( sig == SIGFPE || sig == SIGSEGV ||
38 sig == SIGBUS || sig == SIGILL || 38 sig == SIGBUS || sig == SIGILL ||
39 sig == SIGTRAP ) { 39 sig == SIGTRAP ) {
40 GET_FAULTINFO_FROM_SC(r->faultinfo, sc); 40 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
41 } 41 }
42 42
43 change_sig(SIGUSR1, 1); 43 change_sig(SIGUSR1, 1);
44 info = &sig_info[sig];
45 if(!info->is_irq) unblock_signals();
46 44
47 (*info->handler)(sig, (union uml_pt_regs *) r); 45 handler = sig_info[sig];
46
47 /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */
48 if (sig != SIGIO && sig != SIGWINCH &&
49 sig != SIGVTALRM && sig != SIGALRM)
50 unblock_signals();
51
52 handler(sig, (union uml_pt_regs *) r);
48 53
49 errno = save_errno; 54 errno = save_errno;
50 r->is_user = save_user; 55 r->is_user = save_user;
@@ -54,25 +59,15 @@ extern int ptrace_faultinfo;
54 59
55void user_signal(int sig, union uml_pt_regs *regs, int pid) 60void user_signal(int sig, union uml_pt_regs *regs, int pid)
56{ 61{
57 struct signal_info *info; 62 void (*handler)(int, union uml_pt_regs *);
58 int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || 63 int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
59 (sig == SIGILL) || (sig == SIGTRAP)); 64 (sig == SIGILL) || (sig == SIGTRAP));
60 65
61 if (segv) 66 if (segv)
62 get_skas_faultinfo(pid, &regs->skas.faultinfo); 67 get_skas_faultinfo(pid, &regs->skas.faultinfo);
63 info = &sig_info[sig]; 68
64 (*info->handler)(sig, regs); 69 handler = sig_info[sig];
70 handler(sig, (union uml_pt_regs *) regs);
65 71
66 unblock_signals(); 72 unblock_signals();
67} 73}
68
69/*
70 * Overrides for Emacs so that we follow Linus's tabbing style.
71 * Emacs will notice this stuff at the end of the file and automatically
72 * adjust the settings for this buffer only. This must remain at the end
73 * of the file.
74 * ---------------------------------------------------------------------------
75 * Local variables:
76 * c-file-style: "linux"
77 * End:
78 */
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 29a9e3f43763..b47e5e71d1a5 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -24,7 +24,6 @@
24#include "kern_util.h" 24#include "kern_util.h"
25#include "user.h" 25#include "user.h"
26#include "signal_kern.h" 26#include "signal_kern.h"
27#include "signal_user.h"
28#include "sysdep/ptrace.h" 27#include "sysdep/ptrace.h"
29#include "sysdep/sigcontext.h" 28#include "sysdep/sigcontext.h"
30#include "irq_user.h" 29#include "irq_user.h"
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
new file mode 100644
index 000000000000..321e1c8e227d
--- /dev/null
+++ b/arch/um/os-Linux/trap.c
@@ -0,0 +1,40 @@
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 <signal.h>
8#include <setjmp.h>
9#include "kern_util.h"
10#include "user_util.h"
11#include "os.h"
12#include "mode.h"
13
14void usr2_handler(int sig, union uml_pt_regs *regs)
15{
16 CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
17}
18
19void (*sig_info[NSIG])(int, union uml_pt_regs *);
20
21void os_fill_handlinfo(struct kern_handlers h)
22{
23 sig_info[SIGTRAP] = h.relay_signal;
24 sig_info[SIGFPE] = h.relay_signal;
25 sig_info[SIGILL] = h.relay_signal;
26 sig_info[SIGWINCH] = h.winch;
27 sig_info[SIGBUS] = h.bus_handler;
28 sig_info[SIGSEGV] = h.page_fault;
29 sig_info[SIGIO] = h.sigio_handler;
30 sig_info[SIGVTALRM] = h.timer_handler;
31 sig_info[SIGALRM] = h.timer_handler;
32 sig_info[SIGUSR2] = usr2_handler;
33}
34
35void do_longjmp(void *b, int val)
36{
37 sigjmp_buf *buf = b;
38
39 siglongjmp(*buf, val);
40}
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
index a6db8877931a..cb2648b79d0f 100644
--- a/arch/um/os-Linux/tt.c
+++ b/arch/um/os-Linux/tt.c
@@ -23,7 +23,6 @@
23#include "kern_util.h" 23#include "kern_util.h"
24#include "user.h" 24#include "user.h"
25#include "signal_kern.h" 25#include "signal_kern.h"
26#include "signal_user.h"
27#include "sysdep/ptrace.h" 26#include "sysdep/ptrace.h"
28#include "sysdep/sigcontext.h" 27#include "sysdep/sigcontext.h"
29#include "irq_user.h" 28#include "irq_user.h"
@@ -50,6 +49,20 @@ int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
50 return(0); 49 return(0);
51} 50}
52 51
52void kill_child_dead(int pid)
53{
54 kill(pid, SIGKILL);
55 kill(pid, SIGCONT);
56 do {
57 int n;
58 CATCH_EINTR(n = waitpid(pid, NULL, 0));
59 if (n > 0)
60 kill(pid, SIGCONT);
61 else
62 break;
63 } while(1);
64}
65
53/* 66/*
54 *------------------------- 67 *-------------------------
55 * only for tt mode (will be deleted in future...) 68 * only for tt mode (will be deleted in future...)
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 16bc19928b3c..7cd1a82dc8c2 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -10,7 +10,6 @@
10#include "asm/uaccess.h" 10#include "asm/uaccess.h"
11#include "asm/unistd.h" 11#include "asm/unistd.h"
12#include "frame_kern.h" 12#include "frame_kern.h"
13#include "signal_user.h"
14#include "sigcontext.h" 13#include "sigcontext.h"
15#include "registers.h" 14#include "registers.h"
16#include "mode.h" 15#include "mode.h"
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
index 310865903234..04494638b963 100644
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -10,9 +10,6 @@ mainmenu "uClinux/v850 (w/o MMU) Kernel Configuration"
10config MMU 10config MMU
11 bool 11 bool
12 default n 12 default n
13config UID16
14 bool
15 default n
16config RWSEM_GENERIC_SPINLOCK 13config RWSEM_GENERIC_SPINLOCK
17 bool 14 bool
18 default y 15 default y
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 6ece645e4dbe..4f3e925962c3 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -542,11 +542,6 @@ config SYSVIPC_COMPAT
542 depends on COMPAT && SYSVIPC 542 depends on COMPAT && SYSVIPC
543 default y 543 default y
544 544
545config UID16
546 bool
547 depends on IA32_EMULATION
548 default y
549
550endmenu 545endmenu
551 546
552source "net/Kconfig" 547source "net/Kconfig"
diff --git a/arch/x86_64/boot/compressed/misc.c b/arch/x86_64/boot/compressed/misc.c
index 0e10fd84c7cc..cf4b88c416dc 100644
--- a/arch/x86_64/boot/compressed/misc.c
+++ b/arch/x86_64/boot/compressed/misc.c
@@ -9,7 +9,7 @@
9 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 9 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
10 */ 10 */
11 11
12#include "miscsetup.h" 12#include <linux/screen_info.h>
13#include <asm/io.h> 13#include <asm/io.h>
14#include <asm/page.h> 14#include <asm/page.h>
15 15
diff --git a/arch/x86_64/boot/compressed/miscsetup.h b/arch/x86_64/boot/compressed/miscsetup.h
deleted file mode 100644
index bb1620531703..000000000000
--- a/arch/x86_64/boot/compressed/miscsetup.h
+++ /dev/null
@@ -1,39 +0,0 @@
1#define NULL 0
2//typedef unsigned int size_t;
3
4
5struct screen_info {
6 unsigned char orig_x; /* 0x00 */
7 unsigned char orig_y; /* 0x01 */
8 unsigned short dontuse1; /* 0x02 -- EXT_MEM_K sits here */
9 unsigned short orig_video_page; /* 0x04 */
10 unsigned char orig_video_mode; /* 0x06 */
11 unsigned char orig_video_cols; /* 0x07 */
12 unsigned short unused2; /* 0x08 */
13 unsigned short orig_video_ega_bx; /* 0x0a */
14 unsigned short unused3; /* 0x0c */
15 unsigned char orig_video_lines; /* 0x0e */
16 unsigned char orig_video_isVGA; /* 0x0f */
17 unsigned short orig_video_points; /* 0x10 */
18
19 /* VESA graphic mode -- linear frame buffer */
20 unsigned short lfb_width; /* 0x12 */
21 unsigned short lfb_height; /* 0x14 */
22 unsigned short lfb_depth; /* 0x16 */
23 unsigned long lfb_base; /* 0x18 */
24 unsigned long lfb_size; /* 0x1c */
25 unsigned short dontuse2, dontuse3; /* 0x20 -- CL_MAGIC and CL_OFFSET here */
26 unsigned short lfb_linelength; /* 0x24 */
27 unsigned char red_size; /* 0x26 */
28 unsigned char red_pos; /* 0x27 */
29 unsigned char green_size; /* 0x28 */
30 unsigned char green_pos; /* 0x29 */
31 unsigned char blue_size; /* 0x2a */
32 unsigned char blue_pos; /* 0x2b */
33 unsigned char rsvd_size; /* 0x2c */
34 unsigned char rsvd_pos; /* 0x2d */
35 unsigned short vesapm_seg; /* 0x2e */
36 unsigned short vesapm_off; /* 0x30 */
37 unsigned short pages; /* 0x32 */
38 /* 0x34 -- 0x3f reserved for future expansion */
39};
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index df0773c9bdbe..1f0ff5adc80e 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -643,6 +643,7 @@ ia32_sys_call_table:
643 .quad sys_inotify_init 643 .quad sys_inotify_init
644 .quad sys_inotify_add_watch 644 .quad sys_inotify_add_watch
645 .quad sys_inotify_rm_watch 645 .quad sys_inotify_rm_watch
646 .quad sys_migrate_pages
646ia32_syscall_end: 647ia32_syscall_end:
647 .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 648 .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
648 .quad ni_syscall 649 .quad ni_syscall
diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c
index 2a925e2af390..5f4cdfa56901 100644
--- a/arch/x86_64/ia32/ptrace32.c
+++ b/arch/x86_64/ia32/ptrace32.c
@@ -196,36 +196,6 @@ static int getreg32(struct task_struct *child, unsigned regno, u32 *val)
196 196
197#undef R32 197#undef R32
198 198
199static struct task_struct *find_target(int request, int pid, int *err)
200{
201 struct task_struct *child;
202
203 *err = -EPERM;
204 if (pid == 1)
205 return NULL;
206
207 *err = -ESRCH;
208 read_lock(&tasklist_lock);
209 child = find_task_by_pid(pid);
210 if (child)
211 get_task_struct(child);
212 read_unlock(&tasklist_lock);
213 if (child) {
214 *err = -EPERM;
215 if (child->pid == 1)
216 goto out;
217 *err = ptrace_check_attach(child, request == PTRACE_KILL);
218 if (*err < 0)
219 goto out;
220 return child;
221 }
222 out:
223 if (child)
224 put_task_struct(child);
225 return NULL;
226
227}
228
229asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) 199asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
230{ 200{
231 struct task_struct *child; 201 struct task_struct *child;
@@ -254,9 +224,16 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
254 break; 224 break;
255 } 225 }
256 226
257 child = find_target(request, pid, &ret); 227 if (request == PTRACE_TRACEME)
258 if (!child) 228 return ptrace_traceme();
259 return ret; 229
230 child = ptrace_get_task_struct(pid);
231 if (IS_ERR(child))
232 return PTR_ERR(child);
233
234 ret = ptrace_check_attach(child, request == PTRACE_KILL);
235 if (ret < 0)
236 goto out;
260 237
261 childregs = (struct pt_regs *)(child->thread.rsp0 - sizeof(struct pt_regs)); 238 childregs = (struct pt_regs *)(child->thread.rsp0 - sizeof(struct pt_regs));
262 239
@@ -373,6 +350,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
373 break; 350 break;
374 } 351 }
375 352
353 out:
376 put_task_struct(child); 354 put_task_struct(child);
377 return ret; 355 return ret;
378} 356}
diff --git a/arch/x86_64/kernel/init_task.c b/arch/x86_64/kernel/init_task.c
index e0ba5c1043fd..ce31d904d601 100644
--- a/arch/x86_64/kernel/init_task.c
+++ b/arch/x86_64/kernel/init_task.c
@@ -44,6 +44,6 @@ EXPORT_SYMBOL(init_task);
44 * section. Since TSS's are completely CPU-local, we want them 44 * section. Since TSS's are completely CPU-local, we want them
45 * on exact cacheline boundaries, to eliminate cacheline ping-pong. 45 * on exact cacheline boundaries, to eliminate cacheline ping-pong.
46 */ 46 */
47DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_maxaligned_in_smp = INIT_TSS; 47DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
48 48
49#define ALIGN_TO_4K __attribute__((section(".data.init_task"))) 49#define ALIGN_TO_4K __attribute__((section(".data.init_task")))
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 74102796e5c0..43c9fa0f8d5f 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -1075,8 +1075,6 @@ device_initcall(time_init_device);
1075 */ 1075 */
1076#include <linux/rtc.h> 1076#include <linux/rtc.h>
1077 1077
1078extern irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
1079
1080#define DEFAULT_RTC_INT_FREQ 64 1078#define DEFAULT_RTC_INT_FREQ 64
1081#define RTC_NUM_INTS 1 1079#define RTC_NUM_INTS 1
1082 1080
diff --git a/block/elevator.c b/block/elevator.c
index 39dcccc82ada..99a4d7b2f8ad 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -64,7 +64,7 @@ inline int elv_rq_merge_ok(struct request *rq, struct bio *bio)
64} 64}
65EXPORT_SYMBOL(elv_rq_merge_ok); 65EXPORT_SYMBOL(elv_rq_merge_ok);
66 66
67inline int elv_try_merge(struct request *__rq, struct bio *bio) 67static inline int elv_try_merge(struct request *__rq, struct bio *bio)
68{ 68{
69 int ret = ELEVATOR_NO_MERGE; 69 int ret = ELEVATOR_NO_MERGE;
70 70
@@ -80,7 +80,6 @@ inline int elv_try_merge(struct request *__rq, struct bio *bio)
80 80
81 return ret; 81 return ret;
82} 82}
83EXPORT_SYMBOL(elv_try_merge);
84 83
85static struct elevator_type *elevator_find(const char *name) 84static struct elevator_type *elevator_find(const char *name)
86{ 85{
diff --git a/block/ioctl.c b/block/ioctl.c
index 6e278474f9a8..82030e1dfd63 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -1,6 +1,7 @@
1#include <linux/sched.h> /* for capable() */ 1#include <linux/sched.h> /* for capable() */
2#include <linux/blkdev.h> 2#include <linux/blkdev.h>
3#include <linux/blkpg.h> 3#include <linux/blkpg.h>
4#include <linux/hdreg.h>
4#include <linux/backing-dev.h> 5#include <linux/backing-dev.h>
5#include <linux/buffer_head.h> 6#include <linux/buffer_head.h>
6#include <linux/smp_lock.h> 7#include <linux/smp_lock.h>
@@ -245,6 +246,27 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
245 set_device_ro(bdev, n); 246 set_device_ro(bdev, n);
246 unlock_kernel(); 247 unlock_kernel();
247 return 0; 248 return 0;
249 case HDIO_GETGEO: {
250 struct hd_geometry geo;
251
252 if (!arg)
253 return -EINVAL;
254 if (!disk->fops->getgeo)
255 return -ENOTTY;
256
257 /*
258 * We need to set the startsect first, the driver may
259 * want to override it.
260 */
261 geo.start = get_start_sect(bdev);
262 ret = disk->fops->getgeo(bdev, &geo);
263 if (ret)
264 return ret;
265 if (copy_to_user((struct hd_geometry __user *)arg, &geo,
266 sizeof(geo)))
267 return -EFAULT;
268 return 0;
269 }
248 } 270 }
249 271
250 lock_kernel(); 272 lock_kernel();
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 91d3b4828c49..8e27d0ab0d7c 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -26,7 +26,8 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/swap.h> 27#include <linux/swap.h>
28#include <linux/writeback.h> 28#include <linux/writeback.h>
29#include <linux/blkdev.h> 29#include <linux/interrupt.h>
30#include <linux/cpu.h>
30 31
31/* 32/*
32 * for max sense size 33 * for max sense size
@@ -62,13 +63,15 @@ static wait_queue_head_t congestion_wqh[2] = {
62/* 63/*
63 * Controlling structure to kblockd 64 * Controlling structure to kblockd
64 */ 65 */
65static struct workqueue_struct *kblockd_workqueue; 66static struct workqueue_struct *kblockd_workqueue;
66 67
67unsigned long blk_max_low_pfn, blk_max_pfn; 68unsigned long blk_max_low_pfn, blk_max_pfn;
68 69
69EXPORT_SYMBOL(blk_max_low_pfn); 70EXPORT_SYMBOL(blk_max_low_pfn);
70EXPORT_SYMBOL(blk_max_pfn); 71EXPORT_SYMBOL(blk_max_pfn);
71 72
73static DEFINE_PER_CPU(struct list_head, blk_cpu_done);
74
72/* Amount of time in which a process may batch requests */ 75/* Amount of time in which a process may batch requests */
73#define BLK_BATCH_TIME (HZ/50UL) 76#define BLK_BATCH_TIME (HZ/50UL)
74 77
@@ -207,6 +210,13 @@ void blk_queue_merge_bvec(request_queue_t *q, merge_bvec_fn *mbfn)
207 210
208EXPORT_SYMBOL(blk_queue_merge_bvec); 211EXPORT_SYMBOL(blk_queue_merge_bvec);
209 212
213void blk_queue_softirq_done(request_queue_t *q, softirq_done_fn *fn)
214{
215 q->softirq_done_fn = fn;
216}
217
218EXPORT_SYMBOL(blk_queue_softirq_done);
219
210/** 220/**
211 * blk_queue_make_request - define an alternate make_request function for a device 221 * blk_queue_make_request - define an alternate make_request function for a device
212 * @q: the request queue for the device to be affected 222 * @q: the request queue for the device to be affected
@@ -270,6 +280,7 @@ EXPORT_SYMBOL(blk_queue_make_request);
270static inline void rq_init(request_queue_t *q, struct request *rq) 280static inline void rq_init(request_queue_t *q, struct request *rq)
271{ 281{
272 INIT_LIST_HEAD(&rq->queuelist); 282 INIT_LIST_HEAD(&rq->queuelist);
283 INIT_LIST_HEAD(&rq->donelist);
273 284
274 rq->errors = 0; 285 rq->errors = 0;
275 rq->rq_status = RQ_ACTIVE; 286 rq->rq_status = RQ_ACTIVE;
@@ -286,6 +297,7 @@ static inline void rq_init(request_queue_t *q, struct request *rq)
286 rq->sense = NULL; 297 rq->sense = NULL;
287 rq->end_io = NULL; 298 rq->end_io = NULL;
288 rq->end_io_data = NULL; 299 rq->end_io_data = NULL;
300 rq->completion_data = NULL;
289} 301}
290 302
291/** 303/**
@@ -2735,30 +2747,6 @@ static inline int attempt_front_merge(request_queue_t *q, struct request *rq)
2735 return 0; 2747 return 0;
2736} 2748}
2737 2749
2738/**
2739 * blk_attempt_remerge - attempt to remerge active head with next request
2740 * @q: The &request_queue_t belonging to the device
2741 * @rq: The head request (usually)
2742 *
2743 * Description:
2744 * For head-active devices, the queue can easily be unplugged so quickly
2745 * that proper merging is not done on the front request. This may hurt
2746 * performance greatly for some devices. The block layer cannot safely
2747 * do merging on that first request for these queues, but the driver can
2748 * call this function and make it happen any way. Only the driver knows
2749 * when it is safe to do so.
2750 **/
2751void blk_attempt_remerge(request_queue_t *q, struct request *rq)
2752{
2753 unsigned long flags;
2754
2755 spin_lock_irqsave(q->queue_lock, flags);
2756 attempt_back_merge(q, rq);
2757 spin_unlock_irqrestore(q->queue_lock, flags);
2758}
2759
2760EXPORT_SYMBOL(blk_attempt_remerge);
2761
2762static void init_request_from_bio(struct request *req, struct bio *bio) 2750static void init_request_from_bio(struct request *req, struct bio *bio)
2763{ 2751{
2764 req->flags |= REQ_CMD; 2752 req->flags |= REQ_CMD;
@@ -3287,6 +3275,87 @@ int end_that_request_chunk(struct request *req, int uptodate, int nr_bytes)
3287EXPORT_SYMBOL(end_that_request_chunk); 3275EXPORT_SYMBOL(end_that_request_chunk);
3288 3276
3289/* 3277/*
3278 * splice the completion data to a local structure and hand off to
3279 * process_completion_queue() to complete the requests
3280 */
3281static void blk_done_softirq(struct softirq_action *h)
3282{
3283 struct list_head *cpu_list;
3284 LIST_HEAD(local_list);
3285
3286 local_irq_disable();
3287 cpu_list = &__get_cpu_var(blk_cpu_done);
3288 list_splice_init(cpu_list, &local_list);
3289 local_irq_enable();
3290
3291 while (!list_empty(&local_list)) {
3292 struct request *rq = list_entry(local_list.next, struct request, donelist);
3293
3294 list_del_init(&rq->donelist);
3295 rq->q->softirq_done_fn(rq);
3296 }
3297}
3298
3299#ifdef CONFIG_HOTPLUG_CPU
3300
3301static int blk_cpu_notify(struct notifier_block *self, unsigned long action,
3302 void *hcpu)
3303{
3304 /*
3305 * If a CPU goes away, splice its entries to the current CPU
3306 * and trigger a run of the softirq
3307 */
3308 if (action == CPU_DEAD) {
3309 int cpu = (unsigned long) hcpu;
3310
3311 local_irq_disable();
3312 list_splice_init(&per_cpu(blk_cpu_done, cpu),
3313 &__get_cpu_var(blk_cpu_done));
3314 raise_softirq_irqoff(BLOCK_SOFTIRQ);
3315 local_irq_enable();
3316 }
3317
3318 return NOTIFY_OK;
3319}
3320
3321
3322static struct notifier_block __devinitdata blk_cpu_notifier = {
3323 .notifier_call = blk_cpu_notify,
3324};
3325
3326#endif /* CONFIG_HOTPLUG_CPU */
3327
3328/**
3329 * blk_complete_request - end I/O on a request
3330 * @req: the request being processed
3331 *
3332 * Description:
3333 * Ends all I/O on a request. It does not handle partial completions,
3334 * unless the driver actually implements this in its completionc callback
3335 * through requeueing. Theh actual completion happens out-of-order,
3336 * through a softirq handler. The user must have registered a completion
3337 * callback through blk_queue_softirq_done().
3338 **/
3339
3340void blk_complete_request(struct request *req)
3341{
3342 struct list_head *cpu_list;
3343 unsigned long flags;
3344
3345 BUG_ON(!req->q->softirq_done_fn);
3346
3347 local_irq_save(flags);
3348
3349 cpu_list = &__get_cpu_var(blk_cpu_done);
3350 list_add_tail(&req->donelist, cpu_list);
3351 raise_softirq_irqoff(BLOCK_SOFTIRQ);
3352
3353 local_irq_restore(flags);
3354}
3355
3356EXPORT_SYMBOL(blk_complete_request);
3357
3358/*
3290 * queue lock must be held 3359 * queue lock must be held
3291 */ 3360 */
3292void end_that_request_last(struct request *req, int uptodate) 3361void end_that_request_last(struct request *req, int uptodate)
@@ -3364,6 +3433,8 @@ EXPORT_SYMBOL(kblockd_flush);
3364 3433
3365int __init blk_dev_init(void) 3434int __init blk_dev_init(void)
3366{ 3435{
3436 int i;
3437
3367 kblockd_workqueue = create_workqueue("kblockd"); 3438 kblockd_workqueue = create_workqueue("kblockd");
3368 if (!kblockd_workqueue) 3439 if (!kblockd_workqueue)
3369 panic("Failed to create kblockd\n"); 3440 panic("Failed to create kblockd\n");
@@ -3377,6 +3448,14 @@ int __init blk_dev_init(void)
3377 iocontext_cachep = kmem_cache_create("blkdev_ioc", 3448 iocontext_cachep = kmem_cache_create("blkdev_ioc",
3378 sizeof(struct io_context), 0, SLAB_PANIC, NULL, NULL); 3449 sizeof(struct io_context), 0, SLAB_PANIC, NULL, NULL);
3379 3450
3451 for (i = 0; i < NR_CPUS; i++)
3452 INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i));
3453
3454 open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL);
3455#ifdef CONFIG_HOTPLUG_CPU
3456 register_cpu_notifier(&blk_cpu_notifier);
3457#endif
3458
3380 blk_max_low_pfn = max_low_pfn; 3459 blk_max_low_pfn = max_low_pfn;
3381 blk_max_pfn = max_pfn; 3460 blk_max_pfn = max_pfn;
3382 3461
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index c2ac36dfe4f3..18de84c8ccd8 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -190,16 +190,21 @@ static int verify_command(struct file *file, unsigned char *cmd)
190 safe_for_write(GPCMD_SET_STREAMING), 190 safe_for_write(GPCMD_SET_STREAMING),
191 }; 191 };
192 unsigned char type = cmd_type[cmd[0]]; 192 unsigned char type = cmd_type[cmd[0]];
193 int has_write_perm = 0;
193 194
194 /* Anybody who can open the device can do a read-safe command */ 195 /* Anybody who can open the device can do a read-safe command */
195 if (type & CMD_READ_SAFE) 196 if (type & CMD_READ_SAFE)
196 return 0; 197 return 0;
197 198
199 /*
200 * file can be NULL from ioctl_by_bdev()...
201 */
202 if (file)
203 has_write_perm = file->f_mode & FMODE_WRITE;
204
198 /* Write-safe commands just require a writable open.. */ 205 /* Write-safe commands just require a writable open.. */
199 if (type & CMD_WRITE_SAFE) { 206 if ((type & CMD_WRITE_SAFE) && has_write_perm)
200 if (file->f_mode & FMODE_WRITE) 207 return 0;
201 return 0;
202 }
203 208
204 /* And root can do any command.. */ 209 /* And root can do any command.. */
205 if (capable(CAP_SYS_RAWIO)) 210 if (capable(CAP_SYS_RAWIO))
diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
index 4b65f74d66b1..ce074f6f3369 100644
--- a/drivers/acorn/block/mfmhd.c
+++ b/drivers/acorn/block/mfmhd.c
@@ -129,19 +129,6 @@ static DEFINE_SPINLOCK(mfm_lock);
129#define MAJOR_NR MFM_ACORN_MAJOR 129#define MAJOR_NR MFM_ACORN_MAJOR
130#define QUEUE (mfm_queue) 130#define QUEUE (mfm_queue)
131#define CURRENT elv_next_request(mfm_queue) 131#define CURRENT elv_next_request(mfm_queue)
132/*
133 * This sort of stuff should be in a header file shared with ide.c, hd.c, xd.c etc
134 */
135#ifndef HDIO_GETGEO
136#define HDIO_GETGEO 0x301
137struct hd_geometry {
138 unsigned char heads;
139 unsigned char sectors;
140 unsigned short cylinders;
141 unsigned long start;
142};
143#endif
144
145 132
146/* 133/*
147 * Configuration section 134 * Configuration section
@@ -1153,22 +1140,13 @@ static int mfm_initdrives(void)
1153 * The 'front' end of the mfm driver follows... 1140 * The 'front' end of the mfm driver follows...
1154 */ 1141 */
1155 1142
1156static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg) 1143static int mfm_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1157{ 1144{
1158 struct mfm_info *p = inode->i_bdev->bd_disk->private_data; 1145 struct mfm_info *p = bdev->bd_disk->private_data;
1159 struct hd_geometry *geo = (struct hd_geometry *) arg; 1146
1160 if (cmd != HDIO_GETGEO) 1147 geo->heads = p->heads;
1161 return -EINVAL; 1148 geo->sectors = p->sectors;
1162 if (!arg) 1149 geo->cylinders = p->cylinders;
1163 return -EINVAL;
1164 if (put_user (p->heads, &geo->heads))
1165 return -EFAULT;
1166 if (put_user (p->sectors, &geo->sectors))
1167 return -EFAULT;
1168 if (put_user (p->cylinders, &geo->cylinders))
1169 return -EFAULT;
1170 if (put_user (get_start_sect(inode->i_bdev), &geo->start))
1171 return -EFAULT;
1172 return 0; 1150 return 0;
1173} 1151}
1174 1152
@@ -1219,7 +1197,7 @@ void xd_set_geometry(struct block_device *bdev, unsigned char secsptrack,
1219static struct block_device_operations mfm_fops = 1197static struct block_device_operations mfm_fops =
1220{ 1198{
1221 .owner = THIS_MODULE, 1199 .owner = THIS_MODULE,
1222 .ioctl = mfm_ioctl, 1200 .getgeo = mfm_getgeo,
1223}; 1201};
1224 1202
1225/* 1203/*
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index e3cd0b16031a..20c9a37643c7 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -204,11 +204,13 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size,
204 204
205 return AE_OK; 205 return AE_OK;
206} 206}
207EXPORT_SYMBOL_GPL(acpi_os_map_memory);
207 208
208void acpi_os_unmap_memory(void __iomem * virt, acpi_size size) 209void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
209{ 210{
210 iounmap(virt); 211 iounmap(virt);
211} 212}
213EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
212 214
213#ifdef ACPI_FUTURE_USAGE 215#ifdef ACPI_FUTURE_USAGE
214acpi_status 216acpi_status
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index c57e20dcb0f8..074abc81ec3d 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -2126,8 +2126,7 @@ static void process_rsq(ns_dev *card)
2126 2126
2127 if (!ns_rsqe_valid(card->rsq.next)) 2127 if (!ns_rsqe_valid(card->rsq.next))
2128 return; 2128 return;
2129 while (ns_rsqe_valid(card->rsq.next)) 2129 do {
2130 {
2131 dequeue_rx(card, card->rsq.next); 2130 dequeue_rx(card, card->rsq.next);
2132 ns_rsqe_init(card->rsq.next); 2131 ns_rsqe_init(card->rsq.next);
2133 previous = card->rsq.next; 2132 previous = card->rsq.next;
@@ -2135,7 +2134,7 @@ static void process_rsq(ns_dev *card)
2135 card->rsq.next = card->rsq.base; 2134 card->rsq.next = card->rsq.base;
2136 else 2135 else
2137 card->rsq.next++; 2136 card->rsq.next++;
2138 } 2137 } while (ns_rsqe_valid(card->rsq.next));
2139 writel((((u32) previous) - ((u32) card->rsq.base)), 2138 writel((((u32) previous) - ((u32) card->rsq.base)),
2140 card->membase + RSQH); 2139 card->membase + RSQH);
2141} 2140}
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 21097a39a057..4a7bb7dfce85 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -92,34 +92,28 @@ static int DAC960_open(struct inode *inode, struct file *file)
92 return 0; 92 return 0;
93} 93}
94 94
95static int DAC960_ioctl(struct inode *inode, struct file *file, 95static int DAC960_getgeo(struct block_device *bdev, struct hd_geometry *geo)
96 unsigned int cmd, unsigned long arg)
97{ 96{
98 struct gendisk *disk = inode->i_bdev->bd_disk; 97 struct gendisk *disk = bdev->bd_disk;
99 DAC960_Controller_T *p = disk->queue->queuedata; 98 DAC960_Controller_T *p = disk->queue->queuedata;
100 int drive_nr = (long)disk->private_data; 99 int drive_nr = (long)disk->private_data;
101 struct hd_geometry g;
102 struct hd_geometry __user *loc = (struct hd_geometry __user *)arg;
103
104 if (cmd != HDIO_GETGEO || !loc)
105 return -EINVAL;
106 100
107 if (p->FirmwareType == DAC960_V1_Controller) { 101 if (p->FirmwareType == DAC960_V1_Controller) {
108 g.heads = p->V1.GeometryTranslationHeads; 102 geo->heads = p->V1.GeometryTranslationHeads;
109 g.sectors = p->V1.GeometryTranslationSectors; 103 geo->sectors = p->V1.GeometryTranslationSectors;
110 g.cylinders = p->V1.LogicalDriveInformation[drive_nr]. 104 geo->cylinders = p->V1.LogicalDriveInformation[drive_nr].
111 LogicalDriveSize / (g.heads * g.sectors); 105 LogicalDriveSize / (geo->heads * geo->sectors);
112 } else { 106 } else {
113 DAC960_V2_LogicalDeviceInfo_T *i = 107 DAC960_V2_LogicalDeviceInfo_T *i =
114 p->V2.LogicalDeviceInformation[drive_nr]; 108 p->V2.LogicalDeviceInformation[drive_nr];
115 switch (i->DriveGeometry) { 109 switch (i->DriveGeometry) {
116 case DAC960_V2_Geometry_128_32: 110 case DAC960_V2_Geometry_128_32:
117 g.heads = 128; 111 geo->heads = 128;
118 g.sectors = 32; 112 geo->sectors = 32;
119 break; 113 break;
120 case DAC960_V2_Geometry_255_63: 114 case DAC960_V2_Geometry_255_63:
121 g.heads = 255; 115 geo->heads = 255;
122 g.sectors = 63; 116 geo->sectors = 63;
123 break; 117 break;
124 default: 118 default:
125 DAC960_Error("Illegal Logical Device Geometry %d\n", 119 DAC960_Error("Illegal Logical Device Geometry %d\n",
@@ -127,12 +121,11 @@ static int DAC960_ioctl(struct inode *inode, struct file *file,
127 return -EINVAL; 121 return -EINVAL;
128 } 122 }
129 123
130 g.cylinders = i->ConfigurableDeviceSize / (g.heads * g.sectors); 124 geo->cylinders = i->ConfigurableDeviceSize /
125 (geo->heads * geo->sectors);
131 } 126 }
132 127
133 g.start = get_start_sect(inode->i_bdev); 128 return 0;
134
135 return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0;
136} 129}
137 130
138static int DAC960_media_changed(struct gendisk *disk) 131static int DAC960_media_changed(struct gendisk *disk)
@@ -157,7 +150,7 @@ static int DAC960_revalidate_disk(struct gendisk *disk)
157static struct block_device_operations DAC960_BlockDeviceOperations = { 150static struct block_device_operations DAC960_BlockDeviceOperations = {
158 .owner = THIS_MODULE, 151 .owner = THIS_MODULE,
159 .open = DAC960_open, 152 .open = DAC960_open,
160 .ioctl = DAC960_ioctl, 153 .getgeo = DAC960_getgeo,
161 .media_changed = DAC960_media_changed, 154 .media_changed = DAC960_media_changed,
162 .revalidate_disk = DAC960_revalidate_disk, 155 .revalidate_disk = DAC960_revalidate_disk,
163}; 156};
@@ -3767,7 +3760,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
3767 if (SenseKey == DAC960_SenseKey_VendorSpecific && 3760 if (SenseKey == DAC960_SenseKey_VendorSpecific &&
3768 AdditionalSenseCode == 0x80 && 3761 AdditionalSenseCode == 0x80 &&
3769 AdditionalSenseCodeQualifier < 3762 AdditionalSenseCodeQualifier <
3770 sizeof(DAC960_EventMessages) / sizeof(char *)) 3763 ARRAY_SIZE(DAC960_EventMessages))
3771 DAC960_Critical("Physical Device %d:%d %s\n", Controller, 3764 DAC960_Critical("Physical Device %d:%d %s\n", Controller,
3772 EventLogEntry->Channel, 3765 EventLogEntry->Channel,
3773 EventLogEntry->TargetID, 3766 EventLogEntry->TargetID,
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c
index 5d2d649f7e8d..196c0ec9cd54 100644
--- a/drivers/block/acsi.c
+++ b/drivers/block/acsi.c
@@ -1079,6 +1079,19 @@ static void redo_acsi_request( void )
1079 * 1079 *
1080 ***********************************************************************/ 1080 ***********************************************************************/
1081 1081
1082static int acsi_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1083{
1084 struct acsi_info_struct *aip = bdev->bd_disk->private_data;
1085
1086 /*
1087 * Just fake some geometry here, it's nonsense anyway
1088 * To make it easy, use Adaptec's usual 64/32 mapping
1089 */
1090 geo->heads = 64;
1091 geo->sectors = 32;
1092 geo->cylinders = aip->size >> 11;
1093 return 0;
1094}
1082 1095
1083static int acsi_ioctl( struct inode *inode, struct file *file, 1096static int acsi_ioctl( struct inode *inode, struct file *file,
1084 unsigned int cmd, unsigned long arg ) 1097 unsigned int cmd, unsigned long arg )
@@ -1086,18 +1099,6 @@ static int acsi_ioctl( struct inode *inode, struct file *file,
1086 struct gendisk *disk = inode->i_bdev->bd_disk; 1099 struct gendisk *disk = inode->i_bdev->bd_disk;
1087 struct acsi_info_struct *aip = disk->private_data; 1100 struct acsi_info_struct *aip = disk->private_data;
1088 switch (cmd) { 1101 switch (cmd) {
1089 case HDIO_GETGEO:
1090 /* HDIO_GETGEO is supported more for getting the partition's
1091 * start sector... */
1092 { struct hd_geometry *geo = (struct hd_geometry *)arg;
1093 /* just fake some geometry here, it's nonsense anyway; to make it
1094 * easy, use Adaptec's usual 64/32 mapping */
1095 put_user( 64, &geo->heads );
1096 put_user( 32, &geo->sectors );
1097 put_user( aip->size >> 11, &geo->cylinders );
1098 put_user(get_start_sect(inode->i_bdev), &geo->start);
1099 return 0;
1100 }
1101 case SCSI_IOCTL_GET_IDLUN: 1102 case SCSI_IOCTL_GET_IDLUN:
1102 /* SCSI compatible GET_IDLUN call to get target's ID and LUN number */ 1103 /* SCSI compatible GET_IDLUN call to get target's ID and LUN number */
1103 put_user( aip->target | (aip->lun << 8), 1104 put_user( aip->target | (aip->lun << 8),
@@ -1592,6 +1593,7 @@ static struct block_device_operations acsi_fops = {
1592 .open = acsi_open, 1593 .open = acsi_open,
1593 .release = acsi_release, 1594 .release = acsi_release,
1594 .ioctl = acsi_ioctl, 1595 .ioctl = acsi_ioctl,
1596 .getgeo = acsi_getgeo,
1595 .media_changed = acsi_media_change, 1597 .media_changed = acsi_media_change,
1596 .revalidate_disk= acsi_revalidate, 1598 .revalidate_disk= acsi_revalidate,
1597}; 1599};
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 0acbfff8ad28..3c679d30b698 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -131,7 +131,7 @@ static struct fd_drive_type drive_types[] = {
131{ FD_DD_5, "DD 5.25", 40, 2, 14716, 13630, 1, 40, 81, 6, 30, 2}, 131{ FD_DD_5, "DD 5.25", 40, 2, 14716, 13630, 1, 40, 81, 6, 30, 2},
132{ FD_NODRIVE, "No Drive", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 132{ FD_NODRIVE, "No Drive", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
133}; 133};
134static int num_dr_types = sizeof(drive_types) / sizeof(drive_types[0]); 134static int num_dr_types = ARRAY_SIZE(drive_types);
135 135
136static int amiga_read(int), dos_read(int); 136static int amiga_read(int), dos_read(int);
137static void amiga_write(int), dos_write(int); 137static void amiga_write(int), dos_write(int);
@@ -1424,6 +1424,16 @@ static void do_fd_request(request_queue_t * q)
1424 redo_fd_request(); 1424 redo_fd_request();
1425} 1425}
1426 1426
1427static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1428{
1429 int drive = MINOR(bdev->bd_dev) & 3;
1430
1431 geo->heads = unit[drive].type->heads;
1432 geo->sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;
1433 geo->cylinders = unit[drive].type->tracks;
1434 return 0;
1435}
1436
1427static int fd_ioctl(struct inode *inode, struct file *filp, 1437static int fd_ioctl(struct inode *inode, struct file *filp,
1428 unsigned int cmd, unsigned long param) 1438 unsigned int cmd, unsigned long param)
1429{ 1439{
@@ -1431,18 +1441,6 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
1431 static struct floppy_struct getprm; 1441 static struct floppy_struct getprm;
1432 1442
1433 switch(cmd){ 1443 switch(cmd){
1434 case HDIO_GETGEO:
1435 {
1436 struct hd_geometry loc;
1437 loc.heads = unit[drive].type->heads;
1438 loc.sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;
1439 loc.cylinders = unit[drive].type->tracks;
1440 loc.start = 0;
1441 if (copy_to_user((void *)param, (void *)&loc,
1442 sizeof(struct hd_geometry)))
1443 return -EFAULT;
1444 break;
1445 }
1446 case FDFMTBEG: 1444 case FDFMTBEG:
1447 get_fdc(drive); 1445 get_fdc(drive);
1448 if (fd_ref[drive] > 1) { 1446 if (fd_ref[drive] > 1) {
@@ -1652,6 +1650,7 @@ static struct block_device_operations floppy_fops = {
1652 .open = floppy_open, 1650 .open = floppy_open,
1653 .release = floppy_release, 1651 .release = floppy_release,
1654 .ioctl = fd_ioctl, 1652 .ioctl = fd_ioctl,
1653 .getgeo = fd_getgeo,
1655 .media_changed = amiga_floppy_change, 1654 .media_changed = amiga_floppy_change,
1656}; 1655};
1657 1656
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 0e97fcb9f3a1..c05ee8bffd97 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -169,38 +169,26 @@ aoeblk_make_request(request_queue_t *q, struct bio *bio)
169 return 0; 169 return 0;
170} 170}
171 171
172/* This ioctl implementation expects userland to have the device node
173 * permissions set so that only priviledged users can open an aoe
174 * block device directly.
175 */
176static int 172static int
177aoeblk_ioctl(struct inode *inode, struct file *filp, uint cmd, ulong arg) 173aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
178{ 174{
179 struct aoedev *d; 175 struct aoedev *d = bdev->bd_disk->private_data;
180
181 if (!arg)
182 return -EINVAL;
183 176
184 d = inode->i_bdev->bd_disk->private_data;
185 if ((d->flags & DEVFL_UP) == 0) { 177 if ((d->flags & DEVFL_UP) == 0) {
186 printk(KERN_ERR "aoe: aoeblk_ioctl: disk not up\n"); 178 printk(KERN_ERR "aoe: aoeblk_ioctl: disk not up\n");
187 return -ENODEV; 179 return -ENODEV;
188 } 180 }
189 181
190 if (cmd == HDIO_GETGEO) { 182 geo->cylinders = d->geo.cylinders;
191 d->geo.start = get_start_sect(inode->i_bdev); 183 geo->heads = d->geo.heads;
192 if (!copy_to_user((void __user *) arg, &d->geo, sizeof d->geo)) 184 geo->sectors = d->geo.sectors;
193 return 0; 185 return 0;
194 return -EFAULT;
195 }
196 printk(KERN_INFO "aoe: aoeblk_ioctl: unknown ioctl %d\n", cmd);
197 return -EINVAL;
198} 186}
199 187
200static struct block_device_operations aoe_bdops = { 188static struct block_device_operations aoe_bdops = {
201 .open = aoeblk_open, 189 .open = aoeblk_open,
202 .release = aoeblk_release, 190 .release = aoeblk_release,
203 .ioctl = aoeblk_ioctl, 191 .getgeo = aoeblk_getgeo,
204 .owner = THIS_MODULE, 192 .owner = THIS_MODULE,
205}; 193};
206 194
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 22bda05fc693..3aa68a5447d6 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -181,7 +181,7 @@ static struct {
181 { 6, TYPE_HD }, /* 31: H1640 <- was H1600 == h1600 for PC */ 181 { 6, TYPE_HD }, /* 31: H1640 <- was H1600 == h1600 for PC */
182}; 182};
183 183
184#define NUM_DISK_MINORS (sizeof(minor2disktype)/sizeof(*minor2disktype)) 184#define NUM_DISK_MINORS ARRAY_SIZE(minor2disktype)
185 185
186/* 186/*
187 * Maximum disk size (in kilobytes). This default is used whenever the 187 * Maximum disk size (in kilobytes). This default is used whenever the
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index d2815b7a9150..e4e9f255bd1f 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Disk Array driver for HP SA 5xxx and 6xxx Controllers 2 * Disk Array driver for HP SA 5xxx and 6xxx Controllers
3 * Copyright 2000, 2005 Hewlett-Packard Development Company, L.P. 3 * Copyright 2000, 2006 Hewlett-Packard Development Company, L.P.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -47,12 +47,12 @@
47#include <linux/completion.h> 47#include <linux/completion.h>
48 48
49#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) 49#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
50#define DRIVER_NAME "HP CISS Driver (v 2.6.8)" 50#define DRIVER_NAME "HP CISS Driver (v 2.6.10)"
51#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,8) 51#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,10)
52 52
53/* Embedded module documentation macros - see modules.h */ 53/* Embedded module documentation macros - see modules.h */
54MODULE_AUTHOR("Hewlett-Packard Company"); 54MODULE_AUTHOR("Hewlett-Packard Company");
55MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.8"); 55MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.10");
56MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" 56MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
57 " SA6i P600 P800 P400 P400i E200 E200i"); 57 " SA6i P600 P800 P400 P400i E200 E200i");
58MODULE_LICENSE("GPL"); 58MODULE_LICENSE("GPL");
@@ -103,7 +103,7 @@ static const struct pci_device_id cciss_pci_device_id[] = {
103}; 103};
104MODULE_DEVICE_TABLE(pci, cciss_pci_device_id); 104MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
105 105
106#define NR_PRODUCTS (sizeof(products)/sizeof(struct board_type)) 106#define NR_PRODUCTS ARRAY_SIZE(products)
107 107
108/* board_id = Subsystem Device ID & Vendor ID 108/* board_id = Subsystem Device ID & Vendor ID
109 * product = Marketing Name for the board 109 * product = Marketing Name for the board
@@ -153,6 +153,7 @@ static int cciss_open(struct inode *inode, struct file *filep);
153static int cciss_release(struct inode *inode, struct file *filep); 153static int cciss_release(struct inode *inode, struct file *filep);
154static int cciss_ioctl(struct inode *inode, struct file *filep, 154static int cciss_ioctl(struct inode *inode, struct file *filep,
155 unsigned int cmd, unsigned long arg); 155 unsigned int cmd, unsigned long arg);
156static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
156 157
157static int revalidate_allvol(ctlr_info_t *host); 158static int revalidate_allvol(ctlr_info_t *host);
158static int cciss_revalidate(struct gendisk *disk); 159static int cciss_revalidate(struct gendisk *disk);
@@ -166,7 +167,7 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
166 unsigned int block_size, InquiryData_struct *inq_buff, 167 unsigned int block_size, InquiryData_struct *inq_buff,
167 drive_info_struct *drv); 168 drive_info_struct *drv);
168static void cciss_getgeometry(int cntl_num); 169static void cciss_getgeometry(int cntl_num);
169 170static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, __u32);
170static void start_io( ctlr_info_t *h); 171static void start_io( ctlr_info_t *h);
171static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size, 172static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size,
172 unsigned int use_unit_num, unsigned int log_unit, __u8 page_code, 173 unsigned int use_unit_num, unsigned int log_unit, __u8 page_code,
@@ -194,6 +195,7 @@ static struct block_device_operations cciss_fops = {
194 .open = cciss_open, 195 .open = cciss_open,
195 .release = cciss_release, 196 .release = cciss_release,
196 .ioctl = cciss_ioctl, 197 .ioctl = cciss_ioctl,
198 .getgeo = cciss_getgeo,
197#ifdef CONFIG_COMPAT 199#ifdef CONFIG_COMPAT
198 .compat_ioctl = cciss_compat_ioctl, 200 .compat_ioctl = cciss_compat_ioctl,
199#endif 201#endif
@@ -282,7 +284,7 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
282 h->product_name, 284 h->product_name,
283 (unsigned long)h->board_id, 285 (unsigned long)h->board_id,
284 h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], h->firm_ver[3], 286 h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], h->firm_ver[3],
285 (unsigned int)h->intr, 287 (unsigned int)h->intr[SIMPLE_MODE_INT],
286 h->num_luns, 288 h->num_luns,
287 h->Qdepth, h->commands_outstanding, 289 h->Qdepth, h->commands_outstanding,
288 h->maxQsinceinit, h->max_outstanding, h->maxSG); 290 h->maxQsinceinit, h->max_outstanding, h->maxSG);
@@ -633,6 +635,20 @@ static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd, unsigned
633 return err; 635 return err;
634} 636}
635#endif 637#endif
638
639static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo)
640{
641 drive_info_struct *drv = get_drv(bdev->bd_disk);
642
643 if (!drv->cylinders)
644 return -ENXIO;
645
646 geo->heads = drv->heads;
647 geo->sectors = drv->sectors;
648 geo->cylinders = drv->cylinders;
649 return 0;
650}
651
636/* 652/*
637 * ioctl 653 * ioctl
638 */ 654 */
@@ -651,21 +667,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
651#endif /* CCISS_DEBUG */ 667#endif /* CCISS_DEBUG */
652 668
653 switch(cmd) { 669 switch(cmd) {
654 case HDIO_GETGEO:
655 {
656 struct hd_geometry driver_geo;
657 if (drv->cylinders) {
658 driver_geo.heads = drv->heads;
659 driver_geo.sectors = drv->sectors;
660 driver_geo.cylinders = drv->cylinders;
661 } else
662 return -ENXIO;
663 driver_geo.start= get_start_sect(inode->i_bdev);
664 if (copy_to_user(argp, &driver_geo, sizeof(struct hd_geometry)))
665 return -EFAULT;
666 return(0);
667 }
668
669 case CCISS_GETPCIINFO: 670 case CCISS_GETPCIINFO:
670 { 671 {
671 cciss_pci_info_struct pciinfo; 672 cciss_pci_info_struct pciinfo;
@@ -2177,16 +2178,48 @@ static inline void resend_cciss_cmd( ctlr_info_t *h, CommandList_struct *c)
2177 2178
2178 start_io(h); 2179 start_io(h);
2179} 2180}
2181
2182static void cciss_softirq_done(struct request *rq)
2183{
2184 CommandList_struct *cmd = rq->completion_data;
2185 ctlr_info_t *h = hba[cmd->ctlr];
2186 u64bit temp64;
2187 int i, ddir;
2188
2189 if (cmd->Request.Type.Direction == XFER_READ)
2190 ddir = PCI_DMA_FROMDEVICE;
2191 else
2192 ddir = PCI_DMA_TODEVICE;
2193
2194 /* command did not need to be retried */
2195 /* unmap the DMA mapping for all the scatter gather elements */
2196 for(i=0; i<cmd->Header.SGList; i++) {
2197 temp64.val32.lower = cmd->SG[i].Addr.lower;
2198 temp64.val32.upper = cmd->SG[i].Addr.upper;
2199 pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir);
2200 }
2201
2202 complete_buffers(rq->bio, rq->errors);
2203
2204#ifdef CCISS_DEBUG
2205 printk("Done with %p\n", rq);
2206#endif /* CCISS_DEBUG */
2207
2208 spin_lock_irq(&h->lock);
2209 end_that_request_last(rq, rq->errors);
2210 cmd_free(h, cmd,1);
2211 spin_unlock_irq(&h->lock);
2212}
2213
2180/* checks the status of the job and calls complete buffers to mark all 2214/* checks the status of the job and calls complete buffers to mark all
2181 * buffers for the completed job. 2215 * buffers for the completed job. Note that this function does not need
2216 * to hold the hba/queue lock.
2182 */ 2217 */
2183static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd, 2218static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd,
2184 int timeout) 2219 int timeout)
2185{ 2220{
2186 int status = 1; 2221 int status = 1;
2187 int i;
2188 int retry_cmd = 0; 2222 int retry_cmd = 0;
2189 u64bit temp64;
2190 2223
2191 if (timeout) 2224 if (timeout)
2192 status = 0; 2225 status = 0;
@@ -2294,24 +2327,10 @@ static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd,
2294 resend_cciss_cmd(h,cmd); 2327 resend_cciss_cmd(h,cmd);
2295 return; 2328 return;
2296 } 2329 }
2297 /* command did not need to be retried */
2298 /* unmap the DMA mapping for all the scatter gather elements */
2299 for(i=0; i<cmd->Header.SGList; i++) {
2300 temp64.val32.lower = cmd->SG[i].Addr.lower;
2301 temp64.val32.upper = cmd->SG[i].Addr.upper;
2302 pci_unmap_page(hba[cmd->ctlr]->pdev,
2303 temp64.val, cmd->SG[i].Len,
2304 (cmd->Request.Type.Direction == XFER_READ) ?
2305 PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
2306 }
2307 complete_buffers(cmd->rq->bio, status);
2308 2330
2309#ifdef CCISS_DEBUG 2331 cmd->rq->completion_data = cmd;
2310 printk("Done with %p\n", cmd->rq); 2332 cmd->rq->errors = status;
2311#endif /* CCISS_DEBUG */ 2333 blk_complete_request(cmd->rq);
2312
2313 end_that_request_last(cmd->rq, status ? 1 : -EIO);
2314 cmd_free(h,cmd,1);
2315} 2334}
2316 2335
2317/* 2336/*
@@ -2661,6 +2680,60 @@ static int find_PCI_BAR_index(struct pci_dev *pdev,
2661 return -1; 2680 return -1;
2662} 2681}
2663 2682
2683/* If MSI/MSI-X is supported by the kernel we will try to enable it on
2684 * controllers that are capable. If not, we use IO-APIC mode.
2685 */
2686
2687static void __devinit cciss_interrupt_mode(ctlr_info_t *c, struct pci_dev *pdev, __u32 board_id)
2688{
2689#ifdef CONFIG_PCI_MSI
2690 int err;
2691 struct msix_entry cciss_msix_entries[4] = {{0,0}, {0,1},
2692 {0,2}, {0,3}};
2693
2694 /* Some boards advertise MSI but don't really support it */
2695 if ((board_id == 0x40700E11) ||
2696 (board_id == 0x40800E11) ||
2697 (board_id == 0x40820E11) ||
2698 (board_id == 0x40830E11))
2699 goto default_int_mode;
2700
2701 if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) {
2702 err = pci_enable_msix(pdev, cciss_msix_entries, 4);
2703 if (!err) {
2704 c->intr[0] = cciss_msix_entries[0].vector;
2705 c->intr[1] = cciss_msix_entries[1].vector;
2706 c->intr[2] = cciss_msix_entries[2].vector;
2707 c->intr[3] = cciss_msix_entries[3].vector;
2708 c->msix_vector = 1;
2709 return;
2710 }
2711 if (err > 0) {
2712 printk(KERN_WARNING "cciss: only %d MSI-X vectors "
2713 "available\n", err);
2714 } else {
2715 printk(KERN_WARNING "cciss: MSI-X init failed %d\n",
2716 err);
2717 }
2718 }
2719 if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) {
2720 if (!pci_enable_msi(pdev)) {
2721 c->intr[SIMPLE_MODE_INT] = pdev->irq;
2722 c->msi_vector = 1;
2723 return;
2724 } else {
2725 printk(KERN_WARNING "cciss: MSI init failed\n");
2726 c->intr[SIMPLE_MODE_INT] = pdev->irq;
2727 return;
2728 }
2729 }
2730#endif /* CONFIG_PCI_MSI */
2731 /* if we get here we're going to use the default interrupt mode */
2732default_int_mode:
2733 c->intr[SIMPLE_MODE_INT] = pdev->irq;
2734 return;
2735}
2736
2664static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) 2737static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
2665{ 2738{
2666 ushort subsystem_vendor_id, subsystem_device_id, command; 2739 ushort subsystem_vendor_id, subsystem_device_id, command;
@@ -2721,7 +2794,10 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
2721 printk("board_id = %x\n", board_id); 2794 printk("board_id = %x\n", board_id);
2722#endif /* CCISS_DEBUG */ 2795#endif /* CCISS_DEBUG */
2723 2796
2724 c->intr = pdev->irq; 2797/* If the kernel supports MSI/MSI-X we will try to enable that functionality,
2798 * else we use the IO-APIC interrupt assigned to us by system ROM.
2799 */
2800 cciss_interrupt_mode(c, pdev, board_id);
2725 2801
2726 /* 2802 /*
2727 * Memory base addr is first addr , the second points to the config 2803 * Memory base addr is first addr , the second points to the config
@@ -2775,7 +2851,7 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
2775 c->board_id = board_id; 2851 c->board_id = board_id;
2776 2852
2777#ifdef CCISS_DEBUG 2853#ifdef CCISS_DEBUG
2778 print_cfg_table(c->cfgtable); 2854 print_cfg_table(c->cfgtable);
2779#endif /* CCISS_DEBUG */ 2855#endif /* CCISS_DEBUG */
2780 2856
2781 for(i=0; i<NR_PRODUCTS; i++) { 2857 for(i=0; i<NR_PRODUCTS; i++) {
@@ -3060,7 +3136,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
3060 * 8 controller support. 3136 * 8 controller support.
3061 */ 3137 */
3062 if (i < MAX_CTLR_ORIG) 3138 if (i < MAX_CTLR_ORIG)
3063 hba[i]->major = MAJOR_NR + i; 3139 hba[i]->major = COMPAQ_CISS_MAJOR + i;
3064 rc = register_blkdev(hba[i]->major, hba[i]->devname); 3140 rc = register_blkdev(hba[i]->major, hba[i]->devname);
3065 if(rc == -EBUSY || rc == -EINVAL) { 3141 if(rc == -EBUSY || rc == -EINVAL) {
3066 printk(KERN_ERR 3142 printk(KERN_ERR
@@ -3075,11 +3151,11 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
3075 3151
3076 /* make sure the board interrupts are off */ 3152 /* make sure the board interrupts are off */
3077 hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF); 3153 hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
3078 if( request_irq(hba[i]->intr, do_cciss_intr, 3154 if( request_irq(hba[i]->intr[SIMPLE_MODE_INT], do_cciss_intr,
3079 SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 3155 SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
3080 hba[i]->devname, hba[i])) { 3156 hba[i]->devname, hba[i])) {
3081 printk(KERN_ERR "cciss: Unable to get irq %d for %s\n", 3157 printk(KERN_ERR "cciss: Unable to get irq %d for %s\n",
3082 hba[i]->intr, hba[i]->devname); 3158 hba[i]->intr[SIMPLE_MODE_INT], hba[i]->devname);
3083 goto clean2; 3159 goto clean2;
3084 } 3160 }
3085 hba[i]->cmd_pool_bits = kmalloc(((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), GFP_KERNEL); 3161 hba[i]->cmd_pool_bits = kmalloc(((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), GFP_KERNEL);
@@ -3141,15 +3217,17 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
3141 drv->queue = q; 3217 drv->queue = q;
3142 3218
3143 q->backing_dev_info.ra_pages = READ_AHEAD; 3219 q->backing_dev_info.ra_pages = READ_AHEAD;
3144 blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); 3220 blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask);
3145 3221
3146 /* This is a hardware imposed limit. */ 3222 /* This is a hardware imposed limit. */
3147 blk_queue_max_hw_segments(q, MAXSGENTRIES); 3223 blk_queue_max_hw_segments(q, MAXSGENTRIES);
3148 3224
3149 /* This is a limit in the driver and could be eliminated. */ 3225 /* This is a limit in the driver and could be eliminated. */
3150 blk_queue_max_phys_segments(q, MAXSGENTRIES); 3226 blk_queue_max_phys_segments(q, MAXSGENTRIES);
3151 3227
3152 blk_queue_max_sectors(q, 512); 3228 blk_queue_max_sectors(q, 512);
3229
3230 blk_queue_softirq_done(q, cciss_softirq_done);
3153 3231
3154 q->queuedata = hba[i]; 3232 q->queuedata = hba[i];
3155 sprintf(disk->disk_name, "cciss/c%dd%d", i, j); 3233 sprintf(disk->disk_name, "cciss/c%dd%d", i, j);
@@ -3185,7 +3263,7 @@ clean4:
3185 NR_CMDS * sizeof( ErrorInfo_struct), 3263 NR_CMDS * sizeof( ErrorInfo_struct),
3186 hba[i]->errinfo_pool, 3264 hba[i]->errinfo_pool,
3187 hba[i]->errinfo_pool_dhandle); 3265 hba[i]->errinfo_pool_dhandle);
3188 free_irq(hba[i]->intr, hba[i]); 3266 free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]);
3189clean2: 3267clean2:
3190 unregister_blkdev(hba[i]->major, hba[i]->devname); 3268 unregister_blkdev(hba[i]->major, hba[i]->devname);
3191clean1: 3269clean1:
@@ -3226,7 +3304,15 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
3226 printk(KERN_WARNING "Error Flushing cache on controller %d\n", 3304 printk(KERN_WARNING "Error Flushing cache on controller %d\n",
3227 i); 3305 i);
3228 } 3306 }
3229 free_irq(hba[i]->intr, hba[i]); 3307 free_irq(hba[i]->intr[2], hba[i]);
3308
3309#ifdef CONFIG_PCI_MSI
3310 if (hba[i]->msix_vector)
3311 pci_disable_msix(hba[i]->pdev);
3312 else if (hba[i]->msi_vector)
3313 pci_disable_msi(hba[i]->pdev);
3314#endif /* CONFIG_PCI_MSI */
3315
3230 pci_set_drvdata(pdev, NULL); 3316 pci_set_drvdata(pdev, NULL);
3231 iounmap(hba[i]->vaddr); 3317 iounmap(hba[i]->vaddr);
3232 cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ 3318 cciss_unregister_scsi(i); /* unhook from SCSI subsystem */
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index 3b0858c83897..b24fc0553ccf 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -13,8 +13,6 @@
13#define IO_OK 0 13#define IO_OK 0
14#define IO_ERROR 1 14#define IO_ERROR 1
15 15
16#define MAJOR_NR COMPAQ_CISS_MAJOR
17
18struct ctlr_info; 16struct ctlr_info;
19typedef struct ctlr_info ctlr_info_t; 17typedef struct ctlr_info ctlr_info_t;
20 18
@@ -65,7 +63,6 @@ struct ctlr_info
65 unsigned long io_mem_addr; 63 unsigned long io_mem_addr;
66 unsigned long io_mem_length; 64 unsigned long io_mem_length;
67 CfgTable_struct __iomem *cfgtable; 65 CfgTable_struct __iomem *cfgtable;
68 unsigned int intr;
69 int interrupts_enabled; 66 int interrupts_enabled;
70 int major; 67 int major;
71 int max_commands; 68 int max_commands;
@@ -74,6 +71,13 @@ struct ctlr_info
74 int num_luns; 71 int num_luns;
75 int highest_lun; 72 int highest_lun;
76 int usage_count; /* number of opens all all minor devices */ 73 int usage_count; /* number of opens all all minor devices */
74# define DOORBELL_INT 0
75# define PERF_MODE_INT 1
76# define SIMPLE_MODE_INT 2
77# define MEMQ_MODE_INT 3
78 unsigned int intr[4];
79 unsigned int msix_vector;
80 unsigned int msi_vector;
77 81
78 // information about each logical volume 82 // information about each logical volume
79 drive_info_struct drv[CISS_MAX_LUN]; 83 drive_info_struct drv[CISS_MAX_LUN];
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index 2942d32280a5..9e35de05d5c5 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -714,7 +714,7 @@ cciss_scsi_detect(int ctlr)
714 ((struct cciss_scsi_adapter_data_t *) 714 ((struct cciss_scsi_adapter_data_t *)
715 hba[ctlr]->scsi_ctlr)->scsi_host = (void *) sh; 715 hba[ctlr]->scsi_ctlr)->scsi_host = (void *) sh;
716 sh->hostdata[0] = (unsigned long) hba[ctlr]; 716 sh->hostdata[0] = (unsigned long) hba[ctlr];
717 sh->irq = hba[ctlr]->intr; 717 sh->irq = hba[ctlr]->intr[SIMPLE_MODE_INT];
718 sh->unique_id = sh->irq; 718 sh->unique_id = sh->irq;
719 error = scsi_add_host(sh, &hba[ctlr]->pdev->dev); 719 error = scsi_add_host(sh, &hba[ctlr]->pdev->dev);
720 if (error) 720 if (error)
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 9bddb6874873..862b9abac0ae 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -72,11 +72,11 @@ static ctlr_info_t *hba[MAX_CTLR];
72 72
73static int eisa[8]; 73static int eisa[8];
74 74
75#define NR_PRODUCTS (sizeof(products)/sizeof(struct board_type)) 75#define NR_PRODUCTS ARRAY_SIZE(products)
76 76
77/* board_id = Subsystem Device ID & Vendor ID 77/* board_id = Subsystem Device ID & Vendor ID
78 * product = Marketing Name for the board 78 * product = Marketing Name for the board
79 * access = Address of the struct of function pointers 79 * access = Address of the struct of function pointers
80 */ 80 */
81static struct board_type products[] = { 81static struct board_type products[] = {
82 { 0x0040110E, "IDA", &smart1_access }, 82 { 0x0040110E, "IDA", &smart1_access },
@@ -160,6 +160,7 @@ static int sendcmd(
160static int ida_open(struct inode *inode, struct file *filep); 160static int ida_open(struct inode *inode, struct file *filep);
161static int ida_release(struct inode *inode, struct file *filep); 161static int ida_release(struct inode *inode, struct file *filep);
162static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg); 162static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
163static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo);
163static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io); 164static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io);
164 165
165static void do_ida_request(request_queue_t *q); 166static void do_ida_request(request_queue_t *q);
@@ -199,6 +200,7 @@ static struct block_device_operations ida_fops = {
199 .open = ida_open, 200 .open = ida_open,
200 .release = ida_release, 201 .release = ida_release,
201 .ioctl = ida_ioctl, 202 .ioctl = ida_ioctl,
203 .getgeo = ida_getgeo,
202 .revalidate_disk= ida_revalidate, 204 .revalidate_disk= ida_revalidate,
203}; 205};
204 206
@@ -1124,6 +1126,23 @@ static void ida_timer(unsigned long tdata)
1124 h->misc_tflags = 0; 1126 h->misc_tflags = 0;
1125} 1127}
1126 1128
1129static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1130{
1131 drv_info_t *drv = get_drv(bdev->bd_disk);
1132
1133 if (drv->cylinders) {
1134 geo->heads = drv->heads;
1135 geo->sectors = drv->sectors;
1136 geo->cylinders = drv->cylinders;
1137 } else {
1138 geo->heads = 0xff;
1139 geo->sectors = 0x3f;
1140 geo->cylinders = drv->nr_blks / (0xff*0x3f);
1141 }
1142
1143 return 0;
1144}
1145
1127/* 1146/*
1128 * ida_ioctl does some miscellaneous stuff like reporting drive geometry, 1147 * ida_ioctl does some miscellaneous stuff like reporting drive geometry,
1129 * setting readahead and submitting commands from userspace to the controller. 1148 * setting readahead and submitting commands from userspace to the controller.
@@ -1133,27 +1152,10 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
1133 drv_info_t *drv = get_drv(inode->i_bdev->bd_disk); 1152 drv_info_t *drv = get_drv(inode->i_bdev->bd_disk);
1134 ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); 1153 ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
1135 int error; 1154 int error;
1136 int diskinfo[4];
1137 struct hd_geometry __user *geo = (struct hd_geometry __user *)arg;
1138 ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg; 1155 ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg;
1139 ida_ioctl_t *my_io; 1156 ida_ioctl_t *my_io;
1140 1157
1141 switch(cmd) { 1158 switch(cmd) {
1142 case HDIO_GETGEO:
1143 if (drv->cylinders) {
1144 diskinfo[0] = drv->heads;
1145 diskinfo[1] = drv->sectors;
1146 diskinfo[2] = drv->cylinders;
1147 } else {
1148 diskinfo[0] = 0xff;
1149 diskinfo[1] = 0x3f;
1150 diskinfo[2] = drv->nr_blks / (0xff*0x3f);
1151 }
1152 put_user(diskinfo[0], &geo->heads);
1153 put_user(diskinfo[1], &geo->sectors);
1154 put_user(diskinfo[2], &geo->cylinders);
1155 put_user(get_start_sect(inode->i_bdev), &geo->start);
1156 return 0;
1157 case IDAGETDRVINFO: 1159 case IDAGETDRVINFO:
1158 if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t))) 1160 if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t)))
1159 return -EFAULT; 1161 return -EFAULT;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index a5b857c5c4b8..374621a512e0 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -479,7 +479,6 @@ static struct floppy_struct floppy_type[32] = {
479 { 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5" */ 479 { 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5" */
480}; 480};
481 481
482#define NUMBER(x) (sizeof(x) / sizeof(*(x)))
483#define SECTSIZE (_FD_SECTSIZE(*floppy)) 482#define SECTSIZE (_FD_SECTSIZE(*floppy))
484 483
485/* Auto-detection: Disk type used until the next media change occurs. */ 484/* Auto-detection: Disk type used until the next media change occurs. */
@@ -3445,6 +3444,23 @@ static int get_floppy_geometry(int drive, int type, struct floppy_struct **g)
3445 return 0; 3444 return 0;
3446} 3445}
3447 3446
3447static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
3448{
3449 int drive = (long)bdev->bd_disk->private_data;
3450 int type = ITYPE(drive_state[drive].fd_device);
3451 struct floppy_struct *g;
3452 int ret;
3453
3454 ret = get_floppy_geometry(drive, type, &g);
3455 if (ret)
3456 return ret;
3457
3458 geo->heads = g->head;
3459 geo->sectors = g->sect;
3460 geo->cylinders = g->track;
3461 return 0;
3462}
3463
3448static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 3464static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
3449 unsigned long param) 3465 unsigned long param)
3450{ 3466{
@@ -3474,23 +3490,6 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
3474 cmd = FDEJECT; 3490 cmd = FDEJECT;
3475 } 3491 }
3476 3492
3477 /* generic block device ioctls */
3478 switch (cmd) {
3479 /* the following have been inspired by the corresponding
3480 * code for other block devices. */
3481 struct floppy_struct *g;
3482 case HDIO_GETGEO:
3483 {
3484 struct hd_geometry loc;
3485 ECALL(get_floppy_geometry(drive, type, &g));
3486 loc.heads = g->head;
3487 loc.sectors = g->sect;
3488 loc.cylinders = g->track;
3489 loc.start = 0;
3490 return _COPYOUT(loc);
3491 }
3492 }
3493
3494 /* convert the old style command into a new style command */ 3493 /* convert the old style command into a new style command */
3495 if ((cmd & 0xff00) == 0x0200) { 3494 if ((cmd & 0xff00) == 0x0200) {
3496 ECALL(normalize_ioctl(&cmd, &size)); 3495 ECALL(normalize_ioctl(&cmd, &size));
@@ -3645,7 +3644,7 @@ static void __init config_types(void)
3645 const char *name = NULL; 3644 const char *name = NULL;
3646 static char temparea[32]; 3645 static char temparea[32];
3647 3646
3648 if (type < NUMBER(default_drive_params)) { 3647 if (type < ARRAY_SIZE(default_drive_params)) {
3649 params = &default_drive_params[type].params; 3648 params = &default_drive_params[type].params;
3650 if (type) { 3649 if (type) {
3651 name = default_drive_params[type].name; 3650 name = default_drive_params[type].name;
@@ -3938,6 +3937,7 @@ static struct block_device_operations floppy_fops = {
3938 .open = floppy_open, 3937 .open = floppy_open,
3939 .release = floppy_release, 3938 .release = floppy_release,
3940 .ioctl = fd_ioctl, 3939 .ioctl = fd_ioctl,
3940 .getgeo = fd_getgeo,
3941 .media_changed = check_floppy_change, 3941 .media_changed = check_floppy_change,
3942 .revalidate_disk = floppy_revalidate, 3942 .revalidate_disk = floppy_revalidate,
3943}; 3943};
@@ -3960,7 +3960,7 @@ static void __init register_devfs_entries(int drive)
3960{ 3960{
3961 int base_minor = (drive < 4) ? drive : (124 + drive); 3961 int base_minor = (drive < 4) ? drive : (124 + drive);
3962 3962
3963 if (UDP->cmos < NUMBER(default_drive_params)) { 3963 if (UDP->cmos < ARRAY_SIZE(default_drive_params)) {
3964 int i = 0; 3964 int i = 0;
3965 do { 3965 do {
3966 int minor = base_minor + (table_sup[UDP->cmos][i] << 2); 3966 int minor = base_minor + (table_sup[UDP->cmos][i] << 2);
@@ -4218,7 +4218,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
4218 !(allowed_drive_mask & (1 << drive)) || 4218 !(allowed_drive_mask & (1 << drive)) ||
4219 fdc_state[FDC(drive)].version == FDC_NONE) 4219 fdc_state[FDC(drive)].version == FDC_NONE)
4220 return NULL; 4220 return NULL;
4221 if (((*part >> 2) & 0x1f) >= NUMBER(floppy_type)) 4221 if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type))
4222 return NULL; 4222 return NULL;
4223 *part = 0; 4223 *part = 0;
4224 return get_disk(disks[drive]); 4224 return get_disk(disks[drive]);
@@ -4570,7 +4570,7 @@ static void unregister_devfs_entries(int drive)
4570{ 4570{
4571 int i; 4571 int i;
4572 4572
4573 if (UDP->cmos < NUMBER(default_drive_params)) { 4573 if (UDP->cmos < ARRAY_SIZE(default_drive_params)) {
4574 i = 0; 4574 i = 0;
4575 do { 4575 do {
4576 devfs_remove("floppy/%d%s", drive, 4576 devfs_remove("floppy/%d%s", drive,
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 33d6f237b2ed..6997d8e6bfb5 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -174,7 +174,6 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size,
174 msg.msg_namelen = 0; 174 msg.msg_namelen = 0;
175 msg.msg_control = NULL; 175 msg.msg_control = NULL;
176 msg.msg_controllen = 0; 176 msg.msg_controllen = 0;
177 msg.msg_namelen = 0;
178 msg.msg_flags = msg_flags | MSG_NOSIGNAL; 177 msg.msg_flags = msg_flags | MSG_NOSIGNAL;
179 178
180 if (send) 179 if (send)
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index fa49d62626ba..62d2464c12f2 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -747,32 +747,33 @@ static int pd_open(struct inode *inode, struct file *file)
747 return 0; 747 return 0;
748} 748}
749 749
750static int pd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
751{
752 struct pd_unit *disk = bdev->bd_disk->private_data;
753
754 if (disk->alt_geom) {
755 geo->heads = PD_LOG_HEADS;
756 geo->sectors = PD_LOG_SECTS;
757 geo->cylinders = disk->capacity / (geo->heads * geo->sectors);
758 } else {
759 geo->heads = disk->heads;
760 geo->sectors = disk->sectors;
761 geo->cylinders = disk->cylinders;
762 }
763
764 return 0;
765}
766
750static int pd_ioctl(struct inode *inode, struct file *file, 767static int pd_ioctl(struct inode *inode, struct file *file,
751 unsigned int cmd, unsigned long arg) 768 unsigned int cmd, unsigned long arg)
752{ 769{
753 struct pd_unit *disk = inode->i_bdev->bd_disk->private_data; 770 struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
754 struct hd_geometry __user *geo = (struct hd_geometry __user *) arg;
755 struct hd_geometry g;
756 771
757 switch (cmd) { 772 switch (cmd) {
758 case CDROMEJECT: 773 case CDROMEJECT:
759 if (disk->access == 1) 774 if (disk->access == 1)
760 pd_special_command(disk, pd_eject); 775 pd_special_command(disk, pd_eject);
761 return 0; 776 return 0;
762 case HDIO_GETGEO:
763 if (disk->alt_geom) {
764 g.heads = PD_LOG_HEADS;
765 g.sectors = PD_LOG_SECTS;
766 g.cylinders = disk->capacity / (g.heads * g.sectors);
767 } else {
768 g.heads = disk->heads;
769 g.sectors = disk->sectors;
770 g.cylinders = disk->cylinders;
771 }
772 g.start = get_start_sect(inode->i_bdev);
773 if (copy_to_user(geo, &g, sizeof(struct hd_geometry)))
774 return -EFAULT;
775 return 0;
776 default: 777 default:
777 return -EINVAL; 778 return -EINVAL;
778 } 779 }
@@ -815,6 +816,7 @@ static struct block_device_operations pd_fops = {
815 .open = pd_open, 816 .open = pd_open,
816 .release = pd_release, 817 .release = pd_release,
817 .ioctl = pd_ioctl, 818 .ioctl = pd_ioctl,
819 .getgeo = pd_getgeo,
818 .media_changed = pd_check_media, 820 .media_changed = pd_check_media,
819 .revalidate_disk= pd_revalidate 821 .revalidate_disk= pd_revalidate
820}; 822};
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index e9746af29b9f..852b564e903a 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -205,6 +205,7 @@ static int pf_open(struct inode *inode, struct file *file);
205static void do_pf_request(request_queue_t * q); 205static void do_pf_request(request_queue_t * q);
206static int pf_ioctl(struct inode *inode, struct file *file, 206static int pf_ioctl(struct inode *inode, struct file *file,
207 unsigned int cmd, unsigned long arg); 207 unsigned int cmd, unsigned long arg);
208static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo);
208 209
209static int pf_release(struct inode *inode, struct file *file); 210static int pf_release(struct inode *inode, struct file *file);
210 211
@@ -266,6 +267,7 @@ static struct block_device_operations pf_fops = {
266 .open = pf_open, 267 .open = pf_open,
267 .release = pf_release, 268 .release = pf_release,
268 .ioctl = pf_ioctl, 269 .ioctl = pf_ioctl,
270 .getgeo = pf_getgeo,
269 .media_changed = pf_check_media, 271 .media_changed = pf_check_media,
270}; 272};
271 273
@@ -313,34 +315,34 @@ static int pf_open(struct inode *inode, struct file *file)
313 return 0; 315 return 0;
314} 316}
315 317
316static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 318static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo)
317{ 319{
318 struct pf_unit *pf = inode->i_bdev->bd_disk->private_data; 320 struct pf_unit *pf = bdev->bd_disk->private_data;
319 struct hd_geometry __user *geo = (struct hd_geometry __user *) arg; 321 sector_t capacity = get_capacity(pf->disk);
320 struct hd_geometry g; 322
321 sector_t capacity;
322
323 if (cmd == CDROMEJECT) {
324 if (pf->access == 1) {
325 pf_eject(pf);
326 return 0;
327 }
328 return -EBUSY;
329 }
330 if (cmd != HDIO_GETGEO)
331 return -EINVAL;
332 capacity = get_capacity(pf->disk);
333 if (capacity < PF_FD_MAX) { 323 if (capacity < PF_FD_MAX) {
334 g.cylinders = sector_div(capacity, PF_FD_HDS * PF_FD_SPT); 324 geo->cylinders = sector_div(capacity, PF_FD_HDS * PF_FD_SPT);
335 g.heads = PF_FD_HDS; 325 geo->heads = PF_FD_HDS;
336 g.sectors = PF_FD_SPT; 326 geo->sectors = PF_FD_SPT;
337 } else { 327 } else {
338 g.cylinders = sector_div(capacity, PF_HD_HDS * PF_HD_SPT); 328 geo->cylinders = sector_div(capacity, PF_HD_HDS * PF_HD_SPT);
339 g.heads = PF_HD_HDS; 329 geo->heads = PF_HD_HDS;
340 g.sectors = PF_HD_SPT; 330 geo->sectors = PF_HD_SPT;
341 } 331 }
342 if (copy_to_user(geo, &g, sizeof(g))) 332
343 return -EFAULT; 333 return 0;
334}
335
336static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
337{
338 struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
339
340 if (cmd != CDROMEJECT)
341 return -EINVAL;
342
343 if (pf->access != 1)
344 return -EBUSY;
345 pf_eject(pf);
344 return 0; 346 return 0;
345} 347}
346 348
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index c0233efabeba..51b7a5c5b77a 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -1955,9 +1955,12 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write)
1955 if ((ret = blkdev_get(pd->bdev, FMODE_READ, O_RDONLY))) 1955 if ((ret = blkdev_get(pd->bdev, FMODE_READ, O_RDONLY)))
1956 goto out; 1956 goto out;
1957 1957
1958 if ((ret = bd_claim(pd->bdev, pd)))
1959 goto out_putdev;
1960
1958 if ((ret = pkt_get_last_written(pd, &lba))) { 1961 if ((ret = pkt_get_last_written(pd, &lba))) {
1959 printk("pktcdvd: pkt_get_last_written failed\n"); 1962 printk("pktcdvd: pkt_get_last_written failed\n");
1960 goto out_putdev; 1963 goto out_unclaim;
1961 } 1964 }
1962 1965
1963 set_capacity(pd->disk, lba << 2); 1966 set_capacity(pd->disk, lba << 2);
@@ -1967,7 +1970,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write)
1967 q = bdev_get_queue(pd->bdev); 1970 q = bdev_get_queue(pd->bdev);
1968 if (write) { 1971 if (write) {
1969 if ((ret = pkt_open_write(pd))) 1972 if ((ret = pkt_open_write(pd)))
1970 goto out_putdev; 1973 goto out_unclaim;
1971 /* 1974 /*
1972 * Some CDRW drives can not handle writes larger than one packet, 1975 * Some CDRW drives can not handle writes larger than one packet,
1973 * even if the size is a multiple of the packet size. 1976 * even if the size is a multiple of the packet size.
@@ -1982,13 +1985,15 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write)
1982 } 1985 }
1983 1986
1984 if ((ret = pkt_set_segment_merging(pd, q))) 1987 if ((ret = pkt_set_segment_merging(pd, q)))
1985 goto out_putdev; 1988 goto out_unclaim;
1986 1989
1987 if (write) 1990 if (write)
1988 printk("pktcdvd: %lukB available on disc\n", lba << 1); 1991 printk("pktcdvd: %lukB available on disc\n", lba << 1);
1989 1992
1990 return 0; 1993 return 0;
1991 1994
1995out_unclaim:
1996 bd_release(pd->bdev);
1992out_putdev: 1997out_putdev:
1993 blkdev_put(pd->bdev); 1998 blkdev_put(pd->bdev);
1994out: 1999out:
@@ -2007,6 +2012,7 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush)
2007 pkt_lock_door(pd, 0); 2012 pkt_lock_door(pd, 0);
2008 2013
2009 pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); 2014 pkt_set_speed(pd, MAX_SPEED, MAX_SPEED);
2015 bd_release(pd->bdev);
2010 blkdev_put(pd->bdev); 2016 blkdev_put(pd->bdev);
2011} 2017}
2012 2018
diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
index 29d1518be72a..43415f69839f 100644
--- a/drivers/block/ps2esdi.c
+++ b/drivers/block/ps2esdi.c
@@ -81,8 +81,7 @@ static void (*current_int_handler) (u_int) = NULL;
81static void ps2esdi_normal_interrupt_handler(u_int); 81static void ps2esdi_normal_interrupt_handler(u_int);
82static void ps2esdi_initial_reset_int_handler(u_int); 82static void ps2esdi_initial_reset_int_handler(u_int);
83static void ps2esdi_geometry_int_handler(u_int); 83static void ps2esdi_geometry_int_handler(u_int);
84static int ps2esdi_ioctl(struct inode *inode, struct file *file, 84static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo);
85 u_int cmd, u_long arg);
86 85
87static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer); 86static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer);
88 87
@@ -132,7 +131,7 @@ static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
132static struct block_device_operations ps2esdi_fops = 131static struct block_device_operations ps2esdi_fops =
133{ 132{
134 .owner = THIS_MODULE, 133 .owner = THIS_MODULE,
135 .ioctl = ps2esdi_ioctl, 134 .getgeo = ps2esdi_getgeo,
136}; 135};
137 136
138static struct gendisk *ps2esdi_gendisk[2]; 137static struct gendisk *ps2esdi_gendisk[2];
@@ -1058,21 +1057,13 @@ static void dump_cmd_complete_status(u_int int_ret_code)
1058 1057
1059} 1058}
1060 1059
1061static int ps2esdi_ioctl(struct inode *inode, 1060static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1062 struct file *file, u_int cmd, u_long arg)
1063{ 1061{
1064 struct ps2esdi_i_struct *p = inode->i_bdev->bd_disk->private_data; 1062 struct ps2esdi_i_struct *p = bdev->bd_disk->private_data;
1065 struct ps2esdi_geometry geom; 1063
1066 1064 geo->heads = p->head;
1067 if (cmd != HDIO_GETGEO) 1065 geo->sectors = p->sect;
1068 return -EINVAL; 1066 geo->cylinders = p->cyl;
1069 memset(&geom, 0, sizeof(geom));
1070 geom.heads = p->head;
1071 geom.sectors = p->sect;
1072 geom.cylinders = p->cyl;
1073 geom.start = get_start_sect(inode->i_bdev);
1074 if (copy_to_user((void __user *)arg, &geom, sizeof(geom)))
1075 return -EFAULT;
1076 return 0; 1067 return 0;
1077} 1068}
1078 1069
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index af7cb2bfd670..01f042f6f1c4 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -1083,23 +1083,33 @@ static int swim3_add_device(struct device_node *swim)
1083{ 1083{
1084 struct device_node *mediabay; 1084 struct device_node *mediabay;
1085 struct floppy_state *fs = &floppy_states[floppy_count]; 1085 struct floppy_state *fs = &floppy_states[floppy_count];
1086 struct resource res_reg, res_dma;
1086 1087
1087 if (swim->n_addrs < 2) 1088 if (of_address_to_resource(swim, 0, &res_reg) ||
1088 { 1089 of_address_to_resource(swim, 1, &res_dma)) {
1089 printk(KERN_INFO "swim3: expecting 2 addrs (n_addrs:%d, n_intrs:%d)\n", 1090 printk(KERN_ERR "swim3: Can't get addresses\n");
1090 swim->n_addrs, swim->n_intrs);
1091 return -EINVAL; 1091 return -EINVAL;
1092 } 1092 }
1093 1093 if (request_mem_region(res_reg.start, res_reg.end - res_reg.start + 1,
1094 if (swim->n_intrs < 2) 1094 " (reg)") == NULL) {
1095 { 1095 printk(KERN_ERR "swim3: Can't request register space\n");
1096 printk(KERN_INFO "swim3: expecting 2 intrs (n_addrs:%d, n_intrs:%d)\n", 1096 return -EINVAL;
1097 swim->n_addrs, swim->n_intrs); 1097 }
1098 if (request_mem_region(res_dma.start, res_dma.end - res_dma.start + 1,
1099 " (dma)") == NULL) {
1100 release_mem_region(res_reg.start,
1101 res_reg.end - res_reg.start + 1);
1102 printk(KERN_ERR "swim3: Can't request DMA space\n");
1098 return -EINVAL; 1103 return -EINVAL;
1099 } 1104 }
1100 1105
1101 if (!request_OF_resource(swim, 0, NULL)) { 1106 if (swim->n_intrs < 2) {
1102 printk(KERN_INFO "swim3: can't request IO resource !\n"); 1107 printk(KERN_INFO "swim3: expecting 2 intrs (n_intrs:%d)\n",
1108 swim->n_intrs);
1109 release_mem_region(res_reg.start,
1110 res_reg.end - res_reg.start + 1);
1111 release_mem_region(res_dma.start,
1112 res_dma.end - res_dma.start + 1);
1103 return -EINVAL; 1113 return -EINVAL;
1104 } 1114 }
1105 1115
@@ -1110,10 +1120,8 @@ static int swim3_add_device(struct device_node *swim)
1110 memset(fs, 0, sizeof(*fs)); 1120 memset(fs, 0, sizeof(*fs));
1111 spin_lock_init(&fs->lock); 1121 spin_lock_init(&fs->lock);
1112 fs->state = idle; 1122 fs->state = idle;
1113 fs->swim3 = (struct swim3 __iomem *) 1123 fs->swim3 = (struct swim3 __iomem *)ioremap(res_reg.start, 0x200);
1114 ioremap(swim->addrs[0].address, 0x200); 1124 fs->dma = (struct dbdma_regs __iomem *)ioremap(res_dma.start, 0x200);
1115 fs->dma = (struct dbdma_regs __iomem *)
1116 ioremap(swim->addrs[1].address, 0x200);
1117 fs->swim3_intr = swim->intrs[0].line; 1125 fs->swim3_intr = swim->intrs[0].line;
1118 fs->dma_intr = swim->intrs[1].line; 1126 fs->dma_intr = swim->intrs[1].line;
1119 fs->cur_cyl = -1; 1127 fs->cur_cyl = -1;
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index 9251f4131b53..c0cdc182a8b0 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -407,8 +407,7 @@ struct carm_array_info {
407 407
408static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); 408static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
409static void carm_remove_one (struct pci_dev *pdev); 409static void carm_remove_one (struct pci_dev *pdev);
410static int carm_bdev_ioctl(struct inode *ino, struct file *fil, 410static int carm_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo);
411 unsigned int cmd, unsigned long arg);
412 411
413static struct pci_device_id carm_pci_tbl[] = { 412static struct pci_device_id carm_pci_tbl[] = {
414 { PCI_VENDOR_ID_PROMISE, 0x8000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, 413 { PCI_VENDOR_ID_PROMISE, 0x8000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
@@ -426,7 +425,7 @@ static struct pci_driver carm_driver = {
426 425
427static struct block_device_operations carm_bd_ops = { 426static struct block_device_operations carm_bd_ops = {
428 .owner = THIS_MODULE, 427 .owner = THIS_MODULE,
429 .ioctl = carm_bdev_ioctl, 428 .getgeo = carm_bdev_getgeo,
430}; 429};
431 430
432static unsigned int carm_host_id; 431static unsigned int carm_host_id;
@@ -434,32 +433,14 @@ static unsigned long carm_major_alloc;
434 433
435 434
436 435
437static int carm_bdev_ioctl(struct inode *ino, struct file *fil, 436static int carm_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo)
438 unsigned int cmd, unsigned long arg)
439{ 437{
440 void __user *usermem = (void __user *) arg; 438 struct carm_port *port = bdev->bd_disk->private_data;
441 struct carm_port *port = ino->i_bdev->bd_disk->private_data;
442 struct hd_geometry geom;
443 439
444 switch (cmd) { 440 geo->heads = (u8) port->dev_geom_head;
445 case HDIO_GETGEO: 441 geo->sectors = (u8) port->dev_geom_sect;
446 if (!usermem) 442 geo->cylinders = port->dev_geom_cyl;
447 return -EINVAL; 443 return 0;
448
449 geom.heads = (u8) port->dev_geom_head;
450 geom.sectors = (u8) port->dev_geom_sect;
451 geom.cylinders = port->dev_geom_cyl;
452 geom.start = get_start_sect(ino->i_bdev);
453
454 if (copy_to_user(usermem, &geom, sizeof(geom)))
455 return -EFAULT;
456 return 0;
457
458 default:
459 break;
460 }
461
462 return -EOPNOTSUPP;
463} 444}
464 445
465static const u32 msg_sizes[] = { 32, 64, 128, CARM_MSG_SIZE }; 446static const u32 msg_sizes[] = { 32, 64, 128, CARM_MSG_SIZE };
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 0f48301342da..15299e7a1ade 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -809,34 +809,23 @@ static int mm_revalidate(struct gendisk *disk)
809 set_capacity(disk, card->mm_size << 1); 809 set_capacity(disk, card->mm_size << 1);
810 return 0; 810 return 0;
811} 811}
812/* 812
813----------------------------------------------------------------------------------- 813static int mm_getgeo(struct block_device *bdev, struct hd_geometry *geo)
814-- mm_ioctl
815-----------------------------------------------------------------------------------
816*/
817static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
818{ 814{
819 if (cmd == HDIO_GETGEO) { 815 struct cardinfo *card = bdev->bd_disk->private_data;
820 struct cardinfo *card = i->i_bdev->bd_disk->private_data; 816 int size = card->mm_size * (1024 / MM_HARDSECT);
821 int size = card->mm_size * (1024 / MM_HARDSECT);
822 struct hd_geometry geo;
823 /*
824 * get geometry: we have to fake one... trim the size to a
825 * multiple of 2048 (1M): tell we have 32 sectors, 64 heads,
826 * whatever cylinders.
827 */
828 geo.heads = 64;
829 geo.sectors = 32;
830 geo.start = get_start_sect(i->i_bdev);
831 geo.cylinders = size / (geo.heads * geo.sectors);
832
833 if (copy_to_user((void __user *) arg, &geo, sizeof(geo)))
834 return -EFAULT;
835 return 0;
836 }
837 817
838 return -EINVAL; 818 /*
819 * get geometry: we have to fake one... trim the size to a
820 * multiple of 2048 (1M): tell we have 32 sectors, 64 heads,
821 * whatever cylinders.
822 */
823 geo->heads = 64;
824 geo->sectors = 32;
825 geo->cylinders = size / (geo->heads * geo->sectors);
826 return 0;
839} 827}
828
840/* 829/*
841----------------------------------------------------------------------------------- 830-----------------------------------------------------------------------------------
842-- mm_check_change 831-- mm_check_change
@@ -855,7 +844,7 @@ static int mm_check_change(struct gendisk *disk)
855*/ 844*/
856static struct block_device_operations mm_fops = { 845static struct block_device_operations mm_fops = {
857 .owner = THIS_MODULE, 846 .owner = THIS_MODULE,
858 .ioctl = mm_ioctl, 847 .getgeo = mm_getgeo,
859 .revalidate_disk= mm_revalidate, 848 .revalidate_disk= mm_revalidate,
860 .media_changed = mm_check_change, 849 .media_changed = mm_check_change,
861}; 850};
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index 063f0304a163..d1aaf31bd97e 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -247,43 +247,17 @@ static int viodasd_release(struct inode *ino, struct file *fil)
247 247
248/* External ioctl entry point. 248/* External ioctl entry point.
249 */ 249 */
250static int viodasd_ioctl(struct inode *ino, struct file *fil, 250static int viodasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
251 unsigned int cmd, unsigned long arg)
252{ 251{
253 unsigned char sectors; 252 struct gendisk *disk = bdev->bd_disk;
254 unsigned char heads; 253 struct viodasd_device *d = disk->private_data;
255 unsigned short cylinders;
256 struct hd_geometry *geo;
257 struct gendisk *gendisk;
258 struct viodasd_device *d;
259 254
260 switch (cmd) { 255 geo->sectors = d->sectors ? d->sectors : 0;
261 case HDIO_GETGEO: 256 geo->heads = d->tracks ? d->tracks : 64;
262 geo = (struct hd_geometry *)arg; 257 geo->cylinders = d->cylinders ? d->cylinders :
263 if (geo == NULL) 258 get_capacity(disk) / (geo->cylinders * geo->heads);
264 return -EINVAL;
265 if (!access_ok(VERIFY_WRITE, geo, sizeof(*geo)))
266 return -EFAULT;
267 gendisk = ino->i_bdev->bd_disk;
268 d = gendisk->private_data;
269 sectors = d->sectors;
270 if (sectors == 0)
271 sectors = 32;
272 heads = d->tracks;
273 if (heads == 0)
274 heads = 64;
275 cylinders = d->cylinders;
276 if (cylinders == 0)
277 cylinders = get_capacity(gendisk) / (sectors * heads);
278 if (__put_user(sectors, &geo->sectors) ||
279 __put_user(heads, &geo->heads) ||
280 __put_user(cylinders, &geo->cylinders) ||
281 __put_user(get_start_sect(ino->i_bdev), &geo->start))
282 return -EFAULT;
283 return 0;
284 }
285 259
286 return -EINVAL; 260 return 0;
287} 261}
288 262
289/* 263/*
@@ -293,7 +267,7 @@ static struct block_device_operations viodasd_fops = {
293 .owner = THIS_MODULE, 267 .owner = THIS_MODULE,
294 .open = viodasd_open, 268 .open = viodasd_open,
295 .release = viodasd_release, 269 .release = viodasd_release,
296 .ioctl = viodasd_ioctl, 270 .getgeo = viodasd_getgeo,
297}; 271};
298 272
299/* 273/*
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index 68b6d7b154cf..cbce7c5e9445 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -128,9 +128,12 @@ static DEFINE_SPINLOCK(xd_lock);
128 128
129static struct gendisk *xd_gendisk[2]; 129static struct gendisk *xd_gendisk[2];
130 130
131static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
132
131static struct block_device_operations xd_fops = { 133static struct block_device_operations xd_fops = {
132 .owner = THIS_MODULE, 134 .owner = THIS_MODULE,
133 .ioctl = xd_ioctl, 135 .ioctl = xd_ioctl,
136 .getgeo = xd_getgeo,
134}; 137};
135static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int); 138static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
136static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors; 139static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
@@ -276,11 +279,11 @@ static u_char __init xd_detect (u_char *controller, unsigned int *address)
276 return(1); 279 return(1);
277 } 280 }
278 281
279 for (i = 0; i < (sizeof(xd_bases) / sizeof(xd_bases[0])); i++) { 282 for (i = 0; i < ARRAY_SIZE(xd_bases); i++) {
280 void __iomem *p = ioremap(xd_bases[i], 0x2000); 283 void __iomem *p = ioremap(xd_bases[i], 0x2000);
281 if (!p) 284 if (!p)
282 continue; 285 continue;
283 for (j = 1; j < (sizeof(xd_sigs) / sizeof(xd_sigs[0])); j++) { 286 for (j = 1; j < ARRAY_SIZE(xd_sigs); j++) {
284 const char *s = xd_sigs[j].string; 287 const char *s = xd_sigs[j].string;
285 if (check_signature(p + xd_sigs[j].offset, s, strlen(s))) { 288 if (check_signature(p + xd_sigs[j].offset, s, strlen(s))) {
286 *controller = j; 289 *controller = j;
@@ -330,22 +333,20 @@ static void do_xd_request (request_queue_t * q)
330 } 333 }
331} 334}
332 335
336static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
337{
338 XD_INFO *p = bdev->bd_disk->private_data;
339
340 geo->heads = p->heads;
341 geo->sectors = p->sectors;
342 geo->cylinders = p->cylinders;
343 return 0;
344}
345
333/* xd_ioctl: handle device ioctl's */ 346/* xd_ioctl: handle device ioctl's */
334static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg) 347static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
335{ 348{
336 XD_INFO *p = inode->i_bdev->bd_disk->private_data;
337
338 switch (cmd) { 349 switch (cmd) {
339 case HDIO_GETGEO:
340 {
341 struct hd_geometry g;
342 struct hd_geometry __user *geom= (void __user *)arg;
343 g.heads = p->heads;
344 g.sectors = p->sectors;
345 g.cylinders = p->cylinders;
346 g.start = get_start_sect(inode->i_bdev);
347 return copy_to_user(geom, &g, sizeof(g)) ? -EFAULT : 0;
348 }
349 case HDIO_SET_DMA: 350 case HDIO_SET_DMA:
350 if (!capable(CAP_SYS_ADMIN)) return -EACCES; 351 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
351 if (xdc_busy) return -EBUSY; 352 if (xdc_busy) return -EBUSY;
@@ -1017,7 +1018,7 @@ static void __init do_xd_setup (int *integers)
1017 case 2: if ((integers[2] > 0) && (integers[2] < 16)) 1018 case 2: if ((integers[2] > 0) && (integers[2] < 16))
1018 xd_irq = integers[2]; 1019 xd_irq = integers[2];
1019 case 1: xd_override = 1; 1020 case 1: xd_override = 1;
1020 if ((integers[1] >= 0) && (integers[1] < (sizeof(xd_sigs) / sizeof(xd_sigs[0])))) 1021 if ((integers[1] >= 0) && (integers[1] < ARRAY_SIZE(xd_sigs)))
1021 xd_type = integers[1]; 1022 xd_type = integers[1];
1022 case 0: break; 1023 case 0: break;
1023 default:printk("xd: too many parameters for xd\n"); 1024 default:printk("xd: too many parameters for xd\n");
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 5ebd06b1b4ca..dd7e6901c575 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -220,6 +220,14 @@ config SYNCLINKMP
220 The module will be called synclinkmp. If you want to do that, say M 220 The module will be called synclinkmp. If you want to do that, say M
221 here. 221 here.
222 222
223config SYNCLINK_GT
224 tristate "SyncLink GT/AC support"
225 depends on SERIAL_NONSTANDARD
226 help
227 Support for SyncLink GT and SyncLink AC families of
228 synchronous and asynchronous serial adapters
229 manufactured by Microgate Systems, Ltd. (www.microgate.com)
230
223config N_HDLC 231config N_HDLC
224 tristate "HDLC line discipline support" 232 tristate "HDLC line discipline support"
225 depends on SERIAL_NONSTANDARD 233 depends on SERIAL_NONSTANDARD
@@ -687,7 +695,7 @@ config NVRAM
687 695
688config RTC 696config RTC
689 tristate "Enhanced Real Time Clock Support" 697 tristate "Enhanced Real Time Clock Support"
690 depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) 698 depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV
691 ---help--- 699 ---help---
692 If you say Y here and create a character special file /dev/rtc with 700 If you say Y here and create a character special file /dev/rtc with
693 major number 10 and minor number 135 using mknod ("man mknod"), you 701 major number 10 and minor number 135 using mknod ("man mknod"), you
@@ -735,7 +743,7 @@ config SGI_IP27_RTC
735 743
736config GEN_RTC 744config GEN_RTC
737 tristate "Generic /dev/rtc emulation" 745 tristate "Generic /dev/rtc emulation"
738 depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC 746 depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV
739 ---help--- 747 ---help---
740 If you say Y here and create a character special file /dev/rtc with 748 If you say Y here and create a character special file /dev/rtc with
741 major number 10 and minor number 135 using mknod ("man mknod"), you 749 major number 10 and minor number 135 using mknod ("man mknod"), you
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 4aeae687e88a..d973d14d8f7f 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_RISCOM8) += riscom8.o
36obj-$(CONFIG_ISI) += isicom.o 36obj-$(CONFIG_ISI) += isicom.o
37obj-$(CONFIG_SYNCLINK) += synclink.o 37obj-$(CONFIG_SYNCLINK) += synclink.o
38obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o 38obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o
39obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o
39obj-$(CONFIG_N_HDLC) += n_hdlc.o 40obj-$(CONFIG_N_HDLC) += n_hdlc.o
40obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o 41obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
41obj-$(CONFIG_SX) += sx.o generic_serial.o 42obj-$(CONFIG_SX) += sx.o generic_serial.o
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 3f8f7fa6b0ff..268f78d926d3 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -7,6 +7,7 @@
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/string.h> 8#include <linux/string.h>
9#include <linux/slab.h> 9#include <linux/slab.h>
10#include <linux/jiffies.h>
10#include <linux/agp_backend.h> 11#include <linux/agp_backend.h>
11#include "agp.h" 12#include "agp.h"
12 13
diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c
index 49769f59ea1b..b3bc2e37e616 100644
--- a/drivers/char/hw_random.c
+++ b/drivers/char/hw_random.c
@@ -169,6 +169,7 @@ static struct pci_device_id rng_pci_tbl[] = {
169 169
170 { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, 170 { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
171 { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, 171 { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
172 { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
172 { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, 173 { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
173 { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, 174 { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
174 { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, 175 { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 91dd669273e0..5b2d18035073 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -101,6 +101,11 @@ static inline int valid_phys_addr_range(unsigned long addr, size_t *count)
101 101
102 return 1; 102 return 1;
103} 103}
104
105static inline int valid_mmap_phys_addr_range(unsigned long addr, size_t *size)
106{
107 return 1;
108}
104#endif 109#endif
105 110
106/* 111/*
@@ -228,26 +233,36 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
228 return written; 233 return written;
229} 234}
230 235
236#ifndef __HAVE_PHYS_MEM_ACCESS_PROT
237static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
238 unsigned long size, pgprot_t vma_prot)
239{
240#ifdef pgprot_noncached
241 unsigned long offset = pfn << PAGE_SHIFT;
242
243 if (uncached_access(file, offset))
244 return pgprot_noncached(vma_prot);
245#endif
246 return vma_prot;
247}
248#endif
249
231static int mmap_mem(struct file * file, struct vm_area_struct * vma) 250static int mmap_mem(struct file * file, struct vm_area_struct * vma)
232{ 251{
233#if defined(__HAVE_PHYS_MEM_ACCESS_PROT) 252 size_t size = vma->vm_end - vma->vm_start;
253
254 if (!valid_mmap_phys_addr_range(vma->vm_pgoff << PAGE_SHIFT, &size))
255 return -EINVAL;
256
234 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, 257 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
235 vma->vm_end - vma->vm_start, 258 size,
236 vma->vm_page_prot); 259 vma->vm_page_prot);
237#elif defined(pgprot_noncached)
238 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
239 int uncached;
240
241 uncached = uncached_access(file, offset);
242 if (uncached)
243 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
244#endif
245 260
246 /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */ 261 /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
247 if (remap_pfn_range(vma, 262 if (remap_pfn_range(vma,
248 vma->vm_start, 263 vma->vm_start,
249 vma->vm_pgoff, 264 vma->vm_pgoff,
250 vma->vm_end-vma->vm_start, 265 size,
251 vma->vm_page_prot)) 266 vma->vm_page_prot))
252 return -EAGAIN; 267 return -EAGAIN;
253 return 0; 268 return 0;
@@ -817,7 +832,7 @@ static ssize_t kmsg_write(struct file * file, const char __user * buf,
817 size_t count, loff_t *ppos) 832 size_t count, loff_t *ppos)
818{ 833{
819 char *tmp; 834 char *tmp;
820 int ret; 835 ssize_t ret;
821 836
822 tmp = kmalloc(count + 1, GFP_KERNEL); 837 tmp = kmalloc(count + 1, GFP_KERNEL);
823 if (tmp == NULL) 838 if (tmp == NULL)
@@ -826,6 +841,9 @@ static ssize_t kmsg_write(struct file * file, const char __user * buf,
826 if (!copy_from_user(tmp, buf, count)) { 841 if (!copy_from_user(tmp, buf, count)) {
827 tmp[count] = 0; 842 tmp[count] = 0;
828 ret = printk("%s", tmp); 843 ret = printk("%s", tmp);
844 if (ret > count)
845 /* printk can add a prefix */
846 ret = count;
829 } 847 }
830 kfree(tmp); 848 kfree(tmp);
831 return ret; 849 return ret;
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 51a07370e636..f8dd8527c6aa 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -471,7 +471,6 @@ struct sonypi_keypress {
471 471
472static struct sonypi_device { 472static struct sonypi_device {
473 struct pci_dev *dev; 473 struct pci_dev *dev;
474 struct platform_device *pdev;
475 u16 irq; 474 u16 irq;
476 u16 bits; 475 u16 bits;
477 u16 ioport1; 476 u16 ioport1;
@@ -511,6 +510,11 @@ static struct sonypi_device {
511#define SONYPI_ACPI_ACTIVE 0 510#define SONYPI_ACPI_ACTIVE 0
512#endif /* CONFIG_ACPI */ 511#endif /* CONFIG_ACPI */
513 512
513#ifdef CONFIG_ACPI
514static struct acpi_device *sonypi_acpi_device;
515static int acpi_enabled;
516#endif
517
514static int sonypi_ec_write(u8 addr, u8 value) 518static int sonypi_ec_write(u8 addr, u8 value)
515{ 519{
516#ifdef CONFIG_ACPI_EC 520#ifdef CONFIG_ACPI_EC
@@ -864,6 +868,11 @@ found:
864 if (useinput) 868 if (useinput)
865 sonypi_report_input_event(event); 869 sonypi_report_input_event(event);
866 870
871#ifdef CONFIG_ACPI
872 if (acpi_enabled)
873 acpi_bus_generate_event(sonypi_acpi_device, 1, event);
874#endif
875
867 kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); 876 kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
868 kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); 877 kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
869 wake_up_interruptible(&sonypi_device.fifo_proc_list); 878 wake_up_interruptible(&sonypi_device.fifo_proc_list);
@@ -1165,45 +1174,38 @@ static int sonypi_disable(void)
1165 return 0; 1174 return 0;
1166} 1175}
1167 1176
1168#ifdef CONFIG_PM 1177#ifdef CONFIG_ACPI
1169static int old_camera_power; 1178static int sonypi_acpi_add(struct acpi_device *device)
1170
1171static int sonypi_suspend(struct platform_device *dev, pm_message_t state)
1172{ 1179{
1173 old_camera_power = sonypi_device.camera_power; 1180 sonypi_acpi_device = device;
1174 sonypi_disable(); 1181 strcpy(acpi_device_name(device), "Sony laptop hotkeys");
1175 1182 strcpy(acpi_device_class(device), "sony/hotkey");
1176 return 0; 1183 return 0;
1177} 1184}
1178 1185
1179static int sonypi_resume(struct platform_device *dev) 1186static int sonypi_acpi_remove(struct acpi_device *device, int type)
1180{ 1187{
1181 sonypi_enable(old_camera_power); 1188 sonypi_acpi_device = NULL;
1182 return 0; 1189 return 0;
1183} 1190}
1184#endif
1185
1186static void sonypi_shutdown(struct platform_device *dev)
1187{
1188 sonypi_disable();
1189}
1190 1191
1191static struct platform_driver sonypi_driver = { 1192static struct acpi_driver sonypi_acpi_driver = {
1192#ifdef CONFIG_PM 1193 .name = "sonypi",
1193 .suspend = sonypi_suspend, 1194 .class = "hkey",
1194 .resume = sonypi_resume, 1195 .ids = "SNY6001",
1195#endif 1196 .ops = {
1196 .shutdown = sonypi_shutdown, 1197 .add = sonypi_acpi_add,
1197 .driver = { 1198 .remove = sonypi_acpi_remove,
1198 .name = "sonypi",
1199 }, 1199 },
1200}; 1200};
1201#endif
1201 1202
1202static int __devinit sonypi_create_input_devices(void) 1203static int __devinit sonypi_create_input_devices(void)
1203{ 1204{
1204 struct input_dev *jog_dev; 1205 struct input_dev *jog_dev;
1205 struct input_dev *key_dev; 1206 struct input_dev *key_dev;
1206 int i; 1207 int i;
1208 int error;
1207 1209
1208 sonypi_device.input_jog_dev = jog_dev = input_allocate_device(); 1210 sonypi_device.input_jog_dev = jog_dev = input_allocate_device();
1209 if (!jog_dev) 1211 if (!jog_dev)
@@ -1219,9 +1221,8 @@ static int __devinit sonypi_create_input_devices(void)
1219 1221
1220 sonypi_device.input_key_dev = key_dev = input_allocate_device(); 1222 sonypi_device.input_key_dev = key_dev = input_allocate_device();
1221 if (!key_dev) { 1223 if (!key_dev) {
1222 input_free_device(jog_dev); 1224 error = -ENOMEM;
1223 sonypi_device.input_jog_dev = NULL; 1225 goto err_free_jogdev;
1224 return -ENOMEM;
1225 } 1226 }
1226 1227
1227 key_dev->name = "Sony Vaio Keys"; 1228 key_dev->name = "Sony Vaio Keys";
@@ -1234,56 +1235,122 @@ static int __devinit sonypi_create_input_devices(void)
1234 if (sonypi_inputkeys[i].inputev) 1235 if (sonypi_inputkeys[i].inputev)
1235 set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit); 1236 set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit);
1236 1237
1237 input_register_device(jog_dev); 1238 error = input_register_device(jog_dev);
1238 input_register_device(key_dev); 1239 if (error)
1240 goto err_free_keydev;
1241
1242 error = input_register_device(key_dev);
1243 if (error)
1244 goto err_unregister_jogdev;
1239 1245
1240 return 0; 1246 return 0;
1247
1248 err_unregister_jogdev:
1249 input_unregister_device(jog_dev);
1250 /* Set to NULL so we don't free it again below */
1251 jog_dev = NULL;
1252 err_free_keydev:
1253 input_free_device(key_dev);
1254 sonypi_device.input_key_dev = NULL;
1255 err_free_jogdev:
1256 input_free_device(jog_dev);
1257 sonypi_device.input_jog_dev = NULL;
1258
1259 return error;
1241} 1260}
1242 1261
1243static int __devinit sonypi_probe(void) 1262static int __devinit sonypi_setup_ioports(struct sonypi_device *dev,
1263 const struct sonypi_ioport_list *ioport_list)
1244{ 1264{
1245 int i, ret; 1265 while (ioport_list->port1) {
1246 struct sonypi_ioport_list *ioport_list;
1247 struct sonypi_irq_list *irq_list;
1248 struct pci_dev *pcidev;
1249 1266
1250 if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1267 if (request_region(ioport_list->port1,
1251 PCI_DEVICE_ID_INTEL_82371AB_3, NULL))) 1268 sonypi_device.region_size,
1252 sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE1; 1269 "Sony Programable I/O Device")) {
1253 else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1270 dev->ioport1 = ioport_list->port1;
1254 PCI_DEVICE_ID_INTEL_ICH6_1, NULL))) 1271 dev->ioport2 = ioport_list->port2;
1255 sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3; 1272 return 0;
1256 else 1273 }
1257 sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2; 1274 ioport_list++;
1275 }
1258 1276
1259 sonypi_device.dev = pcidev; 1277 return -EBUSY;
1278}
1279
1280static int __devinit sonypi_setup_irq(struct sonypi_device *dev,
1281 const struct sonypi_irq_list *irq_list)
1282{
1283 while (irq_list->irq) {
1284
1285 if (!request_irq(irq_list->irq, sonypi_irq,
1286 SA_SHIRQ, "sonypi", sonypi_irq)) {
1287 dev->irq = irq_list->irq;
1288 dev->bits = irq_list->bits;
1289 return 0;
1290 }
1291 irq_list++;
1292 }
1293
1294 return -EBUSY;
1295}
1296
1297static void __devinit sonypi_display_info(void)
1298{
1299 printk(KERN_INFO "sonypi: detected type%d model, "
1300 "verbose = %d, fnkeyinit = %s, camera = %s, "
1301 "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n",
1302 sonypi_device.model,
1303 verbose,
1304 fnkeyinit ? "on" : "off",
1305 camera ? "on" : "off",
1306 compat ? "on" : "off",
1307 mask,
1308 useinput ? "on" : "off",
1309 SONYPI_ACPI_ACTIVE ? "on" : "off");
1310 printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n",
1311 sonypi_device.irq,
1312 sonypi_device.ioport1, sonypi_device.ioport2);
1313
1314 if (minor == -1)
1315 printk(KERN_INFO "sonypi: device allocated minor is %d\n",
1316 sonypi_misc_device.minor);
1317}
1318
1319static int __devinit sonypi_probe(struct platform_device *dev)
1320{
1321 const struct sonypi_ioport_list *ioport_list;
1322 const struct sonypi_irq_list *irq_list;
1323 struct pci_dev *pcidev;
1324 int error;
1260 1325
1261 spin_lock_init(&sonypi_device.fifo_lock); 1326 spin_lock_init(&sonypi_device.fifo_lock);
1262 sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, 1327 sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
1263 &sonypi_device.fifo_lock); 1328 &sonypi_device.fifo_lock);
1264 if (IS_ERR(sonypi_device.fifo)) { 1329 if (IS_ERR(sonypi_device.fifo)) {
1265 printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); 1330 printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
1266 ret = PTR_ERR(sonypi_device.fifo); 1331 return PTR_ERR(sonypi_device.fifo);
1267 goto out_fifo;
1268 } 1332 }
1269 1333
1270 init_waitqueue_head(&sonypi_device.fifo_proc_list); 1334 init_waitqueue_head(&sonypi_device.fifo_proc_list);
1271 init_MUTEX(&sonypi_device.lock); 1335 init_MUTEX(&sonypi_device.lock);
1272 sonypi_device.bluetooth_power = -1; 1336 sonypi_device.bluetooth_power = -1;
1273 1337
1338 if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1339 PCI_DEVICE_ID_INTEL_82371AB_3, NULL)))
1340 sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE1;
1341 else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1342 PCI_DEVICE_ID_INTEL_ICH6_1, NULL)))
1343 sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
1344 else
1345 sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2;
1346
1274 if (pcidev && pci_enable_device(pcidev)) { 1347 if (pcidev && pci_enable_device(pcidev)) {
1275 printk(KERN_ERR "sonypi: pci_enable_device failed\n"); 1348 printk(KERN_ERR "sonypi: pci_enable_device failed\n");
1276 ret = -EIO; 1349 error = -EIO;
1277 goto out_pcienable; 1350 goto err_put_pcidev;
1278 }
1279
1280 if (minor != -1)
1281 sonypi_misc_device.minor = minor;
1282 if ((ret = misc_register(&sonypi_misc_device))) {
1283 printk(KERN_ERR "sonypi: misc_register failed\n");
1284 goto out_miscreg;
1285 } 1351 }
1286 1352
1353 sonypi_device.dev = pcidev;
1287 1354
1288 if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) { 1355 if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) {
1289 ioport_list = sonypi_type1_ioport_list; 1356 ioport_list = sonypi_type1_ioport_list;
@@ -1302,43 +1369,36 @@ static int __devinit sonypi_probe(void)
1302 irq_list = sonypi_type3_irq_list; 1369 irq_list = sonypi_type3_irq_list;
1303 } 1370 }
1304 1371
1305 for (i = 0; ioport_list[i].port1; i++) { 1372 error = sonypi_setup_ioports(&sonypi_device, ioport_list);
1306 if (request_region(ioport_list[i].port1, 1373 if (error) {
1307 sonypi_device.region_size, 1374 printk(KERN_ERR "sonypi: failed to request ioports\n");
1308 "Sony Programable I/O Device")) { 1375 goto err_disable_pcidev;
1309 /* get the ioport */
1310 sonypi_device.ioport1 = ioport_list[i].port1;
1311 sonypi_device.ioport2 = ioport_list[i].port2;
1312 break;
1313 }
1314 }
1315 if (!sonypi_device.ioport1) {
1316 printk(KERN_ERR "sonypi: request_region failed\n");
1317 ret = -ENODEV;
1318 goto out_reqreg;
1319 } 1376 }
1320 1377
1321 for (i = 0; irq_list[i].irq; i++) { 1378 error = sonypi_setup_irq(&sonypi_device, irq_list);
1322 1379 if (error) {
1323 sonypi_device.irq = irq_list[i].irq; 1380 printk(KERN_ERR "sonypi: request_irq failed\n");
1324 sonypi_device.bits = irq_list[i].bits; 1381 goto err_free_ioports;
1325
1326 if (!request_irq(sonypi_device.irq, sonypi_irq,
1327 SA_SHIRQ, "sonypi", sonypi_irq))
1328 break;
1329 } 1382 }
1330 1383
1331 if (!irq_list[i].irq) { 1384 if (minor != -1)
1332 printk(KERN_ERR "sonypi: request_irq failed\n"); 1385 sonypi_misc_device.minor = minor;
1333 ret = -ENODEV; 1386 error = misc_register(&sonypi_misc_device);
1334 goto out_reqirq; 1387 if (error) {
1388 printk(KERN_ERR "sonypi: misc_register failed\n");
1389 goto err_free_irq;
1335 } 1390 }
1336 1391
1392 sonypi_display_info();
1393
1337 if (useinput) { 1394 if (useinput) {
1338 1395
1339 ret = sonypi_create_input_devices(); 1396 error = sonypi_create_input_devices();
1340 if (ret) 1397 if (error) {
1341 goto out_inputdevices; 1398 printk(KERN_ERR
1399 "sonypi: failed to create input devices\n");
1400 goto err_miscdev_unregister;
1401 }
1342 1402
1343 spin_lock_init(&sonypi_device.input_fifo_lock); 1403 spin_lock_init(&sonypi_device.input_fifo_lock);
1344 sonypi_device.input_fifo = 1404 sonypi_device.input_fifo =
@@ -1346,91 +1406,104 @@ static int __devinit sonypi_probe(void)
1346 &sonypi_device.input_fifo_lock); 1406 &sonypi_device.input_fifo_lock);
1347 if (IS_ERR(sonypi_device.input_fifo)) { 1407 if (IS_ERR(sonypi_device.input_fifo)) {
1348 printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); 1408 printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
1349 ret = PTR_ERR(sonypi_device.input_fifo); 1409 error = PTR_ERR(sonypi_device.input_fifo);
1350 goto out_infifo; 1410 goto err_inpdev_unregister;
1351 } 1411 }
1352 1412
1353 INIT_WORK(&sonypi_device.input_work, input_keyrelease, NULL); 1413 INIT_WORK(&sonypi_device.input_work, input_keyrelease, NULL);
1354 } 1414 }
1355 1415
1356 sonypi_device.pdev = platform_device_register_simple("sonypi", -1,
1357 NULL, 0);
1358 if (IS_ERR(sonypi_device.pdev)) {
1359 ret = PTR_ERR(sonypi_device.pdev);
1360 goto out_platformdev;
1361 }
1362
1363 sonypi_enable(0); 1416 sonypi_enable(0);
1364 1417
1365 printk(KERN_INFO "sonypi: Sony Programmable I/O Controller Driver"
1366 "v%s.\n", SONYPI_DRIVER_VERSION);
1367 printk(KERN_INFO "sonypi: detected type%d model, "
1368 "verbose = %d, fnkeyinit = %s, camera = %s, "
1369 "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n",
1370 sonypi_device.model,
1371 verbose,
1372 fnkeyinit ? "on" : "off",
1373 camera ? "on" : "off",
1374 compat ? "on" : "off",
1375 mask,
1376 useinput ? "on" : "off",
1377 SONYPI_ACPI_ACTIVE ? "on" : "off");
1378 printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n",
1379 sonypi_device.irq,
1380 sonypi_device.ioport1, sonypi_device.ioport2);
1381
1382 if (minor == -1)
1383 printk(KERN_INFO "sonypi: device allocated minor is %d\n",
1384 sonypi_misc_device.minor);
1385
1386 return 0; 1418 return 0;
1387 1419
1388out_platformdev: 1420 err_inpdev_unregister:
1389 kfifo_free(sonypi_device.input_fifo);
1390out_infifo:
1391 input_unregister_device(sonypi_device.input_key_dev); 1421 input_unregister_device(sonypi_device.input_key_dev);
1392 input_unregister_device(sonypi_device.input_jog_dev); 1422 input_unregister_device(sonypi_device.input_jog_dev);
1393out_inputdevices: 1423 err_miscdev_unregister:
1424 misc_deregister(&sonypi_misc_device);
1425 err_free_irq:
1394 free_irq(sonypi_device.irq, sonypi_irq); 1426 free_irq(sonypi_device.irq, sonypi_irq);
1395out_reqirq: 1427 err_free_ioports:
1396 release_region(sonypi_device.ioport1, sonypi_device.region_size); 1428 release_region(sonypi_device.ioport1, sonypi_device.region_size);
1397out_reqreg: 1429 err_disable_pcidev:
1398 misc_deregister(&sonypi_misc_device);
1399out_miscreg:
1400 if (pcidev) 1430 if (pcidev)
1401 pci_disable_device(pcidev); 1431 pci_disable_device(pcidev);
1402out_pcienable: 1432 err_put_pcidev:
1433 pci_dev_put(pcidev);
1403 kfifo_free(sonypi_device.fifo); 1434 kfifo_free(sonypi_device.fifo);
1404out_fifo: 1435
1405 pci_dev_put(sonypi_device.dev); 1436 return error;
1406 return ret;
1407} 1437}
1408 1438
1409static void __devexit sonypi_remove(void) 1439static int __devexit sonypi_remove(struct platform_device *dev)
1410{ 1440{
1411 sonypi_disable(); 1441 sonypi_disable();
1412 1442
1413 synchronize_sched(); /* Allow sonypi interrupt to complete. */ 1443 synchronize_sched(); /* Allow sonypi interrupt to complete. */
1414 flush_scheduled_work(); 1444 flush_scheduled_work();
1415 1445
1416 platform_device_unregister(sonypi_device.pdev);
1417
1418 if (useinput) { 1446 if (useinput) {
1419 input_unregister_device(sonypi_device.input_key_dev); 1447 input_unregister_device(sonypi_device.input_key_dev);
1420 input_unregister_device(sonypi_device.input_jog_dev); 1448 input_unregister_device(sonypi_device.input_jog_dev);
1421 kfifo_free(sonypi_device.input_fifo); 1449 kfifo_free(sonypi_device.input_fifo);
1422 } 1450 }
1423 1451
1452 misc_deregister(&sonypi_misc_device);
1453
1424 free_irq(sonypi_device.irq, sonypi_irq); 1454 free_irq(sonypi_device.irq, sonypi_irq);
1425 release_region(sonypi_device.ioport1, sonypi_device.region_size); 1455 release_region(sonypi_device.ioport1, sonypi_device.region_size);
1426 misc_deregister(&sonypi_misc_device); 1456
1427 if (sonypi_device.dev) 1457 if (sonypi_device.dev) {
1428 pci_disable_device(sonypi_device.dev); 1458 pci_disable_device(sonypi_device.dev);
1459 pci_dev_put(sonypi_device.dev);
1460 }
1461
1429 kfifo_free(sonypi_device.fifo); 1462 kfifo_free(sonypi_device.fifo);
1430 pci_dev_put(sonypi_device.dev); 1463
1431 printk(KERN_INFO "sonypi: removed.\n"); 1464 return 0;
1432} 1465}
1433 1466
1467#ifdef CONFIG_PM
1468static int old_camera_power;
1469
1470static int sonypi_suspend(struct platform_device *dev, pm_message_t state)
1471{
1472 old_camera_power = sonypi_device.camera_power;
1473 sonypi_disable();
1474
1475 return 0;
1476}
1477
1478static int sonypi_resume(struct platform_device *dev)
1479{
1480 sonypi_enable(old_camera_power);
1481 return 0;
1482}
1483#else
1484#define sonypi_suspend NULL
1485#define sonypi_resume NULL
1486#endif
1487
1488static void sonypi_shutdown(struct platform_device *dev)
1489{
1490 sonypi_disable();
1491}
1492
1493static struct platform_driver sonypi_driver = {
1494 .driver = {
1495 .name = "sonypi",
1496 .owner = THIS_MODULE,
1497 },
1498 .probe = sonypi_probe,
1499 .remove = __devexit_p(sonypi_remove),
1500 .shutdown = sonypi_shutdown,
1501 .suspend = sonypi_suspend,
1502 .resume = sonypi_resume,
1503};
1504
1505static struct platform_device *sonypi_platform_device;
1506
1434static struct dmi_system_id __initdata sonypi_dmi_table[] = { 1507static struct dmi_system_id __initdata sonypi_dmi_table[] = {
1435 { 1508 {
1436 .ident = "Sony Vaio", 1509 .ident = "Sony Vaio",
@@ -1451,26 +1524,52 @@ static struct dmi_system_id __initdata sonypi_dmi_table[] = {
1451 1524
1452static int __init sonypi_init(void) 1525static int __init sonypi_init(void)
1453{ 1526{
1454 int ret; 1527 int error;
1528
1529 printk(KERN_INFO
1530 "sonypi: Sony Programmable I/O Controller Driver v%s.\n",
1531 SONYPI_DRIVER_VERSION);
1455 1532
1456 if (!dmi_check_system(sonypi_dmi_table)) 1533 if (!dmi_check_system(sonypi_dmi_table))
1457 return -ENODEV; 1534 return -ENODEV;
1458 1535
1459 ret = platform_driver_register(&sonypi_driver); 1536 error = platform_driver_register(&sonypi_driver);
1460 if (ret) 1537 if (error)
1461 return ret; 1538 return error;
1462 1539
1463 ret = sonypi_probe(); 1540 sonypi_platform_device = platform_device_alloc("sonypi", -1);
1464 if (ret) 1541 if (!sonypi_platform_device) {
1465 platform_driver_unregister(&sonypi_driver); 1542 error = -ENOMEM;
1543 goto err_driver_unregister;
1544 }
1466 1545
1467 return ret; 1546 error = platform_device_add(sonypi_platform_device);
1547 if (error)
1548 goto err_free_device;
1549
1550#ifdef CONFIG_ACPI
1551 if (acpi_bus_register_driver(&sonypi_acpi_driver) > 0)
1552 acpi_enabled = 1;
1553#endif
1554
1555 return 0;
1556
1557 err_free_device:
1558 platform_device_put(sonypi_platform_device);
1559 err_driver_unregister:
1560 platform_driver_unregister(&sonypi_driver);
1561 return error;
1468} 1562}
1469 1563
1470static void __exit sonypi_exit(void) 1564static void __exit sonypi_exit(void)
1471{ 1565{
1566#ifdef CONFIG_ACPI
1567 if (acpi_enabled)
1568 acpi_bus_unregister_driver(&sonypi_acpi_driver);
1569#endif
1570 platform_device_unregister(sonypi_platform_device);
1472 platform_driver_unregister(&sonypi_driver); 1571 platform_driver_unregister(&sonypi_driver);
1473 sonypi_remove(); 1572 printk(KERN_INFO "sonypi: removed.\n");
1474} 1573}
1475 1574
1476module_init(sonypi_init); 1575module_init(sonypi_init);
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
new file mode 100644
index 000000000000..2b9cde94e2f7
--- /dev/null
+++ b/drivers/char/synclink_gt.c
@@ -0,0 +1,4501 @@
1/*
2 * $Id: synclink_gt.c,v 4.20 2005/11/08 19:51:55 paulkf Exp $
3 *
4 * Device driver for Microgate SyncLink GT serial adapters.
5 *
6 * written by Paul Fulghum for Microgate Corporation
7 * paulkf@microgate.com
8 *
9 * Microgate and SyncLink are trademarks of Microgate Corporation
10 *
11 * This code is released under the GNU General Public License (GPL)
12 *
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
17 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
23 * OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26/*
27 * DEBUG OUTPUT DEFINITIONS
28 *
29 * uncomment lines below to enable specific types of debug output
30 *
31 * DBGINFO information - most verbose output
32 * DBGERR serious errors
33 * DBGBH bottom half service routine debugging
34 * DBGISR interrupt service routine debugging
35 * DBGDATA output receive and transmit data
36 * DBGTBUF output transmit DMA buffers and registers
37 * DBGRBUF output receive DMA buffers and registers
38 */
39
40#define DBGINFO(fmt) if (debug_level >= DEBUG_LEVEL_INFO) printk fmt
41#define DBGERR(fmt) if (debug_level >= DEBUG_LEVEL_ERROR) printk fmt
42#define DBGBH(fmt) if (debug_level >= DEBUG_LEVEL_BH) printk fmt
43#define DBGISR(fmt) if (debug_level >= DEBUG_LEVEL_ISR) printk fmt
44#define DBGDATA(info, buf, size, label) if (debug_level >= DEBUG_LEVEL_DATA) trace_block((info), (buf), (size), (label))
45//#define DBGTBUF(info) dump_tbufs(info)
46//#define DBGRBUF(info) dump_rbufs(info)
47
48
49#include <linux/config.h>
50#include <linux/module.h>
51#include <linux/version.h>
52#include <linux/errno.h>
53#include <linux/signal.h>
54#include <linux/sched.h>
55#include <linux/timer.h>
56#include <linux/interrupt.h>
57#include <linux/pci.h>
58#include <linux/tty.h>
59#include <linux/tty_flip.h>
60#include <linux/serial.h>
61#include <linux/major.h>
62#include <linux/string.h>
63#include <linux/fcntl.h>
64#include <linux/ptrace.h>
65#include <linux/ioport.h>
66#include <linux/mm.h>
67#include <linux/slab.h>
68#include <linux/netdevice.h>
69#include <linux/vmalloc.h>
70#include <linux/init.h>
71#include <linux/delay.h>
72#include <linux/ioctl.h>
73#include <linux/termios.h>
74#include <linux/bitops.h>
75#include <linux/workqueue.h>
76#include <linux/hdlc.h>
77
78#include <asm/serial.h>
79#include <asm/system.h>
80#include <asm/io.h>
81#include <asm/irq.h>
82#include <asm/dma.h>
83#include <asm/types.h>
84#include <asm/uaccess.h>
85
86#include "linux/synclink.h"
87
88#ifdef CONFIG_HDLC_MODULE
89#define CONFIG_HDLC 1
90#endif
91
92/*
93 * module identification
94 */
95static char *driver_name = "SyncLink GT";
96static char *driver_version = "$Revision: 4.20 $";
97static char *tty_driver_name = "synclink_gt";
98static char *tty_dev_prefix = "ttySLG";
99MODULE_LICENSE("GPL");
100#define MGSL_MAGIC 0x5401
101#define MAX_DEVICES 12
102
103static struct pci_device_id pci_table[] = {
104 {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
105 {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT4_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
106 {PCI_VENDOR_ID_MICROGATE, SYNCLINK_AC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
107 {0,}, /* terminate list */
108};
109MODULE_DEVICE_TABLE(pci, pci_table);
110
111static int init_one(struct pci_dev *dev,const struct pci_device_id *ent);
112static void remove_one(struct pci_dev *dev);
113static struct pci_driver pci_driver = {
114 .name = "synclink_gt",
115 .id_table = pci_table,
116 .probe = init_one,
117 .remove = __devexit_p(remove_one),
118};
119
120static int pci_registered;
121
122/*
123 * module configuration and status
124 */
125static struct slgt_info *slgt_device_list;
126static int slgt_device_count;
127
128static int ttymajor;
129static int debug_level;
130static int maxframe[MAX_DEVICES];
131static int dosyncppp[MAX_DEVICES];
132
133module_param(ttymajor, int, 0);
134module_param(debug_level, int, 0);
135module_param_array(maxframe, int, NULL, 0);
136module_param_array(dosyncppp, int, NULL, 0);
137
138MODULE_PARM_DESC(ttymajor, "TTY major device number override: 0=auto assigned");
139MODULE_PARM_DESC(debug_level, "Debug syslog output: 0=disabled, 1 to 5=increasing detail");
140MODULE_PARM_DESC(maxframe, "Maximum frame size used by device (4096 to 65535)");
141MODULE_PARM_DESC(dosyncppp, "Enable synchronous net device, 0=disable 1=enable");
142
143/*
144 * tty support and callbacks
145 */
146#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
147
148static struct tty_driver *serial_driver;
149
150static int open(struct tty_struct *tty, struct file * filp);
151static void close(struct tty_struct *tty, struct file * filp);
152static void hangup(struct tty_struct *tty);
153static void set_termios(struct tty_struct *tty, struct termios *old_termios);
154
155static int write(struct tty_struct *tty, const unsigned char *buf, int count);
156static void put_char(struct tty_struct *tty, unsigned char ch);
157static void send_xchar(struct tty_struct *tty, char ch);
158static void wait_until_sent(struct tty_struct *tty, int timeout);
159static int write_room(struct tty_struct *tty);
160static void flush_chars(struct tty_struct *tty);
161static void flush_buffer(struct tty_struct *tty);
162static void tx_hold(struct tty_struct *tty);
163static void tx_release(struct tty_struct *tty);
164
165static int ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
166static int read_proc(char *page, char **start, off_t off, int count,int *eof, void *data);
167static int chars_in_buffer(struct tty_struct *tty);
168static void throttle(struct tty_struct * tty);
169static void unthrottle(struct tty_struct * tty);
170static void set_break(struct tty_struct *tty, int break_state);
171
172/*
173 * generic HDLC support and callbacks
174 */
175#ifdef CONFIG_HDLC
176#define dev_to_port(D) (dev_to_hdlc(D)->priv)
177static void hdlcdev_tx_done(struct slgt_info *info);
178static void hdlcdev_rx(struct slgt_info *info, char *buf, int size);
179static int hdlcdev_init(struct slgt_info *info);
180static void hdlcdev_exit(struct slgt_info *info);
181#endif
182
183
184/*
185 * device specific structures, macros and functions
186 */
187
188#define SLGT_MAX_PORTS 4
189#define SLGT_REG_SIZE 256
190
191/*
192 * DMA buffer descriptor and access macros
193 */
194struct slgt_desc
195{
196 unsigned short count;
197 unsigned short status;
198 unsigned int pbuf; /* physical address of data buffer */
199 unsigned int next; /* physical address of next descriptor */
200
201 /* driver book keeping */
202 char *buf; /* virtual address of data buffer */
203 unsigned int pdesc; /* physical address of this descriptor */
204 dma_addr_t buf_dma_addr;
205};
206
207#define set_desc_buffer(a,b) (a).pbuf = cpu_to_le32((unsigned int)(b))
208#define set_desc_next(a,b) (a).next = cpu_to_le32((unsigned int)(b))
209#define set_desc_count(a,b)(a).count = cpu_to_le16((unsigned short)(b))
210#define set_desc_eof(a,b) (a).status = cpu_to_le16((b) ? (le16_to_cpu((a).status) | BIT0) : (le16_to_cpu((a).status) & ~BIT0))
211#define desc_count(a) (le16_to_cpu((a).count))
212#define desc_status(a) (le16_to_cpu((a).status))
213#define desc_complete(a) (le16_to_cpu((a).status) & BIT15)
214#define desc_eof(a) (le16_to_cpu((a).status) & BIT2)
215#define desc_crc_error(a) (le16_to_cpu((a).status) & BIT1)
216#define desc_abort(a) (le16_to_cpu((a).status) & BIT0)
217#define desc_residue(a) ((le16_to_cpu((a).status) & 0x38) >> 3)
218
219struct _input_signal_events {
220 int ri_up;
221 int ri_down;
222 int dsr_up;
223 int dsr_down;
224 int dcd_up;
225 int dcd_down;
226 int cts_up;
227 int cts_down;
228};
229
230/*
231 * device instance data structure
232 */
233struct slgt_info {
234 void *if_ptr; /* General purpose pointer (used by SPPP) */
235
236 struct slgt_info *next_device; /* device list link */
237
238 int magic;
239 int flags;
240
241 char device_name[25];
242 struct pci_dev *pdev;
243
244 int port_count; /* count of ports on adapter */
245 int adapter_num; /* adapter instance number */
246 int port_num; /* port instance number */
247
248 /* array of pointers to port contexts on this adapter */
249 struct slgt_info *port_array[SLGT_MAX_PORTS];
250
251 int count; /* count of opens */
252 int line; /* tty line instance number */
253 unsigned short close_delay;
254 unsigned short closing_wait; /* time to wait before closing */
255
256 struct mgsl_icount icount;
257
258 struct tty_struct *tty;
259 int timeout;
260 int x_char; /* xon/xoff character */
261 int blocked_open; /* # of blocked opens */
262 unsigned int read_status_mask;
263 unsigned int ignore_status_mask;
264
265 wait_queue_head_t open_wait;
266 wait_queue_head_t close_wait;
267
268 wait_queue_head_t status_event_wait_q;
269 wait_queue_head_t event_wait_q;
270 struct timer_list tx_timer;
271 struct timer_list rx_timer;
272
273 spinlock_t lock; /* spinlock for synchronizing with ISR */
274
275 struct work_struct task;
276 u32 pending_bh;
277 int bh_requested;
278 int bh_running;
279
280 int isr_overflow;
281 int irq_requested; /* nonzero if IRQ requested */
282 int irq_occurred; /* for diagnostics use */
283
284 /* device configuration */
285
286 unsigned int bus_type;
287 unsigned int irq_level;
288 unsigned long irq_flags;
289
290 unsigned char __iomem * reg_addr; /* memory mapped registers address */
291 u32 phys_reg_addr;
292 u32 reg_offset;
293 int reg_addr_requested;
294
295 MGSL_PARAMS params; /* communications parameters */
296 u32 idle_mode;
297 u32 max_frame_size; /* as set by device config */
298
299 unsigned int raw_rx_size;
300 unsigned int if_mode;
301
302 /* device status */
303
304 int rx_enabled;
305 int rx_restart;
306
307 int tx_enabled;
308 int tx_active;
309
310 unsigned char signals; /* serial signal states */
311 unsigned int init_error; /* initialization error */
312
313 unsigned char *tx_buf;
314 int tx_count;
315
316 char flag_buf[MAX_ASYNC_BUFFER_SIZE];
317 char char_buf[MAX_ASYNC_BUFFER_SIZE];
318 BOOLEAN drop_rts_on_tx_done;
319 struct _input_signal_events input_signal_events;
320
321 int dcd_chkcount; /* check counts to prevent */
322 int cts_chkcount; /* too many IRQs if a signal */
323 int dsr_chkcount; /* is floating */
324 int ri_chkcount;
325
326 char *bufs; /* virtual address of DMA buffer lists */
327 dma_addr_t bufs_dma_addr; /* physical address of buffer descriptors */
328
329 unsigned int rbuf_count;
330 struct slgt_desc *rbufs;
331 unsigned int rbuf_current;
332 unsigned int rbuf_index;
333
334 unsigned int tbuf_count;
335 struct slgt_desc *tbufs;
336 unsigned int tbuf_current;
337 unsigned int tbuf_start;
338
339 unsigned char *tmp_rbuf;
340 unsigned int tmp_rbuf_count;
341
342 /* SPPP/Cisco HDLC device parts */
343
344 int netcount;
345 int dosyncppp;
346 spinlock_t netlock;
347#ifdef CONFIG_HDLC
348 struct net_device *netdev;
349#endif
350
351};
352
353static MGSL_PARAMS default_params = {
354 .mode = MGSL_MODE_HDLC,
355 .loopback = 0,
356 .flags = HDLC_FLAG_UNDERRUN_ABORT15,
357 .encoding = HDLC_ENCODING_NRZI_SPACE,
358 .clock_speed = 0,
359 .addr_filter = 0xff,
360 .crc_type = HDLC_CRC_16_CCITT,
361 .preamble_length = HDLC_PREAMBLE_LENGTH_8BITS,
362 .preamble = HDLC_PREAMBLE_PATTERN_NONE,
363 .data_rate = 9600,
364 .data_bits = 8,
365 .stop_bits = 1,
366 .parity = ASYNC_PARITY_NONE
367};
368
369
370#define BH_RECEIVE 1
371#define BH_TRANSMIT 2
372#define BH_STATUS 4
373#define IO_PIN_SHUTDOWN_LIMIT 100
374
375#define DMABUFSIZE 256
376#define DESC_LIST_SIZE 4096
377
378#define MASK_PARITY BIT1
379#define MASK_FRAMING BIT2
380#define MASK_BREAK BIT3
381#define MASK_OVERRUN BIT4
382
383#define GSR 0x00 /* global status */
384#define TDR 0x80 /* tx data */
385#define RDR 0x80 /* rx data */
386#define TCR 0x82 /* tx control */
387#define TIR 0x84 /* tx idle */
388#define TPR 0x85 /* tx preamble */
389#define RCR 0x86 /* rx control */
390#define VCR 0x88 /* V.24 control */
391#define CCR 0x89 /* clock control */
392#define BDR 0x8a /* baud divisor */
393#define SCR 0x8c /* serial control */
394#define SSR 0x8e /* serial status */
395#define RDCSR 0x90 /* rx DMA control/status */
396#define TDCSR 0x94 /* tx DMA control/status */
397#define RDDAR 0x98 /* rx DMA descriptor address */
398#define TDDAR 0x9c /* tx DMA descriptor address */
399
400#define RXIDLE BIT14
401#define RXBREAK BIT14
402#define IRQ_TXDATA BIT13
403#define IRQ_TXIDLE BIT12
404#define IRQ_TXUNDER BIT11 /* HDLC */
405#define IRQ_RXDATA BIT10
406#define IRQ_RXIDLE BIT9 /* HDLC */
407#define IRQ_RXBREAK BIT9 /* async */
408#define IRQ_RXOVER BIT8
409#define IRQ_DSR BIT7
410#define IRQ_CTS BIT6
411#define IRQ_DCD BIT5
412#define IRQ_RI BIT4
413#define IRQ_ALL 0x3ff0
414#define IRQ_MASTER BIT0
415
416#define slgt_irq_on(info, mask) \
417 wr_reg16((info), SCR, (unsigned short)(rd_reg16((info), SCR) | (mask)))
418#define slgt_irq_off(info, mask) \
419 wr_reg16((info), SCR, (unsigned short)(rd_reg16((info), SCR) & ~(mask)))
420
421static __u8 rd_reg8(struct slgt_info *info, unsigned int addr);
422static void wr_reg8(struct slgt_info *info, unsigned int addr, __u8 value);
423static __u16 rd_reg16(struct slgt_info *info, unsigned int addr);
424static void wr_reg16(struct slgt_info *info, unsigned int addr, __u16 value);
425static __u32 rd_reg32(struct slgt_info *info, unsigned int addr);
426static void wr_reg32(struct slgt_info *info, unsigned int addr, __u32 value);
427
428static void msc_set_vcr(struct slgt_info *info);
429
430static int startup(struct slgt_info *info);
431static int block_til_ready(struct tty_struct *tty, struct file * filp,struct slgt_info *info);
432static void shutdown(struct slgt_info *info);
433static void program_hw(struct slgt_info *info);
434static void change_params(struct slgt_info *info);
435
436static int register_test(struct slgt_info *info);
437static int irq_test(struct slgt_info *info);
438static int loopback_test(struct slgt_info *info);
439static int adapter_test(struct slgt_info *info);
440
441static void reset_adapter(struct slgt_info *info);
442static void reset_port(struct slgt_info *info);
443static void async_mode(struct slgt_info *info);
444static void hdlc_mode(struct slgt_info *info);
445
446static void rx_stop(struct slgt_info *info);
447static void rx_start(struct slgt_info *info);
448static void reset_rbufs(struct slgt_info *info);
449static void free_rbufs(struct slgt_info *info, unsigned int first, unsigned int last);
450static void rdma_reset(struct slgt_info *info);
451static int rx_get_frame(struct slgt_info *info);
452static int rx_get_buf(struct slgt_info *info);
453
454static void tx_start(struct slgt_info *info);
455static void tx_stop(struct slgt_info *info);
456static void tx_set_idle(struct slgt_info *info);
457static unsigned int free_tbuf_count(struct slgt_info *info);
458static void reset_tbufs(struct slgt_info *info);
459static void tdma_reset(struct slgt_info *info);
460static void tx_load(struct slgt_info *info, const char *buf, unsigned int count);
461
462static void get_signals(struct slgt_info *info);
463static void set_signals(struct slgt_info *info);
464static void enable_loopback(struct slgt_info *info);
465static void set_rate(struct slgt_info *info, u32 data_rate);
466
467static int bh_action(struct slgt_info *info);
468static void bh_handler(void* context);
469static void bh_transmit(struct slgt_info *info);
470static void isr_serial(struct slgt_info *info);
471static void isr_rdma(struct slgt_info *info);
472static void isr_txeom(struct slgt_info *info, unsigned short status);
473static void isr_tdma(struct slgt_info *info);
474static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs);
475
476static int alloc_dma_bufs(struct slgt_info *info);
477static void free_dma_bufs(struct slgt_info *info);
478static int alloc_desc(struct slgt_info *info);
479static void free_desc(struct slgt_info *info);
480static int alloc_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count);
481static void free_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count);
482
483static int alloc_tmp_rbuf(struct slgt_info *info);
484static void free_tmp_rbuf(struct slgt_info *info);
485
486static void tx_timeout(unsigned long context);
487static void rx_timeout(unsigned long context);
488
489/*
490 * ioctl handlers
491 */
492static int get_stats(struct slgt_info *info, struct mgsl_icount __user *user_icount);
493static int get_params(struct slgt_info *info, MGSL_PARAMS __user *params);
494static int set_params(struct slgt_info *info, MGSL_PARAMS __user *params);
495static int get_txidle(struct slgt_info *info, int __user *idle_mode);
496static int set_txidle(struct slgt_info *info, int idle_mode);
497static int tx_enable(struct slgt_info *info, int enable);
498static int tx_abort(struct slgt_info *info);
499static int rx_enable(struct slgt_info *info, int enable);
500static int modem_input_wait(struct slgt_info *info,int arg);
501static int wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr);
502static int tiocmget(struct tty_struct *tty, struct file *file);
503static int tiocmset(struct tty_struct *tty, struct file *file,
504 unsigned int set, unsigned int clear);
505static void set_break(struct tty_struct *tty, int break_state);
506static int get_interface(struct slgt_info *info, int __user *if_mode);
507static int set_interface(struct slgt_info *info, int if_mode);
508
509/*
510 * driver functions
511 */
512static void add_device(struct slgt_info *info);
513static void device_init(int adapter_num, struct pci_dev *pdev);
514static int claim_resources(struct slgt_info *info);
515static void release_resources(struct slgt_info *info);
516
517/*
518 * DEBUG OUTPUT CODE
519 */
520#ifndef DBGINFO
521#define DBGINFO(fmt)
522#endif
523#ifndef DBGERR
524#define DBGERR(fmt)
525#endif
526#ifndef DBGBH
527#define DBGBH(fmt)
528#endif
529#ifndef DBGISR
530#define DBGISR(fmt)
531#endif
532
533#ifdef DBGDATA
534static void trace_block(struct slgt_info *info, const char *data, int count, const char *label)
535{
536 int i;
537 int linecount;
538 printk("%s %s data:\n",info->device_name, label);
539 while(count) {
540 linecount = (count > 16) ? 16 : count;
541 for(i=0; i < linecount; i++)
542 printk("%02X ",(unsigned char)data[i]);
543 for(;i<17;i++)
544 printk(" ");
545 for(i=0;i<linecount;i++) {
546 if (data[i]>=040 && data[i]<=0176)
547 printk("%c",data[i]);
548 else
549 printk(".");
550 }
551 printk("\n");
552 data += linecount;
553 count -= linecount;
554 }
555}
556#else
557#define DBGDATA(info, buf, size, label)
558#endif
559
560#ifdef DBGTBUF
561static void dump_tbufs(struct slgt_info *info)
562{
563 int i;
564 printk("tbuf_current=%d\n", info->tbuf_current);
565 for (i=0 ; i < info->tbuf_count ; i++) {
566 printk("%d: count=%04X status=%04X\n",
567 i, le16_to_cpu(info->tbufs[i].count), le16_to_cpu(info->tbufs[i].status));
568 }
569}
570#else
571#define DBGTBUF(info)
572#endif
573
574#ifdef DBGRBUF
575static void dump_rbufs(struct slgt_info *info)
576{
577 int i;
578 printk("rbuf_current=%d\n", info->rbuf_current);
579 for (i=0 ; i < info->rbuf_count ; i++) {
580 printk("%d: count=%04X status=%04X\n",
581 i, le16_to_cpu(info->rbufs[i].count), le16_to_cpu(info->rbufs[i].status));
582 }
583}
584#else
585#define DBGRBUF(info)
586#endif
587
588static inline int sanity_check(struct slgt_info *info, char *devname, const char *name)
589{
590#ifdef SANITY_CHECK
591 if (!info) {
592 printk("null struct slgt_info for (%s) in %s\n", devname, name);
593 return 1;
594 }
595 if (info->magic != MGSL_MAGIC) {
596 printk("bad magic number struct slgt_info (%s) in %s\n", devname, name);
597 return 1;
598 }
599#else
600 if (!info)
601 return 1;
602#endif
603 return 0;
604}
605
606/**
607 * line discipline callback wrappers
608 *
609 * The wrappers maintain line discipline references
610 * while calling into the line discipline.
611 *
612 * ldisc_receive_buf - pass receive data to line discipline
613 */
614static void ldisc_receive_buf(struct tty_struct *tty,
615 const __u8 *data, char *flags, int count)
616{
617 struct tty_ldisc *ld;
618 if (!tty)
619 return;
620 ld = tty_ldisc_ref(tty);
621 if (ld) {
622 if (ld->receive_buf)
623 ld->receive_buf(tty, data, flags, count);
624 tty_ldisc_deref(ld);
625 }
626}
627
628/* tty callbacks */
629
630static int open(struct tty_struct *tty, struct file *filp)
631{
632 struct slgt_info *info;
633 int retval, line;
634 unsigned long flags;
635
636 line = tty->index;
637 if ((line < 0) || (line >= slgt_device_count)) {
638 DBGERR(("%s: open with invalid line #%d.\n", driver_name, line));
639 return -ENODEV;
640 }
641
642 info = slgt_device_list;
643 while(info && info->line != line)
644 info = info->next_device;
645 if (sanity_check(info, tty->name, "open"))
646 return -ENODEV;
647 if (info->init_error) {
648 DBGERR(("%s init error=%d\n", info->device_name, info->init_error));
649 return -ENODEV;
650 }
651
652 tty->driver_data = info;
653 info->tty = tty;
654
655 DBGINFO(("%s open, old ref count = %d\n", info->device_name, info->count));
656
657 /* If port is closing, signal caller to try again */
658 if (tty_hung_up_p(filp) || info->flags & ASYNC_CLOSING){
659 if (info->flags & ASYNC_CLOSING)
660 interruptible_sleep_on(&info->close_wait);
661 retval = ((info->flags & ASYNC_HUP_NOTIFY) ?
662 -EAGAIN : -ERESTARTSYS);
663 goto cleanup;
664 }
665
666 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
667
668 spin_lock_irqsave(&info->netlock, flags);
669 if (info->netcount) {
670 retval = -EBUSY;
671 spin_unlock_irqrestore(&info->netlock, flags);
672 goto cleanup;
673 }
674 info->count++;
675 spin_unlock_irqrestore(&info->netlock, flags);
676
677 if (info->count == 1) {
678 /* 1st open on this device, init hardware */
679 retval = startup(info);
680 if (retval < 0)
681 goto cleanup;
682 }
683
684 retval = block_til_ready(tty, filp, info);
685 if (retval) {
686 DBGINFO(("%s block_til_ready rc=%d\n", info->device_name, retval));
687 goto cleanup;
688 }
689
690 retval = 0;
691
692cleanup:
693 if (retval) {
694 if (tty->count == 1)
695 info->tty = NULL; /* tty layer will release tty struct */
696 if(info->count)
697 info->count--;
698 }
699
700 DBGINFO(("%s open rc=%d\n", info->device_name, retval));
701 return retval;
702}
703
704static void close(struct tty_struct *tty, struct file *filp)
705{
706 struct slgt_info *info = tty->driver_data;
707
708 if (sanity_check(info, tty->name, "close"))
709 return;
710 DBGINFO(("%s close entry, count=%d\n", info->device_name, info->count));
711
712 if (!info->count)
713 return;
714
715 if (tty_hung_up_p(filp))
716 goto cleanup;
717
718 if ((tty->count == 1) && (info->count != 1)) {
719 /*
720 * tty->count is 1 and the tty structure will be freed.
721 * info->count should be one in this case.
722 * if it's not, correct it so that the port is shutdown.
723 */
724 DBGERR(("%s close: bad refcount; tty->count=1, "
725 "info->count=%d\n", info->device_name, info->count));
726 info->count = 1;
727 }
728
729 info->count--;
730
731 /* if at least one open remaining, leave hardware active */
732 if (info->count)
733 goto cleanup;
734
735 info->flags |= ASYNC_CLOSING;
736
737 /* set tty->closing to notify line discipline to
738 * only process XON/XOFF characters. Only the N_TTY
739 * discipline appears to use this (ppp does not).
740 */
741 tty->closing = 1;
742
743 /* wait for transmit data to clear all layers */
744
745 if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
746 DBGINFO(("%s call tty_wait_until_sent\n", info->device_name));
747 tty_wait_until_sent(tty, info->closing_wait);
748 }
749
750 if (info->flags & ASYNC_INITIALIZED)
751 wait_until_sent(tty, info->timeout);
752 if (tty->driver->flush_buffer)
753 tty->driver->flush_buffer(tty);
754 tty_ldisc_flush(tty);
755
756 shutdown(info);
757
758 tty->closing = 0;
759 info->tty = NULL;
760
761 if (info->blocked_open) {
762 if (info->close_delay) {
763 msleep_interruptible(jiffies_to_msecs(info->close_delay));
764 }
765 wake_up_interruptible(&info->open_wait);
766 }
767
768 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
769
770 wake_up_interruptible(&info->close_wait);
771
772cleanup:
773 DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->count));
774}
775
776static void hangup(struct tty_struct *tty)
777{
778 struct slgt_info *info = tty->driver_data;
779
780 if (sanity_check(info, tty->name, "hangup"))
781 return;
782 DBGINFO(("%s hangup\n", info->device_name));
783
784 flush_buffer(tty);
785 shutdown(info);
786
787 info->count = 0;
788 info->flags &= ~ASYNC_NORMAL_ACTIVE;
789 info->tty = NULL;
790
791 wake_up_interruptible(&info->open_wait);
792}
793
794static void set_termios(struct tty_struct *tty, struct termios *old_termios)
795{
796 struct slgt_info *info = tty->driver_data;
797 unsigned long flags;
798
799 DBGINFO(("%s set_termios\n", tty->driver->name));
800
801 /* just return if nothing has changed */
802 if ((tty->termios->c_cflag == old_termios->c_cflag)
803 && (RELEVANT_IFLAG(tty->termios->c_iflag)
804 == RELEVANT_IFLAG(old_termios->c_iflag)))
805 return;
806
807 change_params(info);
808
809 /* Handle transition to B0 status */
810 if (old_termios->c_cflag & CBAUD &&
811 !(tty->termios->c_cflag & CBAUD)) {
812 info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR);
813 spin_lock_irqsave(&info->lock,flags);
814 set_signals(info);
815 spin_unlock_irqrestore(&info->lock,flags);
816 }
817
818 /* Handle transition away from B0 status */
819 if (!(old_termios->c_cflag & CBAUD) &&
820 tty->termios->c_cflag & CBAUD) {
821 info->signals |= SerialSignal_DTR;
822 if (!(tty->termios->c_cflag & CRTSCTS) ||
823 !test_bit(TTY_THROTTLED, &tty->flags)) {
824 info->signals |= SerialSignal_RTS;
825 }
826 spin_lock_irqsave(&info->lock,flags);
827 set_signals(info);
828 spin_unlock_irqrestore(&info->lock,flags);
829 }
830
831 /* Handle turning off CRTSCTS */
832 if (old_termios->c_cflag & CRTSCTS &&
833 !(tty->termios->c_cflag & CRTSCTS)) {
834 tty->hw_stopped = 0;
835 tx_release(tty);
836 }
837}
838
839static int write(struct tty_struct *tty,
840 const unsigned char *buf, int count)
841{
842 int ret = 0;
843 struct slgt_info *info = tty->driver_data;
844 unsigned long flags;
845
846 if (sanity_check(info, tty->name, "write"))
847 goto cleanup;
848 DBGINFO(("%s write count=%d\n", info->device_name, count));
849
850 if (!tty || !info->tx_buf)
851 goto cleanup;
852
853 if (count > info->max_frame_size) {
854 ret = -EIO;
855 goto cleanup;
856 }
857
858 if (!count)
859 goto cleanup;
860
861 if (info->params.mode == MGSL_MODE_RAW) {
862 unsigned int bufs_needed = (count/DMABUFSIZE);
863 unsigned int bufs_free = free_tbuf_count(info);
864 if (count % DMABUFSIZE)
865 ++bufs_needed;
866 if (bufs_needed > bufs_free)
867 goto cleanup;
868 } else {
869 if (info->tx_active)
870 goto cleanup;
871 if (info->tx_count) {
872 /* send accumulated data from send_char() calls */
873 /* as frame and wait before accepting more data. */
874 tx_load(info, info->tx_buf, info->tx_count);
875 goto start;
876 }
877 }
878
879 ret = info->tx_count = count;
880 tx_load(info, buf, count);
881 goto start;
882
883start:
884 if (info->tx_count && !tty->stopped && !tty->hw_stopped) {
885 spin_lock_irqsave(&info->lock,flags);
886 if (!info->tx_active)
887 tx_start(info);
888 spin_unlock_irqrestore(&info->lock,flags);
889 }
890
891cleanup:
892 DBGINFO(("%s write rc=%d\n", info->device_name, ret));
893 return ret;
894}
895
896static void put_char(struct tty_struct *tty, unsigned char ch)
897{
898 struct slgt_info *info = tty->driver_data;
899 unsigned long flags;
900
901 if (sanity_check(info, tty->name, "put_char"))
902 return;
903 DBGINFO(("%s put_char(%d)\n", info->device_name, ch));
904 if (!tty || !info->tx_buf)
905 return;
906 spin_lock_irqsave(&info->lock,flags);
907 if (!info->tx_active && (info->tx_count < info->max_frame_size))
908 info->tx_buf[info->tx_count++] = ch;
909 spin_unlock_irqrestore(&info->lock,flags);
910}
911
912static void send_xchar(struct tty_struct *tty, char ch)
913{
914 struct slgt_info *info = tty->driver_data;
915 unsigned long flags;
916
917 if (sanity_check(info, tty->name, "send_xchar"))
918 return;
919 DBGINFO(("%s send_xchar(%d)\n", info->device_name, ch));
920 info->x_char = ch;
921 if (ch) {
922 spin_lock_irqsave(&info->lock,flags);
923 if (!info->tx_enabled)
924 tx_start(info);
925 spin_unlock_irqrestore(&info->lock,flags);
926 }
927}
928
929static void wait_until_sent(struct tty_struct *tty, int timeout)
930{
931 struct slgt_info *info = tty->driver_data;
932 unsigned long orig_jiffies, char_time;
933
934 if (!info )
935 return;
936 if (sanity_check(info, tty->name, "wait_until_sent"))
937 return;
938 DBGINFO(("%s wait_until_sent entry\n", info->device_name));
939 if (!(info->flags & ASYNC_INITIALIZED))
940 goto exit;
941
942 orig_jiffies = jiffies;
943
944 /* Set check interval to 1/5 of estimated time to
945 * send a character, and make it at least 1. The check
946 * interval should also be less than the timeout.
947 * Note: use tight timings here to satisfy the NIST-PCTS.
948 */
949
950 if (info->params.data_rate) {
951 char_time = info->timeout/(32 * 5);
952 if (!char_time)
953 char_time++;
954 } else
955 char_time = 1;
956
957 if (timeout)
958 char_time = min_t(unsigned long, char_time, timeout);
959
960 while (info->tx_active) {
961 msleep_interruptible(jiffies_to_msecs(char_time));
962 if (signal_pending(current))
963 break;
964 if (timeout && time_after(jiffies, orig_jiffies + timeout))
965 break;
966 }
967
968exit:
969 DBGINFO(("%s wait_until_sent exit\n", info->device_name));
970}
971
972static int write_room(struct tty_struct *tty)
973{
974 struct slgt_info *info = tty->driver_data;
975 int ret;
976
977 if (sanity_check(info, tty->name, "write_room"))
978 return 0;
979 ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE;
980 DBGINFO(("%s write_room=%d\n", info->device_name, ret));
981 return ret;
982}
983
984static void flush_chars(struct tty_struct *tty)
985{
986 struct slgt_info *info = tty->driver_data;
987 unsigned long flags;
988
989 if (sanity_check(info, tty->name, "flush_chars"))
990 return;
991 DBGINFO(("%s flush_chars entry tx_count=%d\n", info->device_name, info->tx_count));
992
993 if (info->tx_count <= 0 || tty->stopped ||
994 tty->hw_stopped || !info->tx_buf)
995 return;
996
997 DBGINFO(("%s flush_chars start transmit\n", info->device_name));
998
999 spin_lock_irqsave(&info->lock,flags);
1000 if (!info->tx_active && info->tx_count) {
1001 tx_load(info, info->tx_buf,info->tx_count);
1002 tx_start(info);
1003 }
1004 spin_unlock_irqrestore(&info->lock,flags);
1005}
1006
1007static void flush_buffer(struct tty_struct *tty)
1008{
1009 struct slgt_info *info = tty->driver_data;
1010 unsigned long flags;
1011
1012 if (sanity_check(info, tty->name, "flush_buffer"))
1013 return;
1014 DBGINFO(("%s flush_buffer\n", info->device_name));
1015
1016 spin_lock_irqsave(&info->lock,flags);
1017 if (!info->tx_active)
1018 info->tx_count = 0;
1019 spin_unlock_irqrestore(&info->lock,flags);
1020
1021 wake_up_interruptible(&tty->write_wait);
1022 tty_wakeup(tty);
1023}
1024
1025/*
1026 * throttle (stop) transmitter
1027 */
1028static void tx_hold(struct tty_struct *tty)
1029{
1030 struct slgt_info *info = tty->driver_data;
1031 unsigned long flags;
1032
1033 if (sanity_check(info, tty->name, "tx_hold"))
1034 return;
1035 DBGINFO(("%s tx_hold\n", info->device_name));
1036 spin_lock_irqsave(&info->lock,flags);
1037 if (info->tx_enabled && info->params.mode == MGSL_MODE_ASYNC)
1038 tx_stop(info);
1039 spin_unlock_irqrestore(&info->lock,flags);
1040}
1041
1042/*
1043 * release (start) transmitter
1044 */
1045static void tx_release(struct tty_struct *tty)
1046{
1047 struct slgt_info *info = tty->driver_data;
1048 unsigned long flags;
1049
1050 if (sanity_check(info, tty->name, "tx_release"))
1051 return;
1052 DBGINFO(("%s tx_release\n", info->device_name));
1053 spin_lock_irqsave(&info->lock,flags);
1054 if (!info->tx_active && info->tx_count) {
1055 tx_load(info, info->tx_buf, info->tx_count);
1056 tx_start(info);
1057 }
1058 spin_unlock_irqrestore(&info->lock,flags);
1059}
1060
1061/*
1062 * Service an IOCTL request
1063 *
1064 * Arguments
1065 *
1066 * tty pointer to tty instance data
1067 * file pointer to associated file object for device
1068 * cmd IOCTL command code
1069 * arg command argument/context
1070 *
1071 * Return 0 if success, otherwise error code
1072 */
1073static int ioctl(struct tty_struct *tty, struct file *file,
1074 unsigned int cmd, unsigned long arg)
1075{
1076 struct slgt_info *info = tty->driver_data;
1077 struct mgsl_icount cnow; /* kernel counter temps */
1078 struct serial_icounter_struct __user *p_cuser; /* user space */
1079 unsigned long flags;
1080 void __user *argp = (void __user *)arg;
1081
1082 if (sanity_check(info, tty->name, "ioctl"))
1083 return -ENODEV;
1084 DBGINFO(("%s ioctl() cmd=%08X\n", info->device_name, cmd));
1085
1086 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
1087 (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
1088 if (tty->flags & (1 << TTY_IO_ERROR))
1089 return -EIO;
1090 }
1091
1092 switch (cmd) {
1093 case MGSL_IOCGPARAMS:
1094 return get_params(info, argp);
1095 case MGSL_IOCSPARAMS:
1096 return set_params(info, argp);
1097 case MGSL_IOCGTXIDLE:
1098 return get_txidle(info, argp);
1099 case MGSL_IOCSTXIDLE:
1100 return set_txidle(info, (int)arg);
1101 case MGSL_IOCTXENABLE:
1102 return tx_enable(info, (int)arg);
1103 case MGSL_IOCRXENABLE:
1104 return rx_enable(info, (int)arg);
1105 case MGSL_IOCTXABORT:
1106 return tx_abort(info);
1107 case MGSL_IOCGSTATS:
1108 return get_stats(info, argp);
1109 case MGSL_IOCWAITEVENT:
1110 return wait_mgsl_event(info, argp);
1111 case TIOCMIWAIT:
1112 return modem_input_wait(info,(int)arg);
1113 case MGSL_IOCGIF:
1114 return get_interface(info, argp);
1115 case MGSL_IOCSIF:
1116 return set_interface(info,(int)arg);
1117 case TIOCGICOUNT:
1118 spin_lock_irqsave(&info->lock,flags);
1119 cnow = info->icount;
1120 spin_unlock_irqrestore(&info->lock,flags);
1121 p_cuser = argp;
1122 if (put_user(cnow.cts, &p_cuser->cts) ||
1123 put_user(cnow.dsr, &p_cuser->dsr) ||
1124 put_user(cnow.rng, &p_cuser->rng) ||
1125 put_user(cnow.dcd, &p_cuser->dcd) ||
1126 put_user(cnow.rx, &p_cuser->rx) ||
1127 put_user(cnow.tx, &p_cuser->tx) ||
1128 put_user(cnow.frame, &p_cuser->frame) ||
1129 put_user(cnow.overrun, &p_cuser->overrun) ||
1130 put_user(cnow.parity, &p_cuser->parity) ||
1131 put_user(cnow.brk, &p_cuser->brk) ||
1132 put_user(cnow.buf_overrun, &p_cuser->buf_overrun))
1133 return -EFAULT;
1134 return 0;
1135 default:
1136 return -ENOIOCTLCMD;
1137 }
1138 return 0;
1139}
1140
1141/*
1142 * proc fs support
1143 */
1144static inline int line_info(char *buf, struct slgt_info *info)
1145{
1146 char stat_buf[30];
1147 int ret;
1148 unsigned long flags;
1149
1150 ret = sprintf(buf, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n",
1151 info->device_name, info->phys_reg_addr,
1152 info->irq_level, info->max_frame_size);
1153
1154 /* output current serial signal states */
1155 spin_lock_irqsave(&info->lock,flags);
1156 get_signals(info);
1157 spin_unlock_irqrestore(&info->lock,flags);
1158
1159 stat_buf[0] = 0;
1160 stat_buf[1] = 0;
1161 if (info->signals & SerialSignal_RTS)
1162 strcat(stat_buf, "|RTS");
1163 if (info->signals & SerialSignal_CTS)
1164 strcat(stat_buf, "|CTS");
1165 if (info->signals & SerialSignal_DTR)
1166 strcat(stat_buf, "|DTR");
1167 if (info->signals & SerialSignal_DSR)
1168 strcat(stat_buf, "|DSR");
1169 if (info->signals & SerialSignal_DCD)
1170 strcat(stat_buf, "|CD");
1171 if (info->signals & SerialSignal_RI)
1172 strcat(stat_buf, "|RI");
1173
1174 if (info->params.mode != MGSL_MODE_ASYNC) {
1175 ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d",
1176 info->icount.txok, info->icount.rxok);
1177 if (info->icount.txunder)
1178 ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
1179 if (info->icount.txabort)
1180 ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
1181 if (info->icount.rxshort)
1182 ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
1183 if (info->icount.rxlong)
1184 ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
1185 if (info->icount.rxover)
1186 ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
1187 if (info->icount.rxcrc)
1188 ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
1189 } else {
1190 ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d",
1191 info->icount.tx, info->icount.rx);
1192 if (info->icount.frame)
1193 ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
1194 if (info->icount.parity)
1195 ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
1196 if (info->icount.brk)
1197 ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
1198 if (info->icount.overrun)
1199 ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
1200 }
1201
1202 /* Append serial signal status to end */
1203 ret += sprintf(buf+ret, " %s\n", stat_buf+1);
1204
1205 ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
1206 info->tx_active,info->bh_requested,info->bh_running,
1207 info->pending_bh);
1208
1209 return ret;
1210}
1211
1212/* Called to print information about devices
1213 */
1214static int read_proc(char *page, char **start, off_t off, int count,
1215 int *eof, void *data)
1216{
1217 int len = 0, l;
1218 off_t begin = 0;
1219 struct slgt_info *info;
1220
1221 len += sprintf(page, "synclink_gt driver:%s\n", driver_version);
1222
1223 info = slgt_device_list;
1224 while( info ) {
1225 l = line_info(page + len, info);
1226 len += l;
1227 if (len+begin > off+count)
1228 goto done;
1229 if (len+begin < off) {
1230 begin += len;
1231 len = 0;
1232 }
1233 info = info->next_device;
1234 }
1235
1236 *eof = 1;
1237done:
1238 if (off >= len+begin)
1239 return 0;
1240 *start = page + (off-begin);
1241 return ((count < begin+len-off) ? count : begin+len-off);
1242}
1243
1244/*
1245 * return count of bytes in transmit buffer
1246 */
1247static int chars_in_buffer(struct tty_struct *tty)
1248{
1249 struct slgt_info *info = tty->driver_data;
1250 if (sanity_check(info, tty->name, "chars_in_buffer"))
1251 return 0;
1252 DBGINFO(("%s chars_in_buffer()=%d\n", info->device_name, info->tx_count));
1253 return info->tx_count;
1254}
1255
1256/*
1257 * signal remote device to throttle send data (our receive data)
1258 */
1259static void throttle(struct tty_struct * tty)
1260{
1261 struct slgt_info *info = tty->driver_data;
1262 unsigned long flags;
1263
1264 if (sanity_check(info, tty->name, "throttle"))
1265 return;
1266 DBGINFO(("%s throttle\n", info->device_name));
1267 if (I_IXOFF(tty))
1268 send_xchar(tty, STOP_CHAR(tty));
1269 if (tty->termios->c_cflag & CRTSCTS) {
1270 spin_lock_irqsave(&info->lock,flags);
1271 info->signals &= ~SerialSignal_RTS;
1272 set_signals(info);
1273 spin_unlock_irqrestore(&info->lock,flags);
1274 }
1275}
1276
1277/*
1278 * signal remote device to stop throttling send data (our receive data)
1279 */
1280static void unthrottle(struct tty_struct * tty)
1281{
1282 struct slgt_info *info = tty->driver_data;
1283 unsigned long flags;
1284
1285 if (sanity_check(info, tty->name, "unthrottle"))
1286 return;
1287 DBGINFO(("%s unthrottle\n", info->device_name));
1288 if (I_IXOFF(tty)) {
1289 if (info->x_char)
1290 info->x_char = 0;
1291 else
1292 send_xchar(tty, START_CHAR(tty));
1293 }
1294 if (tty->termios->c_cflag & CRTSCTS) {
1295 spin_lock_irqsave(&info->lock,flags);
1296 info->signals |= SerialSignal_RTS;
1297 set_signals(info);
1298 spin_unlock_irqrestore(&info->lock,flags);
1299 }
1300}
1301
1302/*
1303 * set or clear transmit break condition
1304 * break_state -1=set break condition, 0=clear
1305 */
1306static void set_break(struct tty_struct *tty, int break_state)
1307{
1308 struct slgt_info *info = tty->driver_data;
1309 unsigned short value;
1310 unsigned long flags;
1311
1312 if (sanity_check(info, tty->name, "set_break"))
1313 return;
1314 DBGINFO(("%s set_break(%d)\n", info->device_name, break_state));
1315
1316 spin_lock_irqsave(&info->lock,flags);
1317 value = rd_reg16(info, TCR);
1318 if (break_state == -1)
1319 value |= BIT6;
1320 else
1321 value &= ~BIT6;
1322 wr_reg16(info, TCR, value);
1323 spin_unlock_irqrestore(&info->lock,flags);
1324}
1325
1326#ifdef CONFIG_HDLC
1327
1328/**
1329 * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
1330 * set encoding and frame check sequence (FCS) options
1331 *
1332 * dev pointer to network device structure
1333 * encoding serial encoding setting
1334 * parity FCS setting
1335 *
1336 * returns 0 if success, otherwise error code
1337 */
1338static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
1339 unsigned short parity)
1340{
1341 struct slgt_info *info = dev_to_port(dev);
1342 unsigned char new_encoding;
1343 unsigned short new_crctype;
1344
1345 /* return error if TTY interface open */
1346 if (info->count)
1347 return -EBUSY;
1348
1349 DBGINFO(("%s hdlcdev_attach\n", info->device_name));
1350
1351 switch (encoding)
1352 {
1353 case ENCODING_NRZ: new_encoding = HDLC_ENCODING_NRZ; break;
1354 case ENCODING_NRZI: new_encoding = HDLC_ENCODING_NRZI_SPACE; break;
1355 case ENCODING_FM_MARK: new_encoding = HDLC_ENCODING_BIPHASE_MARK; break;
1356 case ENCODING_FM_SPACE: new_encoding = HDLC_ENCODING_BIPHASE_SPACE; break;
1357 case ENCODING_MANCHESTER: new_encoding = HDLC_ENCODING_BIPHASE_LEVEL; break;
1358 default: return -EINVAL;
1359 }
1360
1361 switch (parity)
1362 {
1363 case PARITY_NONE: new_crctype = HDLC_CRC_NONE; break;
1364 case PARITY_CRC16_PR1_CCITT: new_crctype = HDLC_CRC_16_CCITT; break;
1365 case PARITY_CRC32_PR1_CCITT: new_crctype = HDLC_CRC_32_CCITT; break;
1366 default: return -EINVAL;
1367 }
1368
1369 info->params.encoding = new_encoding;
1370 info->params.crc_type = new_crctype;;
1371
1372 /* if network interface up, reprogram hardware */
1373 if (info->netcount)
1374 program_hw(info);
1375
1376 return 0;
1377}
1378
1379/**
1380 * called by generic HDLC layer to send frame
1381 *
1382 * skb socket buffer containing HDLC frame
1383 * dev pointer to network device structure
1384 *
1385 * returns 0 if success, otherwise error code
1386 */
1387static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
1388{
1389 struct slgt_info *info = dev_to_port(dev);
1390 struct net_device_stats *stats = hdlc_stats(dev);
1391 unsigned long flags;
1392
1393 DBGINFO(("%s hdlc_xmit\n", dev->name));
1394
1395 /* stop sending until this frame completes */
1396 netif_stop_queue(dev);
1397
1398 /* copy data to device buffers */
1399 info->tx_count = skb->len;
1400 tx_load(info, skb->data, skb->len);
1401
1402 /* update network statistics */
1403 stats->tx_packets++;
1404 stats->tx_bytes += skb->len;
1405
1406 /* done with socket buffer, so free it */
1407 dev_kfree_skb(skb);
1408
1409 /* save start time for transmit timeout detection */
1410 dev->trans_start = jiffies;
1411
1412 /* start hardware transmitter if necessary */
1413 spin_lock_irqsave(&info->lock,flags);
1414 if (!info->tx_active)
1415 tx_start(info);
1416 spin_unlock_irqrestore(&info->lock,flags);
1417
1418 return 0;
1419}
1420
1421/**
1422 * called by network layer when interface enabled
1423 * claim resources and initialize hardware
1424 *
1425 * dev pointer to network device structure
1426 *
1427 * returns 0 if success, otherwise error code
1428 */
1429static int hdlcdev_open(struct net_device *dev)
1430{
1431 struct slgt_info *info = dev_to_port(dev);
1432 int rc;
1433 unsigned long flags;
1434
1435 DBGINFO(("%s hdlcdev_open\n", dev->name));
1436
1437 /* generic HDLC layer open processing */
1438 if ((rc = hdlc_open(dev)))
1439 return rc;
1440
1441 /* arbitrate between network and tty opens */
1442 spin_lock_irqsave(&info->netlock, flags);
1443 if (info->count != 0 || info->netcount != 0) {
1444 DBGINFO(("%s hdlc_open busy\n", dev->name));
1445 spin_unlock_irqrestore(&info->netlock, flags);
1446 return -EBUSY;
1447 }
1448 info->netcount=1;
1449 spin_unlock_irqrestore(&info->netlock, flags);
1450
1451 /* claim resources and init adapter */
1452 if ((rc = startup(info)) != 0) {
1453 spin_lock_irqsave(&info->netlock, flags);
1454 info->netcount=0;
1455 spin_unlock_irqrestore(&info->netlock, flags);
1456 return rc;
1457 }
1458
1459 /* assert DTR and RTS, apply hardware settings */
1460 info->signals |= SerialSignal_RTS + SerialSignal_DTR;
1461 program_hw(info);
1462
1463 /* enable network layer transmit */
1464 dev->trans_start = jiffies;
1465 netif_start_queue(dev);
1466
1467 /* inform generic HDLC layer of current DCD status */
1468 spin_lock_irqsave(&info->lock, flags);
1469 get_signals(info);
1470 spin_unlock_irqrestore(&info->lock, flags);
1471 hdlc_set_carrier(info->signals & SerialSignal_DCD, dev);
1472
1473 return 0;
1474}
1475
1476/**
1477 * called by network layer when interface is disabled
1478 * shutdown hardware and release resources
1479 *
1480 * dev pointer to network device structure
1481 *
1482 * returns 0 if success, otherwise error code
1483 */
1484static int hdlcdev_close(struct net_device *dev)
1485{
1486 struct slgt_info *info = dev_to_port(dev);
1487 unsigned long flags;
1488
1489 DBGINFO(("%s hdlcdev_close\n", dev->name));
1490
1491 netif_stop_queue(dev);
1492
1493 /* shutdown adapter and release resources */
1494 shutdown(info);
1495
1496 hdlc_close(dev);
1497
1498 spin_lock_irqsave(&info->netlock, flags);
1499 info->netcount=0;
1500 spin_unlock_irqrestore(&info->netlock, flags);
1501
1502 return 0;
1503}
1504
1505/**
1506 * called by network layer to process IOCTL call to network device
1507 *
1508 * dev pointer to network device structure
1509 * ifr pointer to network interface request structure
1510 * cmd IOCTL command code
1511 *
1512 * returns 0 if success, otherwise error code
1513 */
1514static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1515{
1516 const size_t size = sizeof(sync_serial_settings);
1517 sync_serial_settings new_line;
1518 sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync;
1519 struct slgt_info *info = dev_to_port(dev);
1520 unsigned int flags;
1521
1522 DBGINFO(("%s hdlcdev_ioctl\n", dev->name));
1523
1524 /* return error if TTY interface open */
1525 if (info->count)
1526 return -EBUSY;
1527
1528 if (cmd != SIOCWANDEV)
1529 return hdlc_ioctl(dev, ifr, cmd);
1530
1531 switch(ifr->ifr_settings.type) {
1532 case IF_GET_IFACE: /* return current sync_serial_settings */
1533
1534 ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL;
1535 if (ifr->ifr_settings.size < size) {
1536 ifr->ifr_settings.size = size; /* data size wanted */
1537 return -ENOBUFS;
1538 }
1539
1540 flags = info->params.flags & (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL |
1541 HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN |
1542 HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL |
1543 HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN);
1544
1545 switch (flags){
1546 case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN): new_line.clock_type = CLOCK_EXT; break;
1547 case (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_INT; break;
1548 case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_TXINT; break;
1549 case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN): new_line.clock_type = CLOCK_TXFROMRX; break;
1550 default: new_line.clock_type = CLOCK_DEFAULT;
1551 }
1552
1553 new_line.clock_rate = info->params.clock_speed;
1554 new_line.loopback = info->params.loopback ? 1:0;
1555
1556 if (copy_to_user(line, &new_line, size))
1557 return -EFAULT;
1558 return 0;
1559
1560 case IF_IFACE_SYNC_SERIAL: /* set sync_serial_settings */
1561
1562 if(!capable(CAP_NET_ADMIN))
1563 return -EPERM;
1564 if (copy_from_user(&new_line, line, size))
1565 return -EFAULT;
1566
1567 switch (new_line.clock_type)
1568 {
1569 case CLOCK_EXT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN; break;
1570 case CLOCK_TXFROMRX: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN; break;
1571 case CLOCK_INT: flags = HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG; break;
1572 case CLOCK_TXINT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG; break;
1573 case CLOCK_DEFAULT: flags = info->params.flags &
1574 (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL |
1575 HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN |
1576 HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL |
1577 HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); break;
1578 default: return -EINVAL;
1579 }
1580
1581 if (new_line.loopback != 0 && new_line.loopback != 1)
1582 return -EINVAL;
1583
1584 info->params.flags &= ~(HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL |
1585 HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN |
1586 HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL |
1587 HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN);
1588 info->params.flags |= flags;
1589
1590 info->params.loopback = new_line.loopback;
1591
1592 if (flags & (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG))
1593 info->params.clock_speed = new_line.clock_rate;
1594 else
1595 info->params.clock_speed = 0;
1596
1597 /* if network interface up, reprogram hardware */
1598 if (info->netcount)
1599 program_hw(info);
1600 return 0;
1601
1602 default:
1603 return hdlc_ioctl(dev, ifr, cmd);
1604 }
1605}
1606
1607/**
1608 * called by network layer when transmit timeout is detected
1609 *
1610 * dev pointer to network device structure
1611 */
1612static void hdlcdev_tx_timeout(struct net_device *dev)
1613{
1614 struct slgt_info *info = dev_to_port(dev);
1615 struct net_device_stats *stats = hdlc_stats(dev);
1616 unsigned long flags;
1617
1618 DBGINFO(("%s hdlcdev_tx_timeout\n", dev->name));
1619
1620 stats->tx_errors++;
1621 stats->tx_aborted_errors++;
1622
1623 spin_lock_irqsave(&info->lock,flags);
1624 tx_stop(info);
1625 spin_unlock_irqrestore(&info->lock,flags);
1626
1627 netif_wake_queue(dev);
1628}
1629
1630/**
1631 * called by device driver when transmit completes
1632 * reenable network layer transmit if stopped
1633 *
1634 * info pointer to device instance information
1635 */
1636static void hdlcdev_tx_done(struct slgt_info *info)
1637{
1638 if (netif_queue_stopped(info->netdev))
1639 netif_wake_queue(info->netdev);
1640}
1641
1642/**
1643 * called by device driver when frame received
1644 * pass frame to network layer
1645 *
1646 * info pointer to device instance information
1647 * buf pointer to buffer contianing frame data
1648 * size count of data bytes in buf
1649 */
1650static void hdlcdev_rx(struct slgt_info *info, char *buf, int size)
1651{
1652 struct sk_buff *skb = dev_alloc_skb(size);
1653 struct net_device *dev = info->netdev;
1654 struct net_device_stats *stats = hdlc_stats(dev);
1655
1656 DBGINFO(("%s hdlcdev_rx\n", dev->name));
1657
1658 if (skb == NULL) {
1659 DBGERR(("%s: can't alloc skb, drop packet\n", dev->name));
1660 stats->rx_dropped++;
1661 return;
1662 }
1663
1664 memcpy(skb_put(skb, size),buf,size);
1665
1666 skb->protocol = hdlc_type_trans(skb, info->netdev);
1667
1668 stats->rx_packets++;
1669 stats->rx_bytes += size;
1670
1671 netif_rx(skb);
1672
1673 info->netdev->last_rx = jiffies;
1674}
1675
1676/**
1677 * called by device driver when adding device instance
1678 * do generic HDLC initialization
1679 *
1680 * info pointer to device instance information
1681 *
1682 * returns 0 if success, otherwise error code
1683 */
1684static int hdlcdev_init(struct slgt_info *info)
1685{
1686 int rc;
1687 struct net_device *dev;
1688 hdlc_device *hdlc;
1689
1690 /* allocate and initialize network and HDLC layer objects */
1691
1692 if (!(dev = alloc_hdlcdev(info))) {
1693 printk(KERN_ERR "%s hdlc device alloc failure\n", info->device_name);
1694 return -ENOMEM;
1695 }
1696
1697 /* for network layer reporting purposes only */
1698 dev->mem_start = info->phys_reg_addr;
1699 dev->mem_end = info->phys_reg_addr + SLGT_REG_SIZE - 1;
1700 dev->irq = info->irq_level;
1701
1702 /* network layer callbacks and settings */
1703 dev->do_ioctl = hdlcdev_ioctl;
1704 dev->open = hdlcdev_open;
1705 dev->stop = hdlcdev_close;
1706 dev->tx_timeout = hdlcdev_tx_timeout;
1707 dev->watchdog_timeo = 10*HZ;
1708 dev->tx_queue_len = 50;
1709
1710 /* generic HDLC layer callbacks and settings */
1711 hdlc = dev_to_hdlc(dev);
1712 hdlc->attach = hdlcdev_attach;
1713 hdlc->xmit = hdlcdev_xmit;
1714
1715 /* register objects with HDLC layer */
1716 if ((rc = register_hdlc_device(dev))) {
1717 printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__);
1718 free_netdev(dev);
1719 return rc;
1720 }
1721
1722 info->netdev = dev;
1723 return 0;
1724}
1725
1726/**
1727 * called by device driver when removing device instance
1728 * do generic HDLC cleanup
1729 *
1730 * info pointer to device instance information
1731 */
1732static void hdlcdev_exit(struct slgt_info *info)
1733{
1734 unregister_hdlc_device(info->netdev);
1735 free_netdev(info->netdev);
1736 info->netdev = NULL;
1737}
1738
1739#endif /* ifdef CONFIG_HDLC */
1740
1741/*
1742 * get async data from rx DMA buffers
1743 */
1744static void rx_async(struct slgt_info *info)
1745{
1746 struct tty_struct *tty = info->tty;
1747 struct mgsl_icount *icount = &info->icount;
1748 unsigned int start, end;
1749 unsigned char *p;
1750 unsigned char status;
1751 struct slgt_desc *bufs = info->rbufs;
1752 int i, count;
1753
1754 start = end = info->rbuf_current;
1755
1756 while(desc_complete(bufs[end])) {
1757 count = desc_count(bufs[end]) - info->rbuf_index;
1758 p = bufs[end].buf + info->rbuf_index;
1759
1760 DBGISR(("%s rx_async count=%d\n", info->device_name, count));
1761 DBGDATA(info, p, count, "rx");
1762
1763 for(i=0 ; i < count; i+=2, p+=2) {
1764 if (tty) {
1765 if (tty->flip.count >= TTY_FLIPBUF_SIZE)
1766 tty_flip_buffer_push(tty);
1767 if (tty->flip.count >= TTY_FLIPBUF_SIZE)
1768 break;
1769 *tty->flip.char_buf_ptr = *p;
1770 *tty->flip.flag_buf_ptr = 0;
1771 }
1772 icount->rx++;
1773
1774 if ((status = *(p+1) & (BIT9 + BIT8))) {
1775 if (status & BIT9)
1776 icount->parity++;
1777 else if (status & BIT8)
1778 icount->frame++;
1779 /* discard char if tty control flags say so */
1780 if (status & info->ignore_status_mask)
1781 continue;
1782 if (tty) {
1783 if (status & BIT9)
1784 *tty->flip.flag_buf_ptr = TTY_PARITY;
1785 else if (status & BIT8)
1786 *tty->flip.flag_buf_ptr = TTY_FRAME;
1787 }
1788 }
1789 if (tty) {
1790 tty->flip.flag_buf_ptr++;
1791 tty->flip.char_buf_ptr++;
1792 tty->flip.count++;
1793 }
1794 }
1795
1796 if (i < count) {
1797 /* receive buffer not completed */
1798 info->rbuf_index += i;
1799 info->rx_timer.expires = jiffies + 1;
1800 add_timer(&info->rx_timer);
1801 break;
1802 }
1803
1804 info->rbuf_index = 0;
1805 free_rbufs(info, end, end);
1806
1807 if (++end == info->rbuf_count)
1808 end = 0;
1809
1810 /* if entire list searched then no frame available */
1811 if (end == start)
1812 break;
1813 }
1814
1815 if (tty && tty->flip.count)
1816 tty_flip_buffer_push(tty);
1817}
1818
1819/*
1820 * return next bottom half action to perform
1821 */
1822static int bh_action(struct slgt_info *info)
1823{
1824 unsigned long flags;
1825 int rc;
1826
1827 spin_lock_irqsave(&info->lock,flags);
1828
1829 if (info->pending_bh & BH_RECEIVE) {
1830 info->pending_bh &= ~BH_RECEIVE;
1831 rc = BH_RECEIVE;
1832 } else if (info->pending_bh & BH_TRANSMIT) {
1833 info->pending_bh &= ~BH_TRANSMIT;
1834 rc = BH_TRANSMIT;
1835 } else if (info->pending_bh & BH_STATUS) {
1836 info->pending_bh &= ~BH_STATUS;
1837 rc = BH_STATUS;
1838 } else {
1839 /* Mark BH routine as complete */
1840 info->bh_running = 0;
1841 info->bh_requested = 0;
1842 rc = 0;
1843 }
1844
1845 spin_unlock_irqrestore(&info->lock,flags);
1846
1847 return rc;
1848}
1849
1850/*
1851 * perform bottom half processing
1852 */
1853static void bh_handler(void* context)
1854{
1855 struct slgt_info *info = context;
1856 int action;
1857
1858 if (!info)
1859 return;
1860 info->bh_running = 1;
1861
1862 while((action = bh_action(info))) {
1863 switch (action) {
1864 case BH_RECEIVE:
1865 DBGBH(("%s bh receive\n", info->device_name));
1866 switch(info->params.mode) {
1867 case MGSL_MODE_ASYNC:
1868 rx_async(info);
1869 break;
1870 case MGSL_MODE_HDLC:
1871 while(rx_get_frame(info));
1872 break;
1873 case MGSL_MODE_RAW:
1874 while(rx_get_buf(info));
1875 break;
1876 }
1877 /* restart receiver if rx DMA buffers exhausted */
1878 if (info->rx_restart)
1879 rx_start(info);
1880 break;
1881 case BH_TRANSMIT:
1882 bh_transmit(info);
1883 break;
1884 case BH_STATUS:
1885 DBGBH(("%s bh status\n", info->device_name));
1886 info->ri_chkcount = 0;
1887 info->dsr_chkcount = 0;
1888 info->dcd_chkcount = 0;
1889 info->cts_chkcount = 0;
1890 break;
1891 default:
1892 DBGBH(("%s unknown action\n", info->device_name));
1893 break;
1894 }
1895 }
1896 DBGBH(("%s bh_handler exit\n", info->device_name));
1897}
1898
1899static void bh_transmit(struct slgt_info *info)
1900{
1901 struct tty_struct *tty = info->tty;
1902
1903 DBGBH(("%s bh_transmit\n", info->device_name));
1904 if (tty) {
1905 tty_wakeup(tty);
1906 wake_up_interruptible(&tty->write_wait);
1907 }
1908}
1909
1910static void dsr_change(struct slgt_info *info)
1911{
1912 get_signals(info);
1913 DBGISR(("dsr_change %s signals=%04X\n", info->device_name, info->signals));
1914 if ((info->dsr_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
1915 slgt_irq_off(info, IRQ_DSR);
1916 return;
1917 }
1918 info->icount.dsr++;
1919 if (info->signals & SerialSignal_DSR)
1920 info->input_signal_events.dsr_up++;
1921 else
1922 info->input_signal_events.dsr_down++;
1923 wake_up_interruptible(&info->status_event_wait_q);
1924 wake_up_interruptible(&info->event_wait_q);
1925 info->pending_bh |= BH_STATUS;
1926}
1927
1928static void cts_change(struct slgt_info *info)
1929{
1930 get_signals(info);
1931 DBGISR(("cts_change %s signals=%04X\n", info->device_name, info->signals));
1932 if ((info->cts_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
1933 slgt_irq_off(info, IRQ_CTS);
1934 return;
1935 }
1936 info->icount.cts++;
1937 if (info->signals & SerialSignal_CTS)
1938 info->input_signal_events.cts_up++;
1939 else
1940 info->input_signal_events.cts_down++;
1941 wake_up_interruptible(&info->status_event_wait_q);
1942 wake_up_interruptible(&info->event_wait_q);
1943 info->pending_bh |= BH_STATUS;
1944
1945 if (info->flags & ASYNC_CTS_FLOW) {
1946 if (info->tty) {
1947 if (info->tty->hw_stopped) {
1948 if (info->signals & SerialSignal_CTS) {
1949 info->tty->hw_stopped = 0;
1950 info->pending_bh |= BH_TRANSMIT;
1951 return;
1952 }
1953 } else {
1954 if (!(info->signals & SerialSignal_CTS))
1955 info->tty->hw_stopped = 1;
1956 }
1957 }
1958 }
1959}
1960
1961static void dcd_change(struct slgt_info *info)
1962{
1963 get_signals(info);
1964 DBGISR(("dcd_change %s signals=%04X\n", info->device_name, info->signals));
1965 if ((info->dcd_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
1966 slgt_irq_off(info, IRQ_DCD);
1967 return;
1968 }
1969 info->icount.dcd++;
1970 if (info->signals & SerialSignal_DCD) {
1971 info->input_signal_events.dcd_up++;
1972 } else {
1973 info->input_signal_events.dcd_down++;
1974 }
1975#ifdef CONFIG_HDLC
1976 if (info->netcount)
1977 hdlc_set_carrier(info->signals & SerialSignal_DCD, info->netdev);
1978#endif
1979 wake_up_interruptible(&info->status_event_wait_q);
1980 wake_up_interruptible(&info->event_wait_q);
1981 info->pending_bh |= BH_STATUS;
1982
1983 if (info->flags & ASYNC_CHECK_CD) {
1984 if (info->signals & SerialSignal_DCD)
1985 wake_up_interruptible(&info->open_wait);
1986 else {
1987 if (info->tty)
1988 tty_hangup(info->tty);
1989 }
1990 }
1991}
1992
1993static void ri_change(struct slgt_info *info)
1994{
1995 get_signals(info);
1996 DBGISR(("ri_change %s signals=%04X\n", info->device_name, info->signals));
1997 if ((info->ri_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
1998 slgt_irq_off(info, IRQ_RI);
1999 return;
2000 }
2001 info->icount.dcd++;
2002 if (info->signals & SerialSignal_RI) {
2003 info->input_signal_events.ri_up++;
2004 } else {
2005 info->input_signal_events.ri_down++;
2006 }
2007 wake_up_interruptible(&info->status_event_wait_q);
2008 wake_up_interruptible(&info->event_wait_q);
2009 info->pending_bh |= BH_STATUS;
2010}
2011
2012static void isr_serial(struct slgt_info *info)
2013{
2014 unsigned short status = rd_reg16(info, SSR);
2015
2016 DBGISR(("%s isr_serial status=%04X\n", info->device_name, status));
2017
2018 wr_reg16(info, SSR, status); /* clear pending */
2019
2020 info->irq_occurred = 1;
2021
2022 if (info->params.mode == MGSL_MODE_ASYNC) {
2023 if (status & IRQ_TXIDLE) {
2024 if (info->tx_count)
2025 isr_txeom(info, status);
2026 }
2027 if ((status & IRQ_RXBREAK) && (status & RXBREAK)) {
2028 info->icount.brk++;
2029 /* process break detection if tty control allows */
2030 if (info->tty) {
2031 if (!(status & info->ignore_status_mask)) {
2032 if (info->read_status_mask & MASK_BREAK) {
2033 *info->tty->flip.flag_buf_ptr = TTY_BREAK;
2034 if (info->flags & ASYNC_SAK)
2035 do_SAK(info->tty);
2036 }
2037 }
2038 }
2039 }
2040 } else {
2041 if (status & (IRQ_TXIDLE + IRQ_TXUNDER))
2042 isr_txeom(info, status);
2043
2044 if (status & IRQ_RXIDLE) {
2045 if (status & RXIDLE)
2046 info->icount.rxidle++;
2047 else
2048 info->icount.exithunt++;
2049 wake_up_interruptible(&info->event_wait_q);
2050 }
2051
2052 if (status & IRQ_RXOVER)
2053 rx_start(info);
2054 }
2055
2056 if (status & IRQ_DSR)
2057 dsr_change(info);
2058 if (status & IRQ_CTS)
2059 cts_change(info);
2060 if (status & IRQ_DCD)
2061 dcd_change(info);
2062 if (status & IRQ_RI)
2063 ri_change(info);
2064}
2065
2066static void isr_rdma(struct slgt_info *info)
2067{
2068 unsigned int status = rd_reg32(info, RDCSR);
2069
2070 DBGISR(("%s isr_rdma status=%08x\n", info->device_name, status));
2071
2072 /* RDCSR (rx DMA control/status)
2073 *
2074 * 31..07 reserved
2075 * 06 save status byte to DMA buffer
2076 * 05 error
2077 * 04 eol (end of list)
2078 * 03 eob (end of buffer)
2079 * 02 IRQ enable
2080 * 01 reset
2081 * 00 enable
2082 */
2083 wr_reg32(info, RDCSR, status); /* clear pending */
2084
2085 if (status & (BIT5 + BIT4)) {
2086 DBGISR(("%s isr_rdma rx_restart=1\n", info->device_name));
2087 info->rx_restart = 1;
2088 }
2089 info->pending_bh |= BH_RECEIVE;
2090}
2091
2092static void isr_tdma(struct slgt_info *info)
2093{
2094 unsigned int status = rd_reg32(info, TDCSR);
2095
2096 DBGISR(("%s isr_tdma status=%08x\n", info->device_name, status));
2097
2098 /* TDCSR (tx DMA control/status)
2099 *
2100 * 31..06 reserved
2101 * 05 error
2102 * 04 eol (end of list)
2103 * 03 eob (end of buffer)
2104 * 02 IRQ enable
2105 * 01 reset
2106 * 00 enable
2107 */
2108 wr_reg32(info, TDCSR, status); /* clear pending */
2109
2110 if (status & (BIT5 + BIT4 + BIT3)) {
2111 // another transmit buffer has completed
2112 // run bottom half to get more send data from user
2113 info->pending_bh |= BH_TRANSMIT;
2114 }
2115}
2116
2117static void isr_txeom(struct slgt_info *info, unsigned short status)
2118{
2119 DBGISR(("%s txeom status=%04x\n", info->device_name, status));
2120
2121 slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER);
2122 tdma_reset(info);
2123 reset_tbufs(info);
2124 if (status & IRQ_TXUNDER) {
2125 unsigned short val = rd_reg16(info, TCR);
2126 wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */
2127 wr_reg16(info, TCR, val); /* clear reset bit */
2128 }
2129
2130 if (info->tx_active) {
2131 if (info->params.mode != MGSL_MODE_ASYNC) {
2132 if (status & IRQ_TXUNDER)
2133 info->icount.txunder++;
2134 else if (status & IRQ_TXIDLE)
2135 info->icount.txok++;
2136 }
2137
2138 info->tx_active = 0;
2139 info->tx_count = 0;
2140
2141 del_timer(&info->tx_timer);
2142
2143 if (info->params.mode != MGSL_MODE_ASYNC && info->drop_rts_on_tx_done) {
2144 info->signals &= ~SerialSignal_RTS;
2145 info->drop_rts_on_tx_done = 0;
2146 set_signals(info);
2147 }
2148
2149#ifdef CONFIG_HDLC
2150 if (info->netcount)
2151 hdlcdev_tx_done(info);
2152 else
2153#endif
2154 {
2155 if (info->tty && (info->tty->stopped || info->tty->hw_stopped)) {
2156 tx_stop(info);
2157 return;
2158 }
2159 info->pending_bh |= BH_TRANSMIT;
2160 }
2161 }
2162}
2163
2164/* interrupt service routine
2165 *
2166 * irq interrupt number
2167 * dev_id device ID supplied during interrupt registration
2168 * regs interrupted processor context
2169 */
2170static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs)
2171{
2172 struct slgt_info *info;
2173 unsigned int gsr;
2174 unsigned int i;
2175
2176 DBGISR(("slgt_interrupt irq=%d entry\n", irq));
2177
2178 info = dev_id;
2179 if (!info)
2180 return IRQ_NONE;
2181
2182 spin_lock(&info->lock);
2183
2184 while((gsr = rd_reg32(info, GSR) & 0xffffff00)) {
2185 DBGISR(("%s gsr=%08x\n", info->device_name, gsr));
2186 info->irq_occurred = 1;
2187 for(i=0; i < info->port_count ; i++) {
2188 if (info->port_array[i] == NULL)
2189 continue;
2190 if (gsr & (BIT8 << i))
2191 isr_serial(info->port_array[i]);
2192 if (gsr & (BIT16 << (i*2)))
2193 isr_rdma(info->port_array[i]);
2194 if (gsr & (BIT17 << (i*2)))
2195 isr_tdma(info->port_array[i]);
2196 }
2197 }
2198
2199 for(i=0; i < info->port_count ; i++) {
2200 struct slgt_info *port = info->port_array[i];
2201
2202 if (port && (port->count || port->netcount) &&
2203 port->pending_bh && !port->bh_running &&
2204 !port->bh_requested) {
2205 DBGISR(("%s bh queued\n", port->device_name));
2206 schedule_work(&port->task);
2207 port->bh_requested = 1;
2208 }
2209 }
2210
2211 spin_unlock(&info->lock);
2212
2213 DBGISR(("slgt_interrupt irq=%d exit\n", irq));
2214 return IRQ_HANDLED;
2215}
2216
2217static int startup(struct slgt_info *info)
2218{
2219 DBGINFO(("%s startup\n", info->device_name));
2220
2221 if (info->flags & ASYNC_INITIALIZED)
2222 return 0;
2223
2224 if (!info->tx_buf) {
2225 info->tx_buf = kmalloc(info->max_frame_size, GFP_KERNEL);
2226 if (!info->tx_buf) {
2227 DBGERR(("%s can't allocate tx buffer\n", info->device_name));
2228 return -ENOMEM;
2229 }
2230 }
2231
2232 info->pending_bh = 0;
2233
2234 memset(&info->icount, 0, sizeof(info->icount));
2235
2236 /* program hardware for current parameters */
2237 change_params(info);
2238
2239 if (info->tty)
2240 clear_bit(TTY_IO_ERROR, &info->tty->flags);
2241
2242 info->flags |= ASYNC_INITIALIZED;
2243
2244 return 0;
2245}
2246
2247/*
2248 * called by close() and hangup() to shutdown hardware
2249 */
2250static void shutdown(struct slgt_info *info)
2251{
2252 unsigned long flags;
2253
2254 if (!(info->flags & ASYNC_INITIALIZED))
2255 return;
2256
2257 DBGINFO(("%s shutdown\n", info->device_name));
2258
2259 /* clear status wait queue because status changes */
2260 /* can't happen after shutting down the hardware */
2261 wake_up_interruptible(&info->status_event_wait_q);
2262 wake_up_interruptible(&info->event_wait_q);
2263
2264 del_timer_sync(&info->tx_timer);
2265 del_timer_sync(&info->rx_timer);
2266
2267 kfree(info->tx_buf);
2268 info->tx_buf = NULL;
2269
2270 spin_lock_irqsave(&info->lock,flags);
2271
2272 tx_stop(info);
2273 rx_stop(info);
2274
2275 slgt_irq_off(info, IRQ_ALL | IRQ_MASTER);
2276
2277 if (!info->tty || info->tty->termios->c_cflag & HUPCL) {
2278 info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
2279 set_signals(info);
2280 }
2281
2282 spin_unlock_irqrestore(&info->lock,flags);
2283
2284 if (info->tty)
2285 set_bit(TTY_IO_ERROR, &info->tty->flags);
2286
2287 info->flags &= ~ASYNC_INITIALIZED;
2288}
2289
2290static void program_hw(struct slgt_info *info)
2291{
2292 unsigned long flags;
2293
2294 spin_lock_irqsave(&info->lock,flags);
2295
2296 rx_stop(info);
2297 tx_stop(info);
2298
2299 if (info->params.mode == MGSL_MODE_HDLC ||
2300 info->params.mode == MGSL_MODE_RAW ||
2301 info->netcount)
2302 hdlc_mode(info);
2303 else
2304 async_mode(info);
2305
2306 set_signals(info);
2307
2308 info->dcd_chkcount = 0;
2309 info->cts_chkcount = 0;
2310 info->ri_chkcount = 0;
2311 info->dsr_chkcount = 0;
2312
2313 slgt_irq_on(info, IRQ_DCD | IRQ_CTS | IRQ_DSR);
2314 get_signals(info);
2315
2316 if (info->netcount ||
2317 (info->tty && info->tty->termios->c_cflag & CREAD))
2318 rx_start(info);
2319
2320 spin_unlock_irqrestore(&info->lock,flags);
2321}
2322
2323/*
2324 * reconfigure adapter based on new parameters
2325 */
2326static void change_params(struct slgt_info *info)
2327{
2328 unsigned cflag;
2329 int bits_per_char;
2330
2331 if (!info->tty || !info->tty->termios)
2332 return;
2333 DBGINFO(("%s change_params\n", info->device_name));
2334
2335 cflag = info->tty->termios->c_cflag;
2336
2337 /* if B0 rate (hangup) specified then negate DTR and RTS */
2338 /* otherwise assert DTR and RTS */
2339 if (cflag & CBAUD)
2340 info->signals |= SerialSignal_RTS + SerialSignal_DTR;
2341 else
2342 info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR);
2343
2344 /* byte size and parity */
2345
2346 switch (cflag & CSIZE) {
2347 case CS5: info->params.data_bits = 5; break;
2348 case CS6: info->params.data_bits = 6; break;
2349 case CS7: info->params.data_bits = 7; break;
2350 case CS8: info->params.data_bits = 8; break;
2351 default: info->params.data_bits = 7; break;
2352 }
2353
2354 info->params.stop_bits = (cflag & CSTOPB) ? 2 : 1;
2355
2356 if (cflag & PARENB)
2357 info->params.parity = (cflag & PARODD) ? ASYNC_PARITY_ODD : ASYNC_PARITY_EVEN;
2358 else
2359 info->params.parity = ASYNC_PARITY_NONE;
2360
2361 /* calculate number of jiffies to transmit a full
2362 * FIFO (32 bytes) at specified data rate
2363 */
2364 bits_per_char = info->params.data_bits +
2365 info->params.stop_bits + 1;
2366
2367 info->params.data_rate = tty_get_baud_rate(info->tty);
2368
2369 if (info->params.data_rate) {
2370 info->timeout = (32*HZ*bits_per_char) /
2371 info->params.data_rate;
2372 }
2373 info->timeout += HZ/50; /* Add .02 seconds of slop */
2374
2375 if (cflag & CRTSCTS)
2376 info->flags |= ASYNC_CTS_FLOW;
2377 else
2378 info->flags &= ~ASYNC_CTS_FLOW;
2379
2380 if (cflag & CLOCAL)
2381 info->flags &= ~ASYNC_CHECK_CD;
2382 else
2383 info->flags |= ASYNC_CHECK_CD;
2384
2385 /* process tty input control flags */
2386
2387 info->read_status_mask = IRQ_RXOVER;
2388 if (I_INPCK(info->tty))
2389 info->read_status_mask |= MASK_PARITY | MASK_FRAMING;
2390 if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
2391 info->read_status_mask |= MASK_BREAK;
2392 if (I_IGNPAR(info->tty))
2393 info->ignore_status_mask |= MASK_PARITY | MASK_FRAMING;
2394 if (I_IGNBRK(info->tty)) {
2395 info->ignore_status_mask |= MASK_BREAK;
2396 /* If ignoring parity and break indicators, ignore
2397 * overruns too. (For real raw support).
2398 */
2399 if (I_IGNPAR(info->tty))
2400 info->ignore_status_mask |= MASK_OVERRUN;
2401 }
2402
2403 program_hw(info);
2404}
2405
2406static int get_stats(struct slgt_info *info, struct mgsl_icount __user *user_icount)
2407{
2408 DBGINFO(("%s get_stats\n", info->device_name));
2409 if (!user_icount) {
2410 memset(&info->icount, 0, sizeof(info->icount));
2411 } else {
2412 if (copy_to_user(user_icount, &info->icount, sizeof(struct mgsl_icount)))
2413 return -EFAULT;
2414 }
2415 return 0;
2416}
2417
2418static int get_params(struct slgt_info *info, MGSL_PARAMS __user *user_params)
2419{
2420 DBGINFO(("%s get_params\n", info->device_name));
2421 if (copy_to_user(user_params, &info->params, sizeof(MGSL_PARAMS)))
2422 return -EFAULT;
2423 return 0;
2424}
2425
2426static int set_params(struct slgt_info *info, MGSL_PARAMS __user *new_params)
2427{
2428 unsigned long flags;
2429 MGSL_PARAMS tmp_params;
2430
2431 DBGINFO(("%s set_params\n", info->device_name));
2432 if (copy_from_user(&tmp_params, new_params, sizeof(MGSL_PARAMS)))
2433 return -EFAULT;
2434
2435 spin_lock_irqsave(&info->lock, flags);
2436 memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS));
2437 spin_unlock_irqrestore(&info->lock, flags);
2438
2439 change_params(info);
2440
2441 return 0;
2442}
2443
2444static int get_txidle(struct slgt_info *info, int __user *idle_mode)
2445{
2446 DBGINFO(("%s get_txidle=%d\n", info->device_name, info->idle_mode));
2447 if (put_user(info->idle_mode, idle_mode))
2448 return -EFAULT;
2449 return 0;
2450}
2451
2452static int set_txidle(struct slgt_info *info, int idle_mode)
2453{
2454 unsigned long flags;
2455 DBGINFO(("%s set_txidle(%d)\n", info->device_name, idle_mode));
2456 spin_lock_irqsave(&info->lock,flags);
2457 info->idle_mode = idle_mode;
2458 tx_set_idle(info);
2459 spin_unlock_irqrestore(&info->lock,flags);
2460 return 0;
2461}
2462
2463static int tx_enable(struct slgt_info *info, int enable)
2464{
2465 unsigned long flags;
2466 DBGINFO(("%s tx_enable(%d)\n", info->device_name, enable));
2467 spin_lock_irqsave(&info->lock,flags);
2468 if (enable) {
2469 if (!info->tx_enabled)
2470 tx_start(info);
2471 } else {
2472 if (info->tx_enabled)
2473 tx_stop(info);
2474 }
2475 spin_unlock_irqrestore(&info->lock,flags);
2476 return 0;
2477}
2478
2479/*
2480 * abort transmit HDLC frame
2481 */
2482static int tx_abort(struct slgt_info *info)
2483{
2484 unsigned long flags;
2485 DBGINFO(("%s tx_abort\n", info->device_name));
2486 spin_lock_irqsave(&info->lock,flags);
2487 tdma_reset(info);
2488 spin_unlock_irqrestore(&info->lock,flags);
2489 return 0;
2490}
2491
2492static int rx_enable(struct slgt_info *info, int enable)
2493{
2494 unsigned long flags;
2495 DBGINFO(("%s rx_enable(%d)\n", info->device_name, enable));
2496 spin_lock_irqsave(&info->lock,flags);
2497 if (enable) {
2498 if (!info->rx_enabled)
2499 rx_start(info);
2500 } else {
2501 if (info->rx_enabled)
2502 rx_stop(info);
2503 }
2504 spin_unlock_irqrestore(&info->lock,flags);
2505 return 0;
2506}
2507
2508/*
2509 * wait for specified event to occur
2510 */
2511static int wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr)
2512{
2513 unsigned long flags;
2514 int s;
2515 int rc=0;
2516 struct mgsl_icount cprev, cnow;
2517 int events;
2518 int mask;
2519 struct _input_signal_events oldsigs, newsigs;
2520 DECLARE_WAITQUEUE(wait, current);
2521
2522 if (get_user(mask, mask_ptr))
2523 return -EFAULT;
2524
2525 DBGINFO(("%s wait_mgsl_event(%d)\n", info->device_name, mask));
2526
2527 spin_lock_irqsave(&info->lock,flags);
2528
2529 /* return immediately if state matches requested events */
2530 get_signals(info);
2531 s = info->signals;
2532
2533 events = mask &
2534 ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) +
2535 ((s & SerialSignal_DCD) ? MgslEvent_DcdActive:MgslEvent_DcdInactive) +
2536 ((s & SerialSignal_CTS) ? MgslEvent_CtsActive:MgslEvent_CtsInactive) +
2537 ((s & SerialSignal_RI) ? MgslEvent_RiActive :MgslEvent_RiInactive) );
2538 if (events) {
2539 spin_unlock_irqrestore(&info->lock,flags);
2540 goto exit;
2541 }
2542
2543 /* save current irq counts */
2544 cprev = info->icount;
2545 oldsigs = info->input_signal_events;
2546
2547 /* enable hunt and idle irqs if needed */
2548 if (mask & (MgslEvent_ExitHuntMode+MgslEvent_IdleReceived)) {
2549 unsigned short val = rd_reg16(info, SCR);
2550 if (!(val & IRQ_RXIDLE))
2551 wr_reg16(info, SCR, (unsigned short)(val | IRQ_RXIDLE));
2552 }
2553
2554 set_current_state(TASK_INTERRUPTIBLE);
2555 add_wait_queue(&info->event_wait_q, &wait);
2556
2557 spin_unlock_irqrestore(&info->lock,flags);
2558
2559 for(;;) {
2560 schedule();
2561 if (signal_pending(current)) {
2562 rc = -ERESTARTSYS;
2563 break;
2564 }
2565
2566 /* get current irq counts */
2567 spin_lock_irqsave(&info->lock,flags);
2568 cnow = info->icount;
2569 newsigs = info->input_signal_events;
2570 set_current_state(TASK_INTERRUPTIBLE);
2571 spin_unlock_irqrestore(&info->lock,flags);
2572
2573 /* if no change, wait aborted for some reason */
2574 if (newsigs.dsr_up == oldsigs.dsr_up &&
2575 newsigs.dsr_down == oldsigs.dsr_down &&
2576 newsigs.dcd_up == oldsigs.dcd_up &&
2577 newsigs.dcd_down == oldsigs.dcd_down &&
2578 newsigs.cts_up == oldsigs.cts_up &&
2579 newsigs.cts_down == oldsigs.cts_down &&
2580 newsigs.ri_up == oldsigs.ri_up &&
2581 newsigs.ri_down == oldsigs.ri_down &&
2582 cnow.exithunt == cprev.exithunt &&
2583 cnow.rxidle == cprev.rxidle) {
2584 rc = -EIO;
2585 break;
2586 }
2587
2588 events = mask &
2589 ( (newsigs.dsr_up != oldsigs.dsr_up ? MgslEvent_DsrActive:0) +
2590 (newsigs.dsr_down != oldsigs.dsr_down ? MgslEvent_DsrInactive:0) +
2591 (newsigs.dcd_up != oldsigs.dcd_up ? MgslEvent_DcdActive:0) +
2592 (newsigs.dcd_down != oldsigs.dcd_down ? MgslEvent_DcdInactive:0) +
2593 (newsigs.cts_up != oldsigs.cts_up ? MgslEvent_CtsActive:0) +
2594 (newsigs.cts_down != oldsigs.cts_down ? MgslEvent_CtsInactive:0) +
2595 (newsigs.ri_up != oldsigs.ri_up ? MgslEvent_RiActive:0) +
2596 (newsigs.ri_down != oldsigs.ri_down ? MgslEvent_RiInactive:0) +
2597 (cnow.exithunt != cprev.exithunt ? MgslEvent_ExitHuntMode:0) +
2598 (cnow.rxidle != cprev.rxidle ? MgslEvent_IdleReceived:0) );
2599 if (events)
2600 break;
2601
2602 cprev = cnow;
2603 oldsigs = newsigs;
2604 }
2605
2606 remove_wait_queue(&info->event_wait_q, &wait);
2607 set_current_state(TASK_RUNNING);
2608
2609
2610 if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) {
2611 spin_lock_irqsave(&info->lock,flags);
2612 if (!waitqueue_active(&info->event_wait_q)) {
2613 /* disable enable exit hunt mode/idle rcvd IRQs */
2614 wr_reg16(info, SCR,
2615 (unsigned short)(rd_reg16(info, SCR) & ~IRQ_RXIDLE));
2616 }
2617 spin_unlock_irqrestore(&info->lock,flags);
2618 }
2619exit:
2620 if (rc == 0)
2621 rc = put_user(events, mask_ptr);
2622 return rc;
2623}
2624
2625static int get_interface(struct slgt_info *info, int __user *if_mode)
2626{
2627 DBGINFO(("%s get_interface=%x\n", info->device_name, info->if_mode));
2628 if (put_user(info->if_mode, if_mode))
2629 return -EFAULT;
2630 return 0;
2631}
2632
2633static int set_interface(struct slgt_info *info, int if_mode)
2634{
2635 unsigned long flags;
2636 unsigned char val;
2637
2638 DBGINFO(("%s set_interface=%x)\n", info->device_name, if_mode));
2639 spin_lock_irqsave(&info->lock,flags);
2640 info->if_mode = if_mode;
2641
2642 msc_set_vcr(info);
2643
2644 /* TCR (tx control) 07 1=RTS driver control */
2645 val = rd_reg16(info, TCR);
2646 if (info->if_mode & MGSL_INTERFACE_RTS_EN)
2647 val |= BIT7;
2648 else
2649 val &= ~BIT7;
2650 wr_reg16(info, TCR, val);
2651
2652 spin_unlock_irqrestore(&info->lock,flags);
2653 return 0;
2654}
2655
2656static int modem_input_wait(struct slgt_info *info,int arg)
2657{
2658 unsigned long flags;
2659 int rc;
2660 struct mgsl_icount cprev, cnow;
2661 DECLARE_WAITQUEUE(wait, current);
2662
2663 /* save current irq counts */
2664 spin_lock_irqsave(&info->lock,flags);
2665 cprev = info->icount;
2666 add_wait_queue(&info->status_event_wait_q, &wait);
2667 set_current_state(TASK_INTERRUPTIBLE);
2668 spin_unlock_irqrestore(&info->lock,flags);
2669
2670 for(;;) {
2671 schedule();
2672 if (signal_pending(current)) {
2673 rc = -ERESTARTSYS;
2674 break;
2675 }
2676
2677 /* get new irq counts */
2678 spin_lock_irqsave(&info->lock,flags);
2679 cnow = info->icount;
2680 set_current_state(TASK_INTERRUPTIBLE);
2681 spin_unlock_irqrestore(&info->lock,flags);
2682
2683 /* if no change, wait aborted for some reason */
2684 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
2685 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
2686 rc = -EIO;
2687 break;
2688 }
2689
2690 /* check for change in caller specified modem input */
2691 if ((arg & TIOCM_RNG && cnow.rng != cprev.rng) ||
2692 (arg & TIOCM_DSR && cnow.dsr != cprev.dsr) ||
2693 (arg & TIOCM_CD && cnow.dcd != cprev.dcd) ||
2694 (arg & TIOCM_CTS && cnow.cts != cprev.cts)) {
2695 rc = 0;
2696 break;
2697 }
2698
2699 cprev = cnow;
2700 }
2701 remove_wait_queue(&info->status_event_wait_q, &wait);
2702 set_current_state(TASK_RUNNING);
2703 return rc;
2704}
2705
2706/*
2707 * return state of serial control and status signals
2708 */
2709static int tiocmget(struct tty_struct *tty, struct file *file)
2710{
2711 struct slgt_info *info = tty->driver_data;
2712 unsigned int result;
2713 unsigned long flags;
2714
2715 spin_lock_irqsave(&info->lock,flags);
2716 get_signals(info);
2717 spin_unlock_irqrestore(&info->lock,flags);
2718
2719 result = ((info->signals & SerialSignal_RTS) ? TIOCM_RTS:0) +
2720 ((info->signals & SerialSignal_DTR) ? TIOCM_DTR:0) +
2721 ((info->signals & SerialSignal_DCD) ? TIOCM_CAR:0) +
2722 ((info->signals & SerialSignal_RI) ? TIOCM_RNG:0) +
2723 ((info->signals & SerialSignal_DSR) ? TIOCM_DSR:0) +
2724 ((info->signals & SerialSignal_CTS) ? TIOCM_CTS:0);
2725
2726 DBGINFO(("%s tiocmget value=%08X\n", info->device_name, result));
2727 return result;
2728}
2729
2730/*
2731 * set modem control signals (DTR/RTS)
2732 *
2733 * cmd signal command: TIOCMBIS = set bit TIOCMBIC = clear bit
2734 * TIOCMSET = set/clear signal values
2735 * value bit mask for command
2736 */
2737static int tiocmset(struct tty_struct *tty, struct file *file,
2738 unsigned int set, unsigned int clear)
2739{
2740 struct slgt_info *info = tty->driver_data;
2741 unsigned long flags;
2742
2743 DBGINFO(("%s tiocmset(%x,%x)\n", info->device_name, set, clear));
2744
2745 if (set & TIOCM_RTS)
2746 info->signals |= SerialSignal_RTS;
2747 if (set & TIOCM_DTR)
2748 info->signals |= SerialSignal_DTR;
2749 if (clear & TIOCM_RTS)
2750 info->signals &= ~SerialSignal_RTS;
2751 if (clear & TIOCM_DTR)
2752 info->signals &= ~SerialSignal_DTR;
2753
2754 spin_lock_irqsave(&info->lock,flags);
2755 set_signals(info);
2756 spin_unlock_irqrestore(&info->lock,flags);
2757 return 0;
2758}
2759
2760/*
2761 * block current process until the device is ready to open
2762 */
2763static int block_til_ready(struct tty_struct *tty, struct file *filp,
2764 struct slgt_info *info)
2765{
2766 DECLARE_WAITQUEUE(wait, current);
2767 int retval;
2768 int do_clocal = 0, extra_count = 0;
2769 unsigned long flags;
2770
2771 DBGINFO(("%s block_til_ready\n", tty->driver->name));
2772
2773 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
2774 /* nonblock mode is set or port is not enabled */
2775 info->flags |= ASYNC_NORMAL_ACTIVE;
2776 return 0;
2777 }
2778
2779 if (tty->termios->c_cflag & CLOCAL)
2780 do_clocal = 1;
2781
2782 /* Wait for carrier detect and the line to become
2783 * free (i.e., not in use by the callout). While we are in
2784 * this loop, info->count is dropped by one, so that
2785 * close() knows when to free things. We restore it upon
2786 * exit, either normal or abnormal.
2787 */
2788
2789 retval = 0;
2790 add_wait_queue(&info->open_wait, &wait);
2791
2792 spin_lock_irqsave(&info->lock, flags);
2793 if (!tty_hung_up_p(filp)) {
2794 extra_count = 1;
2795 info->count--;
2796 }
2797 spin_unlock_irqrestore(&info->lock, flags);
2798 info->blocked_open++;
2799
2800 while (1) {
2801 if ((tty->termios->c_cflag & CBAUD)) {
2802 spin_lock_irqsave(&info->lock,flags);
2803 info->signals |= SerialSignal_RTS + SerialSignal_DTR;
2804 set_signals(info);
2805 spin_unlock_irqrestore(&info->lock,flags);
2806 }
2807
2808 set_current_state(TASK_INTERRUPTIBLE);
2809
2810 if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)){
2811 retval = (info->flags & ASYNC_HUP_NOTIFY) ?
2812 -EAGAIN : -ERESTARTSYS;
2813 break;
2814 }
2815
2816 spin_lock_irqsave(&info->lock,flags);
2817 get_signals(info);
2818 spin_unlock_irqrestore(&info->lock,flags);
2819
2820 if (!(info->flags & ASYNC_CLOSING) &&
2821 (do_clocal || (info->signals & SerialSignal_DCD)) ) {
2822 break;
2823 }
2824
2825 if (signal_pending(current)) {
2826 retval = -ERESTARTSYS;
2827 break;
2828 }
2829
2830 DBGINFO(("%s block_til_ready wait\n", tty->driver->name));
2831 schedule();
2832 }
2833
2834 set_current_state(TASK_RUNNING);
2835 remove_wait_queue(&info->open_wait, &wait);
2836
2837 if (extra_count)
2838 info->count++;
2839 info->blocked_open--;
2840
2841 if (!retval)
2842 info->flags |= ASYNC_NORMAL_ACTIVE;
2843
2844 DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval));
2845 return retval;
2846}
2847
2848static int alloc_tmp_rbuf(struct slgt_info *info)
2849{
2850 info->tmp_rbuf = kmalloc(info->max_frame_size, GFP_KERNEL);
2851 if (info->tmp_rbuf == NULL)
2852 return -ENOMEM;
2853 return 0;
2854}
2855
2856static void free_tmp_rbuf(struct slgt_info *info)
2857{
2858 kfree(info->tmp_rbuf);
2859 info->tmp_rbuf = NULL;
2860}
2861
2862/*
2863 * allocate DMA descriptor lists.
2864 */
2865static int alloc_desc(struct slgt_info *info)
2866{
2867 unsigned int i;
2868 unsigned int pbufs;
2869
2870 /* allocate memory to hold descriptor lists */
2871 info->bufs = pci_alloc_consistent(info->pdev, DESC_LIST_SIZE, &info->bufs_dma_addr);
2872 if (info->bufs == NULL)
2873 return -ENOMEM;
2874
2875 memset(info->bufs, 0, DESC_LIST_SIZE);
2876
2877 info->rbufs = (struct slgt_desc*)info->bufs;
2878 info->tbufs = ((struct slgt_desc*)info->bufs) + info->rbuf_count;
2879
2880 pbufs = (unsigned int)info->bufs_dma_addr;
2881
2882 /*
2883 * Build circular lists of descriptors
2884 */
2885
2886 for (i=0; i < info->rbuf_count; i++) {
2887 /* physical address of this descriptor */
2888 info->rbufs[i].pdesc = pbufs + (i * sizeof(struct slgt_desc));
2889
2890 /* physical address of next descriptor */
2891 if (i == info->rbuf_count - 1)
2892 info->rbufs[i].next = cpu_to_le32(pbufs);
2893 else
2894 info->rbufs[i].next = cpu_to_le32(pbufs + ((i+1) * sizeof(struct slgt_desc)));
2895 set_desc_count(info->rbufs[i], DMABUFSIZE);
2896 }
2897
2898 for (i=0; i < info->tbuf_count; i++) {
2899 /* physical address of this descriptor */
2900 info->tbufs[i].pdesc = pbufs + ((info->rbuf_count + i) * sizeof(struct slgt_desc));
2901
2902 /* physical address of next descriptor */
2903 if (i == info->tbuf_count - 1)
2904 info->tbufs[i].next = cpu_to_le32(pbufs + info->rbuf_count * sizeof(struct slgt_desc));
2905 else
2906 info->tbufs[i].next = cpu_to_le32(pbufs + ((info->rbuf_count + i + 1) * sizeof(struct slgt_desc)));
2907 }
2908
2909 return 0;
2910}
2911
2912static void free_desc(struct slgt_info *info)
2913{
2914 if (info->bufs != NULL) {
2915 pci_free_consistent(info->pdev, DESC_LIST_SIZE, info->bufs, info->bufs_dma_addr);
2916 info->bufs = NULL;
2917 info->rbufs = NULL;
2918 info->tbufs = NULL;
2919 }
2920}
2921
2922static int alloc_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count)
2923{
2924 int i;
2925 for (i=0; i < count; i++) {
2926 if ((bufs[i].buf = pci_alloc_consistent(info->pdev, DMABUFSIZE, &bufs[i].buf_dma_addr)) == NULL)
2927 return -ENOMEM;
2928 bufs[i].pbuf = cpu_to_le32((unsigned int)bufs[i].buf_dma_addr);
2929 }
2930 return 0;
2931}
2932
2933static void free_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count)
2934{
2935 int i;
2936 for (i=0; i < count; i++) {
2937 if (bufs[i].buf == NULL)
2938 continue;
2939 pci_free_consistent(info->pdev, DMABUFSIZE, bufs[i].buf, bufs[i].buf_dma_addr);
2940 bufs[i].buf = NULL;
2941 }
2942}
2943
2944static int alloc_dma_bufs(struct slgt_info *info)
2945{
2946 info->rbuf_count = 32;
2947 info->tbuf_count = 32;
2948
2949 if (alloc_desc(info) < 0 ||
2950 alloc_bufs(info, info->rbufs, info->rbuf_count) < 0 ||
2951 alloc_bufs(info, info->tbufs, info->tbuf_count) < 0 ||
2952 alloc_tmp_rbuf(info) < 0) {
2953 DBGERR(("%s DMA buffer alloc fail\n", info->device_name));
2954 return -ENOMEM;
2955 }
2956 reset_rbufs(info);
2957 return 0;
2958}
2959
2960static void free_dma_bufs(struct slgt_info *info)
2961{
2962 if (info->bufs) {
2963 free_bufs(info, info->rbufs, info->rbuf_count);
2964 free_bufs(info, info->tbufs, info->tbuf_count);
2965 free_desc(info);
2966 }
2967 free_tmp_rbuf(info);
2968}
2969
2970static int claim_resources(struct slgt_info *info)
2971{
2972 if (request_mem_region(info->phys_reg_addr, SLGT_REG_SIZE, "synclink_gt") == NULL) {
2973 DBGERR(("%s reg addr conflict, addr=%08X\n",
2974 info->device_name, info->phys_reg_addr));
2975 info->init_error = DiagStatus_AddressConflict;
2976 goto errout;
2977 }
2978 else
2979 info->reg_addr_requested = 1;
2980
2981 info->reg_addr = ioremap(info->phys_reg_addr, PAGE_SIZE);
2982 if (!info->reg_addr) {
2983 DBGERR(("%s cant map device registers, addr=%08X\n",
2984 info->device_name, info->phys_reg_addr));
2985 info->init_error = DiagStatus_CantAssignPciResources;
2986 goto errout;
2987 }
2988 info->reg_addr += info->reg_offset;
2989 return 0;
2990
2991errout:
2992 release_resources(info);
2993 return -ENODEV;
2994}
2995
2996static void release_resources(struct slgt_info *info)
2997{
2998 if (info->irq_requested) {
2999 free_irq(info->irq_level, info);
3000 info->irq_requested = 0;
3001 }
3002
3003 if (info->reg_addr_requested) {
3004 release_mem_region(info->phys_reg_addr, SLGT_REG_SIZE);
3005 info->reg_addr_requested = 0;
3006 }
3007
3008 if (info->reg_addr) {
3009 iounmap(info->reg_addr - info->reg_offset);
3010 info->reg_addr = NULL;
3011 }
3012}
3013
3014/* Add the specified device instance data structure to the
3015 * global linked list of devices and increment the device count.
3016 */
3017static void add_device(struct slgt_info *info)
3018{
3019 char *devstr;
3020
3021 info->next_device = NULL;
3022 info->line = slgt_device_count;
3023 sprintf(info->device_name, "%s%d", tty_dev_prefix, info->line);
3024
3025 if (info->line < MAX_DEVICES) {
3026 if (maxframe[info->line])
3027 info->max_frame_size = maxframe[info->line];
3028 info->dosyncppp = dosyncppp[info->line];
3029 }
3030
3031 slgt_device_count++;
3032
3033 if (!slgt_device_list)
3034 slgt_device_list = info;
3035 else {
3036 struct slgt_info *current_dev = slgt_device_list;
3037 while(current_dev->next_device)
3038 current_dev = current_dev->next_device;
3039 current_dev->next_device = info;
3040 }
3041
3042 if (info->max_frame_size < 4096)
3043 info->max_frame_size = 4096;
3044 else if (info->max_frame_size > 65535)
3045 info->max_frame_size = 65535;
3046
3047 switch(info->pdev->device) {
3048 case SYNCLINK_GT_DEVICE_ID:
3049 devstr = "GT";
3050 break;
3051 case SYNCLINK_GT4_DEVICE_ID:
3052 devstr = "GT4";
3053 break;
3054 case SYNCLINK_AC_DEVICE_ID:
3055 devstr = "AC";
3056 info->params.mode = MGSL_MODE_ASYNC;
3057 break;
3058 default:
3059 devstr = "(unknown model)";
3060 }
3061 printk("SyncLink %s %s IO=%08x IRQ=%d MaxFrameSize=%u\n",
3062 devstr, info->device_name, info->phys_reg_addr,
3063 info->irq_level, info->max_frame_size);
3064
3065#ifdef CONFIG_HDLC
3066 hdlcdev_init(info);
3067#endif
3068}
3069
3070/*
3071 * allocate device instance structure, return NULL on failure
3072 */
3073static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
3074{
3075 struct slgt_info *info;
3076
3077 info = kmalloc(sizeof(struct slgt_info), GFP_KERNEL);
3078
3079 if (!info) {
3080 DBGERR(("%s device alloc failed adapter=%d port=%d\n",
3081 driver_name, adapter_num, port_num));
3082 } else {
3083 memset(info, 0, sizeof(struct slgt_info));
3084 info->magic = MGSL_MAGIC;
3085 INIT_WORK(&info->task, bh_handler, info);
3086 info->max_frame_size = 4096;
3087 info->raw_rx_size = DMABUFSIZE;
3088 info->close_delay = 5*HZ/10;
3089 info->closing_wait = 30*HZ;
3090 init_waitqueue_head(&info->open_wait);
3091 init_waitqueue_head(&info->close_wait);
3092 init_waitqueue_head(&info->status_event_wait_q);
3093 init_waitqueue_head(&info->event_wait_q);
3094 spin_lock_init(&info->netlock);
3095 memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS));
3096 info->idle_mode = HDLC_TXIDLE_FLAGS;
3097 info->adapter_num = adapter_num;
3098 info->port_num = port_num;
3099
3100 init_timer(&info->tx_timer);
3101 info->tx_timer.data = (unsigned long)info;
3102 info->tx_timer.function = tx_timeout;
3103
3104 init_timer(&info->rx_timer);
3105 info->rx_timer.data = (unsigned long)info;
3106 info->rx_timer.function = rx_timeout;
3107
3108 /* Copy configuration info to device instance data */
3109 info->pdev = pdev;
3110 info->irq_level = pdev->irq;
3111 info->phys_reg_addr = pci_resource_start(pdev,0);
3112
3113 /* veremap works on page boundaries
3114 * map full page starting at the page boundary
3115 */
3116 info->reg_offset = info->phys_reg_addr & (PAGE_SIZE-1);
3117 info->phys_reg_addr &= ~(PAGE_SIZE-1);
3118
3119 info->bus_type = MGSL_BUS_TYPE_PCI;
3120 info->irq_flags = SA_SHIRQ;
3121
3122 info->init_error = -1; /* assume error, set to 0 on successful init */
3123 }
3124
3125 return info;
3126}
3127
3128static void device_init(int adapter_num, struct pci_dev *pdev)
3129{
3130 struct slgt_info *port_array[SLGT_MAX_PORTS];
3131 int i;
3132 int port_count = 1;
3133
3134 if (pdev->device == SYNCLINK_GT4_DEVICE_ID)
3135 port_count = 4;
3136
3137 /* allocate device instances for all ports */
3138 for (i=0; i < port_count; ++i) {
3139 port_array[i] = alloc_dev(adapter_num, i, pdev);
3140 if (port_array[i] == NULL) {
3141 for (--i; i >= 0; --i)
3142 kfree(port_array[i]);
3143 return;
3144 }
3145 }
3146
3147 /* give copy of port_array to all ports and add to device list */
3148 for (i=0; i < port_count; ++i) {
3149 memcpy(port_array[i]->port_array, port_array, sizeof(port_array));
3150 add_device(port_array[i]);
3151 port_array[i]->port_count = port_count;
3152 spin_lock_init(&port_array[i]->lock);
3153 }
3154
3155 /* Allocate and claim adapter resources */
3156 if (!claim_resources(port_array[0])) {
3157
3158 alloc_dma_bufs(port_array[0]);
3159
3160 /* copy resource information from first port to others */
3161 for (i = 1; i < port_count; ++i) {
3162 port_array[i]->lock = port_array[0]->lock;
3163 port_array[i]->irq_level = port_array[0]->irq_level;
3164 port_array[i]->reg_addr = port_array[0]->reg_addr;
3165 alloc_dma_bufs(port_array[i]);
3166 }
3167
3168 if (request_irq(port_array[0]->irq_level,
3169 slgt_interrupt,
3170 port_array[0]->irq_flags,
3171 port_array[0]->device_name,
3172 port_array[0]) < 0) {
3173 DBGERR(("%s request_irq failed IRQ=%d\n",
3174 port_array[0]->device_name,
3175 port_array[0]->irq_level));
3176 } else {
3177 port_array[0]->irq_requested = 1;
3178 adapter_test(port_array[0]);
3179 for (i=1 ; i < port_count ; i++)
3180 port_array[i]->init_error = port_array[0]->init_error;
3181 }
3182 }
3183}
3184
3185static int __devinit init_one(struct pci_dev *dev,
3186 const struct pci_device_id *ent)
3187{
3188 if (pci_enable_device(dev)) {
3189 printk("error enabling pci device %p\n", dev);
3190 return -EIO;
3191 }
3192 pci_set_master(dev);
3193 device_init(slgt_device_count, dev);
3194 return 0;
3195}
3196
3197static void __devexit remove_one(struct pci_dev *dev)
3198{
3199}
3200
3201static struct tty_operations ops = {
3202 .open = open,
3203 .close = close,
3204 .write = write,
3205 .put_char = put_char,
3206 .flush_chars = flush_chars,
3207 .write_room = write_room,
3208 .chars_in_buffer = chars_in_buffer,
3209 .flush_buffer = flush_buffer,
3210 .ioctl = ioctl,
3211 .throttle = throttle,
3212 .unthrottle = unthrottle,
3213 .send_xchar = send_xchar,
3214 .break_ctl = set_break,
3215 .wait_until_sent = wait_until_sent,
3216 .read_proc = read_proc,
3217 .set_termios = set_termios,
3218 .stop = tx_hold,
3219 .start = tx_release,
3220 .hangup = hangup,
3221 .tiocmget = tiocmget,
3222 .tiocmset = tiocmset,
3223};
3224
3225static void slgt_cleanup(void)
3226{
3227 int rc;
3228 struct slgt_info *info;
3229 struct slgt_info *tmp;
3230
3231 printk("unload %s %s\n", driver_name, driver_version);
3232
3233 if (serial_driver) {
3234 if ((rc = tty_unregister_driver(serial_driver)))
3235 DBGERR(("tty_unregister_driver error=%d\n", rc));
3236 put_tty_driver(serial_driver);
3237 }
3238
3239 /* reset devices */
3240 info = slgt_device_list;
3241 while(info) {
3242 reset_port(info);
3243 info = info->next_device;
3244 }
3245
3246 /* release devices */
3247 info = slgt_device_list;
3248 while(info) {
3249#ifdef CONFIG_HDLC
3250 hdlcdev_exit(info);
3251#endif
3252 free_dma_bufs(info);
3253 free_tmp_rbuf(info);
3254 if (info->port_num == 0)
3255 release_resources(info);
3256 tmp = info;
3257 info = info->next_device;
3258 kfree(tmp);
3259 }
3260
3261 if (pci_registered)
3262 pci_unregister_driver(&pci_driver);
3263}
3264
3265/*
3266 * Driver initialization entry point.
3267 */
3268static int __init slgt_init(void)
3269{
3270 int rc;
3271
3272 printk("%s %s\n", driver_name, driver_version);
3273
3274 slgt_device_count = 0;
3275 if ((rc = pci_register_driver(&pci_driver)) < 0) {
3276 printk("%s pci_register_driver error=%d\n", driver_name, rc);
3277 return rc;
3278 }
3279 pci_registered = 1;
3280
3281 if (!slgt_device_list) {
3282 printk("%s no devices found\n",driver_name);
3283 return -ENODEV;
3284 }
3285
3286 serial_driver = alloc_tty_driver(MAX_DEVICES);
3287 if (!serial_driver) {
3288 rc = -ENOMEM;
3289 goto error;
3290 }
3291
3292 /* Initialize the tty_driver structure */
3293
3294 serial_driver->owner = THIS_MODULE;
3295 serial_driver->driver_name = tty_driver_name;
3296 serial_driver->name = tty_dev_prefix;
3297 serial_driver->major = ttymajor;
3298 serial_driver->minor_start = 64;
3299 serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
3300 serial_driver->subtype = SERIAL_TYPE_NORMAL;
3301 serial_driver->init_termios = tty_std_termios;
3302 serial_driver->init_termios.c_cflag =
3303 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
3304 serial_driver->flags = TTY_DRIVER_REAL_RAW;
3305 tty_set_operations(serial_driver, &ops);
3306 if ((rc = tty_register_driver(serial_driver)) < 0) {
3307 DBGERR(("%s can't register serial driver\n", driver_name));
3308 put_tty_driver(serial_driver);
3309 serial_driver = NULL;
3310 goto error;
3311 }
3312
3313 printk("%s %s, tty major#%d\n",
3314 driver_name, driver_version,
3315 serial_driver->major);
3316
3317 return 0;
3318
3319error:
3320 slgt_cleanup();
3321 return rc;
3322}
3323
3324static void __exit slgt_exit(void)
3325{
3326 slgt_cleanup();
3327}
3328
3329module_init(slgt_init);
3330module_exit(slgt_exit);
3331
3332/*
3333 * register access routines
3334 */
3335
3336#define CALC_REGADDR() \
3337 unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \
3338 if (addr >= 0x80) \
3339 reg_addr += (info->port_num) * 32;
3340
3341static __u8 rd_reg8(struct slgt_info *info, unsigned int addr)
3342{
3343 CALC_REGADDR();
3344 return readb((void __iomem *)reg_addr);
3345}
3346
3347static void wr_reg8(struct slgt_info *info, unsigned int addr, __u8 value)
3348{
3349 CALC_REGADDR();
3350 writeb(value, (void __iomem *)reg_addr);
3351}
3352
3353static __u16 rd_reg16(struct slgt_info *info, unsigned int addr)
3354{
3355 CALC_REGADDR();
3356 return readw((void __iomem *)reg_addr);
3357}
3358
3359static void wr_reg16(struct slgt_info *info, unsigned int addr, __u16 value)
3360{
3361 CALC_REGADDR();
3362 writew(value, (void __iomem *)reg_addr);
3363}
3364
3365static __u32 rd_reg32(struct slgt_info *info, unsigned int addr)
3366{
3367 CALC_REGADDR();
3368 return readl((void __iomem *)reg_addr);
3369}
3370
3371static void wr_reg32(struct slgt_info *info, unsigned int addr, __u32 value)
3372{
3373 CALC_REGADDR();
3374 writel(value, (void __iomem *)reg_addr);
3375}
3376
3377static void rdma_reset(struct slgt_info *info)
3378{
3379 unsigned int i;
3380
3381 /* set reset bit */
3382 wr_reg32(info, RDCSR, BIT1);
3383
3384 /* wait for enable bit cleared */
3385 for(i=0 ; i < 1000 ; i++)
3386 if (!(rd_reg32(info, RDCSR) & BIT0))
3387 break;
3388}
3389
3390static void tdma_reset(struct slgt_info *info)
3391{
3392 unsigned int i;
3393
3394 /* set reset bit */
3395 wr_reg32(info, TDCSR, BIT1);
3396
3397 /* wait for enable bit cleared */
3398 for(i=0 ; i < 1000 ; i++)
3399 if (!(rd_reg32(info, TDCSR) & BIT0))
3400 break;
3401}
3402
3403/*
3404 * enable internal loopback
3405 * TxCLK and RxCLK are generated from BRG
3406 * and TxD is looped back to RxD internally.
3407 */
3408static void enable_loopback(struct slgt_info *info)
3409{
3410 /* SCR (serial control) BIT2=looopback enable */
3411 wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) | BIT2));
3412
3413 if (info->params.mode != MGSL_MODE_ASYNC) {
3414 /* CCR (clock control)
3415 * 07..05 tx clock source (010 = BRG)
3416 * 04..02 rx clock source (010 = BRG)
3417 * 01 auxclk enable (0 = disable)
3418 * 00 BRG enable (1 = enable)
3419 *
3420 * 0100 1001
3421 */
3422 wr_reg8(info, CCR, 0x49);
3423
3424 /* set speed if available, otherwise use default */
3425 if (info->params.clock_speed)
3426 set_rate(info, info->params.clock_speed);
3427 else
3428 set_rate(info, 3686400);
3429 }
3430}
3431
3432/*
3433 * set baud rate generator to specified rate
3434 */
3435static void set_rate(struct slgt_info *info, u32 rate)
3436{
3437 unsigned int div;
3438 static unsigned int osc = 14745600;
3439
3440 /* div = osc/rate - 1
3441 *
3442 * Round div up if osc/rate is not integer to
3443 * force to next slowest rate.
3444 */
3445
3446 if (rate) {
3447 div = osc/rate;
3448 if (!(osc % rate) && div)
3449 div--;
3450 wr_reg16(info, BDR, (unsigned short)div);
3451 }
3452}
3453
3454static void rx_stop(struct slgt_info *info)
3455{
3456 unsigned short val;
3457
3458 /* disable and reset receiver */
3459 val = rd_reg16(info, RCR) & ~BIT1; /* clear enable bit */
3460 wr_reg16(info, RCR, (unsigned short)(val | BIT2)); /* set reset bit */
3461 wr_reg16(info, RCR, val); /* clear reset bit */
3462
3463 slgt_irq_off(info, IRQ_RXOVER + IRQ_RXDATA + IRQ_RXIDLE);
3464
3465 /* clear pending rx interrupts */
3466 wr_reg16(info, SSR, IRQ_RXIDLE + IRQ_RXOVER);
3467
3468 rdma_reset(info);
3469
3470 info->rx_enabled = 0;
3471 info->rx_restart = 0;
3472}
3473
3474static void rx_start(struct slgt_info *info)
3475{
3476 unsigned short val;
3477
3478 slgt_irq_off(info, IRQ_RXOVER + IRQ_RXDATA);
3479
3480 /* clear pending rx overrun IRQ */
3481 wr_reg16(info, SSR, IRQ_RXOVER);
3482
3483 /* reset and disable receiver */
3484 val = rd_reg16(info, RCR) & ~BIT1; /* clear enable bit */
3485 wr_reg16(info, RCR, (unsigned short)(val | BIT2)); /* set reset bit */
3486 wr_reg16(info, RCR, val); /* clear reset bit */
3487
3488 rdma_reset(info);
3489 reset_rbufs(info);
3490
3491 /* set 1st descriptor address */
3492 wr_reg32(info, RDDAR, info->rbufs[0].pdesc);
3493
3494 if (info->params.mode != MGSL_MODE_ASYNC) {
3495 /* enable rx DMA and DMA interrupt */
3496 wr_reg32(info, RDCSR, (BIT2 + BIT0));
3497 } else {
3498 /* enable saving of rx status, rx DMA and DMA interrupt */
3499 wr_reg32(info, RDCSR, (BIT6 + BIT2 + BIT0));
3500 }
3501
3502 slgt_irq_on(info, IRQ_RXOVER);
3503
3504 /* enable receiver */
3505 wr_reg16(info, RCR, (unsigned short)(rd_reg16(info, RCR) | BIT1));
3506
3507 info->rx_restart = 0;
3508 info->rx_enabled = 1;
3509}
3510
3511static void tx_start(struct slgt_info *info)
3512{
3513 if (!info->tx_enabled) {
3514 wr_reg16(info, TCR,
3515 (unsigned short)(rd_reg16(info, TCR) | BIT1));
3516 info->tx_enabled = TRUE;
3517 }
3518
3519 if (info->tx_count) {
3520 info->drop_rts_on_tx_done = 0;
3521
3522 if (info->params.mode != MGSL_MODE_ASYNC) {
3523 if (info->params.flags & HDLC_FLAG_AUTO_RTS) {
3524 get_signals(info);
3525 if (!(info->signals & SerialSignal_RTS)) {
3526 info->signals |= SerialSignal_RTS;
3527 set_signals(info);
3528 info->drop_rts_on_tx_done = 1;
3529 }
3530 }
3531
3532 slgt_irq_off(info, IRQ_TXDATA);
3533 slgt_irq_on(info, IRQ_TXUNDER + IRQ_TXIDLE);
3534 /* clear tx idle and underrun status bits */
3535 wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER));
3536
3537 if (!(rd_reg32(info, TDCSR) & BIT0)) {
3538 /* tx DMA stopped, restart tx DMA */
3539 tdma_reset(info);
3540 /* set 1st descriptor address */
3541 wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
3542 if (info->params.mode == MGSL_MODE_RAW)
3543 wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
3544 else
3545 wr_reg32(info, TDCSR, BIT0); /* DMA enable */
3546 }
3547
3548 if (info->params.mode != MGSL_MODE_RAW) {
3549 info->tx_timer.expires = jiffies + msecs_to_jiffies(5000);
3550 add_timer(&info->tx_timer);
3551 }
3552 } else {
3553 tdma_reset(info);
3554 /* set 1st descriptor address */
3555 wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
3556
3557 slgt_irq_off(info, IRQ_TXDATA);
3558 slgt_irq_on(info, IRQ_TXIDLE);
3559 /* clear tx idle status bit */
3560 wr_reg16(info, SSR, IRQ_TXIDLE);
3561
3562 /* enable tx DMA */
3563 wr_reg32(info, TDCSR, BIT0);
3564 }
3565
3566 info->tx_active = 1;
3567 }
3568}
3569
3570static void tx_stop(struct slgt_info *info)
3571{
3572 unsigned short val;
3573
3574 del_timer(&info->tx_timer);
3575
3576 tdma_reset(info);
3577
3578 /* reset and disable transmitter */
3579 val = rd_reg16(info, TCR) & ~BIT1; /* clear enable bit */
3580 wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */
3581 wr_reg16(info, TCR, val); /* clear reset */
3582
3583 slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER);
3584
3585 /* clear tx idle and underrun status bit */
3586 wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER));
3587
3588 reset_tbufs(info);
3589
3590 info->tx_enabled = 0;
3591 info->tx_active = 0;
3592}
3593
3594static void reset_port(struct slgt_info *info)
3595{
3596 if (!info->reg_addr)
3597 return;
3598
3599 tx_stop(info);
3600 rx_stop(info);
3601
3602 info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
3603 set_signals(info);
3604
3605 slgt_irq_off(info, IRQ_ALL | IRQ_MASTER);
3606}
3607
3608static void reset_adapter(struct slgt_info *info)
3609{
3610 int i;
3611 for (i=0; i < info->port_count; ++i) {
3612 if (info->port_array[i])
3613 reset_port(info->port_array[i]);
3614 }
3615}
3616
3617static void async_mode(struct slgt_info *info)
3618{
3619 unsigned short val;
3620
3621 slgt_irq_off(info, IRQ_ALL | IRQ_MASTER);
3622 tx_stop(info);
3623 rx_stop(info);
3624
3625 /* TCR (tx control)
3626 *
3627 * 15..13 mode, 010=async
3628 * 12..10 encoding, 000=NRZ
3629 * 09 parity enable
3630 * 08 1=odd parity, 0=even parity
3631 * 07 1=RTS driver control
3632 * 06 1=break enable
3633 * 05..04 character length
3634 * 00=5 bits
3635 * 01=6 bits
3636 * 10=7 bits
3637 * 11=8 bits
3638 * 03 0=1 stop bit, 1=2 stop bits
3639 * 02 reset
3640 * 01 enable
3641 * 00 auto-CTS enable
3642 */
3643 val = 0x4000;
3644
3645 if (info->if_mode & MGSL_INTERFACE_RTS_EN)
3646 val |= BIT7;
3647
3648 if (info->params.parity != ASYNC_PARITY_NONE) {
3649 val |= BIT9;
3650 if (info->params.parity == ASYNC_PARITY_ODD)
3651 val |= BIT8;
3652 }
3653
3654 switch (info->params.data_bits)
3655 {
3656 case 6: val |= BIT4; break;
3657 case 7: val |= BIT5; break;
3658 case 8: val |= BIT5 + BIT4; break;
3659 }
3660
3661 if (info->params.stop_bits != 1)
3662 val |= BIT3;
3663
3664 if (info->params.flags & HDLC_FLAG_AUTO_CTS)
3665 val |= BIT0;
3666
3667 wr_reg16(info, TCR, val);
3668
3669 /* RCR (rx control)
3670 *
3671 * 15..13 mode, 010=async
3672 * 12..10 encoding, 000=NRZ
3673 * 09 parity enable
3674 * 08 1=odd parity, 0=even parity
3675 * 07..06 reserved, must be 0
3676 * 05..04 character length
3677 * 00=5 bits
3678 * 01=6 bits
3679 * 10=7 bits
3680 * 11=8 bits
3681 * 03 reserved, must be zero
3682 * 02 reset
3683 * 01 enable
3684 * 00 auto-DCD enable
3685 */
3686 val = 0x4000;
3687
3688 if (info->params.parity != ASYNC_PARITY_NONE) {
3689 val |= BIT9;
3690 if (info->params.parity == ASYNC_PARITY_ODD)
3691 val |= BIT8;
3692 }
3693
3694 switch (info->params.data_bits)
3695 {
3696 case 6: val |= BIT4; break;
3697 case 7: val |= BIT5; break;
3698 case 8: val |= BIT5 + BIT4; break;
3699 }
3700
3701 if (info->params.flags & HDLC_FLAG_AUTO_DCD)
3702 val |= BIT0;
3703
3704 wr_reg16(info, RCR, val);
3705
3706 /* CCR (clock control)
3707 *
3708 * 07..05 011 = tx clock source is BRG/16
3709 * 04..02 010 = rx clock source is BRG
3710 * 01 0 = auxclk disabled
3711 * 00 1 = BRG enabled
3712 *
3713 * 0110 1001
3714 */
3715 wr_reg8(info, CCR, 0x69);
3716
3717 msc_set_vcr(info);
3718
3719 tx_set_idle(info);
3720
3721 /* SCR (serial control)
3722 *
3723 * 15 1=tx req on FIFO half empty
3724 * 14 1=rx req on FIFO half full
3725 * 13 tx data IRQ enable
3726 * 12 tx idle IRQ enable
3727 * 11 rx break on IRQ enable
3728 * 10 rx data IRQ enable
3729 * 09 rx break off IRQ enable
3730 * 08 overrun IRQ enable
3731 * 07 DSR IRQ enable
3732 * 06 CTS IRQ enable
3733 * 05 DCD IRQ enable
3734 * 04 RI IRQ enable
3735 * 03 reserved, must be zero
3736 * 02 1=txd->rxd internal loopback enable
3737 * 01 reserved, must be zero
3738 * 00 1=master IRQ enable
3739 */
3740 val = BIT15 + BIT14 + BIT0;
3741 wr_reg16(info, SCR, val);
3742
3743 slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER);
3744
3745 set_rate(info, info->params.data_rate * 16);
3746
3747 if (info->params.loopback)
3748 enable_loopback(info);
3749}
3750
3751static void hdlc_mode(struct slgt_info *info)
3752{
3753 unsigned short val;
3754
3755 slgt_irq_off(info, IRQ_ALL | IRQ_MASTER);
3756 tx_stop(info);
3757 rx_stop(info);
3758
3759 /* TCR (tx control)
3760 *
3761 * 15..13 mode, 000=HDLC 001=raw sync
3762 * 12..10 encoding
3763 * 09 CRC enable
3764 * 08 CRC32
3765 * 07 1=RTS driver control
3766 * 06 preamble enable
3767 * 05..04 preamble length
3768 * 03 share open/close flag
3769 * 02 reset
3770 * 01 enable
3771 * 00 auto-CTS enable
3772 */
3773 val = 0;
3774
3775 if (info->params.mode == MGSL_MODE_RAW)
3776 val |= BIT13;
3777 if (info->if_mode & MGSL_INTERFACE_RTS_EN)
3778 val |= BIT7;
3779
3780 switch(info->params.encoding)
3781 {
3782 case HDLC_ENCODING_NRZB: val |= BIT10; break;
3783 case HDLC_ENCODING_NRZI_MARK: val |= BIT11; break;
3784 case HDLC_ENCODING_NRZI: val |= BIT11 + BIT10; break;
3785 case HDLC_ENCODING_BIPHASE_MARK: val |= BIT12; break;
3786 case HDLC_ENCODING_BIPHASE_SPACE: val |= BIT12 + BIT10; break;
3787 case HDLC_ENCODING_BIPHASE_LEVEL: val |= BIT12 + BIT11; break;
3788 case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break;
3789 }
3790
3791 switch (info->params.crc_type)
3792 {
3793 case HDLC_CRC_16_CCITT: val |= BIT9; break;
3794 case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break;
3795 }
3796
3797 if (info->params.preamble != HDLC_PREAMBLE_PATTERN_NONE)
3798 val |= BIT6;
3799
3800 switch (info->params.preamble_length)
3801 {
3802 case HDLC_PREAMBLE_LENGTH_16BITS: val |= BIT5; break;
3803 case HDLC_PREAMBLE_LENGTH_32BITS: val |= BIT4; break;
3804 case HDLC_PREAMBLE_LENGTH_64BITS: val |= BIT5 + BIT4; break;
3805 }
3806
3807 if (info->params.flags & HDLC_FLAG_AUTO_CTS)
3808 val |= BIT0;
3809
3810 wr_reg16(info, TCR, val);
3811
3812 /* TPR (transmit preamble) */
3813
3814 switch (info->params.preamble)
3815 {
3816 case HDLC_PREAMBLE_PATTERN_FLAGS: val = 0x7e; break;
3817 case HDLC_PREAMBLE_PATTERN_ONES: val = 0xff; break;
3818 case HDLC_PREAMBLE_PATTERN_ZEROS: val = 0x00; break;
3819 case HDLC_PREAMBLE_PATTERN_10: val = 0x55; break;
3820 case HDLC_PREAMBLE_PATTERN_01: val = 0xaa; break;
3821 default: val = 0x7e; break;
3822 }
3823 wr_reg8(info, TPR, (unsigned char)val);
3824
3825 /* RCR (rx control)
3826 *
3827 * 15..13 mode, 000=HDLC 001=raw sync
3828 * 12..10 encoding
3829 * 09 CRC enable
3830 * 08 CRC32
3831 * 07..03 reserved, must be 0
3832 * 02 reset
3833 * 01 enable
3834 * 00 auto-DCD enable
3835 */
3836 val = 0;
3837
3838 if (info->params.mode == MGSL_MODE_RAW)
3839 val |= BIT13;
3840
3841 switch(info->params.encoding)
3842 {
3843 case HDLC_ENCODING_NRZB: val |= BIT10; break;
3844 case HDLC_ENCODING_NRZI_MARK: val |= BIT11; break;
3845 case HDLC_ENCODING_NRZI: val |= BIT11 + BIT10; break;
3846 case HDLC_ENCODING_BIPHASE_MARK: val |= BIT12; break;
3847 case HDLC_ENCODING_BIPHASE_SPACE: val |= BIT12 + BIT10; break;
3848 case HDLC_ENCODING_BIPHASE_LEVEL: val |= BIT12 + BIT11; break;
3849 case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break;
3850 }
3851
3852 switch (info->params.crc_type)
3853 {
3854 case HDLC_CRC_16_CCITT: val |= BIT9; break;
3855 case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break;
3856 }
3857
3858 if (info->params.flags & HDLC_FLAG_AUTO_DCD)
3859 val |= BIT0;
3860
3861 wr_reg16(info, RCR, val);
3862
3863 /* CCR (clock control)
3864 *
3865 * 07..05 tx clock source
3866 * 04..02 rx clock source
3867 * 01 auxclk enable
3868 * 00 BRG enable
3869 */
3870 val = 0;
3871
3872 if (info->params.flags & HDLC_FLAG_TXC_BRG)
3873 {
3874 // when RxC source is DPLL, BRG generates 16X DPLL
3875 // reference clock, so take TxC from BRG/16 to get
3876 // transmit clock at actual data rate
3877 if (info->params.flags & HDLC_FLAG_RXC_DPLL)
3878 val |= BIT6 + BIT5; /* 011, txclk = BRG/16 */
3879 else
3880 val |= BIT6; /* 010, txclk = BRG */
3881 }
3882 else if (info->params.flags & HDLC_FLAG_TXC_DPLL)
3883 val |= BIT7; /* 100, txclk = DPLL Input */
3884 else if (info->params.flags & HDLC_FLAG_TXC_RXCPIN)
3885 val |= BIT5; /* 001, txclk = RXC Input */
3886
3887 if (info->params.flags & HDLC_FLAG_RXC_BRG)
3888 val |= BIT3; /* 010, rxclk = BRG */
3889 else if (info->params.flags & HDLC_FLAG_RXC_DPLL)
3890 val |= BIT4; /* 100, rxclk = DPLL */
3891 else if (info->params.flags & HDLC_FLAG_RXC_TXCPIN)
3892 val |= BIT2; /* 001, rxclk = TXC Input */
3893
3894 if (info->params.clock_speed)
3895 val |= BIT1 + BIT0;
3896
3897 wr_reg8(info, CCR, (unsigned char)val);
3898
3899 if (info->params.flags & (HDLC_FLAG_TXC_DPLL + HDLC_FLAG_RXC_DPLL))
3900 {
3901 // program DPLL mode
3902 switch(info->params.encoding)
3903 {
3904 case HDLC_ENCODING_BIPHASE_MARK:
3905 case HDLC_ENCODING_BIPHASE_SPACE:
3906 val = BIT7; break;
3907 case HDLC_ENCODING_BIPHASE_LEVEL:
3908 case HDLC_ENCODING_DIFF_BIPHASE_LEVEL:
3909 val = BIT7 + BIT6; break;
3910 default: val = BIT6; // NRZ encodings
3911 }
3912 wr_reg16(info, RCR, (unsigned short)(rd_reg16(info, RCR) | val));
3913
3914 // DPLL requires a 16X reference clock from BRG
3915 set_rate(info, info->params.clock_speed * 16);
3916 }
3917 else
3918 set_rate(info, info->params.clock_speed);
3919
3920 tx_set_idle(info);
3921
3922 msc_set_vcr(info);
3923
3924 /* SCR (serial control)
3925 *
3926 * 15 1=tx req on FIFO half empty
3927 * 14 1=rx req on FIFO half full
3928 * 13 tx data IRQ enable
3929 * 12 tx idle IRQ enable
3930 * 11 underrun IRQ enable
3931 * 10 rx data IRQ enable
3932 * 09 rx idle IRQ enable
3933 * 08 overrun IRQ enable
3934 * 07 DSR IRQ enable
3935 * 06 CTS IRQ enable
3936 * 05 DCD IRQ enable
3937 * 04 RI IRQ enable
3938 * 03 reserved, must be zero
3939 * 02 1=txd->rxd internal loopback enable
3940 * 01 reserved, must be zero
3941 * 00 1=master IRQ enable
3942 */
3943 wr_reg16(info, SCR, BIT15 + BIT14 + BIT0);
3944
3945 if (info->params.loopback)
3946 enable_loopback(info);
3947}
3948
3949/*
3950 * set transmit idle mode
3951 */
3952static void tx_set_idle(struct slgt_info *info)
3953{
3954 unsigned char val = 0xff;
3955
3956 switch(info->idle_mode)
3957 {
3958 case HDLC_TXIDLE_FLAGS: val = 0x7e; break;
3959 case HDLC_TXIDLE_ALT_ZEROS_ONES: val = 0xaa; break;
3960 case HDLC_TXIDLE_ZEROS: val = 0x00; break;
3961 case HDLC_TXIDLE_ONES: val = 0xff; break;
3962 case HDLC_TXIDLE_ALT_MARK_SPACE: val = 0xaa; break;
3963 case HDLC_TXIDLE_SPACE: val = 0x00; break;
3964 case HDLC_TXIDLE_MARK: val = 0xff; break;
3965 }
3966
3967 wr_reg8(info, TIR, val);
3968}
3969
3970/*
3971 * get state of V24 status (input) signals
3972 */
3973static void get_signals(struct slgt_info *info)
3974{
3975 unsigned short status = rd_reg16(info, SSR);
3976
3977 /* clear all serial signals except DTR and RTS */
3978 info->signals &= SerialSignal_DTR + SerialSignal_RTS;
3979
3980 if (status & BIT3)
3981 info->signals |= SerialSignal_DSR;
3982 if (status & BIT2)
3983 info->signals |= SerialSignal_CTS;
3984 if (status & BIT1)
3985 info->signals |= SerialSignal_DCD;
3986 if (status & BIT0)
3987 info->signals |= SerialSignal_RI;
3988}
3989
3990/*
3991 * set V.24 Control Register based on current configuration
3992 */
3993static void msc_set_vcr(struct slgt_info *info)
3994{
3995 unsigned char val = 0;
3996
3997 /* VCR (V.24 control)
3998 *
3999 * 07..04 serial IF select
4000 * 03 DTR
4001 * 02 RTS
4002 * 01 LL
4003 * 00 RL
4004 */
4005
4006 switch(info->if_mode & MGSL_INTERFACE_MASK)
4007 {
4008 case MGSL_INTERFACE_RS232:
4009 val |= BIT5; /* 0010 */
4010 break;
4011 case MGSL_INTERFACE_V35:
4012 val |= BIT7 + BIT6 + BIT5; /* 1110 */
4013 break;
4014 case MGSL_INTERFACE_RS422:
4015 val |= BIT6; /* 0100 */
4016 break;
4017 }
4018
4019 if (info->signals & SerialSignal_DTR)
4020 val |= BIT3;
4021 if (info->signals & SerialSignal_RTS)
4022 val |= BIT2;
4023 if (info->if_mode & MGSL_INTERFACE_LL)
4024 val |= BIT1;
4025 if (info->if_mode & MGSL_INTERFACE_RL)
4026 val |= BIT0;
4027 wr_reg8(info, VCR, val);
4028}
4029
4030/*
4031 * set state of V24 control (output) signals
4032 */
4033static void set_signals(struct slgt_info *info)
4034{
4035 unsigned char val = rd_reg8(info, VCR);
4036 if (info->signals & SerialSignal_DTR)
4037 val |= BIT3;
4038 else
4039 val &= ~BIT3;
4040 if (info->signals & SerialSignal_RTS)
4041 val |= BIT2;
4042 else
4043 val &= ~BIT2;
4044 wr_reg8(info, VCR, val);
4045}
4046
4047/*
4048 * free range of receive DMA buffers (i to last)
4049 */
4050static void free_rbufs(struct slgt_info *info, unsigned int i, unsigned int last)
4051{
4052 int done = 0;
4053
4054 while(!done) {
4055 /* reset current buffer for reuse */
4056 info->rbufs[i].status = 0;
4057 if (info->params.mode == MGSL_MODE_RAW)
4058 set_desc_count(info->rbufs[i], info->raw_rx_size);
4059 else
4060 set_desc_count(info->rbufs[i], DMABUFSIZE);
4061
4062 if (i == last)
4063 done = 1;
4064 if (++i == info->rbuf_count)
4065 i = 0;
4066 }
4067 info->rbuf_current = i;
4068}
4069
4070/*
4071 * mark all receive DMA buffers as free
4072 */
4073static void reset_rbufs(struct slgt_info *info)
4074{
4075 free_rbufs(info, 0, info->rbuf_count - 1);
4076}
4077
4078/*
4079 * pass receive HDLC frame to upper layer
4080 *
4081 * return 1 if frame available, otherwise 0
4082 */
4083static int rx_get_frame(struct slgt_info *info)
4084{
4085 unsigned int start, end;
4086 unsigned short status;
4087 unsigned int framesize = 0;
4088 int rc = 0;
4089 unsigned long flags;
4090 struct tty_struct *tty = info->tty;
4091 unsigned char addr_field = 0xff;
4092
4093check_again:
4094
4095 framesize = 0;
4096 addr_field = 0xff;
4097 start = end = info->rbuf_current;
4098
4099 for (;;) {
4100 if (!desc_complete(info->rbufs[end]))
4101 goto cleanup;
4102
4103 if (framesize == 0 && info->params.addr_filter != 0xff)
4104 addr_field = info->rbufs[end].buf[0];
4105
4106 framesize += desc_count(info->rbufs[end]);
4107
4108 if (desc_eof(info->rbufs[end]))
4109 break;
4110
4111 if (++end == info->rbuf_count)
4112 end = 0;
4113
4114 if (end == info->rbuf_current) {
4115 if (info->rx_enabled){
4116 spin_lock_irqsave(&info->lock,flags);
4117 rx_start(info);
4118 spin_unlock_irqrestore(&info->lock,flags);
4119 }
4120 goto cleanup;
4121 }
4122 }
4123
4124 /* status
4125 *
4126 * 15 buffer complete
4127 * 14..06 reserved
4128 * 05..04 residue
4129 * 02 eof (end of frame)
4130 * 01 CRC error
4131 * 00 abort
4132 */
4133 status = desc_status(info->rbufs[end]);
4134
4135 /* ignore CRC bit if not using CRC (bit is undefined) */
4136 if (info->params.crc_type == HDLC_CRC_NONE)
4137 status &= ~BIT1;
4138
4139 if (framesize == 0 ||
4140 (addr_field != 0xff && addr_field != info->params.addr_filter)) {
4141 free_rbufs(info, start, end);
4142 goto check_again;
4143 }
4144
4145 if (framesize < 2 || status & (BIT1+BIT0)) {
4146 if (framesize < 2 || (status & BIT0))
4147 info->icount.rxshort++;
4148 else
4149 info->icount.rxcrc++;
4150 framesize = 0;
4151
4152#ifdef CONFIG_HDLC
4153 {
4154 struct net_device_stats *stats = hdlc_stats(info->netdev);
4155 stats->rx_errors++;
4156 stats->rx_frame_errors++;
4157 }
4158#endif
4159 } else {
4160 /* adjust frame size for CRC, if any */
4161 if (info->params.crc_type == HDLC_CRC_16_CCITT)
4162 framesize -= 2;
4163 else if (info->params.crc_type == HDLC_CRC_32_CCITT)
4164 framesize -= 4;
4165 }
4166
4167 DBGBH(("%s rx frame status=%04X size=%d\n",
4168 info->device_name, status, framesize));
4169 DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, DMABUFSIZE), "rx");
4170
4171 if (framesize) {
4172 if (framesize > info->max_frame_size)
4173 info->icount.rxlong++;
4174 else {
4175 /* copy dma buffer(s) to contiguous temp buffer */
4176 int copy_count = framesize;
4177 int i = start;
4178 unsigned char *p = info->tmp_rbuf;
4179 info->tmp_rbuf_count = framesize;
4180
4181 info->icount.rxok++;
4182
4183 while(copy_count) {
4184 int partial_count = min(copy_count, DMABUFSIZE);
4185 memcpy(p, info->rbufs[i].buf, partial_count);
4186 p += partial_count;
4187 copy_count -= partial_count;
4188 if (++i == info->rbuf_count)
4189 i = 0;
4190 }
4191
4192#ifdef CONFIG_HDLC
4193 if (info->netcount)
4194 hdlcdev_rx(info,info->tmp_rbuf, framesize);
4195 else
4196#endif
4197 ldisc_receive_buf(tty, info->tmp_rbuf, info->flag_buf, framesize);
4198 }
4199 }
4200 free_rbufs(info, start, end);
4201 rc = 1;
4202
4203cleanup:
4204 return rc;
4205}
4206
4207/*
4208 * pass receive buffer (RAW synchronous mode) to tty layer
4209 * return 1 if buffer available, otherwise 0
4210 */
4211static int rx_get_buf(struct slgt_info *info)
4212{
4213 unsigned int i = info->rbuf_current;
4214
4215 if (!desc_complete(info->rbufs[i]))
4216 return 0;
4217 DBGDATA(info, info->rbufs[i].buf, desc_count(info->rbufs[i]), "rx");
4218 DBGINFO(("rx_get_buf size=%d\n", desc_count(info->rbufs[i])));
4219 ldisc_receive_buf(info->tty, info->rbufs[i].buf,
4220 info->flag_buf, desc_count(info->rbufs[i]));
4221 free_rbufs(info, i, i);
4222 return 1;
4223}
4224
4225static void reset_tbufs(struct slgt_info *info)
4226{
4227 unsigned int i;
4228 info->tbuf_current = 0;
4229 for (i=0 ; i < info->tbuf_count ; i++) {
4230 info->tbufs[i].status = 0;
4231 info->tbufs[i].count = 0;
4232 }
4233}
4234
4235/*
4236 * return number of free transmit DMA buffers
4237 */
4238static unsigned int free_tbuf_count(struct slgt_info *info)
4239{
4240 unsigned int count = 0;
4241 unsigned int i = info->tbuf_current;
4242
4243 do
4244 {
4245 if (desc_count(info->tbufs[i]))
4246 break; /* buffer in use */
4247 ++count;
4248 if (++i == info->tbuf_count)
4249 i=0;
4250 } while (i != info->tbuf_current);
4251
4252 /* last buffer with zero count may be in use, assume it is */
4253 if (count)
4254 --count;
4255
4256 return count;
4257}
4258
4259/*
4260 * load transmit DMA buffer(s) with data
4261 */
4262static void tx_load(struct slgt_info *info, const char *buf, unsigned int size)
4263{
4264 unsigned short count;
4265 unsigned int i;
4266 struct slgt_desc *d;
4267
4268 if (size == 0)
4269 return;
4270
4271 DBGDATA(info, buf, size, "tx");
4272
4273 info->tbuf_start = i = info->tbuf_current;
4274
4275 while (size) {
4276 d = &info->tbufs[i];
4277 if (++i == info->tbuf_count)
4278 i = 0;
4279
4280 count = (unsigned short)((size > DMABUFSIZE) ? DMABUFSIZE : size);
4281 memcpy(d->buf, buf, count);
4282
4283 size -= count;
4284 buf += count;
4285
4286 if (!size && info->params.mode != MGSL_MODE_RAW)
4287 set_desc_eof(*d, 1); /* HDLC: set EOF of last desc */
4288 else
4289 set_desc_eof(*d, 0);
4290
4291 set_desc_count(*d, count);
4292 }
4293
4294 info->tbuf_current = i;
4295}
4296
4297static int register_test(struct slgt_info *info)
4298{
4299 static unsigned short patterns[] =
4300 {0x0000, 0xffff, 0xaaaa, 0x5555, 0x6969, 0x9696};
4301 static unsigned int count = sizeof(patterns)/sizeof(patterns[0]);
4302 unsigned int i;
4303 int rc = 0;
4304
4305 for (i=0 ; i < count ; i++) {
4306 wr_reg16(info, TIR, patterns[i]);
4307 wr_reg16(info, BDR, patterns[(i+1)%count]);
4308 if ((rd_reg16(info, TIR) != patterns[i]) ||
4309 (rd_reg16(info, BDR) != patterns[(i+1)%count])) {
4310 rc = -ENODEV;
4311 break;
4312 }
4313 }
4314
4315 info->init_error = rc ? 0 : DiagStatus_AddressFailure;
4316 return rc;
4317}
4318
4319static int irq_test(struct slgt_info *info)
4320{
4321 unsigned long timeout;
4322 unsigned long flags;
4323 struct tty_struct *oldtty = info->tty;
4324 u32 speed = info->params.data_rate;
4325
4326 info->params.data_rate = 921600;
4327 info->tty = NULL;
4328
4329 spin_lock_irqsave(&info->lock, flags);
4330 async_mode(info);
4331 slgt_irq_on(info, IRQ_TXIDLE);
4332
4333 /* enable transmitter */
4334 wr_reg16(info, TCR,
4335 (unsigned short)(rd_reg16(info, TCR) | BIT1));
4336
4337 /* write one byte and wait for tx idle */
4338 wr_reg16(info, TDR, 0);
4339
4340 /* assume failure */
4341 info->init_error = DiagStatus_IrqFailure;
4342 info->irq_occurred = FALSE;
4343
4344 spin_unlock_irqrestore(&info->lock, flags);
4345
4346 timeout=100;
4347 while(timeout-- && !info->irq_occurred)
4348 msleep_interruptible(10);
4349
4350 spin_lock_irqsave(&info->lock,flags);
4351 reset_port(info);
4352 spin_unlock_irqrestore(&info->lock,flags);
4353
4354 info->params.data_rate = speed;
4355 info->tty = oldtty;
4356
4357 info->init_error = info->irq_occurred ? 0 : DiagStatus_IrqFailure;
4358 return info->irq_occurred ? 0 : -ENODEV;
4359}
4360
4361static int loopback_test_rx(struct slgt_info *info)
4362{
4363 unsigned char *src, *dest;
4364 int count;
4365
4366 if (desc_complete(info->rbufs[0])) {
4367 count = desc_count(info->rbufs[0]);
4368 src = info->rbufs[0].buf;
4369 dest = info->tmp_rbuf;
4370
4371 for( ; count ; count-=2, src+=2) {
4372 /* src=data byte (src+1)=status byte */
4373 if (!(*(src+1) & (BIT9 + BIT8))) {
4374 *dest = *src;
4375 dest++;
4376 info->tmp_rbuf_count++;
4377 }
4378 }
4379 DBGDATA(info, info->tmp_rbuf, info->tmp_rbuf_count, "rx");
4380 return 1;
4381 }
4382 return 0;
4383}
4384
4385static int loopback_test(struct slgt_info *info)
4386{
4387#define TESTFRAMESIZE 20
4388
4389 unsigned long timeout;
4390 u16 count = TESTFRAMESIZE;
4391 unsigned char buf[TESTFRAMESIZE];
4392 int rc = -ENODEV;
4393 unsigned long flags;
4394
4395 struct tty_struct *oldtty = info->tty;
4396 MGSL_PARAMS params;
4397
4398 memcpy(&params, &info->params, sizeof(params));
4399
4400 info->params.mode = MGSL_MODE_ASYNC;
4401 info->params.data_rate = 921600;
4402 info->params.loopback = 1;
4403 info->tty = NULL;
4404
4405 /* build and send transmit frame */
4406 for (count = 0; count < TESTFRAMESIZE; ++count)
4407 buf[count] = (unsigned char)count;
4408
4409 info->tmp_rbuf_count = 0;
4410 memset(info->tmp_rbuf, 0, TESTFRAMESIZE);
4411
4412 /* program hardware for HDLC and enabled receiver */
4413 spin_lock_irqsave(&info->lock,flags);
4414 async_mode(info);
4415 rx_start(info);
4416 info->tx_count = count;
4417 tx_load(info, buf, count);
4418 tx_start(info);
4419 spin_unlock_irqrestore(&info->lock, flags);
4420
4421 /* wait for receive complete */
4422 for (timeout = 100; timeout; --timeout) {
4423 msleep_interruptible(10);
4424 if (loopback_test_rx(info)) {
4425 rc = 0;
4426 break;
4427 }
4428 }
4429
4430 /* verify received frame length and contents */
4431 if (!rc && (info->tmp_rbuf_count != count ||
4432 memcmp(buf, info->tmp_rbuf, count))) {
4433 rc = -ENODEV;
4434 }
4435
4436 spin_lock_irqsave(&info->lock,flags);
4437 reset_adapter(info);
4438 spin_unlock_irqrestore(&info->lock,flags);
4439
4440 memcpy(&info->params, &params, sizeof(info->params));
4441 info->tty = oldtty;
4442
4443 info->init_error = rc ? DiagStatus_DmaFailure : 0;
4444 return rc;
4445}
4446
4447static int adapter_test(struct slgt_info *info)
4448{
4449 DBGINFO(("testing %s\n", info->device_name));
4450 if ((info->init_error = register_test(info)) < 0) {
4451 printk("register test failure %s addr=%08X\n",
4452 info->device_name, info->phys_reg_addr);
4453 } else if ((info->init_error = irq_test(info)) < 0) {
4454 printk("IRQ test failure %s IRQ=%d\n",
4455 info->device_name, info->irq_level);
4456 } else if ((info->init_error = loopback_test(info)) < 0) {
4457 printk("loopback test failure %s\n", info->device_name);
4458 }
4459 return info->init_error;
4460}
4461
4462/*
4463 * transmit timeout handler
4464 */
4465static void tx_timeout(unsigned long context)
4466{
4467 struct slgt_info *info = (struct slgt_info*)context;
4468 unsigned long flags;
4469
4470 DBGINFO(("%s tx_timeout\n", info->device_name));
4471 if(info->tx_active && info->params.mode == MGSL_MODE_HDLC) {
4472 info->icount.txtimeout++;
4473 }
4474 spin_lock_irqsave(&info->lock,flags);
4475 info->tx_active = 0;
4476 info->tx_count = 0;
4477 spin_unlock_irqrestore(&info->lock,flags);
4478
4479#ifdef CONFIG_HDLC
4480 if (info->netcount)
4481 hdlcdev_tx_done(info);
4482 else
4483#endif
4484 bh_transmit(info);
4485}
4486
4487/*
4488 * receive buffer polling timer
4489 */
4490static void rx_timeout(unsigned long context)
4491{
4492 struct slgt_info *info = (struct slgt_info*)context;
4493 unsigned long flags;
4494
4495 DBGINFO(("%s rx_timeout\n", info->device_name));
4496 spin_lock_irqsave(&info->lock, flags);
4497 info->pending_bh |= BH_RECEIVE;
4498 spin_unlock_irqrestore(&info->lock, flags);
4499 bh_handler(info);
4500}
4501
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index 2392e404e8d1..ba4582d160fd 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -2,6 +2,9 @@
2# Makefile for the kernel tpm device drivers. 2# Makefile for the kernel tpm device drivers.
3# 3#
4obj-$(CONFIG_TCG_TPM) += tpm.o 4obj-$(CONFIG_TCG_TPM) += tpm.o
5ifdef CONFIG_ACPI
6 obj-$(CONFIG_TCG_TPM) += tpm_bios.o
7endif
5obj-$(CONFIG_TCG_NSC) += tpm_nsc.o 8obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
6obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o 9obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
7obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o 10obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index a9be0e8eaea5..5a3870477ef1 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -466,6 +466,7 @@ void tpm_remove_hardware(struct device *dev)
466 kfree(chip->vendor->miscdev.name); 466 kfree(chip->vendor->miscdev.name);
467 467
468 sysfs_remove_group(&dev->kobj, chip->vendor->attr_group); 468 sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
469 tpm_bios_log_teardown(chip->bios_dir);
469 470
470 dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= 471 dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
471 ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES)); 472 ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
@@ -593,6 +594,8 @@ dev_num_search_complete:
593 594
594 sysfs_create_group(&dev->kobj, chip->vendor->attr_group); 595 sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
595 596
597 chip->bios_dir = tpm_bios_log_setup(devname);
598
596 return 0; 599 return 0;
597} 600}
598EXPORT_SYMBOL_GPL(tpm_register_hardware); 601EXPORT_SYMBOL_GPL(tpm_register_hardware);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 159882ca69dd..fd3a4beaa53d 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -82,6 +82,8 @@ struct tpm_chip {
82 82
83 struct tpm_vendor_specific *vendor; 83 struct tpm_vendor_specific *vendor;
84 84
85 struct dentry **bios_dir;
86
85 struct list_head list; 87 struct list_head list;
86}; 88};
87 89
@@ -107,3 +109,16 @@ extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
107extern void tpm_remove_hardware(struct device *); 109extern void tpm_remove_hardware(struct device *);
108extern int tpm_pm_suspend(struct device *, pm_message_t); 110extern int tpm_pm_suspend(struct device *, pm_message_t);
109extern int tpm_pm_resume(struct device *); 111extern int tpm_pm_resume(struct device *);
112
113#ifdef CONFIG_ACPI
114extern struct dentry ** tpm_bios_log_setup(char *);
115extern void tpm_bios_log_teardown(struct dentry **);
116#else
117static inline struct dentry* tpm_bios_log_setup(char *name)
118{
119 return NULL;
120}
121static inline void tpm_bios_log_teardown(struct dentry **dir)
122{
123}
124#endif
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c
new file mode 100644
index 000000000000..aedf7a8e6da7
--- /dev/null
+++ b/drivers/char/tpm/tpm_bios.c
@@ -0,0 +1,540 @@
1/*
2 * Copyright (C) 2005 IBM Corporation
3 *
4 * Authors:
5 * Seiji Munetoh <munetoh@jp.ibm.com>
6 * Stefan Berger <stefanb@us.ibm.com>
7 * Reiner Sailer <sailer@watson.ibm.com>
8 * Kylene Hall <kjhall@us.ibm.com>
9 *
10 * Access to the eventlog extended by the TCG BIOS of PC platform
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
16 *
17 */
18
19#include <linux/seq_file.h>
20#include <linux/fs.h>
21#include <linux/security.h>
22#include <linux/module.h>
23#include <acpi/acpi.h>
24#include <acpi/actypes.h>
25#include <acpi/actbl.h>
26#include "tpm.h"
27
28#define TCG_EVENT_NAME_LEN_MAX 255
29#define MAX_TEXT_EVENT 1000 /* Max event string length */
30#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */
31
32struct tpm_bios_log {
33 void *bios_event_log;
34 void *bios_event_log_end;
35};
36
37struct acpi_tcpa {
38 struct acpi_table_header hdr;
39 u16 reserved;
40 u32 log_max_len __attribute__ ((packed));
41 u32 log_start_addr __attribute__ ((packed));
42};
43
44struct tcpa_event {
45 u32 pcr_index;
46 u32 event_type;
47 u8 pcr_value[20]; /* SHA1 */
48 u32 event_size;
49 u8 event_data[0];
50};
51
52enum tcpa_event_types {
53 PREBOOT = 0,
54 POST_CODE,
55 UNUSED,
56 NO_ACTION,
57 SEPARATOR,
58 ACTION,
59 EVENT_TAG,
60 SCRTM_CONTENTS,
61 SCRTM_VERSION,
62 CPU_MICROCODE,
63 PLATFORM_CONFIG_FLAGS,
64 TABLE_OF_DEVICES,
65 COMPACT_HASH,
66 IPL,
67 IPL_PARTITION_DATA,
68 NONHOST_CODE,
69 NONHOST_CONFIG,
70 NONHOST_INFO,
71};
72
73static const char* tcpa_event_type_strings[] = {
74 "PREBOOT",
75 "POST CODE",
76 "",
77 "NO ACTION",
78 "SEPARATOR",
79 "ACTION",
80 "EVENT TAG",
81 "S-CRTM Contents",
82 "S-CRTM Version",
83 "CPU Microcode",
84 "Platform Config Flags",
85 "Table of Devices",
86 "Compact Hash",
87 "IPL",
88 "IPL Partition Data",
89 "Non-Host Code",
90 "Non-Host Config",
91 "Non-Host Info"
92};
93
94enum tcpa_pc_event_ids {
95 SMBIOS = 1,
96 BIS_CERT,
97 POST_BIOS_ROM,
98 ESCD,
99 CMOS,
100 NVRAM,
101 OPTION_ROM_EXEC,
102 OPTION_ROM_CONFIG,
103 OPTION_ROM_MICROCODE,
104 S_CRTM_VERSION,
105 S_CRTM_CONTENTS,
106 POST_CONTENTS,
107};
108
109static const char* tcpa_pc_event_id_strings[] = {
110 ""
111 "SMBIOS",
112 "BIS Certificate",
113 "POST BIOS ",
114 "ESCD ",
115 "CMOS",
116 "NVRAM",
117 "Option ROM",
118 "Option ROM config",
119 "Option ROM microcode",
120 "S-CRTM Version",
121 "S-CRTM Contents",
122 "S-CRTM POST Contents",
123};
124
125/* returns pointer to start of pos. entry of tcg log */
126static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos)
127{
128 loff_t i;
129 struct tpm_bios_log *log = m->private;
130 void *addr = log->bios_event_log;
131 void *limit = log->bios_event_log_end;
132 struct tcpa_event *event;
133
134 /* read over *pos measurements */
135 for (i = 0; i < *pos; i++) {
136 event = addr;
137
138 if ((addr + sizeof(struct tcpa_event)) < limit) {
139 if (event->event_type == 0 && event->event_size == 0)
140 return NULL;
141 addr += sizeof(struct tcpa_event) + event->event_size;
142 }
143 }
144
145 /* now check if current entry is valid */
146 if ((addr + sizeof(struct tcpa_event)) >= limit)
147 return NULL;
148
149 event = addr;
150
151 if ((event->event_type == 0 && event->event_size == 0) ||
152 ((addr + sizeof(struct tcpa_event) + event->event_size) >= limit))
153 return NULL;
154
155 return addr;
156}
157
158static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
159 loff_t *pos)
160{
161 struct tcpa_event *event = v;
162 struct tpm_bios_log *log = m->private;
163 void *limit = log->bios_event_log_end;
164
165 v += sizeof(struct tcpa_event) + event->event_size;
166
167 /* now check if current entry is valid */
168 if ((v + sizeof(struct tcpa_event)) >= limit)
169 return NULL;
170
171 event = v;
172
173 if (event->event_type == 0 && event->event_size == 0)
174 return NULL;
175
176 if ((event->event_type == 0 && event->event_size == 0) ||
177 ((v + sizeof(struct tcpa_event) + event->event_size) >= limit))
178 return NULL;
179
180 (*pos)++;
181 return v;
182}
183
184static void tpm_bios_measurements_stop(struct seq_file *m, void *v)
185{
186}
187
188static int get_event_name(char *dest, struct tcpa_event *event,
189 unsigned char * event_entry)
190{
191 const char *name = "";
192 char data[40] = "";
193 int i, n_len = 0, d_len = 0;
194 u32 event_id, event_data_size;
195
196 switch(event->event_type) {
197 case PREBOOT:
198 case POST_CODE:
199 case UNUSED:
200 case NO_ACTION:
201 case SCRTM_CONTENTS:
202 case SCRTM_VERSION:
203 case CPU_MICROCODE:
204 case PLATFORM_CONFIG_FLAGS:
205 case TABLE_OF_DEVICES:
206 case COMPACT_HASH:
207 case IPL:
208 case IPL_PARTITION_DATA:
209 case NONHOST_CODE:
210 case NONHOST_CONFIG:
211 case NONHOST_INFO:
212 name = tcpa_event_type_strings[event->event_type];
213 n_len = strlen(name);
214 break;
215 case SEPARATOR:
216 case ACTION:
217 if (MAX_TEXT_EVENT > event->event_size) {
218 name = event_entry;
219 n_len = event->event_size;
220 }
221 break;
222 case EVENT_TAG:
223 event_id = be32_to_cpu(event_entry);
224 event_data_size = be32_to_cpu(&event_entry[4]);
225
226 /* ToDo Row data -> Base64 */
227
228 switch (event_id) {
229 case SMBIOS:
230 case BIS_CERT:
231 case CMOS:
232 case NVRAM:
233 case OPTION_ROM_EXEC:
234 case OPTION_ROM_CONFIG:
235 case OPTION_ROM_MICROCODE:
236 case S_CRTM_VERSION:
237 case S_CRTM_CONTENTS:
238 case POST_CONTENTS:
239 name = tcpa_pc_event_id_strings[event_id];
240 n_len = strlen(name);
241 break;
242 case POST_BIOS_ROM:
243 case ESCD:
244 name = tcpa_pc_event_id_strings[event_id];
245 n_len = strlen(name);
246 for (i = 0; i < 20; i++)
247 d_len += sprintf(data, "%02x",
248 event_entry[8 + i]);
249 break;
250 default:
251 break;
252 }
253 default:
254 break;
255 }
256
257 return snprintf(dest, MAX_TEXT_EVENT, "[%.*s%.*s]",
258 n_len, name, d_len, data);
259
260}
261
262static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
263{
264
265 char *eventname;
266 char data[4];
267 u32 help;
268 int i, len;
269 struct tcpa_event *event = (struct tcpa_event *) v;
270 unsigned char *event_entry =
271 (unsigned char *) (v + sizeof(struct tcpa_event));
272
273 eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
274 if (!eventname) {
275 printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
276 __func__);
277 return -ENOMEM;
278 }
279
280 /* 1st: PCR used is in little-endian format (4 bytes) */
281 help = le32_to_cpu(event->pcr_index);
282 memcpy(data, &help, 4);
283 for (i = 0; i < 4; i++)
284 seq_putc(m, data[i]);
285
286 /* 2nd: SHA1 (20 bytes) */
287 for (i = 0; i < 20; i++)
288 seq_putc(m, event->pcr_value[i]);
289
290 /* 3rd: event type identifier (4 bytes) */
291 help = le32_to_cpu(event->event_type);
292 memcpy(data, &help, 4);
293 for (i = 0; i < 4; i++)
294 seq_putc(m, data[i]);
295
296 len = 0;
297
298 len += get_event_name(eventname, event, event_entry);
299
300 /* 4th: filename <= 255 + \'0' delimiter */
301 if (len > TCG_EVENT_NAME_LEN_MAX)
302 len = TCG_EVENT_NAME_LEN_MAX;
303
304 for (i = 0; i < len; i++)
305 seq_putc(m, eventname[i]);
306
307 /* 5th: delimiter */
308 seq_putc(m, '\0');
309
310 return 0;
311}
312
313static int tpm_bios_measurements_release(struct inode *inode,
314 struct file *file)
315{
316 struct seq_file *seq = file->private_data;
317 struct tpm_bios_log *log = seq->private;
318
319 if (log) {
320 kfree(log->bios_event_log);
321 kfree(log);
322 }
323
324 return seq_release(inode, file);
325}
326
327static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
328{
329 int len = 0;
330 int i;
331 char *eventname;
332 struct tcpa_event *event = v;
333 unsigned char *event_entry =
334 (unsigned char *) (v + sizeof(struct tcpa_event));
335
336 eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
337 if (!eventname) {
338 printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
339 __func__);
340 return -EFAULT;
341 }
342
343 seq_printf(m, "%2d ", event->pcr_index);
344
345 /* 2nd: SHA1 */
346 for (i = 0; i < 20; i++)
347 seq_printf(m, "%02x", event->pcr_value[i]);
348
349 /* 3rd: event type identifier */
350 seq_printf(m, " %02x", event->event_type);
351
352 len += get_event_name(eventname, event, event_entry);
353
354 /* 4th: eventname <= max + \'0' delimiter */
355 seq_printf(m, " %s\n", eventname);
356
357 return 0;
358}
359
360static struct seq_operations tpm_ascii_b_measurments_seqops = {
361 .start = tpm_bios_measurements_start,
362 .next = tpm_bios_measurements_next,
363 .stop = tpm_bios_measurements_stop,
364 .show = tpm_ascii_bios_measurements_show,
365};
366
367static struct seq_operations tpm_binary_b_measurments_seqops = {
368 .start = tpm_bios_measurements_start,
369 .next = tpm_bios_measurements_next,
370 .stop = tpm_bios_measurements_stop,
371 .show = tpm_binary_bios_measurements_show,
372};
373
374/* read binary bios log */
375static int read_log(struct tpm_bios_log *log)
376{
377 struct acpi_tcpa *buff;
378 acpi_status status;
379 void *virt;
380
381 if (log->bios_event_log != NULL) {
382 printk(KERN_ERR
383 "%s: ERROR - Eventlog already initialized\n",
384 __func__);
385 return -EFAULT;
386 }
387
388 /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
389 status = acpi_get_firmware_table(ACPI_TCPA_SIG, 1,
390 ACPI_LOGICAL_ADDRESSING,
391 (struct acpi_table_header **)
392 &buff);
393
394 if (ACPI_FAILURE(status)) {
395 printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n",
396 __func__);
397 return -EIO;
398 }
399
400 if (buff->log_max_len == 0) {
401 printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
402 return -EIO;
403 }
404
405 /* malloc EventLog space */
406 log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
407 if (!log->bios_event_log) {
408 printk
409 ("%s: ERROR - Not enough Memory for BIOS measurements\n",
410 __func__);
411 return -ENOMEM;
412 }
413
414 log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
415
416 acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, &virt);
417
418 memcpy(log->bios_event_log, virt, buff->log_max_len);
419
420 acpi_os_unmap_memory(virt, buff->log_max_len);
421 return 0;
422}
423
424static int tpm_ascii_bios_measurements_open(struct inode *inode,
425 struct file *file)
426{
427 int err;
428 struct tpm_bios_log *log;
429 struct seq_file *seq;
430
431 log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL);
432 if (!log)
433 return -ENOMEM;
434
435 if ((err = read_log(log)))
436 return err;
437
438 /* now register seq file */
439 err = seq_open(file, &tpm_ascii_b_measurments_seqops);
440 if (!err) {
441 seq = file->private_data;
442 seq->private = log;
443 } else {
444 kfree(log->bios_event_log);
445 kfree(log);
446 }
447 return err;
448}
449
450struct file_operations tpm_ascii_bios_measurements_ops = {
451 .open = tpm_ascii_bios_measurements_open,
452 .read = seq_read,
453 .llseek = seq_lseek,
454 .release = tpm_bios_measurements_release,
455};
456
457static int tpm_binary_bios_measurements_open(struct inode *inode,
458 struct file *file)
459{
460 int err;
461 struct tpm_bios_log *log;
462 struct seq_file *seq;
463
464 log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL);
465 if (!log)
466 return -ENOMEM;
467
468 if ((err = read_log(log)))
469 return err;
470
471 /* now register seq file */
472 err = seq_open(file, &tpm_binary_b_measurments_seqops);
473 if (!err) {
474 seq = file->private_data;
475 seq->private = log;
476 } else {
477 kfree(log->bios_event_log);
478 kfree(log);
479 }
480 return err;
481}
482
483struct file_operations tpm_binary_bios_measurements_ops = {
484 .open = tpm_binary_bios_measurements_open,
485 .read = seq_read,
486 .llseek = seq_lseek,
487 .release = tpm_bios_measurements_release,
488};
489
490struct dentry **tpm_bios_log_setup(char *name)
491{
492 struct dentry **ret = NULL, *tpm_dir, *bin_file, *ascii_file;
493
494 tpm_dir = securityfs_create_dir(name, NULL);
495 if (!tpm_dir)
496 goto out;
497
498 bin_file =
499 securityfs_create_file("binary_bios_measurements",
500 S_IRUSR | S_IRGRP, tpm_dir, NULL,
501 &tpm_binary_bios_measurements_ops);
502 if (!bin_file)
503 goto out_tpm;
504
505 ascii_file =
506 securityfs_create_file("ascii_bios_measurements",
507 S_IRUSR | S_IRGRP, tpm_dir, NULL,
508 &tpm_ascii_bios_measurements_ops);
509 if (!ascii_file)
510 goto out_bin;
511
512 ret = kmalloc(3 * sizeof(struct dentry *), GFP_KERNEL);
513 if (!ret)
514 goto out_ascii;
515
516 ret[0] = ascii_file;
517 ret[1] = bin_file;
518 ret[2] = tpm_dir;
519
520 return ret;
521
522out_ascii:
523 securityfs_remove(ascii_file);
524out_bin:
525 securityfs_remove(bin_file);
526out_tpm:
527 securityfs_remove(tpm_dir);
528out:
529 return NULL;
530}
531EXPORT_SYMBOL_GPL(tpm_bios_log_setup);
532
533void tpm_bios_log_teardown(struct dentry **lst)
534{
535 int i;
536
537 for (i = 0; i < 3; i++)
538 securityfs_remove(lst[i]);
539}
540EXPORT_SYMBOL_GPL(tpm_bios_log_teardown);
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
index 9ac6d43437b3..a5b18e086a94 100644
--- a/drivers/char/vr41xx_giu.c
+++ b/drivers/char/vr41xx_giu.c
@@ -718,7 +718,7 @@ static struct platform_driver giu_device_driver = {
718 }, 718 },
719}; 719};
720 720
721static int __devinit vr41xx_giu_init(void) 721static int __init vr41xx_giu_init(void)
722{ 722{
723 int retval; 723 int retval;
724 724
@@ -733,7 +733,7 @@ static int __devinit vr41xx_giu_init(void)
733 return retval; 733 return retval;
734} 734}
735 735
736static void __devexit vr41xx_giu_exit(void) 736static void __exit vr41xx_giu_exit(void)
737{ 737{
738 platform_driver_unregister(&giu_device_driver); 738 platform_driver_unregister(&giu_device_driver);
739 739
diff --git a/drivers/char/watchdog/mpc8xx_wdt.c b/drivers/char/watchdog/mpc8xx_wdt.c
index 56d62ba7c6ce..b2fc71e20850 100644
--- a/drivers/char/watchdog/mpc8xx_wdt.c
+++ b/drivers/char/watchdog/mpc8xx_wdt.c
@@ -18,6 +18,7 @@
18#include <linux/watchdog.h> 18#include <linux/watchdog.h>
19#include <asm/8xx_immap.h> 19#include <asm/8xx_immap.h>
20#include <asm/uaccess.h> 20#include <asm/uaccess.h>
21#include <asm/io.h>
21#include <syslib/m8xx_wdt.h> 22#include <syslib/m8xx_wdt.h>
22 23
23static unsigned long wdt_opened; 24static unsigned long wdt_opened;
@@ -25,18 +26,26 @@ static int wdt_status;
25 26
26static void mpc8xx_wdt_handler_disable(void) 27static void mpc8xx_wdt_handler_disable(void)
27{ 28{
28 volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR; 29 volatile uint __iomem *piscr;
30 piscr = (uint *)&((immap_t*)IMAP_ADDR)->im_sit.sit_piscr;
29 31
30 imap->im_sit.sit_piscr &= ~(PISCR_PIE | PISCR_PTE); 32 if (!m8xx_has_internal_rtc)
33 m8xx_wdt_stop_timer();
34 else
35 out_be32(piscr, in_be32(piscr) & ~(PISCR_PIE | PISCR_PTE));
31 36
32 printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n"); 37 printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n");
33} 38}
34 39
35static void mpc8xx_wdt_handler_enable(void) 40static void mpc8xx_wdt_handler_enable(void)
36{ 41{
37 volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR; 42 volatile uint __iomem *piscr;
43 piscr = (uint *)&((immap_t*)IMAP_ADDR)->im_sit.sit_piscr;
38 44
39 imap->im_sit.sit_piscr |= PISCR_PIE | PISCR_PTE; 45 if (!m8xx_has_internal_rtc)
46 m8xx_wdt_install_timer();
47 else
48 out_be32(piscr, in_be32(piscr) | PISCR_PIE | PISCR_PTE);
40 49
41 printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n"); 50 printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n");
42} 51}
@@ -68,9 +77,6 @@ static int mpc8xx_wdt_release(struct inode *inode, struct file *file)
68static ssize_t mpc8xx_wdt_write(struct file *file, const char *data, size_t len, 77static ssize_t mpc8xx_wdt_write(struct file *file, const char *data, size_t len,
69 loff_t * ppos) 78 loff_t * ppos)
70{ 79{
71 if (ppos != &file->f_pos)
72 return -ESPIPE;
73
74 if (len) 80 if (len)
75 m8xx_wdt_reset(); 81 m8xx_wdt_reset();
76 82
diff --git a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c
index 44d49dfacbb3..3843900e94c4 100644
--- a/drivers/char/watchdog/wdt977.c
+++ b/drivers/char/watchdog/wdt977.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Wdt977 0.03: A Watchdog Device for Netwinder W83977AF chip 2 * Wdt977 0.04: A Watchdog Device for Netwinder W83977AF chip
3 * 3 *
4 * (c) Copyright 1998 Rebel.com (Woody Suwalski <woody@netwinder.org>) 4 * (c) Copyright 1998 Rebel.com (Woody Suwalski <woody@netwinder.org>)
5 * 5 *
@@ -18,6 +18,8 @@
18 * from minutes to seconds. 18 * from minutes to seconds.
19 * 07-Jul-2003 Daniele Bellucci: Audit return code of misc_register in 19 * 07-Jul-2003 Daniele Bellucci: Audit return code of misc_register in
20 * nwwatchdog_init. 20 * nwwatchdog_init.
21 * 25-Oct-2005 Woody Suwalski: Convert addresses to #defs, add spinlocks
22 * remove limitiation to be used on Netwinders only
21 */ 23 */
22 24
23#include <linux/module.h> 25#include <linux/module.h>
@@ -28,6 +30,7 @@
28#include <linux/fs.h> 30#include <linux/fs.h>
29#include <linux/miscdevice.h> 31#include <linux/miscdevice.h>
30#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/ioport.h>
31#include <linux/watchdog.h> 34#include <linux/watchdog.h>
32#include <linux/notifier.h> 35#include <linux/notifier.h>
33#include <linux/reboot.h> 36#include <linux/reboot.h>
@@ -37,8 +40,18 @@
37#include <asm/mach-types.h> 40#include <asm/mach-types.h>
38#include <asm/uaccess.h> 41#include <asm/uaccess.h>
39 42
40#define PFX "Wdt977: " 43#define WATCHDOG_VERSION "0.04"
41#define WATCHDOG_MINOR 130 44#define WATCHDOG_NAME "Wdt977"
45#define PFX WATCHDOG_NAME ": "
46#define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n"
47
48#define IO_INDEX_PORT 0x370 /* on some systems it can be 0x3F0 */
49#define IO_DATA_PORT (IO_INDEX_PORT+1)
50
51#define UNLOCK_DATA 0x87
52#define LOCK_DATA 0xAA
53#define DEVICE_REGISTER 0x07
54
42 55
43#define DEFAULT_TIMEOUT 60 /* default timeout in seconds */ 56#define DEFAULT_TIMEOUT 60 /* default timeout in seconds */
44 57
@@ -47,6 +60,7 @@ static int timeoutM; /* timeout in minutes */
47static unsigned long timer_alive; 60static unsigned long timer_alive;
48static int testmode; 61static int testmode;
49static char expect_close; 62static char expect_close;
63static spinlock_t spinlock;
50 64
51module_param(timeout, int, 0); 65module_param(timeout, int, 0);
52MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (60..15300), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")"); 66MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (60..15300), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")");
@@ -63,9 +77,13 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
63 77
64static int wdt977_start(void) 78static int wdt977_start(void)
65{ 79{
80 unsigned long flags;
81
82 spin_lock_irqsave(&spinlock, flags);
83
66 /* unlock the SuperIO chip */ 84 /* unlock the SuperIO chip */
67 outb(0x87,0x370); 85 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
68 outb(0x87,0x370); 86 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
69 87
70 /* select device Aux2 (device=8) and set watchdog regs F2, F3 and F4 88 /* select device Aux2 (device=8) and set watchdog regs F2, F3 and F4
71 * F2 has the timeout in minutes 89 * F2 has the timeout in minutes
@@ -73,28 +91,29 @@ static int wdt977_start(void)
73 * at timeout, and to reset timer on kbd/mouse activity (not impl.) 91 * at timeout, and to reset timer on kbd/mouse activity (not impl.)
74 * F4 is used to just clear the TIMEOUT'ed state (bit 0) 92 * F4 is used to just clear the TIMEOUT'ed state (bit 0)
75 */ 93 */
76 outb(0x07,0x370); 94 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
77 outb(0x08,0x371); 95 outb_p(0x08, IO_DATA_PORT);
78 outb(0xF2,0x370); 96 outb_p(0xF2, IO_INDEX_PORT);
79 outb(timeoutM,0x371); 97 outb_p(timeoutM, IO_DATA_PORT);
80 outb(0xF3,0x370); 98 outb_p(0xF3, IO_INDEX_PORT);
81 outb(0x00,0x371); /* another setting is 0E for kbd/mouse/LED */ 99 outb_p(0x00, IO_DATA_PORT); /* another setting is 0E for kbd/mouse/LED */
82 outb(0xF4,0x370); 100 outb_p(0xF4, IO_INDEX_PORT);
83 outb(0x00,0x371); 101 outb_p(0x00, IO_DATA_PORT);
84 102
85 /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ 103 /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */
86 /* in test mode watch the bit 1 on F4 to indicate "triggered" */ 104 /* in test mode watch the bit 1 on F4 to indicate "triggered" */
87 if (!testmode) 105 if (!testmode)
88 { 106 {
89 outb(0x07,0x370); 107 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
90 outb(0x07,0x371); 108 outb_p(0x07, IO_DATA_PORT);
91 outb(0xE6,0x370); 109 outb_p(0xE6, IO_INDEX_PORT);
92 outb(0x08,0x371); 110 outb_p(0x08, IO_DATA_PORT);
93 } 111 }
94 112
95 /* lock the SuperIO chip */ 113 /* lock the SuperIO chip */
96 outb(0xAA,0x370); 114 outb_p(LOCK_DATA, IO_INDEX_PORT);
97 115
116 spin_unlock_irqrestore(&spinlock, flags);
98 printk(KERN_INFO PFX "activated.\n"); 117 printk(KERN_INFO PFX "activated.\n");
99 118
100 return 0; 119 return 0;
@@ -106,35 +125,39 @@ static int wdt977_start(void)
106 125
107static int wdt977_stop(void) 126static int wdt977_stop(void)
108{ 127{
128 unsigned long flags;
129 spin_lock_irqsave(&spinlock, flags);
130
109 /* unlock the SuperIO chip */ 131 /* unlock the SuperIO chip */
110 outb(0x87,0x370); 132 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
111 outb(0x87,0x370); 133 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
112 134
113 /* select device Aux2 (device=8) and set watchdog regs F2,F3 and F4 135 /* select device Aux2 (device=8) and set watchdog regs F2,F3 and F4
114 * F3 is reset to its default state 136 * F3 is reset to its default state
115 * F4 can clear the TIMEOUT'ed state (bit 0) - back to default 137 * F4 can clear the TIMEOUT'ed state (bit 0) - back to default
116 * We can not use GP17 as a PowerLed, as we use its usage as a RedLed 138 * We can not use GP17 as a PowerLed, as we use its usage as a RedLed
117 */ 139 */
118 outb(0x07,0x370); 140 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
119 outb(0x08,0x371); 141 outb_p(0x08, IO_DATA_PORT);
120 outb(0xF2,0x370); 142 outb_p(0xF2, IO_INDEX_PORT);
121 outb(0xFF,0x371); 143 outb_p(0xFF, IO_DATA_PORT);
122 outb(0xF3,0x370); 144 outb_p(0xF3, IO_INDEX_PORT);
123 outb(0x00,0x371); 145 outb_p(0x00, IO_DATA_PORT);
124 outb(0xF4,0x370); 146 outb_p(0xF4, IO_INDEX_PORT);
125 outb(0x00,0x371); 147 outb_p(0x00, IO_DATA_PORT);
126 outb(0xF2,0x370); 148 outb_p(0xF2, IO_INDEX_PORT);
127 outb(0x00,0x371); 149 outb_p(0x00, IO_DATA_PORT);
128 150
129 /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ 151 /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */
130 outb(0x07,0x370); 152 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
131 outb(0x07,0x371); 153 outb_p(0x07, IO_DATA_PORT);
132 outb(0xE6,0x370); 154 outb_p(0xE6, IO_INDEX_PORT);
133 outb(0x08,0x371); 155 outb_p(0x08, IO_DATA_PORT);
134 156
135 /* lock the SuperIO chip */ 157 /* lock the SuperIO chip */
136 outb(0xAA,0x370); 158 outb_p(LOCK_DATA, IO_INDEX_PORT);
137 159
160 spin_unlock_irqrestore(&spinlock, flags);
138 printk(KERN_INFO PFX "shutdown.\n"); 161 printk(KERN_INFO PFX "shutdown.\n");
139 162
140 return 0; 163 return 0;
@@ -147,19 +170,23 @@ static int wdt977_stop(void)
147 170
148static int wdt977_keepalive(void) 171static int wdt977_keepalive(void)
149{ 172{
173 unsigned long flags;
174 spin_lock_irqsave(&spinlock, flags);
175
150 /* unlock the SuperIO chip */ 176 /* unlock the SuperIO chip */
151 outb(0x87,0x370); 177 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
152 outb(0x87,0x370); 178 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
153 179
154 /* select device Aux2 (device=8) and kicks watchdog reg F2 */ 180 /* select device Aux2 (device=8) and kicks watchdog reg F2 */
155 /* F2 has the timeout in minutes */ 181 /* F2 has the timeout in minutes */
156 outb(0x07,0x370); 182 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
157 outb(0x08,0x371); 183 outb_p(0x08, IO_DATA_PORT);
158 outb(0xF2,0x370); 184 outb_p(0xF2, IO_INDEX_PORT);
159 outb(timeoutM,0x371); 185 outb_p(timeoutM, IO_DATA_PORT);
160 186
161 /* lock the SuperIO chip */ 187 /* lock the SuperIO chip */
162 outb(0xAA,0x370); 188 outb_p(LOCK_DATA, IO_INDEX_PORT);
189 spin_unlock_irqrestore(&spinlock, flags);
163 190
164 return 0; 191 return 0;
165} 192}
@@ -198,22 +225,26 @@ static int wdt977_set_timeout(int t)
198static int wdt977_get_status(int *status) 225static int wdt977_get_status(int *status)
199{ 226{
200 int new_status; 227 int new_status;
228 unsigned long flags;
201 229
202 *status=0; 230 spin_lock_irqsave(&spinlock, flags);
203 231
204 /* unlock the SuperIO chip */ 232 /* unlock the SuperIO chip */
205 outb(0x87,0x370); 233 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
206 outb(0x87,0x370); 234 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
207 235
208 /* select device Aux2 (device=8) and read watchdog reg F4 */ 236 /* select device Aux2 (device=8) and read watchdog reg F4 */
209 outb(0x07,0x370); 237 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
210 outb(0x08,0x371); 238 outb_p(0x08, IO_DATA_PORT);
211 outb(0xF4,0x370); 239 outb_p(0xF4, IO_INDEX_PORT);
212 new_status = inb(0x371); 240 new_status = inb_p(IO_DATA_PORT);
213 241
214 /* lock the SuperIO chip */ 242 /* lock the SuperIO chip */
215 outb(0xAA,0x370); 243 outb_p(LOCK_DATA, IO_INDEX_PORT);
216 244
245 spin_unlock_irqrestore(&spinlock, flags);
246
247 *status=0;
217 if (new_status & 1) 248 if (new_status & 1)
218 *status |= WDIOF_CARDRESET; 249 *status |= WDIOF_CARDRESET;
219 250
@@ -249,8 +280,8 @@ static int wdt977_release(struct inode *inode, struct file *file)
249 wdt977_stop(); 280 wdt977_stop();
250 clear_bit(0,&timer_alive); 281 clear_bit(0,&timer_alive);
251 } else { 282 } else {
252 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
253 wdt977_keepalive(); 283 wdt977_keepalive();
284 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
254 } 285 }
255 expect_close = 0; 286 expect_close = 0;
256 return 0; 287 return 0;
@@ -271,14 +302,17 @@ static int wdt977_release(struct inode *inode, struct file *file)
271static ssize_t wdt977_write(struct file *file, const char __user *buf, 302static ssize_t wdt977_write(struct file *file, const char __user *buf,
272 size_t count, loff_t *ppos) 303 size_t count, loff_t *ppos)
273{ 304{
274 if (count) { 305 if (count)
275 if (!nowayout) { 306 {
307 if (!nowayout)
308 {
276 size_t i; 309 size_t i;
277 310
278 /* In case it was set long ago */ 311 /* In case it was set long ago */
279 expect_close = 0; 312 expect_close = 0;
280 313
281 for (i = 0; i != count; i++) { 314 for (i = 0; i != count; i++)
315 {
282 char c; 316 char c;
283 if (get_user(c, buf + i)) 317 if (get_user(c, buf + i))
284 return -EFAULT; 318 return -EFAULT;
@@ -287,6 +321,7 @@ static ssize_t wdt977_write(struct file *file, const char __user *buf,
287 } 321 }
288 } 322 }
289 323
324 /* someone wrote to us, we should restart timer */
290 wdt977_keepalive(); 325 wdt977_keepalive();
291 } 326 }
292 return count; 327 return count;
@@ -308,7 +343,7 @@ static struct watchdog_info ident = {
308 WDIOF_MAGICCLOSE | 343 WDIOF_MAGICCLOSE |
309 WDIOF_KEEPALIVEPING, 344 WDIOF_KEEPALIVEPING,
310 .firmware_version = 1, 345 .firmware_version = 1,
311 .identity = "Winbond 83977", 346 .identity = WATCHDOG_NAME,
312}; 347};
313 348
314static int wdt977_ioctl(struct inode *inode, struct file *file, 349static int wdt977_ioctl(struct inode *inode, struct file *file,
@@ -405,50 +440,81 @@ static struct notifier_block wdt977_notifier = {
405 .notifier_call = wdt977_notify_sys, 440 .notifier_call = wdt977_notify_sys,
406}; 441};
407 442
408static int __init nwwatchdog_init(void) 443static int __init wd977_init(void)
409{ 444{
410 int retval; 445 int rc;
411 if (!machine_is_netwinder()) 446
412 return -ENODEV; 447 //if (!machine_is_netwinder())
448 // return -ENODEV;
449
450 printk(KERN_INFO PFX DRIVER_VERSION);
451
452 spin_lock_init(&spinlock);
413 453
414 /* Check that the timeout value is within it's range ; if not reset to the default */ 454 /* Check that the timeout value is within it's range ; if not reset to the default */
415 if (wdt977_set_timeout(timeout)) { 455 if (wdt977_set_timeout(timeout))
456 {
416 wdt977_set_timeout(DEFAULT_TIMEOUT); 457 wdt977_set_timeout(DEFAULT_TIMEOUT);
417 printk(KERN_INFO PFX "timeout value must be 60<timeout<15300, using %d\n", 458 printk(KERN_INFO PFX "timeout value must be 60<timeout<15300, using %d\n",
418 DEFAULT_TIMEOUT); 459 DEFAULT_TIMEOUT);
419 } 460 }
420 461
421 retval = register_reboot_notifier(&wdt977_notifier); 462 /* on Netwinder the IOports are already reserved by
422 if (retval) { 463 * arch/arm/mach-footbridge/netwinder-hw.c
423 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 464 */
424 retval); 465 if (!machine_is_netwinder())
425 return retval; 466 {
467 if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME))
468 {
469 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
470 IO_INDEX_PORT);
471 rc = -EIO;
472 goto err_out;
473 }
426 } 474 }
427 475
428 retval = misc_register(&wdt977_miscdev); 476 rc = misc_register(&wdt977_miscdev);
429 if (retval) { 477 if (rc)
478 {
430 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 479 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
431 WATCHDOG_MINOR, retval); 480 wdt977_miscdev.minor, rc);
432 unregister_reboot_notifier(&wdt977_notifier); 481 goto err_out_region;
433 return retval; 482 }
483
484 rc = register_reboot_notifier(&wdt977_notifier);
485 if (rc)
486 {
487 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
488 rc);
489 goto err_out_miscdev;
434 } 490 }
435 491
436 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d, testmode = %i)\n", 492 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d, testmode=%i)\n",
437 timeout, nowayout, testmode); 493 timeout, nowayout, testmode);
438 494
439 return 0; 495 return 0;
496
497err_out_miscdev:
498 misc_deregister(&wdt977_miscdev);
499err_out_region:
500 if (!machine_is_netwinder())
501 release_region(IO_INDEX_PORT,2);
502err_out:
503 return rc;
440} 504}
441 505
442static void __exit nwwatchdog_exit(void) 506static void __exit wd977_exit(void)
443{ 507{
508 wdt977_stop();
444 misc_deregister(&wdt977_miscdev); 509 misc_deregister(&wdt977_miscdev);
445 unregister_reboot_notifier(&wdt977_notifier); 510 unregister_reboot_notifier(&wdt977_notifier);
511 release_region(IO_INDEX_PORT,2);
446} 512}
447 513
448module_init(nwwatchdog_init); 514module_init(wd977_init);
449module_exit(nwwatchdog_exit); 515module_exit(wd977_exit);
450 516
451MODULE_AUTHOR("Woody Suwalski <woody@netwinder.org>"); 517MODULE_AUTHOR("Woody Suwalski <woodys@xandros.com>");
452MODULE_DESCRIPTION("W83977AF Watchdog driver"); 518MODULE_DESCRIPTION("W83977AF Watchdog driver");
453MODULE_LICENSE("GPL"); 519MODULE_LICENSE("GPL");
454MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 520MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 969d2b4aaec0..385e52930c02 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -34,14 +34,14 @@
34static atomic_t proc_event_num_listeners = ATOMIC_INIT(0); 34static atomic_t proc_event_num_listeners = ATOMIC_INIT(0);
35static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC }; 35static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC };
36 36
37/* proc_counts is used as the sequence number of the netlink message */ 37/* proc_event_counts is used as the sequence number of the netlink message */
38static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 }; 38static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 };
39 39
40static inline void get_seq(__u32 *ts, int *cpu) 40static inline void get_seq(__u32 *ts, int *cpu)
41{ 41{
42 *ts = get_cpu_var(proc_event_counts)++; 42 *ts = get_cpu_var(proc_event_counts)++;
43 *cpu = smp_processor_id(); 43 *cpu = smp_processor_id();
44 put_cpu_var(proc_counts); 44 put_cpu_var(proc_event_counts);
45} 45}
46 46
47void proc_fork_connector(struct task_struct *task) 47void proc_fork_connector(struct task_struct *task)
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 4010fe92e72b..08d5b8fed2dc 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -236,27 +236,17 @@ config I2C_IXP2000
236 This support is also available as a module. If so, the module 236 This support is also available as a module. If so, the module
237 will be called i2c-ixp2000. 237 will be called i2c-ixp2000.
238 238
239config I2C_KEYWEST 239config I2C_POWERMAC
240 tristate "Powermac Keywest I2C interface" 240 tristate "Powermac I2C interface"
241 depends on I2C && PPC_PMAC 241 depends on I2C && PPC_PMAC
242 default y
242 help 243 help
243 This supports the use of the I2C interface in the combo-I/O 244 This exposes the various PowerMac i2c interfaces to the linux i2c
244 chip on recent Apple machines. Say Y if you have such a machine. 245 layer and to userland. It is used by various drivers on the powemac
245 246 platform, thus should generally be enabled.
246 This support is also available as a module. If so, the module
247 will be called i2c-keywest.
248
249config I2C_PMAC_SMU
250 tristate "Powermac SMU I2C interface"
251 depends on I2C && PMAC_SMU
252 help
253 This supports the use of the I2C interface in the SMU
254 chip on recent Apple machines like the iMac G5. It is used
255 among others by the thermal control driver for those machines.
256 Say Y if you have such a machine.
257 247
258 This support is also available as a module. If so, the module 248 This support is also available as a module. If so, the module
259 will be called i2c-pmac-smu. 249 will be called i2c-powermac.
260 250
261config I2C_MPC 251config I2C_MPC
262 tristate "MPC107/824x/85xx/52xx" 252 tristate "MPC107/824x/85xx/52xx"
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index f1df00f66c6c..b44831dff683 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -19,8 +19,7 @@ obj-$(CONFIG_I2C_ISA) += i2c-isa.o
19obj-$(CONFIG_I2C_ITE) += i2c-ite.o 19obj-$(CONFIG_I2C_ITE) += i2c-ite.o
20obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o 20obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o
21obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o 21obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o
22obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o 22obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o
23obj-$(CONFIG_I2C_PMAC_SMU) += i2c-pmac-smu.o
24obj-$(CONFIG_I2C_MPC) += i2c-mpc.o 23obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
25obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o 24obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
26obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o 25obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o
diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c
deleted file mode 100644
index d61f748278fc..000000000000
--- a/drivers/i2c/busses/i2c-keywest.c
+++ /dev/null
@@ -1,751 +0,0 @@
1/*
2 i2c Support for Apple Keywest I2C Bus Controller
3
4 Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
5
6 Original work by
7
8 Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24 Changes:
25
26 2001/12/13 BenH New implementation
27 2001/12/15 BenH Add support for "byte" and "quick"
28 transfers. Add i2c_xfer routine.
29 2003/09/21 BenH Rework state machine with Paulus help
30 2004/01/21 BenH Merge in Greg KH changes, polled mode is back
31 2004/02/05 BenH Merge 64 bits fixes from the g5 ppc64 tree
32
33 My understanding of the various modes supported by keywest are:
34
35 - Dumb mode : not implemented, probably direct tweaking of lines
36 - Standard mode : simple i2c transaction of type
37 S Addr R/W A Data A Data ... T
38 - Standard sub mode : combined 8 bit subaddr write with data read
39 S Addr R/W A SubAddr A Data A Data ... T
40 - Combined mode : Subaddress and Data sequences appended with no stop
41 S Addr R/W A SubAddr S Addr R/W A Data A Data ... T
42
43 Currently, this driver uses only Standard mode for i2c xfer, and
44 smbus byte & quick transfers ; and uses StandardSub mode for
45 other smbus transfers instead of combined as we need that for the
46 sound driver to be happy
47*/
48
49#include <linux/module.h>
50#include <linux/kernel.h>
51#include <linux/ioport.h>
52#include <linux/pci.h>
53#include <linux/types.h>
54#include <linux/delay.h>
55#include <linux/i2c.h>
56#include <linux/init.h>
57#include <linux/mm.h>
58#include <linux/timer.h>
59#include <linux/spinlock.h>
60#include <linux/completion.h>
61#include <linux/interrupt.h>
62
63#include <asm/io.h>
64#include <asm/prom.h>
65#include <asm/machdep.h>
66#include <asm/pmac_feature.h>
67#include <asm/pmac_low_i2c.h>
68
69#include "i2c-keywest.h"
70
71#undef POLLED_MODE
72
73/* Some debug macros */
74#define WRONG_STATE(name) do {\
75 pr_debug("KW: wrong state. Got %s, state: %s (isr: %02x)\n", \
76 name, __kw_state_names[iface->state], isr); \
77 } while(0)
78
79#ifdef DEBUG
80static const char *__kw_state_names[] = {
81 "state_idle",
82 "state_addr",
83 "state_read",
84 "state_write",
85 "state_stop",
86 "state_dead"
87};
88#endif /* DEBUG */
89
90MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
91MODULE_DESCRIPTION("I2C driver for Apple's Keywest");
92MODULE_LICENSE("GPL");
93
94#ifdef POLLED_MODE
95/* Don't schedule, the g5 fan controller is too
96 * timing sensitive
97 */
98static u8
99wait_interrupt(struct keywest_iface* iface)
100{
101 int i;
102 u8 isr;
103
104 for (i = 0; i < 200000; i++) {
105 isr = read_reg(reg_isr) & KW_I2C_IRQ_MASK;
106 if (isr != 0)
107 return isr;
108 udelay(10);
109 }
110 return isr;
111}
112#endif /* POLLED_MODE */
113
114static void
115do_stop(struct keywest_iface* iface, int result)
116{
117 write_reg(reg_control, KW_I2C_CTL_STOP);
118 iface->state = state_stop;
119 iface->result = result;
120}
121
122/* Main state machine for standard & standard sub mode */
123static void
124handle_interrupt(struct keywest_iface *iface, u8 isr)
125{
126 int ack;
127
128 if (isr == 0) {
129 if (iface->state != state_stop) {
130 pr_debug("KW: Timeout !\n");
131 do_stop(iface, -EIO);
132 }
133 if (iface->state == state_stop) {
134 ack = read_reg(reg_status);
135 if (!(ack & KW_I2C_STAT_BUSY)) {
136 iface->state = state_idle;
137 write_reg(reg_ier, 0x00);
138#ifndef POLLED_MODE
139 complete(&iface->complete);
140#endif /* POLLED_MODE */
141 }
142 }
143 return;
144 }
145
146 if (isr & KW_I2C_IRQ_ADDR) {
147 ack = read_reg(reg_status);
148 if (iface->state != state_addr) {
149 write_reg(reg_isr, KW_I2C_IRQ_ADDR);
150 WRONG_STATE("KW_I2C_IRQ_ADDR");
151 do_stop(iface, -EIO);
152 return;
153 }
154 if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
155 iface->state = state_stop;
156 iface->result = -ENODEV;
157 pr_debug("KW: NAK on address\n");
158 } else {
159 /* Handle rw "quick" mode */
160 if (iface->datalen == 0) {
161 do_stop(iface, 0);
162 } else if (iface->read_write == I2C_SMBUS_READ) {
163 iface->state = state_read;
164 if (iface->datalen > 1)
165 write_reg(reg_control, KW_I2C_CTL_AAK);
166 } else {
167 iface->state = state_write;
168 write_reg(reg_data, *(iface->data++));
169 iface->datalen--;
170 }
171 }
172 write_reg(reg_isr, KW_I2C_IRQ_ADDR);
173 }
174
175 if (isr & KW_I2C_IRQ_DATA) {
176 if (iface->state == state_read) {
177 *(iface->data++) = read_reg(reg_data);
178 write_reg(reg_isr, KW_I2C_IRQ_DATA);
179 iface->datalen--;
180 if (iface->datalen == 0)
181 iface->state = state_stop;
182 else if (iface->datalen == 1)
183 write_reg(reg_control, 0);
184 } else if (iface->state == state_write) {
185 /* Check ack status */
186 ack = read_reg(reg_status);
187 if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
188 pr_debug("KW: nack on data write (%x): %x\n",
189 iface->data[-1], ack);
190 do_stop(iface, -EIO);
191 } else if (iface->datalen) {
192 write_reg(reg_data, *(iface->data++));
193 iface->datalen--;
194 } else {
195 write_reg(reg_control, KW_I2C_CTL_STOP);
196 iface->state = state_stop;
197 iface->result = 0;
198 }
199 write_reg(reg_isr, KW_I2C_IRQ_DATA);
200 } else {
201 write_reg(reg_isr, KW_I2C_IRQ_DATA);
202 WRONG_STATE("KW_I2C_IRQ_DATA");
203 if (iface->state != state_stop)
204 do_stop(iface, -EIO);
205 }
206 }
207
208 if (isr & KW_I2C_IRQ_STOP) {
209 write_reg(reg_isr, KW_I2C_IRQ_STOP);
210 if (iface->state != state_stop) {
211 WRONG_STATE("KW_I2C_IRQ_STOP");
212 iface->result = -EIO;
213 }
214 iface->state = state_idle;
215 write_reg(reg_ier, 0x00);
216#ifndef POLLED_MODE
217 complete(&iface->complete);
218#endif /* POLLED_MODE */
219 }
220
221 if (isr & KW_I2C_IRQ_START)
222 write_reg(reg_isr, KW_I2C_IRQ_START);
223}
224
225#ifndef POLLED_MODE
226
227/* Interrupt handler */
228static irqreturn_t
229keywest_irq(int irq, void *dev_id, struct pt_regs *regs)
230{
231 struct keywest_iface *iface = (struct keywest_iface *)dev_id;
232 unsigned long flags;
233
234 spin_lock_irqsave(&iface->lock, flags);
235 del_timer(&iface->timeout_timer);
236 handle_interrupt(iface, read_reg(reg_isr));
237 if (iface->state != state_idle) {
238 iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
239 add_timer(&iface->timeout_timer);
240 }
241 spin_unlock_irqrestore(&iface->lock, flags);
242 return IRQ_HANDLED;
243}
244
245static void
246keywest_timeout(unsigned long data)
247{
248 struct keywest_iface *iface = (struct keywest_iface *)data;
249 unsigned long flags;
250
251 pr_debug("timeout !\n");
252 spin_lock_irqsave(&iface->lock, flags);
253 handle_interrupt(iface, read_reg(reg_isr));
254 if (iface->state != state_idle) {
255 iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
256 add_timer(&iface->timeout_timer);
257 }
258 spin_unlock_irqrestore(&iface->lock, flags);
259}
260
261#endif /* POLLED_MODE */
262
263/*
264 * SMBUS-type transfer entrypoint
265 */
266static s32
267keywest_smbus_xfer( struct i2c_adapter* adap,
268 u16 addr,
269 unsigned short flags,
270 char read_write,
271 u8 command,
272 int size,
273 union i2c_smbus_data* data)
274{
275 struct keywest_chan* chan = i2c_get_adapdata(adap);
276 struct keywest_iface* iface = chan->iface;
277 int len;
278 u8* buffer;
279 u16 cur_word;
280 int rc = 0;
281
282 if (iface->state == state_dead)
283 return -ENXIO;
284
285 /* Prepare datas & select mode */
286 iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK;
287 switch (size) {
288 case I2C_SMBUS_QUICK:
289 len = 0;
290 buffer = NULL;
291 iface->cur_mode |= KW_I2C_MODE_STANDARD;
292 break;
293 case I2C_SMBUS_BYTE:
294 len = 1;
295 buffer = &data->byte;
296 iface->cur_mode |= KW_I2C_MODE_STANDARD;
297 break;
298 case I2C_SMBUS_BYTE_DATA:
299 len = 1;
300 buffer = &data->byte;
301 iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
302 break;
303 case I2C_SMBUS_WORD_DATA:
304 len = 2;
305 cur_word = cpu_to_le16(data->word);
306 buffer = (u8 *)&cur_word;
307 iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
308 break;
309 case I2C_SMBUS_BLOCK_DATA:
310 len = data->block[0];
311 buffer = &data->block[1];
312 iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
313 break;
314 default:
315 return -1;
316 }
317
318 /* Turn a standardsub read into a combined mode access */
319 if (read_write == I2C_SMBUS_READ
320 && (iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB) {
321 iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK;
322 iface->cur_mode |= KW_I2C_MODE_COMBINED;
323 }
324
325 /* Original driver had this limitation */
326 if (len > 32)
327 len = 32;
328
329 if (pmac_low_i2c_lock(iface->node))
330 return -ENXIO;
331
332 pr_debug("chan: %d, addr: 0x%x, transfer len: %d, read: %d\n",
333 chan->chan_no, addr, len, read_write == I2C_SMBUS_READ);
334
335 iface->data = buffer;
336 iface->datalen = len;
337 iface->state = state_addr;
338 iface->result = 0;
339 iface->read_write = read_write;
340
341 /* Setup channel & clear pending irqs */
342 write_reg(reg_isr, read_reg(reg_isr));
343 write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4));
344 write_reg(reg_status, 0);
345
346 /* Set up address and r/w bit */
347 write_reg(reg_addr,
348 (addr << 1) | ((read_write == I2C_SMBUS_READ) ? 0x01 : 0x00));
349
350 /* Set up the sub address */
351 if ((iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB
352 || (iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED)
353 write_reg(reg_subaddr, command);
354
355#ifndef POLLED_MODE
356 /* Arm timeout */
357 iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
358 add_timer(&iface->timeout_timer);
359#endif
360
361 /* Start sending address & enable interrupt*/
362 write_reg(reg_control, KW_I2C_CTL_XADDR);
363 write_reg(reg_ier, KW_I2C_IRQ_MASK);
364
365#ifdef POLLED_MODE
366 pr_debug("using polled mode...\n");
367 /* State machine, to turn into an interrupt handler */
368 while(iface->state != state_idle) {
369 unsigned long flags;
370
371 u8 isr = wait_interrupt(iface);
372 spin_lock_irqsave(&iface->lock, flags);
373 handle_interrupt(iface, isr);
374 spin_unlock_irqrestore(&iface->lock, flags);
375 }
376#else /* POLLED_MODE */
377 pr_debug("using interrupt mode...\n");
378 wait_for_completion(&iface->complete);
379#endif /* POLLED_MODE */
380
381 rc = iface->result;
382 pr_debug("transfer done, result: %d\n", rc);
383
384 if (rc == 0 && size == I2C_SMBUS_WORD_DATA && read_write == I2C_SMBUS_READ)
385 data->word = le16_to_cpu(cur_word);
386
387 /* Release sem */
388 pmac_low_i2c_unlock(iface->node);
389
390 return rc;
391}
392
393/*
394 * Generic i2c master transfer entrypoint
395 */
396static int
397keywest_xfer( struct i2c_adapter *adap,
398 struct i2c_msg *msgs,
399 int num)
400{
401 struct keywest_chan* chan = i2c_get_adapdata(adap);
402 struct keywest_iface* iface = chan->iface;
403 struct i2c_msg *pmsg;
404 int i, completed;
405 int rc = 0;
406
407 if (iface->state == state_dead)
408 return -ENXIO;
409
410 if (pmac_low_i2c_lock(iface->node))
411 return -ENXIO;
412
413 /* Set adapter to standard mode */
414 iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK;
415 iface->cur_mode |= KW_I2C_MODE_STANDARD;
416
417 completed = 0;
418 for (i = 0; rc >= 0 && i < num;) {
419 u8 addr;
420
421 pmsg = &msgs[i++];
422 addr = pmsg->addr;
423 if (pmsg->flags & I2C_M_TEN) {
424 printk(KERN_ERR "i2c-keywest: 10 bits addr not supported !\n");
425 rc = -EINVAL;
426 break;
427 }
428 pr_debug("xfer: chan: %d, doing %s %d bytes to 0x%02x - %d of %d messages\n",
429 chan->chan_no,
430 pmsg->flags & I2C_M_RD ? "read" : "write",
431 pmsg->len, addr, i, num);
432
433 /* Setup channel & clear pending irqs */
434 write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4));
435 write_reg(reg_isr, read_reg(reg_isr));
436 write_reg(reg_status, 0);
437
438 iface->data = pmsg->buf;
439 iface->datalen = pmsg->len;
440 iface->state = state_addr;
441 iface->result = 0;
442 if (pmsg->flags & I2C_M_RD)
443 iface->read_write = I2C_SMBUS_READ;
444 else
445 iface->read_write = I2C_SMBUS_WRITE;
446
447 /* Set up address and r/w bit */
448 if (pmsg->flags & I2C_M_REV_DIR_ADDR)
449 addr ^= 1;
450 write_reg(reg_addr,
451 (addr << 1) |
452 ((iface->read_write == I2C_SMBUS_READ) ? 0x01 : 0x00));
453
454#ifndef POLLED_MODE
455 /* Arm timeout */
456 iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
457 add_timer(&iface->timeout_timer);
458#endif
459
460 /* Start sending address & enable interrupt*/
461 write_reg(reg_ier, KW_I2C_IRQ_MASK);
462 write_reg(reg_control, KW_I2C_CTL_XADDR);
463
464#ifdef POLLED_MODE
465 pr_debug("using polled mode...\n");
466 /* State machine, to turn into an interrupt handler */
467 while(iface->state != state_idle) {
468 u8 isr = wait_interrupt(iface);
469 handle_interrupt(iface, isr);
470 }
471#else /* POLLED_MODE */
472 pr_debug("using interrupt mode...\n");
473 wait_for_completion(&iface->complete);
474#endif /* POLLED_MODE */
475
476 rc = iface->result;
477 if (rc == 0)
478 completed++;
479 pr_debug("transfer done, result: %d\n", rc);
480 }
481
482 /* Release sem */
483 pmac_low_i2c_unlock(iface->node);
484
485 return completed;
486}
487
488static u32
489keywest_func(struct i2c_adapter * adapter)
490{
491 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
492 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
493 I2C_FUNC_SMBUS_BLOCK_DATA;
494}
495
496/* For now, we only handle combined mode (smbus) */
497static struct i2c_algorithm keywest_algorithm = {
498 .smbus_xfer = keywest_smbus_xfer,
499 .master_xfer = keywest_xfer,
500 .functionality = keywest_func,
501};
502
503
504static int
505create_iface(struct device_node *np, struct device *dev)
506{
507 unsigned long steps;
508 unsigned bsteps, tsize, i, nchan, addroffset;
509 struct keywest_iface* iface;
510 u32 *psteps, *prate;
511 int rc;
512
513 if (np->n_intrs < 1 || np->n_addrs < 1) {
514 printk(KERN_ERR "%s: Missing interrupt or address !\n",
515 np->full_name);
516 return -ENODEV;
517 }
518 if (pmac_low_i2c_lock(np))
519 return -ENODEV;
520
521 psteps = (u32 *)get_property(np, "AAPL,address-step", NULL);
522 steps = psteps ? (*psteps) : 0x10;
523
524 /* Hrm... maybe we can be smarter here */
525 for (bsteps = 0; (steps & 0x01) == 0; bsteps++)
526 steps >>= 1;
527
528 if (np->parent->name[0] == 'u') {
529 nchan = 2;
530 addroffset = 3;
531 } else {
532 addroffset = 0;
533 nchan = 1;
534 }
535
536 tsize = sizeof(struct keywest_iface) +
537 (sizeof(struct keywest_chan) + 4) * nchan;
538 iface = kzalloc(tsize, GFP_KERNEL);
539 if (iface == NULL) {
540 printk(KERN_ERR "i2c-keywest: can't allocate inteface !\n");
541 pmac_low_i2c_unlock(np);
542 return -ENOMEM;
543 }
544 spin_lock_init(&iface->lock);
545 init_completion(&iface->complete);
546 iface->node = of_node_get(np);
547 iface->bsteps = bsteps;
548 iface->chan_count = nchan;
549 iface->state = state_idle;
550 iface->irq = np->intrs[0].line;
551 iface->channels = (struct keywest_chan *)
552 (((unsigned long)(iface + 1) + 3UL) & ~3UL);
553 iface->base = ioremap(np->addrs[0].address + addroffset,
554 np->addrs[0].size);
555 if (!iface->base) {
556 printk(KERN_ERR "i2c-keywest: can't map inteface !\n");
557 kfree(iface);
558 pmac_low_i2c_unlock(np);
559 return -ENOMEM;
560 }
561
562#ifndef POLLED_MODE
563 init_timer(&iface->timeout_timer);
564 iface->timeout_timer.function = keywest_timeout;
565 iface->timeout_timer.data = (unsigned long)iface;
566#endif
567
568 /* Select interface rate */
569 iface->cur_mode = KW_I2C_MODE_100KHZ;
570 prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL);
571 if (prate) switch(*prate) {
572 case 100:
573 iface->cur_mode = KW_I2C_MODE_100KHZ;
574 break;
575 case 50:
576 iface->cur_mode = KW_I2C_MODE_50KHZ;
577 break;
578 case 25:
579 iface->cur_mode = KW_I2C_MODE_25KHZ;
580 break;
581 default:
582 printk(KERN_WARNING "i2c-keywest: unknown rate %ldKhz, using 100KHz\n",
583 (long)*prate);
584 }
585
586 /* Select standard mode by default */
587 iface->cur_mode |= KW_I2C_MODE_STANDARD;
588
589 /* Write mode */
590 write_reg(reg_mode, iface->cur_mode);
591
592 /* Switch interrupts off & clear them*/
593 write_reg(reg_ier, 0x00);
594 write_reg(reg_isr, KW_I2C_IRQ_MASK);
595
596#ifndef POLLED_MODE
597 /* Request chip interrupt */
598 rc = request_irq(iface->irq, keywest_irq, SA_INTERRUPT, "keywest i2c", iface);
599 if (rc) {
600 printk(KERN_ERR "i2c-keywest: can't get IRQ %d !\n", iface->irq);
601 iounmap(iface->base);
602 kfree(iface);
603 pmac_low_i2c_unlock(np);
604 return -ENODEV;
605 }
606#endif /* POLLED_MODE */
607
608 pmac_low_i2c_unlock(np);
609 dev_set_drvdata(dev, iface);
610
611 for (i=0; i<nchan; i++) {
612 struct keywest_chan* chan = &iface->channels[i];
613
614 sprintf(chan->adapter.name, "%s %d", np->parent->name, i);
615 chan->iface = iface;
616 chan->chan_no = i;
617 chan->adapter.algo = &keywest_algorithm;
618 chan->adapter.algo_data = NULL;
619 chan->adapter.client_register = NULL;
620 chan->adapter.client_unregister = NULL;
621 i2c_set_adapdata(&chan->adapter, chan);
622 chan->adapter.dev.parent = dev;
623
624 rc = i2c_add_adapter(&chan->adapter);
625 if (rc) {
626 printk("i2c-keywest.c: Adapter %s registration failed\n",
627 chan->adapter.name);
628 i2c_set_adapdata(&chan->adapter, NULL);
629 }
630 }
631
632 printk(KERN_INFO "Found KeyWest i2c on \"%s\", %d channel%s, stepping: %d bits\n",
633 np->parent->name, nchan, nchan > 1 ? "s" : "", bsteps);
634
635 return 0;
636}
637
638static int
639dispose_iface(struct device *dev)
640{
641 struct keywest_iface *iface = dev_get_drvdata(dev);
642 int i, rc;
643
644 /* Make sure we stop all activity */
645 if (pmac_low_i2c_lock(iface->node))
646 return -ENODEV;
647
648#ifndef POLLED_MODE
649 spin_lock_irq(&iface->lock);
650 while (iface->state != state_idle) {
651 spin_unlock_irq(&iface->lock);
652 msleep(100);
653 spin_lock_irq(&iface->lock);
654 }
655#endif /* POLLED_MODE */
656 iface->state = state_dead;
657#ifndef POLLED_MODE
658 spin_unlock_irq(&iface->lock);
659 free_irq(iface->irq, iface);
660#endif /* POLLED_MODE */
661
662 pmac_low_i2c_unlock(iface->node);
663
664 /* Release all channels */
665 for (i=0; i<iface->chan_count; i++) {
666 struct keywest_chan* chan = &iface->channels[i];
667 if (i2c_get_adapdata(&chan->adapter) == NULL)
668 continue;
669 rc = i2c_del_adapter(&chan->adapter);
670 i2c_set_adapdata(&chan->adapter, NULL);
671 /* We aren't that prepared to deal with this... */
672 if (rc)
673 printk("i2c-keywest.c: i2c_del_adapter failed, that's bad !\n");
674 }
675 iounmap(iface->base);
676 dev_set_drvdata(dev, NULL);
677 of_node_put(iface->node);
678 kfree(iface);
679
680 return 0;
681}
682
683static int
684create_iface_macio(struct macio_dev* dev, const struct of_device_id *match)
685{
686 return create_iface(dev->ofdev.node, &dev->ofdev.dev);
687}
688
689static int
690dispose_iface_macio(struct macio_dev* dev)
691{
692 return dispose_iface(&dev->ofdev.dev);
693}
694
695static int
696create_iface_of_platform(struct of_device* dev, const struct of_device_id *match)
697{
698 return create_iface(dev->node, &dev->dev);
699}
700
701static int
702dispose_iface_of_platform(struct of_device* dev)
703{
704 return dispose_iface(&dev->dev);
705}
706
707static struct of_device_id i2c_keywest_match[] =
708{
709 {
710 .type = "i2c",
711 .compatible = "keywest"
712 },
713 {},
714};
715
716static struct macio_driver i2c_keywest_macio_driver =
717{
718 .owner = THIS_MODULE,
719 .name = "i2c-keywest",
720 .match_table = i2c_keywest_match,
721 .probe = create_iface_macio,
722 .remove = dispose_iface_macio
723};
724
725static struct of_platform_driver i2c_keywest_of_platform_driver =
726{
727 .owner = THIS_MODULE,
728 .name = "i2c-keywest",
729 .match_table = i2c_keywest_match,
730 .probe = create_iface_of_platform,
731 .remove = dispose_iface_of_platform
732};
733
734static int __init
735i2c_keywest_init(void)
736{
737 of_register_driver(&i2c_keywest_of_platform_driver);
738 macio_register_driver(&i2c_keywest_macio_driver);
739
740 return 0;
741}
742
743static void __exit
744i2c_keywest_cleanup(void)
745{
746 of_unregister_driver(&i2c_keywest_of_platform_driver);
747 macio_unregister_driver(&i2c_keywest_macio_driver);
748}
749
750module_init(i2c_keywest_init);
751module_exit(i2c_keywest_cleanup);
diff --git a/drivers/i2c/busses/i2c-keywest.h b/drivers/i2c/busses/i2c-keywest.h
deleted file mode 100644
index c5022e1ca6ff..000000000000
--- a/drivers/i2c/busses/i2c-keywest.h
+++ /dev/null
@@ -1,108 +0,0 @@
1#ifndef __I2C_KEYWEST_H__
2#define __I2C_KEYWEST_H__
3
4/* The Tumbler audio equalizer can be really slow sometimes */
5#define POLL_TIMEOUT (2*HZ)
6
7/* Register indices */
8typedef enum {
9 reg_mode = 0,
10 reg_control,
11 reg_status,
12 reg_isr,
13 reg_ier,
14 reg_addr,
15 reg_subaddr,
16 reg_data
17} reg_t;
18
19
20/* Mode register */
21#define KW_I2C_MODE_100KHZ 0x00
22#define KW_I2C_MODE_50KHZ 0x01
23#define KW_I2C_MODE_25KHZ 0x02
24#define KW_I2C_MODE_DUMB 0x00
25#define KW_I2C_MODE_STANDARD 0x04
26#define KW_I2C_MODE_STANDARDSUB 0x08
27#define KW_I2C_MODE_COMBINED 0x0C
28#define KW_I2C_MODE_MODE_MASK 0x0C
29#define KW_I2C_MODE_CHAN_MASK 0xF0
30
31/* Control register */
32#define KW_I2C_CTL_AAK 0x01
33#define KW_I2C_CTL_XADDR 0x02
34#define KW_I2C_CTL_STOP 0x04
35#define KW_I2C_CTL_START 0x08
36
37/* Status register */
38#define KW_I2C_STAT_BUSY 0x01
39#define KW_I2C_STAT_LAST_AAK 0x02
40#define KW_I2C_STAT_LAST_RW 0x04
41#define KW_I2C_STAT_SDA 0x08
42#define KW_I2C_STAT_SCL 0x10
43
44/* IER & ISR registers */
45#define KW_I2C_IRQ_DATA 0x01
46#define KW_I2C_IRQ_ADDR 0x02
47#define KW_I2C_IRQ_STOP 0x04
48#define KW_I2C_IRQ_START 0x08
49#define KW_I2C_IRQ_MASK 0x0F
50
51/* Physical interface */
52struct keywest_iface
53{
54 struct device_node *node;
55 void __iomem * base;
56 unsigned bsteps;
57 int irq;
58 spinlock_t lock;
59 struct keywest_chan *channels;
60 unsigned chan_count;
61 u8 cur_mode;
62 char read_write;
63 u8 *data;
64 unsigned datalen;
65 int state;
66 int result;
67 struct timer_list timeout_timer;
68 struct completion complete;
69};
70
71enum {
72 state_idle,
73 state_addr,
74 state_read,
75 state_write,
76 state_stop,
77 state_dead
78};
79
80/* Channel on an interface */
81struct keywest_chan
82{
83 struct i2c_adapter adapter;
84 struct keywest_iface* iface;
85 unsigned chan_no;
86};
87
88/* Register access */
89
90static inline u8 __read_reg(struct keywest_iface *iface, reg_t reg)
91{
92 return in_8(iface->base
93 + (((unsigned)reg) << iface->bsteps));
94}
95
96static inline void __write_reg(struct keywest_iface *iface, reg_t reg, u8 val)
97{
98 out_8(iface->base
99 + (((unsigned)reg) << iface->bsteps), val);
100 (void)__read_reg(iface, reg_subaddr);
101}
102
103#define write_reg(reg, val) __write_reg(iface, reg, val)
104#define read_reg(reg) __read_reg(iface, reg)
105
106
107
108#endif /* __I2C_KEYWEST_H__ */
diff --git a/drivers/i2c/busses/i2c-pmac-smu.c b/drivers/i2c/busses/i2c-pmac-smu.c
deleted file mode 100644
index bfefe7f7a53d..000000000000
--- a/drivers/i2c/busses/i2c-pmac-smu.c
+++ /dev/null
@@ -1,315 +0,0 @@
1/*
2 i2c Support for Apple SMU Controller
3
4 Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp.
5 <benh@kernel.crashing.org>
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 as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#include <linux/config.h>
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/types.h>
27#include <linux/i2c.h>
28#include <linux/init.h>
29#include <linux/completion.h>
30#include <linux/device.h>
31#include <asm/prom.h>
32#include <asm/of_device.h>
33#include <asm/smu.h>
34
35static int probe;
36
37MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
38MODULE_DESCRIPTION("I2C driver for Apple's SMU");
39MODULE_LICENSE("GPL");
40module_param(probe, bool, 0);
41
42
43/* Physical interface */
44struct smu_iface
45{
46 struct i2c_adapter adapter;
47 struct completion complete;
48 u32 busid;
49};
50
51static void smu_i2c_done(struct smu_i2c_cmd *cmd, void *misc)
52{
53 struct smu_iface *iface = misc;
54 complete(&iface->complete);
55}
56
57/*
58 * SMBUS-type transfer entrypoint
59 */
60static s32 smu_smbus_xfer( struct i2c_adapter* adap,
61 u16 addr,
62 unsigned short flags,
63 char read_write,
64 u8 command,
65 int size,
66 union i2c_smbus_data* data)
67{
68 struct smu_iface *iface = i2c_get_adapdata(adap);
69 struct smu_i2c_cmd cmd;
70 int rc = 0;
71 int read = (read_write == I2C_SMBUS_READ);
72
73 cmd.info.bus = iface->busid;
74 cmd.info.devaddr = (addr << 1) | (read ? 0x01 : 0x00);
75
76 /* Prepare datas & select mode */
77 switch (size) {
78 case I2C_SMBUS_QUICK:
79 cmd.info.type = SMU_I2C_TRANSFER_SIMPLE;
80 cmd.info.datalen = 0;
81 break;
82 case I2C_SMBUS_BYTE:
83 cmd.info.type = SMU_I2C_TRANSFER_SIMPLE;
84 cmd.info.datalen = 1;
85 if (!read)
86 cmd.info.data[0] = data->byte;
87 break;
88 case I2C_SMBUS_BYTE_DATA:
89 cmd.info.type = SMU_I2C_TRANSFER_STDSUB;
90 cmd.info.datalen = 1;
91 cmd.info.sublen = 1;
92 cmd.info.subaddr[0] = command;
93 cmd.info.subaddr[1] = 0;
94 cmd.info.subaddr[2] = 0;
95 if (!read)
96 cmd.info.data[0] = data->byte;
97 break;
98 case I2C_SMBUS_WORD_DATA:
99 cmd.info.type = SMU_I2C_TRANSFER_STDSUB;
100 cmd.info.datalen = 2;
101 cmd.info.sublen = 1;
102 cmd.info.subaddr[0] = command;
103 cmd.info.subaddr[1] = 0;
104 cmd.info.subaddr[2] = 0;
105 if (!read) {
106 cmd.info.data[0] = data->byte & 0xff;
107 cmd.info.data[1] = (data->byte >> 8) & 0xff;
108 }
109 break;
110 /* Note that these are broken vs. the expected smbus API where
111 * on reads, the lenght is actually returned from the function,
112 * but I think the current API makes no sense and I don't want
113 * any driver that I haven't verified for correctness to go
114 * anywhere near a pmac i2c bus anyway ...
115 */
116 case I2C_SMBUS_BLOCK_DATA:
117 cmd.info.type = SMU_I2C_TRANSFER_STDSUB;
118 cmd.info.datalen = data->block[0] + 1;
119 if (cmd.info.datalen > 6)
120 return -EINVAL;
121 if (!read)
122 memcpy(cmd.info.data, data->block, cmd.info.datalen);
123 cmd.info.sublen = 1;
124 cmd.info.subaddr[0] = command;
125 cmd.info.subaddr[1] = 0;
126 cmd.info.subaddr[2] = 0;
127 break;
128 case I2C_SMBUS_I2C_BLOCK_DATA:
129 cmd.info.type = SMU_I2C_TRANSFER_STDSUB;
130 cmd.info.datalen = data->block[0];
131 if (cmd.info.datalen > 7)
132 return -EINVAL;
133 if (!read)
134 memcpy(cmd.info.data, &data->block[1],
135 cmd.info.datalen);
136 cmd.info.sublen = 1;
137 cmd.info.subaddr[0] = command;
138 cmd.info.subaddr[1] = 0;
139 cmd.info.subaddr[2] = 0;
140 break;
141
142 default:
143 return -EINVAL;
144 }
145
146 /* Turn a standardsub read into a combined mode access */
147 if (read_write == I2C_SMBUS_READ &&
148 cmd.info.type == SMU_I2C_TRANSFER_STDSUB)
149 cmd.info.type = SMU_I2C_TRANSFER_COMBINED;
150
151 /* Finish filling command and submit it */
152 cmd.done = smu_i2c_done;
153 cmd.misc = iface;
154 rc = smu_queue_i2c(&cmd);
155 if (rc < 0)
156 return rc;
157 wait_for_completion(&iface->complete);
158 rc = cmd.status;
159
160 if (!read || rc < 0)
161 return rc;
162
163 switch (size) {
164 case I2C_SMBUS_BYTE:
165 case I2C_SMBUS_BYTE_DATA:
166 data->byte = cmd.info.data[0];
167 break;
168 case I2C_SMBUS_WORD_DATA:
169 data->word = ((u16)cmd.info.data[1]) << 8;
170 data->word |= cmd.info.data[0];
171 break;
172 /* Note that these are broken vs. the expected smbus API where
173 * on reads, the lenght is actually returned from the function,
174 * but I think the current API makes no sense and I don't want
175 * any driver that I haven't verified for correctness to go
176 * anywhere near a pmac i2c bus anyway ...
177 */
178 case I2C_SMBUS_BLOCK_DATA:
179 case I2C_SMBUS_I2C_BLOCK_DATA:
180 memcpy(&data->block[0], cmd.info.data, cmd.info.datalen);
181 break;
182 }
183
184 return rc;
185}
186
187static u32
188smu_smbus_func(struct i2c_adapter * adapter)
189{
190 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
191 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
192 I2C_FUNC_SMBUS_BLOCK_DATA;
193}
194
195/* For now, we only handle combined mode (smbus) */
196static struct i2c_algorithm smu_algorithm = {
197 .smbus_xfer = smu_smbus_xfer,
198 .functionality = smu_smbus_func,
199};
200
201static int create_iface(struct device_node *np, struct device *dev)
202{
203 struct smu_iface* iface;
204 u32 *reg, busid;
205 int rc;
206
207 reg = (u32 *)get_property(np, "reg", NULL);
208 if (reg == NULL) {
209 printk(KERN_ERR "i2c-pmac-smu: can't find bus number !\n");
210 return -ENXIO;
211 }
212 busid = *reg;
213
214 iface = kzalloc(sizeof(struct smu_iface), GFP_KERNEL);
215 if (iface == NULL) {
216 printk(KERN_ERR "i2c-pmac-smu: can't allocate inteface !\n");
217 return -ENOMEM;
218 }
219 init_completion(&iface->complete);
220 iface->busid = busid;
221
222 dev_set_drvdata(dev, iface);
223
224 sprintf(iface->adapter.name, "smu-i2c-%02x", busid);
225 iface->adapter.algo = &smu_algorithm;
226 iface->adapter.algo_data = NULL;
227 iface->adapter.client_register = NULL;
228 iface->adapter.client_unregister = NULL;
229 i2c_set_adapdata(&iface->adapter, iface);
230 iface->adapter.dev.parent = dev;
231
232 rc = i2c_add_adapter(&iface->adapter);
233 if (rc) {
234 printk(KERN_ERR "i2c-pamc-smu.c: Adapter %s registration "
235 "failed\n", iface->adapter.name);
236 i2c_set_adapdata(&iface->adapter, NULL);
237 }
238
239 if (probe) {
240 unsigned char addr;
241 printk("Probe: ");
242 for (addr = 0x00; addr <= 0x7f; addr++) {
243 if (i2c_smbus_xfer(&iface->adapter,addr,
244 0,0,0,I2C_SMBUS_QUICK,NULL) >= 0)
245 printk("%02x ", addr);
246 }
247 printk("\n");
248 }
249
250 printk(KERN_INFO "SMU i2c bus %x registered\n", busid);
251
252 return 0;
253}
254
255static int dispose_iface(struct device *dev)
256{
257 struct smu_iface *iface = dev_get_drvdata(dev);
258 int rc;
259
260 rc = i2c_del_adapter(&iface->adapter);
261 i2c_set_adapdata(&iface->adapter, NULL);
262 /* We aren't that prepared to deal with this... */
263 if (rc)
264 printk("i2c-pmac-smu.c: Failed to remove bus %s !\n",
265 iface->adapter.name);
266 dev_set_drvdata(dev, NULL);
267 kfree(iface);
268
269 return 0;
270}
271
272
273static int create_iface_of_platform(struct of_device* dev,
274 const struct of_device_id *match)
275{
276 return create_iface(dev->node, &dev->dev);
277}
278
279
280static int dispose_iface_of_platform(struct of_device* dev)
281{
282 return dispose_iface(&dev->dev);
283}
284
285
286static struct of_device_id i2c_smu_match[] =
287{
288 {
289 .compatible = "smu-i2c",
290 },
291 {},
292};
293static struct of_platform_driver i2c_smu_of_platform_driver =
294{
295 .name = "i2c-smu",
296 .match_table = i2c_smu_match,
297 .probe = create_iface_of_platform,
298 .remove = dispose_iface_of_platform
299};
300
301
302static int __init i2c_pmac_smu_init(void)
303{
304 of_register_driver(&i2c_smu_of_platform_driver);
305 return 0;
306}
307
308
309static void __exit i2c_pmac_smu_cleanup(void)
310{
311 of_unregister_driver(&i2c_smu_of_platform_driver);
312}
313
314module_init(i2c_pmac_smu_init);
315module_exit(i2c_pmac_smu_cleanup);
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
new file mode 100644
index 000000000000..df786eb55295
--- /dev/null
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -0,0 +1,290 @@
1/*
2 i2c Support for Apple SMU Controller
3
4 Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp.
5 <benh@kernel.crashing.org>
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 as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#include <linux/config.h>
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/types.h>
27#include <linux/i2c.h>
28#include <linux/init.h>
29#include <linux/completion.h>
30#include <linux/device.h>
31#include <linux/platform_device.h>
32#include <asm/prom.h>
33#include <asm/pmac_low_i2c.h>
34
35MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
36MODULE_DESCRIPTION("I2C driver for Apple PowerMac");
37MODULE_LICENSE("GPL");
38
39/*
40 * SMBUS-type transfer entrypoint
41 */
42static s32 i2c_powermac_smbus_xfer( struct i2c_adapter* adap,
43 u16 addr,
44 unsigned short flags,
45 char read_write,
46 u8 command,
47 int size,
48 union i2c_smbus_data* data)
49{
50 struct pmac_i2c_bus *bus = i2c_get_adapdata(adap);
51 int rc = 0;
52 int read = (read_write == I2C_SMBUS_READ);
53 int addrdir = (addr << 1) | read;
54 u8 local[2];
55
56 rc = pmac_i2c_open(bus, 0);
57 if (rc)
58 return rc;
59
60 switch (size) {
61 case I2C_SMBUS_QUICK:
62 rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
63 if (rc)
64 goto bail;
65 rc = pmac_i2c_xfer(bus, addrdir, 0, 0, NULL, 0);
66 break;
67 case I2C_SMBUS_BYTE:
68 rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
69 if (rc)
70 goto bail;
71 rc = pmac_i2c_xfer(bus, addrdir, 0, 0, &data->byte, 1);
72 break;
73 case I2C_SMBUS_BYTE_DATA:
74 rc = pmac_i2c_setmode(bus, read ?
75 pmac_i2c_mode_combined :
76 pmac_i2c_mode_stdsub);
77 if (rc)
78 goto bail;
79 rc = pmac_i2c_xfer(bus, addrdir, 1, command, &data->byte, 1);
80 break;
81 case I2C_SMBUS_WORD_DATA:
82 rc = pmac_i2c_setmode(bus, read ?
83 pmac_i2c_mode_combined :
84 pmac_i2c_mode_stdsub);
85 if (rc)
86 goto bail;
87 if (!read) {
88 local[0] = data->word & 0xff;
89 local[1] = (data->word >> 8) & 0xff;
90 }
91 rc = pmac_i2c_xfer(bus, addrdir, 1, command, local, 2);
92 if (rc == 0 && read) {
93 data->word = ((u16)local[1]) << 8;
94 data->word |= local[0];
95 }
96 break;
97
98 /* Note that these are broken vs. the expected smbus API where
99 * on reads, the lenght is actually returned from the function,
100 * but I think the current API makes no sense and I don't want
101 * any driver that I haven't verified for correctness to go
102 * anywhere near a pmac i2c bus anyway ...
103 *
104 * I'm also not completely sure what kind of phases to do between
105 * the actual command and the data (what I am _supposed_ to do that
106 * is). For now, I assume writes are a single stream and reads have
107 * a repeat start/addr phase (but not stop in between)
108 */
109 case I2C_SMBUS_BLOCK_DATA:
110 rc = pmac_i2c_setmode(bus, read ?
111 pmac_i2c_mode_combined :
112 pmac_i2c_mode_stdsub);
113 if (rc)
114 goto bail;
115 rc = pmac_i2c_xfer(bus, addrdir, 1, command, data->block,
116 data->block[0] + 1);
117
118 break;
119 case I2C_SMBUS_I2C_BLOCK_DATA:
120 rc = pmac_i2c_setmode(bus, read ?
121 pmac_i2c_mode_combined :
122 pmac_i2c_mode_stdsub);
123 if (rc)
124 goto bail;
125 rc = pmac_i2c_xfer(bus, addrdir, 1, command,
126 read ? data->block : &data->block[1],
127 data->block[0]);
128 break;
129
130 default:
131 rc = -EINVAL;
132 }
133 bail:
134 pmac_i2c_close(bus);
135 return rc;
136}
137
138/*
139 * Generic i2c master transfer entrypoint. This driver only support single
140 * messages (for "lame i2c" transfers). Anything else should use the smbus
141 * entry point
142 */
143static int i2c_powermac_master_xfer( struct i2c_adapter *adap,
144 struct i2c_msg *msgs,
145 int num)
146{
147 struct pmac_i2c_bus *bus = i2c_get_adapdata(adap);
148 int rc = 0;
149 int read;
150 int addrdir;
151
152 if (num != 1)
153 return -EINVAL;
154 if (msgs->flags & I2C_M_TEN)
155 return -EINVAL;
156 read = (msgs->flags & I2C_M_RD) != 0;
157 addrdir = (msgs->addr << 1) | read;
158 if (msgs->flags & I2C_M_REV_DIR_ADDR)
159 addrdir ^= 1;
160
161 rc = pmac_i2c_open(bus, 0);
162 if (rc)
163 return rc;
164 rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
165 if (rc)
166 goto bail;
167 rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len);
168 bail:
169 pmac_i2c_close(bus);
170 return rc < 0 ? rc : msgs->len;
171}
172
173static u32 i2c_powermac_func(struct i2c_adapter * adapter)
174{
175 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
176 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
177 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_I2C;
178}
179
180/* For now, we only handle smbus */
181static struct i2c_algorithm i2c_powermac_algorithm = {
182 .smbus_xfer = i2c_powermac_smbus_xfer,
183 .master_xfer = i2c_powermac_master_xfer,
184 .functionality = i2c_powermac_func,
185};
186
187
188static int i2c_powermac_remove(struct device *dev)
189{
190 struct i2c_adapter *adapter = dev_get_drvdata(dev);
191 struct pmac_i2c_bus *bus = i2c_get_adapdata(adapter);
192 int rc;
193
194 rc = i2c_del_adapter(adapter);
195 pmac_i2c_detach_adapter(bus, adapter);
196 i2c_set_adapdata(adapter, NULL);
197 /* We aren't that prepared to deal with this... */
198 if (rc)
199 printk("i2c-powermac.c: Failed to remove bus %s !\n",
200 adapter->name);
201 dev_set_drvdata(dev, NULL);
202 kfree(adapter);
203
204 return 0;
205}
206
207
208static int i2c_powermac_probe(struct device *dev)
209{
210 struct pmac_i2c_bus *bus = dev->platform_data;
211 struct device_node *parent = NULL;
212 struct i2c_adapter *adapter;
213 char name[32], *basename;
214 int rc;
215
216 if (bus == NULL)
217 return -EINVAL;
218
219 /* Ok, now we need to make up a name for the interface that will
220 * match what we used to do in the past, that is basically the
221 * controller's parent device node for keywest. PMU didn't have a
222 * naming convention and SMU has a different one
223 */
224 switch(pmac_i2c_get_type(bus)) {
225 case pmac_i2c_bus_keywest:
226 parent = of_get_parent(pmac_i2c_get_controller(bus));
227 if (parent == NULL)
228 return -EINVAL;
229 basename = parent->name;
230 break;
231 case pmac_i2c_bus_pmu:
232 basename = "pmu";
233 break;
234 case pmac_i2c_bus_smu:
235 /* This is not what we used to do but I'm fixing drivers at
236 * the same time as this change
237 */
238 basename = "smu";
239 break;
240 default:
241 return -EINVAL;
242 }
243 snprintf(name, 32, "%s %d", basename, pmac_i2c_get_channel(bus));
244 of_node_put(parent);
245
246 adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
247 if (adapter == NULL) {
248 printk(KERN_ERR "i2c-powermac: can't allocate inteface !\n");
249 return -ENOMEM;
250 }
251 dev_set_drvdata(dev, adapter);
252 strcpy(adapter->name, name);
253 adapter->algo = &i2c_powermac_algorithm;
254 i2c_set_adapdata(adapter, bus);
255 adapter->dev.parent = dev;
256 pmac_i2c_attach_adapter(bus, adapter);
257 rc = i2c_add_adapter(adapter);
258 if (rc) {
259 printk(KERN_ERR "i2c-powermac: Adapter %s registration "
260 "failed\n", name);
261 i2c_set_adapdata(adapter, NULL);
262 pmac_i2c_detach_adapter(bus, adapter);
263 }
264
265 printk(KERN_INFO "PowerMac i2c bus %s registered\n", name);
266 return rc;
267}
268
269
270static struct device_driver i2c_powermac_driver = {
271 .name = "i2c-powermac",
272 .bus = &platform_bus_type,
273 .probe = i2c_powermac_probe,
274 .remove = i2c_powermac_remove,
275};
276
277static int __init i2c_powermac_init(void)
278{
279 driver_register(&i2c_powermac_driver);
280 return 0;
281}
282
283
284static void __exit i2c_powermac_cleanup(void)
285{
286 driver_unregister(&i2c_powermac_driver);
287}
288
289module_init(i2c_powermac_init);
290module_exit(i2c_powermac_cleanup);
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
index e70b3db69edd..1af3dfbb8086 100644
--- a/drivers/i2c/chips/tps65010.c
+++ b/drivers/i2c/chips/tps65010.c
@@ -494,6 +494,7 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind)
494{ 494{
495 struct tps65010 *tps; 495 struct tps65010 *tps;
496 int status; 496 int status;
497 unsigned long irqflags;
497 498
498 if (the_tps) { 499 if (the_tps) {
499 dev_dbg(&bus->dev, "only one %s for now\n", DRIVER_NAME); 500 dev_dbg(&bus->dev, "only one %s for now\n", DRIVER_NAME);
@@ -520,13 +521,14 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind)
520 } 521 }
521 522
522#ifdef CONFIG_ARM 523#ifdef CONFIG_ARM
524 irqflags = SA_SAMPLE_RANDOM | SA_TRIGGER_LOW;
523 if (machine_is_omap_h2()) { 525 if (machine_is_omap_h2()) {
524 tps->model = TPS65010; 526 tps->model = TPS65010;
525 omap_cfg_reg(W4_GPIO58); 527 omap_cfg_reg(W4_GPIO58);
526 tps->irq = OMAP_GPIO_IRQ(58); 528 tps->irq = OMAP_GPIO_IRQ(58);
527 omap_request_gpio(58); 529 omap_request_gpio(58);
528 omap_set_gpio_direction(58, 1); 530 omap_set_gpio_direction(58, 1);
529 set_irq_type(tps->irq, IRQT_FALLING); 531 irqflags |= SA_TRIGGER_FALLING;
530 } 532 }
531 if (machine_is_omap_osk()) { 533 if (machine_is_omap_osk()) {
532 tps->model = TPS65010; 534 tps->model = TPS65010;
@@ -534,7 +536,7 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind)
534 tps->irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1)); 536 tps->irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1));
535 omap_request_gpio(OMAP_MPUIO(1)); 537 omap_request_gpio(OMAP_MPUIO(1));
536 omap_set_gpio_direction(OMAP_MPUIO(1), 1); 538 omap_set_gpio_direction(OMAP_MPUIO(1), 1);
537 set_irq_type(tps->irq, IRQT_FALLING); 539 irqflags |= SA_TRIGGER_FALLING;
538 } 540 }
539 if (machine_is_omap_h3()) { 541 if (machine_is_omap_h3()) {
540 tps->model = TPS65013; 542 tps->model = TPS65013;
@@ -542,13 +544,12 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind)
542 // FIXME set up this board's IRQ ... 544 // FIXME set up this board's IRQ ...
543 } 545 }
544#else 546#else
545#define set_irq_type(num,trigger) do{}while(0) 547 irqflags = SA_SAMPLE_RANDOM;
546#endif 548#endif
547 549
548 if (tps->irq > 0) { 550 if (tps->irq > 0) {
549 set_irq_type(tps->irq, IRQT_LOW);
550 status = request_irq(tps->irq, tps65010_irq, 551 status = request_irq(tps->irq, tps65010_irq,
551 SA_SAMPLE_RANDOM, DRIVER_NAME, tps); 552 irqflags, DRIVER_NAME, tps);
552 if (status < 0) { 553 if (status < 0) {
553 dev_dbg(&tps->client.dev, "can't get IRQ %d, err %d\n", 554 dev_dbg(&tps->client.dev, "can't get IRQ %d, err %d\n",
554 tps->irq, status); 555 tps->irq, status);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index d31117eb95aa..e4d55ad32d2f 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -1332,8 +1332,6 @@ static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
1332 if (cdrom_read_from_buffer(drive)) 1332 if (cdrom_read_from_buffer(drive))
1333 return ide_stopped; 1333 return ide_stopped;
1334 1334
1335 blk_attempt_remerge(drive->queue, rq);
1336
1337 /* Clear the local sector buffer. */ 1335 /* Clear the local sector buffer. */
1338 info->nsectors_buffered = 0; 1336 info->nsectors_buffered = 0;
1339 1337
@@ -1874,14 +1872,6 @@ static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq)
1874 return ide_stopped; 1872 return ide_stopped;
1875 } 1873 }
1876 1874
1877 /*
1878 * for dvd-ram and such media, it's a really big deal to get
1879 * big writes all the time. so scour the queue and attempt to
1880 * remerge requests, often the plugging will not have had time
1881 * to do this properly
1882 */
1883 blk_attempt_remerge(drive->queue, rq);
1884
1885 info->nsectors_buffered = 0; 1875 info->nsectors_buffered = 0;
1886 1876
1887 /* use dma, if possible. we don't need to check more, since we 1877 /* use dma, if possible. we don't need to check more, since we
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 4b441720b6ba..cab362ea0336 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1130,6 +1130,17 @@ static int idedisk_release(struct inode *inode, struct file *filp)
1130 return 0; 1130 return 0;
1131} 1131}
1132 1132
1133static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1134{
1135 struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);
1136 ide_drive_t *drive = idkp->drive;
1137
1138 geo->heads = drive->bios_head;
1139 geo->sectors = drive->bios_sect;
1140 geo->cylinders = (u16)drive->bios_cyl; /* truncate */
1141 return 0;
1142}
1143
1133static int idedisk_ioctl(struct inode *inode, struct file *file, 1144static int idedisk_ioctl(struct inode *inode, struct file *file,
1134 unsigned int cmd, unsigned long arg) 1145 unsigned int cmd, unsigned long arg)
1135{ 1146{
@@ -1164,6 +1175,7 @@ static struct block_device_operations idedisk_ops = {
1164 .open = idedisk_open, 1175 .open = idedisk_open,
1165 .release = idedisk_release, 1176 .release = idedisk_release,
1166 .ioctl = idedisk_ioctl, 1177 .ioctl = idedisk_ioctl,
1178 .getgeo = idedisk_getgeo,
1167 .media_changed = idedisk_media_changed, 1179 .media_changed = idedisk_media_changed,
1168 .revalidate_disk= idedisk_revalidate_disk 1180 .revalidate_disk= idedisk_revalidate_disk
1169}; 1181};
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index fba3fffc2d66..5945f551aaaa 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -2031,6 +2031,17 @@ static int idefloppy_release(struct inode *inode, struct file *filp)
2031 return 0; 2031 return 0;
2032} 2032}
2033 2033
2034static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
2035{
2036 struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk);
2037 ide_drive_t *drive = floppy->drive;
2038
2039 geo->heads = drive->bios_head;
2040 geo->sectors = drive->bios_sect;
2041 geo->cylinders = (u16)drive->bios_cyl; /* truncate */
2042 return 0;
2043}
2044
2034static int idefloppy_ioctl(struct inode *inode, struct file *file, 2045static int idefloppy_ioctl(struct inode *inode, struct file *file,
2035 unsigned int cmd, unsigned long arg) 2046 unsigned int cmd, unsigned long arg)
2036{ 2047{
@@ -2120,6 +2131,7 @@ static struct block_device_operations idefloppy_ops = {
2120 .open = idefloppy_open, 2131 .open = idefloppy_open,
2121 .release = idefloppy_release, 2132 .release = idefloppy_release,
2122 .ioctl = idefloppy_ioctl, 2133 .ioctl = idefloppy_ioctl,
2134 .getgeo = idefloppy_getgeo,
2123 .media_changed = idefloppy_media_changed, 2135 .media_changed = idefloppy_media_changed,
2124 .revalidate_disk= idefloppy_revalidate_disk 2136 .revalidate_disk= idefloppy_revalidate_disk
2125}; 2137};
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index b5dc6df8e67d..dea2d4dcc698 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -55,9 +55,22 @@
55#include <asm/io.h> 55#include <asm/io.h>
56#include <asm/bitops.h> 56#include <asm/bitops.h>
57 57
58void ide_softirq_done(struct request *rq)
59{
60 request_queue_t *q = rq->q;
61
62 add_disk_randomness(rq->rq_disk);
63 end_that_request_chunk(rq, rq->errors, rq->data_len);
64
65 spin_lock_irq(q->queue_lock);
66 end_that_request_last(rq, rq->errors);
67 spin_unlock_irq(q->queue_lock);
68}
69
58int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, 70int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate,
59 int nr_sectors) 71 int nr_sectors)
60{ 72{
73 unsigned int nbytes;
61 int ret = 1; 74 int ret = 1;
62 75
63 BUG_ON(!(rq->flags & REQ_STARTED)); 76 BUG_ON(!(rq->flags & REQ_STARTED));
@@ -81,17 +94,28 @@ int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate,
81 HWGROUP(drive)->hwif->ide_dma_on(drive); 94 HWGROUP(drive)->hwif->ide_dma_on(drive);
82 } 95 }
83 96
84 if (!end_that_request_first(rq, uptodate, nr_sectors)) { 97 /*
85 add_disk_randomness(rq->rq_disk); 98 * For partial completions (or non fs/pc requests), use the regular
86 99 * direct completion path.
87 if (blk_rq_tagged(rq)) 100 */
88 blk_queue_end_tag(drive->queue, rq); 101 nbytes = nr_sectors << 9;
89 102 if (rq_all_done(rq, nbytes)) {
103 rq->errors = uptodate;
104 rq->data_len = nbytes;
90 blkdev_dequeue_request(rq); 105 blkdev_dequeue_request(rq);
91 HWGROUP(drive)->rq = NULL; 106 HWGROUP(drive)->rq = NULL;
92 end_that_request_last(rq, uptodate); 107 blk_complete_request(rq);
93 ret = 0; 108 ret = 0;
109 } else {
110 if (!end_that_request_first(rq, uptodate, nr_sectors)) {
111 add_disk_randomness(rq->rq_disk);
112 blkdev_dequeue_request(rq);
113 HWGROUP(drive)->rq = NULL;
114 end_that_request_last(rq, uptodate);
115 ret = 0;
116 }
94 } 117 }
118
95 return ret; 119 return ret;
96} 120}
97EXPORT_SYMBOL(__ide_end_request); 121EXPORT_SYMBOL(__ide_end_request);
@@ -113,6 +137,10 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors)
113 unsigned long flags; 137 unsigned long flags;
114 int ret = 1; 138 int ret = 1;
115 139
140 /*
141 * room for locking improvements here, the calls below don't
142 * need the queue lock held at all
143 */
116 spin_lock_irqsave(&ide_lock, flags); 144 spin_lock_irqsave(&ide_lock, flags);
117 rq = HWGROUP(drive)->rq; 145 rq = HWGROUP(drive)->rq;
118 146
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 02167a5b751d..1ddaa71a8f45 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1011,6 +1011,8 @@ static int ide_init_queue(ide_drive_t *drive)
1011 blk_queue_max_hw_segments(q, max_sg_entries); 1011 blk_queue_max_hw_segments(q, max_sg_entries);
1012 blk_queue_max_phys_segments(q, max_sg_entries); 1012 blk_queue_max_phys_segments(q, max_sg_entries);
1013 1013
1014 blk_queue_softirq_done(q, ide_softirq_done);
1015
1014 /* assign drive queue */ 1016 /* assign drive queue */
1015 drive->queue = q; 1017 drive->queue = q;
1016 1018
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 4b524f6b3ecd..b069b13b75a7 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1278,19 +1278,6 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
1278 up(&ide_setting_sem); 1278 up(&ide_setting_sem);
1279 1279
1280 switch (cmd) { 1280 switch (cmd) {
1281 case HDIO_GETGEO:
1282 {
1283 struct hd_geometry geom;
1284 if (!p || (drive->media != ide_disk && drive->media != ide_floppy)) return -EINVAL;
1285 geom.heads = drive->bios_head;
1286 geom.sectors = drive->bios_sect;
1287 geom.cylinders = (u16)drive->bios_cyl; /* truncate */
1288 geom.start = get_start_sect(bdev);
1289 if (copy_to_user(p, &geom, sizeof(struct hd_geometry)))
1290 return -EFAULT;
1291 return 0;
1292 }
1293
1294 case HDIO_OBSOLETE_IDENTITY: 1281 case HDIO_OBSOLETE_IDENTITY:
1295 case HDIO_GET_IDENTITY: 1282 case HDIO_GET_IDENTITY:
1296 if (bdev != bdev->bd_contains) 1283 if (bdev != bdev->bd_contains)
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
index 242029c9c0ca..6439dec66881 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -658,22 +658,14 @@ static void do_hd_request (request_queue_t * q)
658 enable_irq(HD_IRQ); 658 enable_irq(HD_IRQ);
659} 659}
660 660
661static int hd_ioctl(struct inode * inode, struct file * file, 661static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
662 unsigned int cmd, unsigned long arg)
663{ 662{
664 struct hd_i_struct *disk = inode->i_bdev->bd_disk->private_data; 663 struct hd_i_struct *disk = bdev->bd_disk->private_data;
665 struct hd_geometry __user *loc = (struct hd_geometry __user *) arg; 664
666 struct hd_geometry g; 665 geo->heads = disk->head;
667 666 geo->sectors = disk->sect;
668 if (cmd != HDIO_GETGEO) 667 geo->cylinders = disk->cyl;
669 return -EINVAL; 668 return 0;
670 if (!loc)
671 return -EINVAL;
672 g.heads = disk->head;
673 g.sectors = disk->sect;
674 g.cylinders = disk->cyl;
675 g.start = get_start_sect(inode->i_bdev);
676 return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0;
677} 669}
678 670
679/* 671/*
@@ -695,7 +687,7 @@ static irqreturn_t hd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
695} 687}
696 688
697static struct block_device_operations hd_fops = { 689static struct block_device_operations hd_fops = {
698 .ioctl = hd_ioctl, 690 .getgeo = hd_getgeo,
699}; 691};
700 692
701/* 693/*
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index ff2e217a8c84..0d3073f4eab4 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -69,7 +69,7 @@ static int check_in_drive_lists (ide_drive_t *drive, const char **list)
69static u8 svwks_ratemask (ide_drive_t *drive) 69static u8 svwks_ratemask (ide_drive_t *drive)
70{ 70{
71 struct pci_dev *dev = HWIF(drive)->pci_dev; 71 struct pci_dev *dev = HWIF(drive)->pci_dev;
72 u8 mode; 72 u8 mode = 0;
73 73
74 if (!svwks_revision) 74 if (!svwks_revision)
75 pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision); 75 pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision);
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 16b28357885b..5013b1285e22 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1271,7 +1271,7 @@ static int
1271pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) 1271pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
1272{ 1272{
1273 struct device_node *np = pmif->node; 1273 struct device_node *np = pmif->node;
1274 int *bidp, i; 1274 int *bidp;
1275 1275
1276 pmif->cable_80 = 0; 1276 pmif->cable_80 = 0;
1277 pmif->broken_dma = pmif->broken_dma_warn = 0; 1277 pmif->broken_dma = pmif->broken_dma_warn = 0;
@@ -1430,7 +1430,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
1430 pmif = &pmac_ide[i]; 1430 pmif = &pmac_ide[i];
1431 hwif = &ide_hwifs[i]; 1431 hwif = &ide_hwifs[i];
1432 1432
1433 if (mdev->ofdev.node->n_addrs == 0) { 1433 if (macio_resource_count(mdev) == 0) {
1434 printk(KERN_WARNING "ide%d: no address for %s\n", 1434 printk(KERN_WARNING "ide%d: no address for %s\n",
1435 i, mdev->ofdev.node->full_name); 1435 i, mdev->ofdev.node->full_name);
1436 return -ENXIO; 1436 return -ENXIO;
@@ -1686,7 +1686,7 @@ pmac_ide_probe(void)
1686#else 1686#else
1687 macio_register_driver(&pmac_ide_macio_driver); 1687 macio_register_driver(&pmac_ide_macio_driver);
1688 pci_register_driver(&pmac_ide_pci_driver); 1688 pci_register_driver(&pmac_ide_pci_driver);
1689#endif 1689#endif
1690} 1690}
1691 1691
1692#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC 1692#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 02110e00d145..3a611fe5497e 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -308,10 +308,11 @@ static int cm_alloc_id(struct cm_id_private *cm_id_priv)
308{ 308{
309 unsigned long flags; 309 unsigned long flags;
310 int ret; 310 int ret;
311 static int next_id;
311 312
312 do { 313 do {
313 spin_lock_irqsave(&cm.lock, flags); 314 spin_lock_irqsave(&cm.lock, flags);
314 ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, 1, 315 ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, next_id++,
315 (__force int *) &cm_id_priv->id.local_id); 316 (__force int *) &cm_id_priv->id.local_id);
316 spin_unlock_irqrestore(&cm.lock, flags); 317 spin_unlock_irqrestore(&cm.lock, flags);
317 } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) ); 318 } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) );
@@ -684,6 +685,13 @@ retest:
684 cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT); 685 cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT);
685 break; 686 break;
686 case IB_CM_REQ_SENT: 687 case IB_CM_REQ_SENT:
688 ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
689 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
690 ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT,
691 &cm_id_priv->av.port->cm_dev->ca_guid,
692 sizeof cm_id_priv->av.port->cm_dev->ca_guid,
693 NULL, 0);
694 break;
687 case IB_CM_MRA_REQ_RCVD: 695 case IB_CM_MRA_REQ_RCVD:
688 case IB_CM_REP_SENT: 696 case IB_CM_REP_SENT:
689 case IB_CM_MRA_REP_RCVD: 697 case IB_CM_MRA_REP_RCVD:
@@ -694,10 +702,8 @@ retest:
694 case IB_CM_REP_RCVD: 702 case IB_CM_REP_RCVD:
695 case IB_CM_MRA_REP_SENT: 703 case IB_CM_MRA_REP_SENT:
696 spin_unlock_irqrestore(&cm_id_priv->lock, flags); 704 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
697 ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT, 705 ib_send_cm_rej(cm_id, IB_CM_REJ_CONSUMER_DEFINED,
698 &cm_id_priv->av.port->cm_dev->ca_guid, 706 NULL, 0, NULL, 0);
699 sizeof cm_id_priv->av.port->cm_dev->ca_guid,
700 NULL, 0);
701 break; 707 break;
702 case IB_CM_ESTABLISHED: 708 case IB_CM_ESTABLISHED:
703 spin_unlock_irqrestore(&cm_id_priv->lock, flags); 709 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index eb7f52537ccc..c908de8db5a9 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -197,8 +197,8 @@ static void send_handler(struct ib_mad_agent *agent,
197 memcpy(timeout->mad.data, packet->mad.data, 197 memcpy(timeout->mad.data, packet->mad.data,
198 sizeof (struct ib_mad_hdr)); 198 sizeof (struct ib_mad_hdr));
199 199
200 if (!queue_packet(file, agent, timeout)) 200 if (queue_packet(file, agent, timeout))
201 return; 201 kfree(timeout);
202 } 202 }
203out: 203out:
204 kfree(packet); 204 kfree(packet);
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index a57d021d435a..a02c5a05c984 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -489,6 +489,7 @@ err_idr:
489 489
490err_unreg: 490err_unreg:
491 ib_dereg_mr(mr); 491 ib_dereg_mr(mr);
492 atomic_dec(&pd->usecnt);
492 493
493err_up: 494err_up:
494 up(&ib_uverbs_idr_mutex); 495 up(&ib_uverbs_idr_mutex);
@@ -593,13 +594,18 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
593 if (cmd.comp_vector >= file->device->num_comp_vectors) 594 if (cmd.comp_vector >= file->device->num_comp_vectors)
594 return -EINVAL; 595 return -EINVAL;
595 596
596 if (cmd.comp_channel >= 0)
597 ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel);
598
599 uobj = kmalloc(sizeof *uobj, GFP_KERNEL); 597 uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
600 if (!uobj) 598 if (!uobj)
601 return -ENOMEM; 599 return -ENOMEM;
602 600
601 if (cmd.comp_channel >= 0) {
602 ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel);
603 if (!ev_file) {
604 ret = -EINVAL;
605 goto err;
606 }
607 }
608
603 uobj->uobject.user_handle = cmd.user_handle; 609 uobj->uobject.user_handle = cmd.user_handle;
604 uobj->uobject.context = file->ucontext; 610 uobj->uobject.context = file->ucontext;
605 uobj->uverbs_file = file; 611 uobj->uverbs_file = file;
@@ -663,6 +669,8 @@ err_up:
663 ib_destroy_cq(cq); 669 ib_destroy_cq(cq);
664 670
665err: 671err:
672 if (ev_file)
673 ib_uverbs_release_ucq(file, ev_file, uobj);
666 kfree(uobj); 674 kfree(uobj);
667 return ret; 675 return ret;
668} 676}
@@ -935,6 +943,11 @@ err_idr:
935 943
936err_destroy: 944err_destroy:
937 ib_destroy_qp(qp); 945 ib_destroy_qp(qp);
946 atomic_dec(&pd->usecnt);
947 atomic_dec(&attr.send_cq->usecnt);
948 atomic_dec(&attr.recv_cq->usecnt);
949 if (attr.srq)
950 atomic_dec(&attr.srq->usecnt);
938 951
939err_up: 952err_up:
940 up(&ib_uverbs_idr_mutex); 953 up(&ib_uverbs_idr_mutex);
@@ -1448,6 +1461,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
1448 attr.sl = cmd.attr.sl; 1461 attr.sl = cmd.attr.sl;
1449 attr.src_path_bits = cmd.attr.src_path_bits; 1462 attr.src_path_bits = cmd.attr.src_path_bits;
1450 attr.static_rate = cmd.attr.static_rate; 1463 attr.static_rate = cmd.attr.static_rate;
1464 attr.ah_flags = cmd.attr.is_global ? IB_AH_GRH : 0;
1451 attr.port_num = cmd.attr.port_num; 1465 attr.port_num = cmd.attr.port_num;
1452 attr.grh.flow_label = cmd.attr.grh.flow_label; 1466 attr.grh.flow_label = cmd.attr.grh.flow_label;
1453 attr.grh.sgid_index = cmd.attr.grh.sgid_index; 1467 attr.grh.sgid_index = cmd.attr.grh.sgid_index;
@@ -1729,6 +1743,7 @@ err_idr:
1729 1743
1730err_destroy: 1744err_destroy:
1731 ib_destroy_srq(srq); 1745 ib_destroy_srq(srq);
1746 atomic_dec(&pd->usecnt);
1732 1747
1733err_up: 1748err_up:
1734 up(&ib_uverbs_idr_mutex); 1749 up(&ib_uverbs_idr_mutex);
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 4c15e112736c..c857361be449 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -107,9 +107,9 @@ struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc,
107 107
108 if (wc->wc_flags & IB_WC_GRH) { 108 if (wc->wc_flags & IB_WC_GRH) {
109 ah_attr.ah_flags = IB_AH_GRH; 109 ah_attr.ah_flags = IB_AH_GRH;
110 ah_attr.grh.dgid = grh->dgid; 110 ah_attr.grh.dgid = grh->sgid;
111 111
112 ret = ib_find_cached_gid(pd->device, &grh->sgid, &port_num, 112 ret = ib_find_cached_gid(pd->device, &grh->dgid, &port_num,
113 &gid_index); 113 &gid_index);
114 if (ret) 114 if (ret)
115 return ERR_PTR(ret); 115 return ERR_PTR(ret);
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 9ed34587fc5c..22ac72bc20c3 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -937,10 +937,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
937 if (err) 937 if (err)
938 goto out; 938 goto out;
939 939
940 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET);
941 dev_lim->max_srq_sz = (1 << field) - 1;
942 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET);
943 dev_lim->max_qp_sz = (1 << field) - 1;
944 MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_QP_OFFSET); 940 MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_QP_OFFSET);
945 dev_lim->reserved_qps = 1 << (field & 0xf); 941 dev_lim->reserved_qps = 1 << (field & 0xf);
946 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_OFFSET); 942 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_OFFSET);
@@ -1056,6 +1052,10 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
1056 mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags); 1052 mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags);
1057 1053
1058 if (mthca_is_memfree(dev)) { 1054 if (mthca_is_memfree(dev)) {
1055 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET);
1056 dev_lim->max_srq_sz = 1 << field;
1057 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET);
1058 dev_lim->max_qp_sz = 1 << field;
1059 MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSZ_SRQ_OFFSET); 1059 MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSZ_SRQ_OFFSET);
1060 dev_lim->hca.arbel.resize_srq = field & 1; 1060 dev_lim->hca.arbel.resize_srq = field & 1;
1061 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET); 1061 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET);
@@ -1087,6 +1087,10 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
1087 mthca_dbg(dev, "Max ICM size %lld MB\n", 1087 mthca_dbg(dev, "Max ICM size %lld MB\n",
1088 (unsigned long long) dev_lim->hca.arbel.max_icm_sz >> 20); 1088 (unsigned long long) dev_lim->hca.arbel.max_icm_sz >> 20);
1089 } else { 1089 } else {
1090 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET);
1091 dev_lim->max_srq_sz = (1 << field) - 1;
1092 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET);
1093 dev_lim->max_qp_sz = (1 << field) - 1;
1090 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_AV_OFFSET); 1094 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_AV_OFFSET);
1091 dev_lim->hca.tavor.max_avs = 1 << (field & 0x3f); 1095 dev_lim->hca.tavor.max_avs = 1 << (field & 0x3f);
1092 dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE; 1096 dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE;
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index 4a8adcef2079..96f1a86bf049 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -128,12 +128,12 @@ struct mthca_err_cqe {
128 __be32 my_qpn; 128 __be32 my_qpn;
129 u32 reserved1[3]; 129 u32 reserved1[3];
130 u8 syndrome; 130 u8 syndrome;
131 u8 reserved2; 131 u8 vendor_err;
132 __be16 db_cnt; 132 __be16 db_cnt;
133 u32 reserved3; 133 u32 reserved2;
134 __be32 wqe; 134 __be32 wqe;
135 u8 opcode; 135 u8 opcode;
136 u8 reserved4[2]; 136 u8 reserved3[2];
137 u8 owner; 137 u8 owner;
138}; 138};
139 139
@@ -253,6 +253,15 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn,
253 wake_up(&cq->wait); 253 wake_up(&cq->wait);
254} 254}
255 255
256static inline int is_recv_cqe(struct mthca_cqe *cqe)
257{
258 if ((cqe->opcode & MTHCA_ERROR_CQE_OPCODE_MASK) ==
259 MTHCA_ERROR_CQE_OPCODE_MASK)
260 return !(cqe->opcode & 0x01);
261 else
262 return !(cqe->is_send & 0x80);
263}
264
256void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, 265void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
257 struct mthca_srq *srq) 266 struct mthca_srq *srq)
258{ 267{
@@ -296,7 +305,7 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
296 while ((int) --prod_index - (int) cq->cons_index >= 0) { 305 while ((int) --prod_index - (int) cq->cons_index >= 0) {
297 cqe = get_cqe(cq, prod_index & cq->ibcq.cqe); 306 cqe = get_cqe(cq, prod_index & cq->ibcq.cqe);
298 if (cqe->my_qpn == cpu_to_be32(qpn)) { 307 if (cqe->my_qpn == cpu_to_be32(qpn)) {
299 if (srq) 308 if (srq && is_recv_cqe(cqe))
300 mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe)); 309 mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe));
301 ++nfreed; 310 ++nfreed;
302 } else if (nfreed) 311 } else if (nfreed)
@@ -333,8 +342,8 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq,
333 } 342 }
334 343
335 /* 344 /*
336 * For completions in error, only work request ID, status (and 345 * For completions in error, only work request ID, status, vendor error
337 * freed resource count for RD) have to be set. 346 * (and freed resource count for RD) have to be set.
338 */ 347 */
339 switch (cqe->syndrome) { 348 switch (cqe->syndrome) {
340 case SYNDROME_LOCAL_LENGTH_ERR: 349 case SYNDROME_LOCAL_LENGTH_ERR:
@@ -396,6 +405,8 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq,
396 break; 405 break;
397 } 406 }
398 407
408 entry->vendor_err = cqe->vendor_err;
409
399 /* 410 /*
400 * Mem-free HCAs always generate one CQE per WQE, even in the 411 * Mem-free HCAs always generate one CQE per WQE, even in the
401 * error case, so we don't have to check the doorbell count, etc. 412 * error case, so we don't have to check the doorbell count, etc.
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index 497ff794ef6a..795b379260bf 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -43,6 +43,7 @@
43#include <linux/kernel.h> 43#include <linux/kernel.h>
44#include <linux/pci.h> 44#include <linux/pci.h>
45#include <linux/dma-mapping.h> 45#include <linux/dma-mapping.h>
46#include <linux/timer.h>
46#include <asm/semaphore.h> 47#include <asm/semaphore.h>
47 48
48#include "mthca_provider.h" 49#include "mthca_provider.h"
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
index 34d68e5a72d8..e8a948f087c0 100644
--- a/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -484,8 +484,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev,
484 u8 intr, 484 u8 intr,
485 struct mthca_eq *eq) 485 struct mthca_eq *eq)
486{ 486{
487 int npages = (nent * MTHCA_EQ_ENTRY_SIZE + PAGE_SIZE - 1) / 487 int npages;
488 PAGE_SIZE;
489 u64 *dma_list = NULL; 488 u64 *dma_list = NULL;
490 dma_addr_t t; 489 dma_addr_t t;
491 struct mthca_mailbox *mailbox; 490 struct mthca_mailbox *mailbox;
@@ -496,6 +495,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev,
496 495
497 eq->dev = dev; 496 eq->dev = dev;
498 eq->nent = roundup_pow_of_two(max(nent, 2)); 497 eq->nent = roundup_pow_of_two(max(nent, 2));
498 npages = ALIGN(eq->nent * MTHCA_EQ_ENTRY_SIZE, PAGE_SIZE) / PAGE_SIZE;
499 499
500 eq->page_list = kmalloc(npages * sizeof *eq->page_list, 500 eq->page_list = kmalloc(npages * sizeof *eq->page_list,
501 GFP_KERNEL); 501 GFP_KERNEL);
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 6f94b25f3acd..8b00d9a0f6f4 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -261,6 +261,10 @@ static int __devinit mthca_init_tavor(struct mthca_dev *mdev)
261 } 261 }
262 262
263 err = mthca_dev_lim(mdev, &dev_lim); 263 err = mthca_dev_lim(mdev, &dev_lim);
264 if (err) {
265 mthca_err(mdev, "QUERY_DEV_LIM command failed, aborting.\n");
266 goto err_disable;
267 }
264 268
265 profile = default_profile; 269 profile = default_profile;
266 profile.num_uar = dev_lim.uar_size / PAGE_SIZE; 270 profile.num_uar = dev_lim.uar_size / PAGE_SIZE;
diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c
index 2fc449da418d..77bc6c746f43 100644
--- a/drivers/infiniband/hw/mthca/mthca_mcg.c
+++ b/drivers/infiniband/hw/mthca/mthca_mcg.c
@@ -111,7 +111,8 @@ static int find_mgm(struct mthca_dev *dev,
111 goto out; 111 goto out;
112 if (status) { 112 if (status) {
113 mthca_err(dev, "READ_MGM returned status %02x\n", status); 113 mthca_err(dev, "READ_MGM returned status %02x\n", status);
114 return -EINVAL; 114 err = -EINVAL;
115 goto out;
115 } 116 }
116 117
117 if (!memcmp(mgm->gid, zero_gid, 16)) { 118 if (!memcmp(mgm->gid, zero_gid, 16)) {
@@ -126,7 +127,7 @@ static int find_mgm(struct mthca_dev *dev,
126 goto out; 127 goto out;
127 128
128 *prev = *index; 129 *prev = *index;
129 *index = be32_to_cpu(mgm->next_gid_index) >> 5; 130 *index = be32_to_cpu(mgm->next_gid_index) >> 6;
130 } while (*index); 131 } while (*index);
131 132
132 *index = -1; 133 *index = -1;
@@ -153,8 +154,10 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
153 return PTR_ERR(mailbox); 154 return PTR_ERR(mailbox);
154 mgm = mailbox->buf; 155 mgm = mailbox->buf;
155 156
156 if (down_interruptible(&dev->mcg_table.sem)) 157 if (down_interruptible(&dev->mcg_table.sem)) {
157 return -EINTR; 158 err = -EINTR;
159 goto err_sem;
160 }
158 161
159 err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); 162 err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index);
160 if (err) 163 if (err)
@@ -181,9 +184,8 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
181 err = -EINVAL; 184 err = -EINVAL;
182 goto out; 185 goto out;
183 } 186 }
184 187 memset(mgm, 0, sizeof *mgm);
185 memcpy(mgm->gid, gid->raw, 16); 188 memcpy(mgm->gid, gid->raw, 16);
186 mgm->next_gid_index = 0;
187 } 189 }
188 190
189 for (i = 0; i < MTHCA_QP_PER_MGM; ++i) 191 for (i = 0; i < MTHCA_QP_PER_MGM; ++i)
@@ -209,6 +211,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
209 if (status) { 211 if (status) {
210 mthca_err(dev, "WRITE_MGM returned status %02x\n", status); 212 mthca_err(dev, "WRITE_MGM returned status %02x\n", status);
211 err = -EINVAL; 213 err = -EINVAL;
214 goto out;
212 } 215 }
213 216
214 if (!link) 217 if (!link)
@@ -223,7 +226,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
223 goto out; 226 goto out;
224 } 227 }
225 228
226 mgm->next_gid_index = cpu_to_be32(index << 5); 229 mgm->next_gid_index = cpu_to_be32(index << 6);
227 230
228 err = mthca_WRITE_MGM(dev, prev, mailbox, &status); 231 err = mthca_WRITE_MGM(dev, prev, mailbox, &status);
229 if (err) 232 if (err)
@@ -234,7 +237,12 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
234 } 237 }
235 238
236 out: 239 out:
240 if (err && link && index != -1) {
241 BUG_ON(index < dev->limits.num_mgms);
242 mthca_free(&dev->mcg_table.alloc, index);
243 }
237 up(&dev->mcg_table.sem); 244 up(&dev->mcg_table.sem);
245 err_sem:
238 mthca_free_mailbox(dev, mailbox); 246 mthca_free_mailbox(dev, mailbox);
239 return err; 247 return err;
240} 248}
@@ -255,8 +263,10 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
255 return PTR_ERR(mailbox); 263 return PTR_ERR(mailbox);
256 mgm = mailbox->buf; 264 mgm = mailbox->buf;
257 265
258 if (down_interruptible(&dev->mcg_table.sem)) 266 if (down_interruptible(&dev->mcg_table.sem)) {
259 return -EINTR; 267 err = -EINTR;
268 goto err_sem;
269 }
260 270
261 err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); 271 err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index);
262 if (err) 272 if (err)
@@ -305,13 +315,11 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
305 if (i != 1) 315 if (i != 1)
306 goto out; 316 goto out;
307 317
308 goto out;
309
310 if (prev == -1) { 318 if (prev == -1) {
311 /* Remove entry from MGM */ 319 /* Remove entry from MGM */
312 if (be32_to_cpu(mgm->next_gid_index) >> 5) { 320 int amgm_index_to_free = be32_to_cpu(mgm->next_gid_index) >> 6;
313 err = mthca_READ_MGM(dev, 321 if (amgm_index_to_free) {
314 be32_to_cpu(mgm->next_gid_index) >> 5, 322 err = mthca_READ_MGM(dev, amgm_index_to_free,
315 mailbox, &status); 323 mailbox, &status);
316 if (err) 324 if (err)
317 goto out; 325 goto out;
@@ -332,9 +340,13 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
332 err = -EINVAL; 340 err = -EINVAL;
333 goto out; 341 goto out;
334 } 342 }
343 if (amgm_index_to_free) {
344 BUG_ON(amgm_index_to_free < dev->limits.num_mgms);
345 mthca_free(&dev->mcg_table.alloc, amgm_index_to_free);
346 }
335 } else { 347 } else {
336 /* Remove entry from AMGM */ 348 /* Remove entry from AMGM */
337 index = be32_to_cpu(mgm->next_gid_index) >> 5; 349 int curr_next_index = be32_to_cpu(mgm->next_gid_index) >> 6;
338 err = mthca_READ_MGM(dev, prev, mailbox, &status); 350 err = mthca_READ_MGM(dev, prev, mailbox, &status);
339 if (err) 351 if (err)
340 goto out; 352 goto out;
@@ -344,7 +356,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
344 goto out; 356 goto out;
345 } 357 }
346 358
347 mgm->next_gid_index = cpu_to_be32(index << 5); 359 mgm->next_gid_index = cpu_to_be32(curr_next_index << 6);
348 360
349 err = mthca_WRITE_MGM(dev, prev, mailbox, &status); 361 err = mthca_WRITE_MGM(dev, prev, mailbox, &status);
350 if (err) 362 if (err)
@@ -354,10 +366,13 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
354 err = -EINVAL; 366 err = -EINVAL;
355 goto out; 367 goto out;
356 } 368 }
369 BUG_ON(index < dev->limits.num_mgms);
370 mthca_free(&dev->mcg_table.alloc, index);
357 } 371 }
358 372
359 out: 373 out:
360 up(&dev->mcg_table.sem); 374 up(&dev->mcg_table.sem);
375 err_sem:
361 mthca_free_mailbox(dev, mailbox); 376 mthca_free_mailbox(dev, mailbox);
362 return err; 377 return err;
363} 378}
@@ -365,11 +380,12 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
365int __devinit mthca_init_mcg_table(struct mthca_dev *dev) 380int __devinit mthca_init_mcg_table(struct mthca_dev *dev)
366{ 381{
367 int err; 382 int err;
383 int table_size = dev->limits.num_mgms + dev->limits.num_amgms;
368 384
369 err = mthca_alloc_init(&dev->mcg_table.alloc, 385 err = mthca_alloc_init(&dev->mcg_table.alloc,
370 dev->limits.num_amgms, 386 table_size,
371 dev->limits.num_amgms - 1, 387 table_size - 1,
372 0); 388 dev->limits.num_mgms);
373 if (err) 389 if (err)
374 return err; 390 return err;
375 391
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index d72fe95cba08..9fb985a016e9 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -233,7 +233,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj)
233 for (i = 0; i < chunk->npages; ++i) { 233 for (i = 0; i < chunk->npages; ++i) {
234 if (chunk->mem[i].length >= offset) { 234 if (chunk->mem[i].length >= offset) {
235 page = chunk->mem[i].page; 235 page = chunk->mem[i].page;
236 break; 236 goto out;
237 } 237 }
238 offset -= chunk->mem[i].length; 238 offset -= chunk->mem[i].length;
239 } 239 }
@@ -485,6 +485,8 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
485 put_page(db_tab->page[i].mem.page); 485 put_page(db_tab->page[i].mem.page);
486 } 486 }
487 } 487 }
488
489 kfree(db_tab);
488} 490}
489 491
490int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type, 492int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type,
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 7450550db736..564b6d51c394 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -383,12 +383,10 @@ static const struct {
383 [UC] = (IB_QP_CUR_STATE | 383 [UC] = (IB_QP_CUR_STATE |
384 IB_QP_ALT_PATH | 384 IB_QP_ALT_PATH |
385 IB_QP_ACCESS_FLAGS | 385 IB_QP_ACCESS_FLAGS |
386 IB_QP_PKEY_INDEX |
387 IB_QP_PATH_MIG_STATE), 386 IB_QP_PATH_MIG_STATE),
388 [RC] = (IB_QP_CUR_STATE | 387 [RC] = (IB_QP_CUR_STATE |
389 IB_QP_ALT_PATH | 388 IB_QP_ALT_PATH |
390 IB_QP_ACCESS_FLAGS | 389 IB_QP_ACCESS_FLAGS |
391 IB_QP_PKEY_INDEX |
392 IB_QP_MIN_RNR_TIMER | 390 IB_QP_MIN_RNR_TIMER |
393 IB_QP_PATH_MIG_STATE), 391 IB_QP_PATH_MIG_STATE),
394 [MLX] = (IB_QP_CUR_STATE | 392 [MLX] = (IB_QP_CUR_STATE |
@@ -476,9 +474,8 @@ static const struct {
476 .opt_param = { 474 .opt_param = {
477 [UD] = (IB_QP_CUR_STATE | 475 [UD] = (IB_QP_CUR_STATE |
478 IB_QP_QKEY), 476 IB_QP_QKEY),
479 [UC] = IB_QP_CUR_STATE, 477 [UC] = (IB_QP_CUR_STATE |
480 [RC] = (IB_QP_CUR_STATE | 478 IB_QP_ACCESS_FLAGS),
481 IB_QP_MIN_RNR_TIMER),
482 [MLX] = (IB_QP_CUR_STATE | 479 [MLX] = (IB_QP_CUR_STATE |
483 IB_QP_QKEY), 480 IB_QP_QKEY),
484 } 481 }
@@ -522,6 +519,55 @@ static void init_port(struct mthca_dev *dev, int port)
522 mthca_warn(dev, "INIT_IB returned status %02x.\n", status); 519 mthca_warn(dev, "INIT_IB returned status %02x.\n", status);
523} 520}
524 521
522static __be32 get_hw_access_flags(struct mthca_qp *qp, struct ib_qp_attr *attr,
523 int attr_mask)
524{
525 u8 dest_rd_atomic;
526 u32 access_flags;
527 u32 hw_access_flags = 0;
528
529 if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
530 dest_rd_atomic = attr->max_dest_rd_atomic;
531 else
532 dest_rd_atomic = qp->resp_depth;
533
534 if (attr_mask & IB_QP_ACCESS_FLAGS)
535 access_flags = attr->qp_access_flags;
536 else
537 access_flags = qp->atomic_rd_en;
538
539 if (!dest_rd_atomic)
540 access_flags &= IB_ACCESS_REMOTE_WRITE;
541
542 if (access_flags & IB_ACCESS_REMOTE_READ)
543 hw_access_flags |= MTHCA_QP_BIT_RRE;
544 if (access_flags & IB_ACCESS_REMOTE_ATOMIC)
545 hw_access_flags |= MTHCA_QP_BIT_RAE;
546 if (access_flags & IB_ACCESS_REMOTE_WRITE)
547 hw_access_flags |= MTHCA_QP_BIT_RWE;
548
549 return cpu_to_be32(hw_access_flags);
550}
551
552static void mthca_path_set(struct ib_ah_attr *ah, struct mthca_qp_path *path)
553{
554 path->g_mylmc = ah->src_path_bits & 0x7f;
555 path->rlid = cpu_to_be16(ah->dlid);
556 path->static_rate = !!ah->static_rate;
557
558 if (ah->ah_flags & IB_AH_GRH) {
559 path->g_mylmc |= 1 << 7;
560 path->mgid_index = ah->grh.sgid_index;
561 path->hop_limit = ah->grh.hop_limit;
562 path->sl_tclass_flowlabel =
563 cpu_to_be32((ah->sl << 28) |
564 (ah->grh.traffic_class << 20) |
565 (ah->grh.flow_label));
566 memcpy(path->rgid, ah->grh.dgid.raw, 16);
567 } else
568 path->sl_tclass_flowlabel = cpu_to_be32(ah->sl << 28);
569}
570
525int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) 571int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
526{ 572{
527 struct mthca_dev *dev = to_mdev(ibqp->device); 573 struct mthca_dev *dev = to_mdev(ibqp->device);
@@ -591,6 +637,26 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
591 return -EINVAL; 637 return -EINVAL;
592 } 638 }
593 639
640 if ((attr_mask & IB_QP_PORT) &&
641 (attr->port_num == 0 || attr->port_num > dev->limits.num_ports)) {
642 mthca_dbg(dev, "Port number (%u) is invalid\n", attr->port_num);
643 return -EINVAL;
644 }
645
646 if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
647 attr->max_rd_atomic > dev->limits.max_qp_init_rdma) {
648 mthca_dbg(dev, "Max rdma_atomic as initiator %u too large (max is %d)\n",
649 attr->max_rd_atomic, dev->limits.max_qp_init_rdma);
650 return -EINVAL;
651 }
652
653 if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
654 attr->max_dest_rd_atomic > 1 << dev->qp_table.rdb_shift) {
655 mthca_dbg(dev, "Max rdma_atomic as responder %u too large (max %d)\n",
656 attr->max_dest_rd_atomic, 1 << dev->qp_table.rdb_shift);
657 return -EINVAL;
658 }
659
594 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); 660 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
595 if (IS_ERR(mailbox)) 661 if (IS_ERR(mailbox))
596 return PTR_ERR(mailbox); 662 return PTR_ERR(mailbox);
@@ -665,28 +731,14 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
665 } 731 }
666 732
667 if (attr_mask & IB_QP_RNR_RETRY) { 733 if (attr_mask & IB_QP_RNR_RETRY) {
668 qp_context->pri_path.rnr_retry = attr->rnr_retry << 5; 734 qp_context->alt_path.rnr_retry = qp_context->pri_path.rnr_retry =
669 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY); 735 attr->rnr_retry << 5;
736 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY |
737 MTHCA_QP_OPTPAR_ALT_RNR_RETRY);
670 } 738 }
671 739
672 if (attr_mask & IB_QP_AV) { 740 if (attr_mask & IB_QP_AV) {
673 qp_context->pri_path.g_mylmc = attr->ah_attr.src_path_bits & 0x7f; 741 mthca_path_set(&attr->ah_attr, &qp_context->pri_path);
674 qp_context->pri_path.rlid = cpu_to_be16(attr->ah_attr.dlid);
675 qp_context->pri_path.static_rate = !!attr->ah_attr.static_rate;
676 if (attr->ah_attr.ah_flags & IB_AH_GRH) {
677 qp_context->pri_path.g_mylmc |= 1 << 7;
678 qp_context->pri_path.mgid_index = attr->ah_attr.grh.sgid_index;
679 qp_context->pri_path.hop_limit = attr->ah_attr.grh.hop_limit;
680 qp_context->pri_path.sl_tclass_flowlabel =
681 cpu_to_be32((attr->ah_attr.sl << 28) |
682 (attr->ah_attr.grh.traffic_class << 20) |
683 (attr->ah_attr.grh.flow_label));
684 memcpy(qp_context->pri_path.rgid,
685 attr->ah_attr.grh.dgid.raw, 16);
686 } else {
687 qp_context->pri_path.sl_tclass_flowlabel =
688 cpu_to_be32(attr->ah_attr.sl << 28);
689 }
690 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH); 742 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH);
691 } 743 }
692 744
@@ -695,7 +747,19 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
695 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT); 747 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT);
696 } 748 }
697 749
698 /* XXX alt_path */ 750 if (attr_mask & IB_QP_ALT_PATH) {
751 if (attr->alt_port_num == 0 || attr->alt_port_num > dev->limits.num_ports) {
752 mthca_dbg(dev, "Alternate port number (%u) is invalid\n",
753 attr->alt_port_num);
754 return -EINVAL;
755 }
756
757 mthca_path_set(&attr->alt_ah_attr, &qp_context->alt_path);
758 qp_context->alt_path.port_pkey |= cpu_to_be32(attr->alt_pkey_index |
759 attr->alt_port_num << 24);
760 qp_context->alt_path.ackto = attr->alt_timeout << 3;
761 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ALT_ADDR_PATH);
762 }
699 763
700 /* leave rdd as 0 */ 764 /* leave rdd as 0 */
701 qp_context->pd = cpu_to_be32(to_mpd(ibqp->pd)->pd_num); 765 qp_context->pd = cpu_to_be32(to_mpd(ibqp->pd)->pd_num);
@@ -703,9 +767,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
703 qp_context->wqe_lkey = cpu_to_be32(qp->mr.ibmr.lkey); 767 qp_context->wqe_lkey = cpu_to_be32(qp->mr.ibmr.lkey);
704 qp_context->params1 = cpu_to_be32((MTHCA_ACK_REQ_FREQ << 28) | 768 qp_context->params1 = cpu_to_be32((MTHCA_ACK_REQ_FREQ << 28) |
705 (MTHCA_FLIGHT_LIMIT << 24) | 769 (MTHCA_FLIGHT_LIMIT << 24) |
706 MTHCA_QP_BIT_SRE | 770 MTHCA_QP_BIT_SWE);
707 MTHCA_QP_BIT_SWE |
708 MTHCA_QP_BIT_SAE);
709 if (qp->sq_policy == IB_SIGNAL_ALL_WR) 771 if (qp->sq_policy == IB_SIGNAL_ALL_WR)
710 qp_context->params1 |= cpu_to_be32(MTHCA_QP_BIT_SSC); 772 qp_context->params1 |= cpu_to_be32(MTHCA_QP_BIT_SSC);
711 if (attr_mask & IB_QP_RETRY_CNT) { 773 if (attr_mask & IB_QP_RETRY_CNT) {
@@ -714,9 +776,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
714 } 776 }
715 777
716 if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) { 778 if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) {
717 qp_context->params1 |= cpu_to_be32(min(attr->max_rd_atomic ? 779 if (attr->max_rd_atomic) {
718 ffs(attr->max_rd_atomic) - 1 : 0, 780 qp_context->params1 |=
719 7) << 21); 781 cpu_to_be32(MTHCA_QP_BIT_SRE |
782 MTHCA_QP_BIT_SAE);
783 qp_context->params1 |=
784 cpu_to_be32(fls(attr->max_rd_atomic - 1) << 21);
785 }
720 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_SRA_MAX); 786 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_SRA_MAX);
721 } 787 }
722 788
@@ -729,71 +795,19 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
729 qp_context->snd_db_index = cpu_to_be32(qp->sq.db_index); 795 qp_context->snd_db_index = cpu_to_be32(qp->sq.db_index);
730 } 796 }
731 797
732 if (attr_mask & IB_QP_ACCESS_FLAGS) {
733 qp_context->params2 |=
734 cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ?
735 MTHCA_QP_BIT_RWE : 0);
736
737 /*
738 * Only enable RDMA reads and atomics if we have
739 * responder resources set to a non-zero value.
740 */
741 if (qp->resp_depth) {
742 qp_context->params2 |=
743 cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_READ ?
744 MTHCA_QP_BIT_RRE : 0);
745 qp_context->params2 |=
746 cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC ?
747 MTHCA_QP_BIT_RAE : 0);
748 }
749
750 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
751 MTHCA_QP_OPTPAR_RRE |
752 MTHCA_QP_OPTPAR_RAE);
753
754 qp->atomic_rd_en = attr->qp_access_flags;
755 }
756
757 if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) { 798 if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) {
758 u8 rra_max; 799 if (attr->max_dest_rd_atomic)
759
760 if (qp->resp_depth && !attr->max_dest_rd_atomic) {
761 /*
762 * Lowering our responder resources to zero.
763 * Turn off reads RDMA and atomics as responder.
764 * (RRE/RAE in params2 already zero)
765 */
766 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE |
767 MTHCA_QP_OPTPAR_RAE);
768 }
769
770 if (!qp->resp_depth && attr->max_dest_rd_atomic) {
771 /*
772 * Increasing our responder resources from
773 * zero. Turn on RDMA reads and atomics as
774 * appropriate.
775 */
776 qp_context->params2 |= 800 qp_context->params2 |=
777 cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_READ ? 801 cpu_to_be32(fls(attr->max_dest_rd_atomic - 1) << 21);
778 MTHCA_QP_BIT_RRE : 0);
779 qp_context->params2 |=
780 cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_ATOMIC ?
781 MTHCA_QP_BIT_RAE : 0);
782
783 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE |
784 MTHCA_QP_OPTPAR_RAE);
785 }
786 802
787 for (rra_max = 0;
788 1 << rra_max < attr->max_dest_rd_atomic &&
789 rra_max < dev->qp_table.rdb_shift;
790 ++rra_max)
791 ; /* nothing */
792
793 qp_context->params2 |= cpu_to_be32(rra_max << 21);
794 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRA_MAX); 803 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRA_MAX);
804 }
795 805
796 qp->resp_depth = attr->max_dest_rd_atomic; 806 if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC)) {
807 qp_context->params2 |= get_hw_access_flags(qp, attr, attr_mask);
808 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
809 MTHCA_QP_OPTPAR_RRE |
810 MTHCA_QP_OPTPAR_RAE);
797 } 811 }
798 812
799 qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC); 813 qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC);
@@ -835,8 +849,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
835 err = -EINVAL; 849 err = -EINVAL;
836 } 850 }
837 851
838 if (!err) 852 if (!err) {
839 qp->state = new_state; 853 qp->state = new_state;
854 if (attr_mask & IB_QP_ACCESS_FLAGS)
855 qp->atomic_rd_en = attr->qp_access_flags;
856 if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
857 qp->resp_depth = attr->max_dest_rd_atomic;
858 }
840 859
841 mthca_free_mailbox(dev, mailbox); 860 mthca_free_mailbox(dev, mailbox);
842 861
@@ -885,18 +904,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
885 return err; 904 return err;
886} 905}
887 906
888static void mthca_adjust_qp_caps(struct mthca_dev *dev, 907static int mthca_max_data_size(struct mthca_dev *dev, struct mthca_qp *qp, int desc_sz)
889 struct mthca_pd *pd,
890 struct mthca_qp *qp)
891{ 908{
892 int max_data_size;
893
894 /* 909 /*
895 * Calculate the maximum size of WQE s/g segments, excluding 910 * Calculate the maximum size of WQE s/g segments, excluding
896 * the next segment and other non-data segments. 911 * the next segment and other non-data segments.
897 */ 912 */
898 max_data_size = min(dev->limits.max_desc_sz, 1 << qp->sq.wqe_shift) - 913 int max_data_size = desc_sz - sizeof (struct mthca_next_seg);
899 sizeof (struct mthca_next_seg);
900 914
901 switch (qp->transport) { 915 switch (qp->transport) {
902 case MLX: 916 case MLX:
@@ -915,11 +929,24 @@ static void mthca_adjust_qp_caps(struct mthca_dev *dev,
915 break; 929 break;
916 } 930 }
917 931
932 return max_data_size;
933}
934
935static inline int mthca_max_inline_data(struct mthca_pd *pd, int max_data_size)
936{
918 /* We don't support inline data for kernel QPs (yet). */ 937 /* We don't support inline data for kernel QPs (yet). */
919 if (!pd->ibpd.uobject) 938 return pd->ibpd.uobject ? max_data_size - MTHCA_INLINE_HEADER_SIZE : 0;
920 qp->max_inline_data = 0; 939}
921 else 940
922 qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE; 941static void mthca_adjust_qp_caps(struct mthca_dev *dev,
942 struct mthca_pd *pd,
943 struct mthca_qp *qp)
944{
945 int max_data_size = mthca_max_data_size(dev, qp,
946 min(dev->limits.max_desc_sz,
947 1 << qp->sq.wqe_shift));
948
949 qp->max_inline_data = mthca_max_inline_data(pd, max_data_size);
923 950
924 qp->sq.max_gs = min_t(int, dev->limits.max_sg, 951 qp->sq.max_gs = min_t(int, dev->limits.max_sg,
925 max_data_size / sizeof (struct mthca_data_seg)); 952 max_data_size / sizeof (struct mthca_data_seg));
@@ -1186,13 +1213,23 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
1186} 1213}
1187 1214
1188static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap, 1215static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap,
1189 struct mthca_qp *qp) 1216 struct mthca_pd *pd, struct mthca_qp *qp)
1190{ 1217{
1218 int max_data_size = mthca_max_data_size(dev, qp, dev->limits.max_desc_sz);
1219
1191 /* Sanity check QP size before proceeding */ 1220 /* Sanity check QP size before proceeding */
1192 if (cap->max_send_wr > dev->limits.max_wqes || 1221 if (cap->max_send_wr > dev->limits.max_wqes ||
1193 cap->max_recv_wr > dev->limits.max_wqes || 1222 cap->max_recv_wr > dev->limits.max_wqes ||
1194 cap->max_send_sge > dev->limits.max_sg || 1223 cap->max_send_sge > dev->limits.max_sg ||
1195 cap->max_recv_sge > dev->limits.max_sg) 1224 cap->max_recv_sge > dev->limits.max_sg ||
1225 cap->max_inline_data > mthca_max_inline_data(pd, max_data_size))
1226 return -EINVAL;
1227
1228 /*
1229 * For MLX transport we need 2 extra S/G entries:
1230 * one for the header and one for the checksum at the end
1231 */
1232 if (qp->transport == MLX && cap->max_recv_sge + 2 > dev->limits.max_sg)
1196 return -EINVAL; 1233 return -EINVAL;
1197 1234
1198 if (mthca_is_memfree(dev)) { 1235 if (mthca_is_memfree(dev)) {
@@ -1211,14 +1248,6 @@ static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap,
1211 MTHCA_INLINE_CHUNK_SIZE) / 1248 MTHCA_INLINE_CHUNK_SIZE) /
1212 sizeof (struct mthca_data_seg)); 1249 sizeof (struct mthca_data_seg));
1213 1250
1214 /*
1215 * For MLX transport we need 2 extra S/G entries:
1216 * one for the header and one for the checksum at the end
1217 */
1218 if ((qp->transport == MLX && qp->sq.max_gs + 2 > dev->limits.max_sg) ||
1219 qp->sq.max_gs > dev->limits.max_sg || qp->rq.max_gs > dev->limits.max_sg)
1220 return -EINVAL;
1221
1222 return 0; 1251 return 0;
1223} 1252}
1224 1253
@@ -1233,7 +1262,7 @@ int mthca_alloc_qp(struct mthca_dev *dev,
1233{ 1262{
1234 int err; 1263 int err;
1235 1264
1236 err = mthca_set_qp_size(dev, cap, qp); 1265 err = mthca_set_qp_size(dev, cap, pd, qp);
1237 if (err) 1266 if (err)
1238 return err; 1267 return err;
1239 1268
@@ -1276,7 +1305,7 @@ int mthca_alloc_sqp(struct mthca_dev *dev,
1276 u32 mqpn = qpn * 2 + dev->qp_table.sqp_start + port - 1; 1305 u32 mqpn = qpn * 2 + dev->qp_table.sqp_start + port - 1;
1277 int err; 1306 int err;
1278 1307
1279 err = mthca_set_qp_size(dev, cap, &sqp->qp); 1308 err = mthca_set_qp_size(dev, cap, pd, &sqp->qp);
1280 if (err) 1309 if (err)
1281 return err; 1310 return err;
1282 1311
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index f7d234295efe..e7e153d9c4c6 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -201,7 +201,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
201 if (mthca_is_memfree(dev)) 201 if (mthca_is_memfree(dev))
202 srq->max = roundup_pow_of_two(srq->max + 1); 202 srq->max = roundup_pow_of_two(srq->max + 1);
203 203
204 ds = min(64UL, 204 ds = max(64UL,
205 roundup_pow_of_two(sizeof (struct mthca_next_seg) + 205 roundup_pow_of_two(sizeof (struct mthca_next_seg) +
206 srq->max_gs * sizeof (struct mthca_data_seg))); 206 srq->max_gs * sizeof (struct mthca_data_seg)));
207 srq->wqe_shift = long_log2(ds); 207 srq->wqe_shift = long_log2(ds);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index ee9fe226ae99..dd488d3cffa9 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -39,6 +39,7 @@
39#include <linux/string.h> 39#include <linux/string.h>
40#include <linux/parser.h> 40#include <linux/parser.h>
41#include <linux/random.h> 41#include <linux/random.h>
42#include <linux/jiffies.h>
42 43
43#include <asm/atomic.h> 44#include <asm/atomic.h>
44 45
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index 64672d491222..e301ee4ca264 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -19,7 +19,6 @@
19#include <linux/jiffies.h> 19#include <linux/jiffies.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <asm/irq.h>
23 22
24#include <asm/arch/corgi.h> 23#include <asm/arch/corgi.h>
25#include <asm/arch/hardware.h> 24#include <asm/arch/hardware.h>
@@ -343,10 +342,9 @@ static int __init corgikbd_probe(struct platform_device *pdev)
343 for (i = 0; i < CORGI_KEY_SENSE_NUM; i++) { 342 for (i = 0; i < CORGI_KEY_SENSE_NUM; i++) {
344 pxa_gpio_mode(CORGI_GPIO_KEY_SENSE(i) | GPIO_IN); 343 pxa_gpio_mode(CORGI_GPIO_KEY_SENSE(i) | GPIO_IN);
345 if (request_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd_interrupt, 344 if (request_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd_interrupt,
346 SA_INTERRUPT, "corgikbd", corgikbd)) 345 SA_INTERRUPT | SA_TRIGGER_RISING,
346 "corgikbd", corgikbd))
347 printk(KERN_WARNING "corgikbd: Can't get IRQ: %d!\n", i); 347 printk(KERN_WARNING "corgikbd: Can't get IRQ: %d!\n", i);
348 else
349 set_irq_type(CORGI_IRQ_GPIO_KEY_SENSE(i),IRQT_RISING);
350 } 348 }
351 349
352 /* Set Strobe lines as outputs - set high */ 350 /* Set Strobe lines as outputs - set high */
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index 6a15fe3bc527..83999d583122 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -19,7 +19,6 @@
19#include <linux/jiffies.h> 19#include <linux/jiffies.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <asm/irq.h>
23 22
24#include <asm/arch/spitz.h> 23#include <asm/arch/spitz.h>
25#include <asm/arch/hardware.h> 24#include <asm/arch/hardware.h>
@@ -407,10 +406,9 @@ static int __init spitzkbd_probe(struct platform_device *dev)
407 for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++) { 406 for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++) {
408 pxa_gpio_mode(spitz_senses[i] | GPIO_IN); 407 pxa_gpio_mode(spitz_senses[i] | GPIO_IN);
409 if (request_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd_interrupt, 408 if (request_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd_interrupt,
410 SA_INTERRUPT, "Spitzkbd Sense", spitzkbd)) 409 SA_INTERRUPT|SA_TRIGGER_RISING,
410 "Spitzkbd Sense", spitzkbd))
411 printk(KERN_WARNING "spitzkbd: Can't get Sense IRQ: %d!\n", i); 411 printk(KERN_WARNING "spitzkbd: Can't get Sense IRQ: %d!\n", i);
412 else
413 set_irq_type(IRQ_GPIO(spitz_senses[i]),IRQT_RISING);
414 } 412 }
415 413
416 /* Set Strobe lines as outputs - set high */ 414 /* Set Strobe lines as outputs - set high */
@@ -422,15 +420,18 @@ static int __init spitzkbd_probe(struct platform_device *dev)
422 pxa_gpio_mode(SPITZ_GPIO_SWA | GPIO_IN); 420 pxa_gpio_mode(SPITZ_GPIO_SWA | GPIO_IN);
423 pxa_gpio_mode(SPITZ_GPIO_SWB | GPIO_IN); 421 pxa_gpio_mode(SPITZ_GPIO_SWB | GPIO_IN);
424 422
425 request_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd_interrupt, SA_INTERRUPT, "Spitzkbd Sync", spitzkbd); 423 request_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd_interrupt,
426 request_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd_interrupt, SA_INTERRUPT, "Spitzkbd PwrOn", spitzkbd); 424 SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
427 request_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd_hinge_isr, SA_INTERRUPT, "Spitzkbd SWA", spitzkbd); 425 "Spitzkbd Sync", spitzkbd);
428 request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr, SA_INTERRUPT, "Spitzkbd SWB", spitzkbd); 426 request_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd_interrupt,
429 427 SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
430 set_irq_type(SPITZ_IRQ_GPIO_SYNC, IRQT_BOTHEDGE); 428 "Spitzkbd PwrOn", spitzkbd);
431 set_irq_type(SPITZ_IRQ_GPIO_ON_KEY, IRQT_BOTHEDGE); 429 request_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd_hinge_isr,
432 set_irq_type(SPITZ_IRQ_GPIO_SWA, IRQT_BOTHEDGE); 430 SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
433 set_irq_type(SPITZ_IRQ_GPIO_SWB, IRQT_BOTHEDGE); 431 "Spitzkbd SWA", spitzkbd);
432 request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr,
433 SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
434 "Spitzkbd SWB", spitzkbd);
434 435
435 printk(KERN_INFO "input: Spitz Keyboard Registered\n"); 436 printk(KERN_INFO "input: Spitz Keyboard Registered\n");
436 437
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c
index 1cd7657f7e42..1be963961c15 100644
--- a/drivers/input/misc/hp_sdc_rtc.c
+++ b/drivers/input/misc/hp_sdc_rtc.c
@@ -60,8 +60,6 @@ static struct fasync_struct *hp_sdc_rtc_async_queue;
60 60
61static DECLARE_WAIT_QUEUE_HEAD(hp_sdc_rtc_wait); 61static DECLARE_WAIT_QUEUE_HEAD(hp_sdc_rtc_wait);
62 62
63static loff_t hp_sdc_rtc_llseek(struct file *file, loff_t offset, int origin);
64
65static ssize_t hp_sdc_rtc_read(struct file *file, char *buf, 63static ssize_t hp_sdc_rtc_read(struct file *file, char *buf,
66 size_t count, loff_t *ppos); 64 size_t count, loff_t *ppos);
67 65
@@ -387,11 +385,6 @@ static int hp_sdc_rtc_set_i8042timer (struct timeval *setto, uint8_t setcmd)
387 return 0; 385 return 0;
388} 386}
389 387
390static loff_t hp_sdc_rtc_llseek(struct file *file, loff_t offset, int origin)
391{
392 return -ESPIPE;
393}
394
395static ssize_t hp_sdc_rtc_read(struct file *file, char *buf, 388static ssize_t hp_sdc_rtc_read(struct file *file, char *buf,
396 size_t count, loff_t *ppos) { 389 size_t count, loff_t *ppos) {
397 ssize_t retval; 390 ssize_t retval;
@@ -679,7 +672,7 @@ static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file,
679 672
680static struct file_operations hp_sdc_rtc_fops = { 673static struct file_operations hp_sdc_rtc_fops = {
681 .owner = THIS_MODULE, 674 .owner = THIS_MODULE,
682 .llseek = hp_sdc_rtc_llseek, 675 .llseek = no_llseek,
683 .read = hp_sdc_rtc_read, 676 .read = hp_sdc_rtc_read,
684 .poll = hp_sdc_rtc_poll, 677 .poll = hp_sdc_rtc_poll,
685 .ioctl = hp_sdc_rtc_ioctl, 678 .ioctl = hp_sdc_rtc_ioctl,
diff --git a/drivers/isdn/act2000/act2000.h b/drivers/isdn/act2000/act2000.h
index b091d1a54125..d4c50512a1ff 100644
--- a/drivers/isdn/act2000/act2000.h
+++ b/drivers/isdn/act2000/act2000.h
@@ -181,17 +181,17 @@ typedef struct act2000_card {
181 char regname[35]; /* Name used for request_region */ 181 char regname[35]; /* Name used for request_region */
182} act2000_card; 182} act2000_card;
183 183
184extern __inline__ void act2000_schedule_tx(act2000_card *card) 184static inline void act2000_schedule_tx(act2000_card *card)
185{ 185{
186 schedule_work(&card->snd_tq); 186 schedule_work(&card->snd_tq);
187} 187}
188 188
189extern __inline__ void act2000_schedule_rx(act2000_card *card) 189static inline void act2000_schedule_rx(act2000_card *card)
190{ 190{
191 schedule_work(&card->rcv_tq); 191 schedule_work(&card->rcv_tq);
192} 192}
193 193
194extern __inline__ void act2000_schedule_poll(act2000_card *card) 194static inline void act2000_schedule_poll(act2000_card *card)
195{ 195{
196 schedule_work(&card->poll_tq); 196 schedule_work(&card->poll_tq);
197} 197}
diff --git a/drivers/isdn/act2000/capi.h b/drivers/isdn/act2000/capi.h
index f6d5f530b86b..49f453c53c64 100644
--- a/drivers/isdn/act2000/capi.h
+++ b/drivers/isdn/act2000/capi.h
@@ -78,29 +78,29 @@ typedef union actcapi_infoel { /* info element */
78typedef struct actcapi_msn { 78typedef struct actcapi_msn {
79 __u8 eaz; 79 __u8 eaz;
80 __u8 len; /* Length of MSN */ 80 __u8 len; /* Length of MSN */
81 __u8 msn[15] __attribute__ ((packed)); 81 __u8 msn[15];
82} actcapi_msn; 82} __attribute__((packed)) actcapi_msn;
83 83
84typedef struct actcapi_dlpd { 84typedef struct actcapi_dlpd {
85 __u8 len; /* Length of structure */ 85 __u8 len; /* Length of structure */
86 __u16 dlen __attribute__ ((packed)); /* Data Length */ 86 __u16 dlen; /* Data Length */
87 __u8 laa __attribute__ ((packed)); /* Link Address A */ 87 __u8 laa; /* Link Address A */
88 __u8 lab; /* Link Address B */ 88 __u8 lab; /* Link Address B */
89 __u8 modulo; /* Modulo Mode */ 89 __u8 modulo; /* Modulo Mode */
90 __u8 win; /* Window size */ 90 __u8 win; /* Window size */
91 __u8 xid[100]; /* XID Information */ 91 __u8 xid[100]; /* XID Information */
92} actcapi_dlpd; 92} __attribute__((packed)) actcapi_dlpd;
93 93
94typedef struct actcapi_ncpd { 94typedef struct actcapi_ncpd {
95 __u8 len; /* Length of structure */ 95 __u8 len; /* Length of structure */
96 __u16 lic __attribute__ ((packed)); 96 __u16 lic;
97 __u16 hic __attribute__ ((packed)); 97 __u16 hic;
98 __u16 ltc __attribute__ ((packed)); 98 __u16 ltc;
99 __u16 htc __attribute__ ((packed)); 99 __u16 htc;
100 __u16 loc __attribute__ ((packed)); 100 __u16 loc;
101 __u16 hoc __attribute__ ((packed)); 101 __u16 hoc;
102 __u8 modulo __attribute__ ((packed)); 102 __u8 modulo;
103} actcapi_ncpd; 103} __attribute__((packed)) actcapi_ncpd;
104#define actcapi_ncpi actcapi_ncpd 104#define actcapi_ncpi actcapi_ncpd
105 105
106/* 106/*
@@ -168,19 +168,19 @@ typedef struct actcapi_msg {
168 __u16 manuf_msg; 168 __u16 manuf_msg;
169 __u16 controller; 169 __u16 controller;
170 actcapi_msn msnmap; 170 actcapi_msn msnmap;
171 } manufacturer_req_msn; 171 } __attribute ((packed)) manufacturer_req_msn;
172 /* TODO: TraceInit-req/conf/ind/resp and 172 /* TODO: TraceInit-req/conf/ind/resp and
173 * TraceDump-req/conf/ind/resp 173 * TraceDump-req/conf/ind/resp
174 */ 174 */
175 struct connect_req { 175 struct connect_req {
176 __u8 controller; 176 __u8 controller;
177 __u8 bchan; 177 __u8 bchan;
178 __u32 infomask __attribute__ ((packed)); 178 __u32 infomask;
179 __u8 si1; 179 __u8 si1;
180 __u8 si2; 180 __u8 si2;
181 __u8 eaz; 181 __u8 eaz;
182 actcapi_addr addr; 182 actcapi_addr addr;
183 } connect_req; 183 } __attribute__ ((packed)) connect_req;
184 struct connect_conf { 184 struct connect_conf {
185 __u16 plci; 185 __u16 plci;
186 __u16 info; 186 __u16 info;
@@ -192,7 +192,7 @@ typedef struct actcapi_msg {
192 __u8 si2; 192 __u8 si2;
193 __u8 eaz; 193 __u8 eaz;
194 actcapi_addr addr; 194 actcapi_addr addr;
195 } connect_ind; 195 } __attribute__ ((packed)) connect_ind;
196 struct connect_resp { 196 struct connect_resp {
197 __u16 plci; 197 __u16 plci;
198 __u8 rejectcause; 198 __u8 rejectcause;
@@ -200,14 +200,14 @@ typedef struct actcapi_msg {
200 struct connect_active_ind { 200 struct connect_active_ind {
201 __u16 plci; 201 __u16 plci;
202 actcapi_addr addr; 202 actcapi_addr addr;
203 } connect_active_ind; 203 } __attribute__ ((packed)) connect_active_ind;
204 struct connect_active_resp { 204 struct connect_active_resp {
205 __u16 plci; 205 __u16 plci;
206 } connect_active_resp; 206 } connect_active_resp;
207 struct connect_b3_req { 207 struct connect_b3_req {
208 __u16 plci; 208 __u16 plci;
209 actcapi_ncpi ncpi; 209 actcapi_ncpi ncpi;
210 } connect_b3_req; 210 } __attribute__ ((packed)) connect_b3_req;
211 struct connect_b3_conf { 211 struct connect_b3_conf {
212 __u16 plci; 212 __u16 plci;
213 __u16 ncci; 213 __u16 ncci;
@@ -217,12 +217,12 @@ typedef struct actcapi_msg {
217 __u16 ncci; 217 __u16 ncci;
218 __u16 plci; 218 __u16 plci;
219 actcapi_ncpi ncpi; 219 actcapi_ncpi ncpi;
220 } connect_b3_ind; 220 } __attribute__ ((packed)) connect_b3_ind;
221 struct connect_b3_resp { 221 struct connect_b3_resp {
222 __u16 ncci; 222 __u16 ncci;
223 __u8 rejectcause; 223 __u8 rejectcause;
224 actcapi_ncpi ncpi __attribute__ ((packed)); 224 actcapi_ncpi ncpi;
225 } connect_b3_resp; 225 } __attribute__ ((packed)) connect_b3_resp;
226 struct disconnect_req { 226 struct disconnect_req {
227 __u16 plci; 227 __u16 plci;
228 __u8 cause; 228 __u8 cause;
@@ -241,14 +241,14 @@ typedef struct actcapi_msg {
241 struct connect_b3_active_ind { 241 struct connect_b3_active_ind {
242 __u16 ncci; 242 __u16 ncci;
243 actcapi_ncpi ncpi; 243 actcapi_ncpi ncpi;
244 } connect_b3_active_ind; 244 } __attribute__ ((packed)) connect_b3_active_ind;
245 struct connect_b3_active_resp { 245 struct connect_b3_active_resp {
246 __u16 ncci; 246 __u16 ncci;
247 } connect_b3_active_resp; 247 } connect_b3_active_resp;
248 struct disconnect_b3_req { 248 struct disconnect_b3_req {
249 __u16 ncci; 249 __u16 ncci;
250 actcapi_ncpi ncpi; 250 actcapi_ncpi ncpi;
251 } disconnect_b3_req; 251 } __attribute__ ((packed)) disconnect_b3_req;
252 struct disconnect_b3_conf { 252 struct disconnect_b3_conf {
253 __u16 ncci; 253 __u16 ncci;
254 __u16 info; 254 __u16 info;
@@ -257,7 +257,7 @@ typedef struct actcapi_msg {
257 __u16 ncci; 257 __u16 ncci;
258 __u16 info; 258 __u16 info;
259 actcapi_ncpi ncpi; 259 actcapi_ncpi ncpi;
260 } disconnect_b3_ind; 260 } __attribute__ ((packed)) disconnect_b3_ind;
261 struct disconnect_b3_resp { 261 struct disconnect_b3_resp {
262 __u16 ncci; 262 __u16 ncci;
263 } disconnect_b3_resp; 263 } disconnect_b3_resp;
@@ -265,7 +265,7 @@ typedef struct actcapi_msg {
265 __u16 plci; 265 __u16 plci;
266 actcapi_infonr nr; 266 actcapi_infonr nr;
267 actcapi_infoel el; 267 actcapi_infoel el;
268 } info_ind; 268 } __attribute__ ((packed)) info_ind;
269 struct info_resp { 269 struct info_resp {
270 __u16 plci; 270 __u16 plci;
271 } info_resp; 271 } info_resp;
@@ -279,8 +279,8 @@ typedef struct actcapi_msg {
279 struct select_b2_protocol_req { 279 struct select_b2_protocol_req {
280 __u16 plci; 280 __u16 plci;
281 __u8 protocol; 281 __u8 protocol;
282 actcapi_dlpd dlpd __attribute__ ((packed)); 282 actcapi_dlpd dlpd;
283 } select_b2_protocol_req; 283 } __attribute__ ((packed)) select_b2_protocol_req;
284 struct select_b2_protocol_conf { 284 struct select_b2_protocol_conf {
285 __u16 plci; 285 __u16 plci;
286 __u16 info; 286 __u16 info;
@@ -288,49 +288,49 @@ typedef struct actcapi_msg {
288 struct select_b3_protocol_req { 288 struct select_b3_protocol_req {
289 __u16 plci; 289 __u16 plci;
290 __u8 protocol; 290 __u8 protocol;
291 actcapi_ncpd ncpd __attribute__ ((packed)); 291 actcapi_ncpd ncpd;
292 } select_b3_protocol_req; 292 } __attribute__ ((packed)) select_b3_protocol_req;
293 struct select_b3_protocol_conf { 293 struct select_b3_protocol_conf {
294 __u16 plci; 294 __u16 plci;
295 __u16 info; 295 __u16 info;
296 } select_b3_protocol_conf; 296 } select_b3_protocol_conf;
297 struct listen_req { 297 struct listen_req {
298 __u8 controller; 298 __u8 controller;
299 __u32 infomask __attribute__ ((packed)); 299 __u32 infomask;
300 __u16 eazmask __attribute__ ((packed)); 300 __u16 eazmask;
301 __u16 simask __attribute__ ((packed)); 301 __u16 simask;
302 } listen_req; 302 } __attribute__ ((packed)) listen_req;
303 struct listen_conf { 303 struct listen_conf {
304 __u8 controller; 304 __u8 controller;
305 __u16 info __attribute__ ((packed)); 305 __u16 info;
306 } listen_conf; 306 } __attribute__ ((packed)) listen_conf;
307 struct data_b3_req { 307 struct data_b3_req {
308 __u16 fakencci; 308 __u16 fakencci;
309 __u16 datalen; 309 __u16 datalen;
310 __u32 unused; 310 __u32 unused;
311 __u8 blocknr; 311 __u8 blocknr;
312 __u16 flags __attribute__ ((packed)); 312 __u16 flags;
313 } data_b3_req; 313 } __attribute ((packed)) data_b3_req;
314 struct data_b3_ind { 314 struct data_b3_ind {
315 __u16 fakencci; 315 __u16 fakencci;
316 __u16 datalen; 316 __u16 datalen;
317 __u32 unused; 317 __u32 unused;
318 __u8 blocknr; 318 __u8 blocknr;
319 __u16 flags __attribute__ ((packed)); 319 __u16 flags;
320 } data_b3_ind; 320 } __attribute__ ((packed)) data_b3_ind;
321 struct data_b3_resp { 321 struct data_b3_resp {
322 __u16 ncci; 322 __u16 ncci;
323 __u8 blocknr; 323 __u8 blocknr;
324 } data_b3_resp; 324 } __attribute__ ((packed)) data_b3_resp;
325 struct data_b3_conf { 325 struct data_b3_conf {
326 __u16 ncci; 326 __u16 ncci;
327 __u8 blocknr; 327 __u8 blocknr;
328 __u16 info __attribute__ ((packed)); 328 __u16 info;
329 } data_b3_conf; 329 } __attribute__ ((packed)) data_b3_conf;
330 } msg; 330 } msg;
331} actcapi_msg; 331} __attribute__ ((packed)) actcapi_msg;
332 332
333extern __inline__ unsigned short 333static inline unsigned short
334actcapi_nextsmsg(act2000_card *card) 334actcapi_nextsmsg(act2000_card *card)
335{ 335{
336 unsigned long flags; 336 unsigned long flags;
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
index 7b564c0dd996..207cae366256 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -17,6 +17,8 @@
17#include <linux/ctype.h> 17#include <linux/ctype.h>
18#include <linux/sched.h> /* current */ 18#include <linux/sched.h> /* current */
19 19
20#include "capifs.h"
21
20MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem"); 22MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem");
21MODULE_AUTHOR("Carsten Paeth"); 23MODULE_AUTHOR("Carsten Paeth");
22MODULE_LICENSE("GPL"); 24MODULE_LICENSE("GPL");
diff --git a/drivers/isdn/hardware/eicon/os_4bri.c b/drivers/isdn/hardware/eicon/os_4bri.c
index cccfabc1117d..11e6f937c1e4 100644
--- a/drivers/isdn/hardware/eicon/os_4bri.c
+++ b/drivers/isdn/hardware/eicon/os_4bri.c
@@ -16,6 +16,7 @@
16#include "diva_pci.h" 16#include "diva_pci.h"
17#include "mi_pc.h" 17#include "mi_pc.h"
18#include "dsrv4bri.h" 18#include "dsrv4bri.h"
19#include "helpers.h"
19 20
20static void *diva_xdiLoadFileFile = NULL; 21static void *diva_xdiLoadFileFile = NULL;
21static dword diva_xdiLoadFileLength = 0; 22static dword diva_xdiLoadFileLength = 0;
@@ -815,7 +816,7 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
815 return (ret); 816 return (ret);
816} 817}
817 818
818void *xdiLoadFile(char *FileName, unsigned long *FileLength, 819void *xdiLoadFile(char *FileName, dword *FileLength,
819 unsigned long lim) 820 unsigned long lim)
820{ 821{
821 void *ret = diva_xdiLoadFileFile; 822 void *ret = diva_xdiLoadFileFile;
diff --git a/drivers/isdn/hardware/eicon/os_bri.c b/drivers/isdn/hardware/eicon/os_bri.c
index 4cc44a5dd1db..f31bba5b16ff 100644
--- a/drivers/isdn/hardware/eicon/os_bri.c
+++ b/drivers/isdn/hardware/eicon/os_bri.c
@@ -16,6 +16,7 @@
16#include "diva_pci.h" 16#include "diva_pci.h"
17#include "mi_pc.h" 17#include "mi_pc.h"
18#include "pc_maint.h" 18#include "pc_maint.h"
19#include "dsrv_bri.h"
19 20
20/* 21/*
21** IMPORTS 22** IMPORTS
diff --git a/drivers/isdn/hardware/eicon/os_pri.c b/drivers/isdn/hardware/eicon/os_pri.c
index 8ac207f75e54..a296a846f296 100644
--- a/drivers/isdn/hardware/eicon/os_pri.c
+++ b/drivers/isdn/hardware/eicon/os_pri.c
@@ -18,6 +18,7 @@
18#include "pc_maint.h" 18#include "pc_maint.h"
19#include "dsp_tst.h" 19#include "dsp_tst.h"
20#include "diva_dma.h" 20#include "diva_dma.h"
21#include "dsrv_pri.h"
21 22
22/* -------------------------------------------------------------------------- 23/* --------------------------------------------------------------------------
23 OS Dependent part of XDI driver for DIVA PRI Adapter 24 OS Dependent part of XDI driver for DIVA PRI Adapter
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index c82105920d71..0ef560144be3 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -110,7 +110,7 @@ config HISAX_16_3
110 110
111config HISAX_TELESPCI 111config HISAX_TELESPCI
112 bool "Teles PCI" 112 bool "Teles PCI"
113 depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) 113 depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
114 help 114 help
115 This enables HiSax support for the Teles PCI. 115 This enables HiSax support for the Teles PCI.
116 See <file:Documentation/isdn/README.HiSax> on how to configure it. 116 See <file:Documentation/isdn/README.HiSax> on how to configure it.
@@ -238,7 +238,7 @@ config HISAX_MIC
238 238
239config HISAX_NETJET 239config HISAX_NETJET
240 bool "NETjet card" 240 bool "NETjet card"
241 depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) 241 depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
242 help 242 help
243 This enables HiSax support for the NetJet from Traverse 243 This enables HiSax support for the NetJet from Traverse
244 Technologies. 244 Technologies.
@@ -249,7 +249,7 @@ config HISAX_NETJET
249 249
250config HISAX_NETJET_U 250config HISAX_NETJET_U
251 bool "NETspider U card" 251 bool "NETspider U card"
252 depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) 252 depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
253 help 253 help
254 This enables HiSax support for the Netspider U interface ISDN card 254 This enables HiSax support for the Netspider U interface ISDN card
255 from Traverse Technologies. 255 from Traverse Technologies.
@@ -317,7 +317,7 @@ config HISAX_GAZEL
317 317
318config HISAX_HFC_PCI 318config HISAX_HFC_PCI
319 bool "HFC PCI-Bus cards" 319 bool "HFC PCI-Bus cards"
320 depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) 320 depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
321 help 321 help
322 This enables HiSax support for the HFC-S PCI 2BDS0 based cards. 322 This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
323 323
@@ -344,7 +344,7 @@ config HISAX_HFC_SX
344 344
345config HISAX_ENTERNOW_PCI 345config HISAX_ENTERNOW_PCI
346 bool "Formula-n enter:now PCI card" 346 bool "Formula-n enter:now PCI card"
347 depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) 347 depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
348 help 348 help
349 This enables HiSax support for the Formula-n enter:now PCI 349 This enables HiSax support for the Formula-n enter:now PCI
350 ISDN card. 350 ISDN card.
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index 26c545fa223b..1b85ce166af8 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -396,17 +396,17 @@ struct isar_hw {
396 396
397struct hdlc_stat_reg { 397struct hdlc_stat_reg {
398#ifdef __BIG_ENDIAN 398#ifdef __BIG_ENDIAN
399 u_char fill __attribute__((packed)); 399 u_char fill;
400 u_char mode __attribute__((packed)); 400 u_char mode;
401 u_char xml __attribute__((packed)); 401 u_char xml;
402 u_char cmd __attribute__((packed)); 402 u_char cmd;
403#else 403#else
404 u_char cmd __attribute__((packed)); 404 u_char cmd;
405 u_char xml __attribute__((packed)); 405 u_char xml;
406 u_char mode __attribute__((packed)); 406 u_char mode;
407 u_char fill __attribute__((packed)); 407 u_char fill;
408#endif 408#endif
409}; 409} __attribute__((packed));
410 410
411struct hdlc_hw { 411struct hdlc_hw {
412 union { 412 union {
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.h b/drivers/isdn/hisax/hisax_fcpcipnp.h
index bd8a22e4d6a2..21fbcedf3a94 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.h
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.h
@@ -12,17 +12,17 @@ enum {
12 12
13struct hdlc_stat_reg { 13struct hdlc_stat_reg {
14#ifdef __BIG_ENDIAN 14#ifdef __BIG_ENDIAN
15 u_char fill __attribute__((packed)); 15 u_char fill;
16 u_char mode __attribute__((packed)); 16 u_char mode;
17 u_char xml __attribute__((packed)); 17 u_char xml;
18 u_char cmd __attribute__((packed)); 18 u_char cmd;
19#else 19#else
20 u_char cmd __attribute__((packed)); 20 u_char cmd;
21 u_char xml __attribute__((packed)); 21 u_char xml;
22 u_char mode __attribute__((packed)); 22 u_char mode;
23 u_char fill __attribute__((packed)); 23 u_char fill;
24#endif 24#endif
25}; 25} __attribute__((packed));
26 26
27struct fritz_bcs { 27struct fritz_bcs {
28 struct hisax_b_if b_if; 28 struct hisax_b_if b_if;
diff --git a/drivers/isdn/sc/command.c b/drivers/isdn/sc/command.c
index 19f2fcf0ae4a..b4b24335f716 100644
--- a/drivers/isdn/sc/command.c
+++ b/drivers/isdn/sc/command.c
@@ -43,7 +43,6 @@ extern int send_and_receive(int, unsigned int, unsigned char, unsigned char,
43 RspMessage *, int); 43 RspMessage *, int);
44extern int sendmessage(int, unsigned int, unsigned int, unsigned int, 44extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
45 unsigned int, unsigned int, unsigned int, unsigned int *); 45 unsigned int, unsigned int, unsigned int, unsigned int *);
46extern inline void pullphone(char *, char *);
47 46
48#ifdef DEBUG 47#ifdef DEBUG
49/* 48/*
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index a0ea44c3e8b1..7d4a0ac28c06 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -149,14 +149,14 @@ config MAC_EMUMOUSEBTN
149 149
150config THERM_WINDTUNNEL 150config THERM_WINDTUNNEL
151 tristate "Support for thermal management on Windtunnel G4s" 151 tristate "Support for thermal management on Windtunnel G4s"
152 depends on I2C && I2C_KEYWEST && PPC_PMAC && !PPC_PMAC64 152 depends on I2C && I2C_POWERMAC && PPC_PMAC && !PPC_PMAC64
153 help 153 help
154 This driver provides some thermostat and fan control for the desktop 154 This driver provides some thermostat and fan control for the desktop
155 G4 "Windtunnel" 155 G4 "Windtunnel"
156 156
157config THERM_ADT746X 157config THERM_ADT746X
158 tristate "Support for thermal mgmnt on laptops with ADT 746x chipset" 158 tristate "Support for thermal mgmnt on laptops with ADT 746x chipset"
159 depends on I2C && I2C_KEYWEST && PPC_PMAC && !PPC_PMAC64 159 depends on I2C && I2C_POWERMAC && PPC_PMAC && !PPC_PMAC64
160 help 160 help
161 This driver provides some thermostat and fan control for the 161 This driver provides some thermostat and fan control for the
162 iBook G4, and the ATI based aluminium PowerBooks, allowing slighlty 162 iBook G4, and the ATI based aluminium PowerBooks, allowing slighlty
@@ -164,7 +164,7 @@ config THERM_ADT746X
164 164
165config THERM_PM72 165config THERM_PM72
166 tristate "Support for thermal management on PowerMac G5" 166 tristate "Support for thermal management on PowerMac G5"
167 depends on I2C && I2C_KEYWEST && PPC_PMAC64 167 depends on I2C && I2C_POWERMAC && PPC_PMAC64
168 help 168 help
169 This driver provides thermostat and fan control for the desktop 169 This driver provides thermostat and fan control for the desktop
170 G5 machines. 170 G5 machines.
@@ -175,14 +175,14 @@ config WINDFARM
175config WINDFARM_PM81 175config WINDFARM_PM81
176 tristate "Support for thermal management on iMac G5" 176 tristate "Support for thermal management on iMac G5"
177 depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU 177 depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU
178 select I2C_PMAC_SMU 178 select I2C_POWERMAC
179 help 179 help
180 This driver provides thermal control for the iMacG5 180 This driver provides thermal control for the iMacG5
181 181
182config WINDFARM_PM91 182config WINDFARM_PM91
183 tristate "Support for thermal management on PowerMac9,1" 183 tristate "Support for thermal management on PowerMac9,1"
184 depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU 184 depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU
185 select I2C_PMAC_SMU 185 select I2C_POWERMAC
186 help 186 help
187 This driver provides thermal control for the PowerMac9,1 187 This driver provides thermal control for the PowerMac9,1
188 which is the recent (SMU based) single CPU desktop G5 188 which is the recent (SMU based) single CPU desktop G5
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 228e1852a836..2a545ceb523b 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -3,6 +3,13 @@
3 * a MacIO ASIC. Interface to new driver model mostly 3 * a MacIO ASIC. Interface to new driver model mostly
4 * stolen from the PCI version. 4 * stolen from the PCI version.
5 * 5 *
6 * Copyright (C) 2005 Ben. Herrenschmidt (benh@kernel.crashing.org)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 *
6 * TODO: 13 * TODO:
7 * 14 *
8 * - Don't probe below media bay by default, but instead provide 15 * - Don't probe below media bay by default, but instead provide
@@ -218,12 +225,14 @@ postcore_initcall(macio_bus_driver_init);
218 225
219 226
220/** 227/**
221 * macio_release_dev - free a macio device structure when all users of it are finished. 228 * macio_release_dev - free a macio device structure when all users of it are
229 * finished.
222 * @dev: device that's been disconnected 230 * @dev: device that's been disconnected
223 * 231 *
224 * Will be called only by the device core when all users of this macio device are 232 * Will be called only by the device core when all users of this macio device
225 * done. This currently means never as we don't hot remove any macio device yet, 233 * are done. This currently means never as we don't hot remove any macio
226 * though that will happen with mediabay based devices in a later implementation. 234 * device yet, though that will happen with mediabay based devices in a later
235 * implementation.
227 */ 236 */
228static void macio_release_dev(struct device *dev) 237static void macio_release_dev(struct device *dev)
229{ 238{
@@ -242,49 +251,114 @@ static void macio_release_dev(struct device *dev)
242 * If this routine returns non-null, then the resource is completely 251 * If this routine returns non-null, then the resource is completely
243 * skipped. 252 * skipped.
244 */ 253 */
245static int macio_resource_quirks(struct device_node *np, struct resource *res, int index) 254static int macio_resource_quirks(struct device_node *np, struct resource *res,
255 int index)
246{ 256{
247 if (res->flags & IORESOURCE_MEM) { 257 if (res->flags & IORESOURCE_MEM) {
248 /* Grand Central has too large resource 0 on some machines */ 258 /* Grand Central has too large resource 0 on some machines */
249 if (index == 0 && !strcmp(np->name, "gc")) { 259 if (index == 0 && !strcmp(np->name, "gc"))
250 np->addrs[0].size = 0x20000;
251 res->end = res->start + 0x1ffff; 260 res->end = res->start + 0x1ffff;
252 } 261
253 /* Airport has bogus resource 2 */ 262 /* Airport has bogus resource 2 */
254 if (index >= 2 && !strcmp(np->name, "radio")) 263 if (index >= 2 && !strcmp(np->name, "radio"))
255 return 1; 264 return 1;
265
266#ifndef CONFIG_PPC64
256 /* DBDMAs may have bogus sizes */ 267 /* DBDMAs may have bogus sizes */
257 if ((res->start & 0x0001f000) == 0x00008000) { 268 if ((res->start & 0x0001f000) == 0x00008000)
258 np->addrs[index].size = 0x100;
259 res->end = res->start + 0xff; 269 res->end = res->start + 0xff;
260 } 270#endif /* CONFIG_PPC64 */
261 /* ESCC parent eats child resources. We could have added a level of hierarchy, 271
262 * but I don't really feel the need for it */ 272 /* ESCC parent eats child resources. We could have added a
273 * level of hierarchy, but I don't really feel the need
274 * for it
275 */
263 if (!strcmp(np->name, "escc")) 276 if (!strcmp(np->name, "escc"))
264 return 1; 277 return 1;
278
265 /* ESCC has bogus resources >= 3 */ 279 /* ESCC has bogus resources >= 3 */
266 if (index >= 3 && !(strcmp(np->name, "ch-a") && strcmp(np->name, "ch-b"))) 280 if (index >= 3 && !(strcmp(np->name, "ch-a") &&
281 strcmp(np->name, "ch-b")))
267 return 1; 282 return 1;
283
268 /* Media bay has too many resources, keep only first one */ 284 /* Media bay has too many resources, keep only first one */
269 if (index > 0 && !strcmp(np->name, "media-bay")) 285 if (index > 0 && !strcmp(np->name, "media-bay"))
270 return 1; 286 return 1;
287
271 /* Some older IDE resources have bogus sizes */ 288 /* Some older IDE resources have bogus sizes */
272 if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") && 289 if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") &&
273 strcmp(np->type, "ide") && strcmp(np->type, "ata"))) { 290 strcmp(np->type, "ide") && strcmp(np->type, "ata"))) {
274 if (index == 0 && np->addrs[0].size > 0x1000) { 291 if (index == 0 && (res->end - res->start) > 0xfff)
275 np->addrs[0].size = 0x1000;
276 res->end = res->start + 0xfff; 292 res->end = res->start + 0xfff;
277 } 293 if (index == 1 && (res->end - res->start) > 0xff)
278 if (index == 1 && np->addrs[1].size > 0x100) {
279 np->addrs[1].size = 0x100;
280 res->end = res->start + 0xff; 294 res->end = res->start + 0xff;
281 }
282 } 295 }
283 } 296 }
284 return 0; 297 return 0;
285} 298}
286 299
287 300
301static void macio_setup_interrupts(struct macio_dev *dev)
302{
303 struct device_node *np = dev->ofdev.node;
304 int i,j;
305
306 /* For now, we use pre-parsed entries in the device-tree for
307 * interrupt routing and addresses, but we should change that
308 * to dynamically parsed entries and so get rid of most of the
309 * clutter in struct device_node
310 */
311 for (i = j = 0; i < np->n_intrs; i++) {
312 struct resource *res = &dev->interrupt[j];
313
314 if (j >= MACIO_DEV_COUNT_IRQS)
315 break;
316 res->start = np->intrs[i].line;
317 res->flags = IORESOURCE_IO;
318 if (np->intrs[j].sense)
319 res->flags |= IORESOURCE_IRQ_LOWLEVEL;
320 else
321 res->flags |= IORESOURCE_IRQ_HIGHEDGE;
322 res->name = dev->ofdev.dev.bus_id;
323 if (macio_resource_quirks(np, res, i))
324 memset(res, 0, sizeof(struct resource));
325 else
326 j++;
327 }
328 dev->n_interrupts = j;
329}
330
331static void macio_setup_resources(struct macio_dev *dev,
332 struct resource *parent_res)
333{
334 struct device_node *np = dev->ofdev.node;
335 struct resource r;
336 int index;
337
338 for (index = 0; of_address_to_resource(np, index, &r) == 0; index++) {
339 struct resource *res = &dev->resource[index];
340 if (index >= MACIO_DEV_COUNT_RESOURCES)
341 break;
342 *res = r;
343 res->name = dev->ofdev.dev.bus_id;
344
345 if (macio_resource_quirks(np, res, index)) {
346 memset(res, 0, sizeof(struct resource));
347 continue;
348 }
349 /* Currently, we consider failure as harmless, this may
350 * change in the future, once I've found all the device
351 * tree bugs in older machines & worked around them
352 */
353 if (insert_resource(parent_res, res)) {
354 printk(KERN_WARNING "Can't request resource "
355 "%d for MacIO device %s\n",
356 index, dev->ofdev.dev.bus_id);
357 }
358 }
359 dev->n_resources = index;
360}
361
288/** 362/**
289 * macio_add_one_device - Add one device from OF node to the device tree 363 * macio_add_one_device - Add one device from OF node to the device tree
290 * @chip: pointer to the macio_chip holding the device 364 * @chip: pointer to the macio_chip holding the device
@@ -294,12 +368,13 @@ static int macio_resource_quirks(struct device_node *np, struct resource *res, i
294 * When media-bay is changed to hotswap drivers, this function will 368 * When media-bay is changed to hotswap drivers, this function will
295 * be exposed to the bay driver some way... 369 * be exposed to the bay driver some way...
296 */ 370 */
297static struct macio_dev * macio_add_one_device(struct macio_chip *chip, struct device *parent, 371static struct macio_dev * macio_add_one_device(struct macio_chip *chip,
298 struct device_node *np, struct macio_dev *in_bay, 372 struct device *parent,
373 struct device_node *np,
374 struct macio_dev *in_bay,
299 struct resource *parent_res) 375 struct resource *parent_res)
300{ 376{
301 struct macio_dev *dev; 377 struct macio_dev *dev;
302 int i, j;
303 u32 *reg; 378 u32 *reg;
304 379
305 if (np == NULL) 380 if (np == NULL)
@@ -326,7 +401,8 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, struct d
326 401
327 /* MacIO itself has a different reg, we use it's PCI base */ 402 /* MacIO itself has a different reg, we use it's PCI base */
328 if (np == chip->of_node) { 403 if (np == chip->of_node) {
329 sprintf(dev->ofdev.dev.bus_id, "%1d.%08lx:%.*s", chip->lbus.index, 404 sprintf(dev->ofdev.dev.bus_id, "%1d.%08lx:%.*s",
405 chip->lbus.index,
330#ifdef CONFIG_PCI 406#ifdef CONFIG_PCI
331 pci_resource_start(chip->lbus.pdev, 0), 407 pci_resource_start(chip->lbus.pdev, 0),
332#else 408#else
@@ -335,57 +411,16 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, struct d
335 MAX_NODE_NAME_SIZE, np->name); 411 MAX_NODE_NAME_SIZE, np->name);
336 } else { 412 } else {
337 reg = (u32 *)get_property(np, "reg", NULL); 413 reg = (u32 *)get_property(np, "reg", NULL);
338 sprintf(dev->ofdev.dev.bus_id, "%1d.%08x:%.*s", chip->lbus.index, 414 sprintf(dev->ofdev.dev.bus_id, "%1d.%08x:%.*s",
415 chip->lbus.index,
339 reg ? *reg : 0, MAX_NODE_NAME_SIZE, np->name); 416 reg ? *reg : 0, MAX_NODE_NAME_SIZE, np->name);
340 } 417 }
341 418
342 /* For now, we use pre-parsed entries in the device-tree for 419 /* Setup interrupts & resources */
343 * interrupt routing and addresses, but we should change that 420 macio_setup_interrupts(dev);
344 * to dynamically parsed entries and so get rid of most of the 421 macio_setup_resources(dev, parent_res);
345 * clutter in struct device_node
346 */
347 for (i = j = 0; i < np->n_intrs; i++) {
348 struct resource *res = &dev->interrupt[j];
349
350 if (j >= MACIO_DEV_COUNT_IRQS)
351 break;
352 res->start = np->intrs[i].line;
353 res->flags = IORESOURCE_IO;
354 if (np->intrs[j].sense)
355 res->flags |= IORESOURCE_IRQ_LOWLEVEL;
356 else
357 res->flags |= IORESOURCE_IRQ_HIGHEDGE;
358 res->name = dev->ofdev.dev.bus_id;
359 if (macio_resource_quirks(np, res, i))
360 memset(res, 0, sizeof(struct resource));
361 else
362 j++;
363 }
364 dev->n_interrupts = j;
365 for (i = j = 0; i < np->n_addrs; i++) {
366 struct resource *res = &dev->resource[j];
367
368 if (j >= MACIO_DEV_COUNT_RESOURCES)
369 break;
370 res->start = np->addrs[i].address;
371 res->end = np->addrs[i].address + np->addrs[i].size - 1;
372 res->flags = IORESOURCE_MEM;
373 res->name = dev->ofdev.dev.bus_id;
374 if (macio_resource_quirks(np, res, i))
375 memset(res, 0, sizeof(struct resource));
376 else {
377 j++;
378 /* Currently, we consider failure as harmless, this may
379 * change in the future, once I've found all the device
380 * tree bugs in older machines & worked around them
381 */
382 if (insert_resource(parent_res, res))
383 printk(KERN_WARNING "Can't request resource %d for MacIO"
384 " device %s\n", i, dev->ofdev.dev.bus_id);
385 }
386 }
387 dev->n_resources = j;
388 422
423 /* Register with core */
389 if (of_device_register(&dev->ofdev) != 0) { 424 if (of_device_register(&dev->ofdev) != 0) {
390 printk(KERN_DEBUG"macio: device registration error for %s!\n", 425 printk(KERN_DEBUG"macio: device registration error for %s!\n",
391 dev->ofdev.dev.bus_id); 426 dev->ofdev.dev.bus_id);
@@ -442,36 +477,42 @@ static void macio_pci_add_devices(struct macio_chip *chip)
442 477
443 /* First scan 1st level */ 478 /* First scan 1st level */
444 for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) { 479 for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) {
445 if (!macio_skip_device(np)) { 480 if (macio_skip_device(np))
446 of_node_get(np); 481 continue;
447 mdev = macio_add_one_device(chip, &rdev->ofdev.dev, np, NULL, root_res); 482 of_node_get(np);
448 if (mdev == NULL) 483 mdev = macio_add_one_device(chip, &rdev->ofdev.dev, np, NULL,
449 of_node_put(np); 484 root_res);
450 else if (strncmp(np->name, "media-bay", 9) == 0) 485 if (mdev == NULL)
451 mbdev = mdev; 486 of_node_put(np);
452 else if (strncmp(np->name, "escc", 4) == 0) 487 else if (strncmp(np->name, "media-bay", 9) == 0)
453 sdev = mdev; 488 mbdev = mdev;
454 } 489 else if (strncmp(np->name, "escc", 4) == 0)
490 sdev = mdev;
455 } 491 }
456 492
457 /* Add media bay devices if any */ 493 /* Add media bay devices if any */
458 if (mbdev) 494 if (mbdev)
459 for (np = NULL; (np = of_get_next_child(mbdev->ofdev.node, np)) != NULL;) 495 for (np = NULL; (np = of_get_next_child(mbdev->ofdev.node, np))
460 if (!macio_skip_device(np)) { 496 != NULL;) {
461 of_node_get(np); 497 if (macio_skip_device(np))
462 if (macio_add_one_device(chip, &mbdev->ofdev.dev, np, mbdev, 498 continue;
463 root_res) == NULL) 499 of_node_get(np);
464 of_node_put(np); 500 if (macio_add_one_device(chip, &mbdev->ofdev.dev, np,
465 } 501 mbdev, root_res) == NULL)
502 of_node_put(np);
503 }
504
466 /* Add serial ports if any */ 505 /* Add serial ports if any */
467 if (sdev) { 506 if (sdev) {
468 for (np = NULL; (np = of_get_next_child(sdev->ofdev.node, np)) != NULL;) 507 for (np = NULL; (np = of_get_next_child(sdev->ofdev.node, np))
469 if (!macio_skip_device(np)) { 508 != NULL;) {
470 of_node_get(np); 509 if (macio_skip_device(np))
471 if (macio_add_one_device(chip, &sdev->ofdev.dev, np, NULL, 510 continue;
472 root_res) == NULL) 511 of_node_get(np);
473 of_node_put(np); 512 if (macio_add_one_device(chip, &sdev->ofdev.dev, np,
474 } 513 NULL, root_res) == NULL)
514 of_node_put(np);
515 }
475 } 516 }
476} 517}
477 518
@@ -519,7 +560,8 @@ void macio_unregister_driver(struct macio_driver *drv)
519 * Returns 0 on success, or %EBUSY on error. A warning 560 * Returns 0 on success, or %EBUSY on error. A warning
520 * message is also printed on failure. 561 * message is also printed on failure.
521 */ 562 */
522int macio_request_resource(struct macio_dev *dev, int resource_no, const char *name) 563int macio_request_resource(struct macio_dev *dev, int resource_no,
564 const char *name)
523{ 565{
524 if (macio_resource_len(dev, resource_no) == 0) 566 if (macio_resource_len(dev, resource_no) == 0)
525 return 0; 567 return 0;
@@ -606,20 +648,20 @@ static int __devinit macio_pci_probe(struct pci_dev *pdev, const struct pci_devi
606 if (ent->vendor != PCI_VENDOR_ID_APPLE) 648 if (ent->vendor != PCI_VENDOR_ID_APPLE)
607 return -ENODEV; 649 return -ENODEV;
608 650
609 /* Note regarding refcounting: We assume pci_device_to_OF_node() is ported 651 /* Note regarding refcounting: We assume pci_device_to_OF_node() is
610 * to new OF APIs and returns a node with refcount incremented. This isn't 652 * ported to new OF APIs and returns a node with refcount incremented.
611 * the case today, but on the other hand ppc32 doesn't do refcounting. This
612 * will have to be fixed when going to ppc64. --BenH.
613 */ 653 */
614 np = pci_device_to_OF_node(pdev); 654 np = pci_device_to_OF_node(pdev);
615 if (np == NULL) 655 if (np == NULL)
616 return -ENODEV; 656 return -ENODEV;
617 657
618 /* This assumption is wrong, fix that here for now until I fix the arch */ 658 /* The above assumption is wrong !!!
659 * fix that here for now until I fix the arch code
660 */
619 of_node_get(np); 661 of_node_get(np);
620 662
621 /* We also assume that pmac_feature will have done a get() on nodes stored 663 /* We also assume that pmac_feature will have done a get() on nodes
622 * in the macio chips array 664 * stored in the macio chips array
623 */ 665 */
624 chip = macio_find(np, macio_unknown); 666 chip = macio_find(np, macio_unknown);
625 of_node_put(np); 667 of_node_put(np);
@@ -639,9 +681,9 @@ static int __devinit macio_pci_probe(struct pci_dev *pdev, const struct pci_devi
639 681
640 /* 682 /*
641 * HACK ALERT: The WallStreet PowerBook and some OHare based machines 683 * HACK ALERT: The WallStreet PowerBook and some OHare based machines
642 * have 2 macio ASICs. I must probe the "main" one first or IDE ordering 684 * have 2 macio ASICs. I must probe the "main" one first or IDE
643 * will be incorrect. So I put on "hold" the second one since it seem to 685 * ordering will be incorrect. So I put on "hold" the second one since
644 * appear first on PCI 686 * it seem to appear first on PCI
645 */ 687 */
646 if (chip->type == macio_gatwick || chip->type == macio_ohareII) 688 if (chip->type == macio_gatwick || chip->type == macio_ohareII)
647 if (macio_chips[0].lbus.pdev == NULL) { 689 if (macio_chips[0].lbus.pdev == NULL) {
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index b856bb67169c..8dbf2852bae0 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -647,6 +647,7 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de
647 struct media_bay_info* bay; 647 struct media_bay_info* bay;
648 u32 __iomem *regbase; 648 u32 __iomem *regbase;
649 struct device_node *ofnode; 649 struct device_node *ofnode;
650 unsigned long base;
650 int i; 651 int i;
651 652
652 ofnode = mdev->ofdev.node; 653 ofnode = mdev->ofdev.node;
@@ -656,10 +657,11 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de
656 if (macio_request_resources(mdev, "media-bay")) 657 if (macio_request_resources(mdev, "media-bay"))
657 return -EBUSY; 658 return -EBUSY;
658 /* Media bay registers are located at the beginning of the 659 /* Media bay registers are located at the beginning of the
659 * mac-io chip, we get the parent address for now (hrm...) 660 * mac-io chip, for now, we trick and align down the first
661 * resource passed in
660 */ 662 */
661 regbase = (u32 __iomem *) 663 base = macio_resource_start(mdev, 0) & 0xffff0000u;
662 ioremap(ofnode->parent->addrs[0].address, 0x100); 664 regbase = (u32 __iomem *)ioremap(base, 0x100);
663 if (regbase == NULL) { 665 if (regbase == NULL) {
664 macio_release_resources(mdev); 666 macio_release_resources(mdev);
665 return -ENOMEM; 667 return -ENOMEM;
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index e8378274d710..db2ae71d07ef 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -53,7 +53,7 @@
53#undef DEBUG_SMU 53#undef DEBUG_SMU
54 54
55#ifdef DEBUG_SMU 55#ifdef DEBUG_SMU
56#define DPRINTK(fmt, args...) do { udbg_printf(KERN_DEBUG fmt , ##args); } while (0) 56#define DPRINTK(fmt, args...) do { printk(KERN_DEBUG fmt , ##args); } while (0)
57#else 57#else
58#define DPRINTK(fmt, args...) do { } while (0) 58#define DPRINTK(fmt, args...) do { } while (0)
59#endif 59#endif
@@ -94,6 +94,8 @@ struct smu_device {
94static struct smu_device *smu; 94static struct smu_device *smu;
95static DECLARE_MUTEX(smu_part_access); 95static DECLARE_MUTEX(smu_part_access);
96 96
97static void smu_i2c_retry(unsigned long data);
98
97/* 99/*
98 * SMU driver low level stuff 100 * SMU driver low level stuff
99 */ 101 */
@@ -469,7 +471,6 @@ int __init smu_init (void)
469 smu->of_node = np; 471 smu->of_node = np;
470 smu->db_irq = NO_IRQ; 472 smu->db_irq = NO_IRQ;
471 smu->msg_irq = NO_IRQ; 473 smu->msg_irq = NO_IRQ;
472 init_timer(&smu->i2c_timer);
473 474
474 /* smu_cmdbuf_abs is in the low 2G of RAM, can be converted to a 475 /* smu_cmdbuf_abs is in the low 2G of RAM, can be converted to a
475 * 32 bits value safely 476 * 32 bits value safely
@@ -544,6 +545,10 @@ static int smu_late_init(void)
544 if (!smu) 545 if (!smu)
545 return 0; 546 return 0;
546 547
548 init_timer(&smu->i2c_timer);
549 smu->i2c_timer.function = smu_i2c_retry;
550 smu->i2c_timer.data = (unsigned long)smu;
551
547 /* 552 /*
548 * Try to request the interrupts 553 * Try to request the interrupts
549 */ 554 */
@@ -570,7 +575,10 @@ static int smu_late_init(void)
570 575
571 return 0; 576 return 0;
572} 577}
573arch_initcall(smu_late_init); 578/* This has to be before arch_initcall as the low i2c stuff relies on the
579 * above having been done before we reach arch_initcalls
580 */
581core_initcall(smu_late_init);
574 582
575/* 583/*
576 * sysfs visibility 584 * sysfs visibility
@@ -580,20 +588,10 @@ static void smu_expose_childs(void *unused)
580{ 588{
581 struct device_node *np; 589 struct device_node *np;
582 590
583 for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;) { 591 for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;)
584 if (device_is_compatible(np, "smu-i2c")) {
585 char name[32];
586 u32 *reg = (u32 *)get_property(np, "reg", NULL);
587
588 if (reg == NULL)
589 continue;
590 sprintf(name, "smu-i2c-%02x", *reg);
591 of_platform_device_create(np, name, &smu->of_dev->dev);
592 }
593 if (device_is_compatible(np, "smu-sensors")) 592 if (device_is_compatible(np, "smu-sensors"))
594 of_platform_device_create(np, "smu-sensors", &smu->of_dev->dev); 593 of_platform_device_create(np, "smu-sensors",
595 } 594 &smu->of_dev->dev);
596
597} 595}
598 596
599static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs, NULL); 597static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs, NULL);
@@ -712,13 +710,13 @@ static void smu_i2c_complete_command(struct smu_i2c_cmd *cmd, int fail)
712 710
713static void smu_i2c_retry(unsigned long data) 711static void smu_i2c_retry(unsigned long data)
714{ 712{
715 struct smu_i2c_cmd *cmd = (struct smu_i2c_cmd *)data; 713 struct smu_i2c_cmd *cmd = smu->cmd_i2c_cur;
716 714
717 DPRINTK("SMU: i2c failure, requeuing...\n"); 715 DPRINTK("SMU: i2c failure, requeuing...\n");
718 716
719 /* requeue command simply by resetting reply_len */ 717 /* requeue command simply by resetting reply_len */
720 cmd->pdata[0] = 0xff; 718 cmd->pdata[0] = 0xff;
721 cmd->scmd.reply_len = 0x10; 719 cmd->scmd.reply_len = sizeof(cmd->pdata);
722 smu_queue_cmd(&cmd->scmd); 720 smu_queue_cmd(&cmd->scmd);
723} 721}
724 722
@@ -747,10 +745,8 @@ static void smu_i2c_low_completion(struct smu_cmd *scmd, void *misc)
747 */ 745 */
748 if (fail && --cmd->retries > 0) { 746 if (fail && --cmd->retries > 0) {
749 DPRINTK("SMU: i2c failure, starting timer...\n"); 747 DPRINTK("SMU: i2c failure, starting timer...\n");
750 smu->i2c_timer.function = smu_i2c_retry; 748 BUG_ON(cmd != smu->cmd_i2c_cur);
751 smu->i2c_timer.data = (unsigned long)cmd; 749 mod_timer(&smu->i2c_timer, jiffies + msecs_to_jiffies(5));
752 smu->i2c_timer.expires = jiffies + msecs_to_jiffies(5);
753 add_timer(&smu->i2c_timer);
754 return; 750 return;
755 } 751 }
756 752
@@ -764,7 +760,7 @@ static void smu_i2c_low_completion(struct smu_cmd *scmd, void *misc)
764 760
765 /* Ok, initial command complete, now poll status */ 761 /* Ok, initial command complete, now poll status */
766 scmd->reply_buf = cmd->pdata; 762 scmd->reply_buf = cmd->pdata;
767 scmd->reply_len = 0x10; 763 scmd->reply_len = sizeof(cmd->pdata);
768 scmd->data_buf = cmd->pdata; 764 scmd->data_buf = cmd->pdata;
769 scmd->data_len = 1; 765 scmd->data_len = 1;
770 cmd->pdata[0] = 0; 766 cmd->pdata[0] = 0;
@@ -786,7 +782,7 @@ int smu_queue_i2c(struct smu_i2c_cmd *cmd)
786 cmd->scmd.done = smu_i2c_low_completion; 782 cmd->scmd.done = smu_i2c_low_completion;
787 cmd->scmd.misc = cmd; 783 cmd->scmd.misc = cmd;
788 cmd->scmd.reply_buf = cmd->pdata; 784 cmd->scmd.reply_buf = cmd->pdata;
789 cmd->scmd.reply_len = 0x10; 785 cmd->scmd.reply_len = sizeof(cmd->pdata);
790 cmd->scmd.data_buf = (u8 *)(char *)&cmd->info; 786 cmd->scmd.data_buf = (u8 *)(char *)&cmd->info;
791 cmd->scmd.status = 1; 787 cmd->scmd.status = 1;
792 cmd->stage = 0; 788 cmd->stage = 0;
@@ -909,10 +905,13 @@ static struct smu_sdbp_header *smu_create_sdb_partition(int id)
909 struct property *prop; 905 struct property *prop;
910 906
911 /* First query the partition info */ 907 /* First query the partition info */
908 DPRINTK("SMU: Query partition infos ... (irq=%d)\n", smu->db_irq);
912 smu_queue_simple(&cmd, SMU_CMD_PARTITION_COMMAND, 2, 909 smu_queue_simple(&cmd, SMU_CMD_PARTITION_COMMAND, 2,
913 smu_done_complete, &comp, 910 smu_done_complete, &comp,
914 SMU_CMD_PARTITION_LATEST, id); 911 SMU_CMD_PARTITION_LATEST, id);
915 wait_for_completion(&comp); 912 wait_for_completion(&comp);
913 DPRINTK("SMU: done, status: %d, reply_len: %d\n",
914 cmd.cmd.status, cmd.cmd.reply_len);
916 915
917 /* Partition doesn't exist (or other error) */ 916 /* Partition doesn't exist (or other error) */
918 if (cmd.cmd.status != 0 || cmd.cmd.reply_len != 6) 917 if (cmd.cmd.status != 0 || cmd.cmd.reply_len != 6)
@@ -975,6 +974,8 @@ struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size,
975 974
976 sprintf(pname, "sdb-partition-%02x", id); 975 sprintf(pname, "sdb-partition-%02x", id);
977 976
977 DPRINTK("smu_get_sdb_partition(%02x)\n", id);
978
978 if (interruptible) { 979 if (interruptible) {
979 int rc; 980 int rc;
980 rc = down_interruptible(&smu_part_access); 981 rc = down_interruptible(&smu_part_access);
@@ -986,6 +987,7 @@ struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size,
986 part = (struct smu_sdbp_header *)get_property(smu->of_node, 987 part = (struct smu_sdbp_header *)get_property(smu->of_node,
987 pname, size); 988 pname, size);
988 if (part == NULL) { 989 if (part == NULL) {
990 DPRINTK("trying to extract from SMU ...\n");
989 part = smu_create_sdb_partition(id); 991 part = smu_create_sdb_partition(id);
990 if (part != NULL && size) 992 if (part != NULL && size)
991 *size = part->len << 2; 993 *size = part->len << 2;
diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
index d843a6c9c6df..2d9d79150403 100644
--- a/drivers/macintosh/via-cuda.c
+++ b/drivers/macintosh/via-cuda.c
@@ -127,39 +127,34 @@ struct adb_driver via_cuda_driver = {
127#endif /* CONFIG_ADB */ 127#endif /* CONFIG_ADB */
128 128
129#ifdef CONFIG_PPC 129#ifdef CONFIG_PPC
130int __init 130int __init find_via_cuda(void)
131find_via_cuda(void)
132{ 131{
133 int err;
134 struct adb_request req; 132 struct adb_request req;
133 phys_addr_t taddr;
134 u32 *reg;
135 int err;
135 136
136 if (vias != 0) 137 if (vias != 0)
137 return 1; 138 return 1;
138 vias = find_devices("via-cuda"); 139 vias = of_find_node_by_name(NULL, "via-cuda");
139 if (vias == 0) 140 if (vias == 0)
140 return 0; 141 return 0;
141 if (vias->next != 0)
142 printk(KERN_WARNING "Warning: only using 1st via-cuda\n");
143
144#if 0
145 { int i;
146
147 printk("find_via_cuda: node = %p, addrs =", vias->node);
148 for (i = 0; i < vias->n_addrs; ++i)
149 printk(" %x(%x)", vias->addrs[i].address, vias->addrs[i].size);
150 printk(", intrs =");
151 for (i = 0; i < vias->n_intrs; ++i)
152 printk(" %x", vias->intrs[i].line);
153 printk("\n"); }
154#endif
155 142
156 if (vias->n_addrs != 1 || vias->n_intrs != 1) { 143 reg = (u32 *)get_property(vias, "reg", NULL);
157 printk(KERN_ERR "via-cuda: expecting 1 address (%d) and 1 interrupt (%d)\n", 144 if (reg == NULL) {
158 vias->n_addrs, vias->n_intrs); 145 printk(KERN_ERR "via-cuda: No \"reg\" property !\n");
159 if (vias->n_addrs < 1 || vias->n_intrs < 1) 146 goto fail;
160 return 0; 147 }
148 taddr = of_translate_address(vias, reg);
149 if (taddr == 0) {
150 printk(KERN_ERR "via-cuda: Can't translate address !\n");
151 goto fail;
152 }
153 via = ioremap(taddr, 0x2000);
154 if (via == NULL) {
155 printk(KERN_ERR "via-cuda: Can't map address !\n");
156 goto fail;
161 } 157 }
162 via = ioremap(vias->addrs->address, 0x2000);
163 158
164 cuda_state = idle; 159 cuda_state = idle;
165 sys_ctrler = SYS_CTRLER_CUDA; 160 sys_ctrler = SYS_CTRLER_CUDA;
@@ -185,6 +180,11 @@ find_via_cuda(void)
185 cuda_poll(); 180 cuda_poll();
186 181
187 return 1; 182 return 1;
183
184 fail:
185 of_node_put(vias);
186 vias = NULL;
187 return 0;
188} 188}
189#endif /* CONFIG_PPC */ 189#endif /* CONFIG_PPC */
190 190
@@ -193,10 +193,6 @@ static int __init via_cuda_start(void)
193 if (via == NULL) 193 if (via == NULL)
194 return -ENODEV; 194 return -ENODEV;
195 195
196#ifdef CONFIG_PPC
197 request_OF_resource(vias, 0, NULL);
198#endif
199
200 if (request_irq(CUDA_IRQ, cuda_interrupt, 0, "ADB", cuda_interrupt)) { 196 if (request_irq(CUDA_IRQ, cuda_interrupt, 0, "ADB", cuda_interrupt)) {
201 printk(KERN_ERR "cuda_init: can't get irq %d\n", CUDA_IRQ); 197 printk(KERN_ERR "cuda_init: can't get irq %d\n", CUDA_IRQ);
202 return -EAGAIN; 198 return -EAGAIN;
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 564043508569..6eb93e45fcd3 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -55,6 +55,8 @@
55#include <asm/sections.h> 55#include <asm/sections.h>
56#include <asm/irq.h> 56#include <asm/irq.h>
57#include <asm/pmac_feature.h> 57#include <asm/pmac_feature.h>
58#include <asm/pmac_pfunc.h>
59#include <asm/pmac_low_i2c.h>
58#include <asm/uaccess.h> 60#include <asm/uaccess.h>
59#include <asm/mmu_context.h> 61#include <asm/mmu_context.h>
60#include <asm/cputable.h> 62#include <asm/cputable.h>
@@ -147,6 +149,7 @@ static struct device_node *vias;
147static int pmu_kind = PMU_UNKNOWN; 149static int pmu_kind = PMU_UNKNOWN;
148static int pmu_fully_inited = 0; 150static int pmu_fully_inited = 0;
149static int pmu_has_adb; 151static int pmu_has_adb;
152static struct device_node *gpio_node;
150static unsigned char __iomem *gpio_reg = NULL; 153static unsigned char __iomem *gpio_reg = NULL;
151static int gpio_irq = -1; 154static int gpio_irq = -1;
152static int gpio_irq_enabled = -1; 155static int gpio_irq_enabled = -1;
@@ -157,8 +160,8 @@ static int pmu_version;
157static int drop_interrupts; 160static int drop_interrupts;
158#if defined(CONFIG_PM) && defined(CONFIG_PPC32) 161#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
159static int option_lid_wakeup = 1; 162static int option_lid_wakeup = 1;
160static int sleep_in_progress;
161#endif /* CONFIG_PM && CONFIG_PPC32 */ 163#endif /* CONFIG_PM && CONFIG_PPC32 */
164static int sleep_in_progress;
162static unsigned long async_req_locks; 165static unsigned long async_req_locks;
163static unsigned int pmu_irq_stats[11]; 166static unsigned int pmu_irq_stats[11];
164 167
@@ -196,7 +199,6 @@ static int pmu_adb_reset_bus(void);
196#endif /* CONFIG_ADB */ 199#endif /* CONFIG_ADB */
197 200
198static int init_pmu(void); 201static int init_pmu(void);
199static int pmu_queue_request(struct adb_request *req);
200static void pmu_start(void); 202static void pmu_start(void);
201static irqreturn_t via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs); 203static irqreturn_t via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs);
202static irqreturn_t gpio1_interrupt(int irq, void *arg, struct pt_regs *regs); 204static irqreturn_t gpio1_interrupt(int irq, void *arg, struct pt_regs *regs);
@@ -295,22 +297,26 @@ static struct backlight_controller pmu_backlight_controller = {
295}; 297};
296#endif /* CONFIG_PMAC_BACKLIGHT */ 298#endif /* CONFIG_PMAC_BACKLIGHT */
297 299
298int 300int __init find_via_pmu(void)
299find_via_pmu(void)
300{ 301{
302 u64 taddr;
303 u32 *reg;
304
301 if (via != 0) 305 if (via != 0)
302 return 1; 306 return 1;
303 vias = find_devices("via-pmu"); 307 vias = of_find_node_by_name(NULL, "via-pmu");
304 if (vias == 0) 308 if (vias == NULL)
305 return 0; 309 return 0;
306 if (vias->next != 0)
307 printk(KERN_WARNING "Warning: only using 1st via-pmu\n");
308 310
309 if (vias->n_addrs < 1 || vias->n_intrs < 1) { 311 reg = (u32 *)get_property(vias, "reg", NULL);
310 printk(KERN_ERR "via-pmu: %d addresses, %d interrupts!\n", 312 if (reg == NULL) {
311 vias->n_addrs, vias->n_intrs); 313 printk(KERN_ERR "via-pmu: No \"reg\" property !\n");
312 if (vias->n_addrs < 1 || vias->n_intrs < 1) 314 goto fail;
313 return 0; 315 }
316 taddr = of_translate_address(vias, reg);
317 if (taddr == OF_BAD_ADDR) {
318 printk(KERN_ERR "via-pmu: Can't translate address !\n");
319 goto fail;
314 } 320 }
315 321
316 spin_lock_init(&pmu_lock); 322 spin_lock_init(&pmu_lock);
@@ -331,7 +337,8 @@ find_via_pmu(void)
331 pmu_kind = PMU_HEATHROW_BASED; 337 pmu_kind = PMU_HEATHROW_BASED;
332 else if (device_is_compatible(vias->parent, "Keylargo") 338 else if (device_is_compatible(vias->parent, "Keylargo")
333 || device_is_compatible(vias->parent, "K2-Keylargo")) { 339 || device_is_compatible(vias->parent, "K2-Keylargo")) {
334 struct device_node *gpio, *gpiop; 340 struct device_node *gpiop;
341 u64 gaddr = OF_BAD_ADDR;
335 342
336 pmu_kind = PMU_KEYLARGO_BASED; 343 pmu_kind = PMU_KEYLARGO_BASED;
337 pmu_has_adb = (find_type_devices("adb") != NULL); 344 pmu_has_adb = (find_type_devices("adb") != NULL);
@@ -341,19 +348,24 @@ find_via_pmu(void)
341 PMU_INT_TICK | 348 PMU_INT_TICK |
342 PMU_INT_ENVIRONMENT; 349 PMU_INT_ENVIRONMENT;
343 350
344 gpiop = find_devices("gpio"); 351 gpiop = of_find_node_by_name(NULL, "gpio");
345 if (gpiop && gpiop->n_addrs) { 352 if (gpiop) {
346 gpio_reg = ioremap(gpiop->addrs->address, 0x10); 353 reg = (u32 *)get_property(gpiop, "reg", NULL);
347 gpio = find_devices("extint-gpio1"); 354 if (reg)
348 if (gpio == NULL) 355 gaddr = of_translate_address(gpiop, reg);
349 gpio = find_devices("pmu-interrupt"); 356 if (gaddr != OF_BAD_ADDR)
350 if (gpio && gpio->parent == gpiop && gpio->n_intrs) 357 gpio_reg = ioremap(gaddr, 0x10);
351 gpio_irq = gpio->intrs[0].line;
352 } 358 }
359 if (gpio_reg == NULL)
360 printk(KERN_ERR "via-pmu: Can't find GPIO reg !\n");
353 } else 361 } else
354 pmu_kind = PMU_UNKNOWN; 362 pmu_kind = PMU_UNKNOWN;
355 363
356 via = ioremap(vias->addrs->address, 0x2000); 364 via = ioremap(taddr, 0x2000);
365 if (via == NULL) {
366 printk(KERN_ERR "via-pmu: Can't map address !\n");
367 goto fail;
368 }
357 369
358 out_8(&via[IER], IER_CLR | 0x7f); /* disable all intrs */ 370 out_8(&via[IER], IER_CLR | 0x7f); /* disable all intrs */
359 out_8(&via[IFR], 0x7f); /* clear IFR */ 371 out_8(&via[IFR], 0x7f); /* clear IFR */
@@ -365,23 +377,25 @@ find_via_pmu(void)
365 return 0; 377 return 0;
366 } 378 }
367 379
368 printk(KERN_INFO "PMU driver %d initialized for %s, firmware: %02x\n", 380 printk(KERN_INFO "PMU driver v%d initialized for %s, firmware: %02x\n",
369 PMU_DRIVER_VERSION, pbook_type[pmu_kind], pmu_version); 381 PMU_DRIVER_VERSION, pbook_type[pmu_kind], pmu_version);
370 382
371 sys_ctrler = SYS_CTRLER_PMU; 383 sys_ctrler = SYS_CTRLER_PMU;
372 384
373 return 1; 385 return 1;
386 fail:
387 of_node_put(vias);
388 vias = NULL;
389 return 0;
374} 390}
375 391
376#ifdef CONFIG_ADB 392#ifdef CONFIG_ADB
377static int 393static int pmu_probe(void)
378pmu_probe(void)
379{ 394{
380 return vias == NULL? -ENODEV: 0; 395 return vias == NULL? -ENODEV: 0;
381} 396}
382 397
383static int __init 398static int __init pmu_init(void)
384pmu_init(void)
385{ 399{
386 if (vias == NULL) 400 if (vias == NULL)
387 return -ENODEV; 401 return -ENODEV;
@@ -405,7 +419,7 @@ static int __init via_pmu_start(void)
405 bright_req_2.complete = 1; 419 bright_req_2.complete = 1;
406 batt_req.complete = 1; 420 batt_req.complete = 1;
407 421
408#if defined(CONFIG_PPC32) && !defined(CONFIG_PPC_MERGE) 422#ifndef CONFIG_PPC_MERGE
409 if (pmu_kind == PMU_KEYLARGO_BASED) 423 if (pmu_kind == PMU_KEYLARGO_BASED)
410 openpic_set_irq_priority(vias->intrs[0].line, 424 openpic_set_irq_priority(vias->intrs[0].line,
411 OPENPIC_PRIORITY_DEFAULT + 1); 425 OPENPIC_PRIORITY_DEFAULT + 1);
@@ -418,10 +432,22 @@ static int __init via_pmu_start(void)
418 return -EAGAIN; 432 return -EAGAIN;
419 } 433 }
420 434
421 if (pmu_kind == PMU_KEYLARGO_BASED && gpio_irq != -1) { 435 if (pmu_kind == PMU_KEYLARGO_BASED) {
422 if (request_irq(gpio_irq, gpio1_interrupt, 0, "GPIO1 ADB", (void *)0)) 436 gpio_node = of_find_node_by_name(NULL, "extint-gpio1");
423 printk(KERN_ERR "pmu: can't get irq %d (GPIO1)\n", gpio_irq); 437 if (gpio_node == NULL)
424 gpio_irq_enabled = 1; 438 gpio_node = of_find_node_by_name(NULL,
439 "pmu-interrupt");
440 if (gpio_node && gpio_node->n_intrs > 0)
441 gpio_irq = gpio_node->intrs[0].line;
442
443 if (gpio_irq != -1) {
444 if (request_irq(gpio_irq, gpio1_interrupt, 0,
445 "GPIO1 ADB", (void *)0))
446 printk(KERN_ERR "pmu: can't get irq %d"
447 " (GPIO1)\n", gpio_irq);
448 else
449 gpio_irq_enabled = 1;
450 }
425 } 451 }
426 452
427 /* Enable interrupts */ 453 /* Enable interrupts */
@@ -454,9 +480,6 @@ static int __init via_pmu_dev_init(void)
454 if (vias == NULL) 480 if (vias == NULL)
455 return -ENODEV; 481 return -ENODEV;
456 482
457#ifndef CONFIG_PPC64
458 request_OF_resource(vias, 0, NULL);
459#endif
460#ifdef CONFIG_PMAC_BACKLIGHT 483#ifdef CONFIG_PMAC_BACKLIGHT
461 /* Enable backlight */ 484 /* Enable backlight */
462 register_backlight_controller(&pmu_backlight_controller, NULL, "pmu"); 485 register_backlight_controller(&pmu_backlight_controller, NULL, "pmu");
@@ -1371,7 +1394,6 @@ next:
1371 } 1394 }
1372 pmu_done(req); 1395 pmu_done(req);
1373 } else { 1396 } else {
1374#if defined(CONFIG_XMON) && !defined(CONFIG_PPC64)
1375 if (len == 4 && data[1] == 0x2c) { 1397 if (len == 4 && data[1] == 0x2c) {
1376 extern int xmon_wants_key, xmon_adb_keycode; 1398 extern int xmon_wants_key, xmon_adb_keycode;
1377 if (xmon_wants_key) { 1399 if (xmon_wants_key) {
@@ -1379,7 +1401,6 @@ next:
1379 return; 1401 return;
1380 } 1402 }
1381 } 1403 }
1382#endif /* defined(CONFIG_XMON) && !defined(CONFIG_PPC64) */
1383#ifdef CONFIG_ADB 1404#ifdef CONFIG_ADB
1384 /* 1405 /*
1385 * XXX On the [23]400 the PMU gives us an up 1406 * XXX On the [23]400 the PMU gives us an up
@@ -1782,258 +1803,6 @@ pmu_present(void)
1782 return via != 0; 1803 return via != 0;
1783} 1804}
1784 1805
1785struct pmu_i2c_hdr {
1786 u8 bus;
1787 u8 mode;
1788 u8 bus2;
1789 u8 address;
1790 u8 sub_addr;
1791 u8 comb_addr;
1792 u8 count;
1793};
1794
1795int
1796pmu_i2c_combined_read(int bus, int addr, int subaddr, u8* data, int len)
1797{
1798 struct adb_request req;
1799 struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1];
1800 int retry;
1801 int rc;
1802
1803 for (retry=0; retry<16; retry++) {
1804 memset(&req, 0, sizeof(req));
1805
1806 hdr->bus = bus;
1807 hdr->address = addr & 0xfe;
1808 hdr->mode = PMU_I2C_MODE_COMBINED;
1809 hdr->bus2 = 0;
1810 hdr->sub_addr = subaddr;
1811 hdr->comb_addr = addr | 1;
1812 hdr->count = len;
1813
1814 req.nbytes = sizeof(struct pmu_i2c_hdr) + 1;
1815 req.reply_expected = 0;
1816 req.reply_len = 0;
1817 req.data[0] = PMU_I2C_CMD;
1818 req.reply[0] = 0xff;
1819 rc = pmu_queue_request(&req);
1820 if (rc)
1821 return rc;
1822 while(!req.complete)
1823 pmu_poll();
1824 if (req.reply[0] == PMU_I2C_STATUS_OK)
1825 break;
1826 mdelay(15);
1827 }
1828 if (req.reply[0] != PMU_I2C_STATUS_OK)
1829 return -1;
1830
1831 for (retry=0; retry<16; retry++) {
1832 memset(&req, 0, sizeof(req));
1833
1834 mdelay(15);
1835
1836 hdr->bus = PMU_I2C_BUS_STATUS;
1837 req.reply[0] = 0xff;
1838
1839 req.nbytes = 2;
1840 req.reply_expected = 0;
1841 req.reply_len = 0;
1842 req.data[0] = PMU_I2C_CMD;
1843 rc = pmu_queue_request(&req);
1844 if (rc)
1845 return rc;
1846 while(!req.complete)
1847 pmu_poll();
1848 if (req.reply[0] == PMU_I2C_STATUS_DATAREAD) {
1849 memcpy(data, &req.reply[1], req.reply_len - 1);
1850 return req.reply_len - 1;
1851 }
1852 }
1853 return -1;
1854}
1855
1856int
1857pmu_i2c_stdsub_write(int bus, int addr, int subaddr, u8* data, int len)
1858{
1859 struct adb_request req;
1860 struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1];
1861 int retry;
1862 int rc;
1863
1864 for (retry=0; retry<16; retry++) {
1865 memset(&req, 0, sizeof(req));
1866
1867 hdr->bus = bus;
1868 hdr->address = addr & 0xfe;
1869 hdr->mode = PMU_I2C_MODE_STDSUB;
1870 hdr->bus2 = 0;
1871 hdr->sub_addr = subaddr;
1872 hdr->comb_addr = addr & 0xfe;
1873 hdr->count = len;
1874
1875 req.data[0] = PMU_I2C_CMD;
1876 memcpy(&req.data[sizeof(struct pmu_i2c_hdr) + 1], data, len);
1877 req.nbytes = sizeof(struct pmu_i2c_hdr) + len + 1;
1878 req.reply_expected = 0;
1879 req.reply_len = 0;
1880 req.reply[0] = 0xff;
1881 rc = pmu_queue_request(&req);
1882 if (rc)
1883 return rc;
1884 while(!req.complete)
1885 pmu_poll();
1886 if (req.reply[0] == PMU_I2C_STATUS_OK)
1887 break;
1888 mdelay(15);
1889 }
1890 if (req.reply[0] != PMU_I2C_STATUS_OK)
1891 return -1;
1892
1893 for (retry=0; retry<16; retry++) {
1894 memset(&req, 0, sizeof(req));
1895
1896 mdelay(15);
1897
1898 hdr->bus = PMU_I2C_BUS_STATUS;
1899 req.reply[0] = 0xff;
1900
1901 req.nbytes = 2;
1902 req.reply_expected = 0;
1903 req.reply_len = 0;
1904 req.data[0] = PMU_I2C_CMD;
1905 rc = pmu_queue_request(&req);
1906 if (rc)
1907 return rc;
1908 while(!req.complete)
1909 pmu_poll();
1910 if (req.reply[0] == PMU_I2C_STATUS_OK)
1911 return len;
1912 }
1913 return -1;
1914}
1915
1916int
1917pmu_i2c_simple_read(int bus, int addr, u8* data, int len)
1918{
1919 struct adb_request req;
1920 struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1];
1921 int retry;
1922 int rc;
1923
1924 for (retry=0; retry<16; retry++) {
1925 memset(&req, 0, sizeof(req));
1926
1927 hdr->bus = bus;
1928 hdr->address = addr | 1;
1929 hdr->mode = PMU_I2C_MODE_SIMPLE;
1930 hdr->bus2 = 0;
1931 hdr->sub_addr = 0;
1932 hdr->comb_addr = 0;
1933 hdr->count = len;
1934
1935 req.data[0] = PMU_I2C_CMD;
1936 req.nbytes = sizeof(struct pmu_i2c_hdr) + 1;
1937 req.reply_expected = 0;
1938 req.reply_len = 0;
1939 req.reply[0] = 0xff;
1940 rc = pmu_queue_request(&req);
1941 if (rc)
1942 return rc;
1943 while(!req.complete)
1944 pmu_poll();
1945 if (req.reply[0] == PMU_I2C_STATUS_OK)
1946 break;
1947 mdelay(15);
1948 }
1949 if (req.reply[0] != PMU_I2C_STATUS_OK)
1950 return -1;
1951
1952 for (retry=0; retry<16; retry++) {
1953 memset(&req, 0, sizeof(req));
1954
1955 mdelay(15);
1956
1957 hdr->bus = PMU_I2C_BUS_STATUS;
1958 req.reply[0] = 0xff;
1959
1960 req.nbytes = 2;
1961 req.reply_expected = 0;
1962 req.reply_len = 0;
1963 req.data[0] = PMU_I2C_CMD;
1964 rc = pmu_queue_request(&req);
1965 if (rc)
1966 return rc;
1967 while(!req.complete)
1968 pmu_poll();
1969 if (req.reply[0] == PMU_I2C_STATUS_DATAREAD) {
1970 memcpy(data, &req.reply[1], req.reply_len - 1);
1971 return req.reply_len - 1;
1972 }
1973 }
1974 return -1;
1975}
1976
1977int
1978pmu_i2c_simple_write(int bus, int addr, u8* data, int len)
1979{
1980 struct adb_request req;
1981 struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1];
1982 int retry;
1983 int rc;
1984
1985 for (retry=0; retry<16; retry++) {
1986 memset(&req, 0, sizeof(req));
1987
1988 hdr->bus = bus;
1989 hdr->address = addr & 0xfe;
1990 hdr->mode = PMU_I2C_MODE_SIMPLE;
1991 hdr->bus2 = 0;
1992 hdr->sub_addr = 0;
1993 hdr->comb_addr = 0;
1994 hdr->count = len;
1995
1996 req.data[0] = PMU_I2C_CMD;
1997 memcpy(&req.data[sizeof(struct pmu_i2c_hdr) + 1], data, len);
1998 req.nbytes = sizeof(struct pmu_i2c_hdr) + len + 1;
1999 req.reply_expected = 0;
2000 req.reply_len = 0;
2001 req.reply[0] = 0xff;
2002 rc = pmu_queue_request(&req);
2003 if (rc)
2004 return rc;
2005 while(!req.complete)
2006 pmu_poll();
2007 if (req.reply[0] == PMU_I2C_STATUS_OK)
2008 break;
2009 mdelay(15);
2010 }
2011 if (req.reply[0] != PMU_I2C_STATUS_OK)
2012 return -1;
2013
2014 for (retry=0; retry<16; retry++) {
2015 memset(&req, 0, sizeof(req));
2016
2017 mdelay(15);
2018
2019 hdr->bus = PMU_I2C_BUS_STATUS;
2020 req.reply[0] = 0xff;
2021
2022 req.nbytes = 2;
2023 req.reply_expected = 0;
2024 req.reply_len = 0;
2025 req.data[0] = PMU_I2C_CMD;
2026 rc = pmu_queue_request(&req);
2027 if (rc)
2028 return rc;
2029 while(!req.complete)
2030 pmu_poll();
2031 if (req.reply[0] == PMU_I2C_STATUS_OK)
2032 return len;
2033 }
2034 return -1;
2035}
2036
2037#ifdef CONFIG_PM 1806#ifdef CONFIG_PM
2038 1807
2039static LIST_HEAD(sleep_notifiers); 1808static LIST_HEAD(sleep_notifiers);
@@ -2338,8 +2107,9 @@ pmac_suspend_devices(void)
2338 return -EBUSY; 2107 return -EBUSY;
2339 } 2108 }
2340 2109
2341 /* Disable clock spreading on some machines */ 2110 /* Call platform functions marked "on sleep" */
2342 pmac_tweak_clock_spreading(0); 2111 pmac_pfunc_i2c_suspend();
2112 pmac_pfunc_base_suspend();
2343 2113
2344 /* Stop preemption */ 2114 /* Stop preemption */
2345 preempt_disable(); 2115 preempt_disable();
@@ -2411,8 +2181,9 @@ pmac_wakeup_devices(void)
2411 mdelay(10); 2181 mdelay(10);
2412 preempt_enable(); 2182 preempt_enable();
2413 2183
2414 /* Re-enable clock spreading on some machines */ 2184 /* Call platform functions marked "on wake" */
2415 pmac_tweak_clock_spreading(1); 2185 pmac_pfunc_base_resume();
2186 pmac_pfunc_i2c_resume();
2416 2187
2417 /* Resume devices */ 2188 /* Resume devices */
2418 device_resume(); 2189 device_resume();
@@ -3130,16 +2901,13 @@ static int __init init_pmu_sysfs(void)
3130subsys_initcall(init_pmu_sysfs); 2901subsys_initcall(init_pmu_sysfs);
3131 2902
3132EXPORT_SYMBOL(pmu_request); 2903EXPORT_SYMBOL(pmu_request);
2904EXPORT_SYMBOL(pmu_queue_request);
3133EXPORT_SYMBOL(pmu_poll); 2905EXPORT_SYMBOL(pmu_poll);
3134EXPORT_SYMBOL(pmu_poll_adb); 2906EXPORT_SYMBOL(pmu_poll_adb);
3135EXPORT_SYMBOL(pmu_wait_complete); 2907EXPORT_SYMBOL(pmu_wait_complete);
3136EXPORT_SYMBOL(pmu_suspend); 2908EXPORT_SYMBOL(pmu_suspend);
3137EXPORT_SYMBOL(pmu_resume); 2909EXPORT_SYMBOL(pmu_resume);
3138EXPORT_SYMBOL(pmu_unlock); 2910EXPORT_SYMBOL(pmu_unlock);
3139EXPORT_SYMBOL(pmu_i2c_combined_read);
3140EXPORT_SYMBOL(pmu_i2c_stdsub_write);
3141EXPORT_SYMBOL(pmu_i2c_simple_read);
3142EXPORT_SYMBOL(pmu_i2c_simple_write);
3143#if defined(CONFIG_PM) && defined(CONFIG_PPC32) 2911#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
3144EXPORT_SYMBOL(pmu_enable_irled); 2912EXPORT_SYMBOL(pmu_enable_irled);
3145EXPORT_SYMBOL(pmu_battery_count); 2913EXPORT_SYMBOL(pmu_battery_count);
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index 57460e46c89f..906d3ecae6e6 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -21,6 +21,7 @@
21#include <asm/io.h> 21#include <asm/io.h>
22#include <asm/system.h> 22#include <asm/system.h>
23#include <asm/sections.h> 23#include <asm/sections.h>
24#include <asm/pmac_low_i2c.h>
24 25
25#include "windfarm.h" 26#include "windfarm.h"
26 27
@@ -157,53 +158,21 @@ static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter,
157 158
158static int wf_lm75_attach(struct i2c_adapter *adapter) 159static int wf_lm75_attach(struct i2c_adapter *adapter)
159{ 160{
160 u8 bus_id; 161 struct device_node *busnode, *dev;
161 struct device_node *smu, *bus, *dev; 162 struct pmac_i2c_bus *bus;
162
163 /* We currently only deal with LM75's hanging off the SMU
164 * i2c busses. If we extend that driver to other/older
165 * machines, we should split this function into SMU-i2c,
166 * keywest-i2c, PMU-i2c, ...
167 */
168 163
169 DBG("wf_lm75: adapter %s detected\n", adapter->name); 164 DBG("wf_lm75: adapter %s detected\n", adapter->name);
170 165
171 if (strncmp(adapter->name, "smu-i2c-", 8) != 0) 166 bus = pmac_i2c_adapter_to_bus(adapter);
172 return 0; 167 if (bus == NULL)
173 smu = of_find_node_by_type(NULL, "smu"); 168 return -ENODEV;
174 if (smu == NULL) 169 busnode = pmac_i2c_get_bus_node(bus);
175 return 0;
176
177 /* Look for the bus in the device-tree */
178 bus_id = (u8)simple_strtoul(adapter->name + 8, NULL, 16);
179
180 DBG("wf_lm75: bus ID is %x\n", bus_id);
181
182 /* Look for sensors subdir */
183 for (bus = NULL;
184 (bus = of_get_next_child(smu, bus)) != NULL;) {
185 u32 *reg;
186
187 if (strcmp(bus->name, "i2c"))
188 continue;
189 reg = (u32 *)get_property(bus, "reg", NULL);
190 if (reg == NULL)
191 continue;
192 if (bus_id == *reg)
193 break;
194 }
195 of_node_put(smu);
196 if (bus == NULL) {
197 printk(KERN_WARNING "windfarm: SMU i2c bus 0x%x not found"
198 " in device-tree !\n", bus_id);
199 return 0;
200 }
201 170
202 DBG("wf_lm75: bus found, looking for device...\n"); 171 DBG("wf_lm75: bus found, looking for device...\n");
203 172
204 /* Now look for lm75(s) in there */ 173 /* Now look for lm75(s) in there */
205 for (dev = NULL; 174 for (dev = NULL;
206 (dev = of_get_next_child(bus, dev)) != NULL;) { 175 (dev = of_get_next_child(busnode, dev)) != NULL;) {
207 const char *loc = 176 const char *loc =
208 get_property(dev, "hwsensor-location", NULL); 177 get_property(dev, "hwsensor-location", NULL);
209 u32 *reg = (u32 *)get_property(dev, "reg", NULL); 178 u32 *reg = (u32 *)get_property(dev, "reg", NULL);
@@ -217,9 +186,6 @@ static int wf_lm75_attach(struct i2c_adapter *adapter)
217 else if (device_is_compatible(dev, "ds1775")) 186 else if (device_is_compatible(dev, "ds1775"))
218 wf_lm75_create(adapter, *reg, 1, loc); 187 wf_lm75_create(adapter, *reg, 1, loc);
219 } 188 }
220
221 of_node_put(bus);
222
223 return 0; 189 return 0;
224} 190}
225 191
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
index 2c3158c81ff2..4d811600bdab 100644
--- a/drivers/macintosh/windfarm_smu_controls.c
+++ b/drivers/macintosh/windfarm_smu_controls.c
@@ -14,6 +14,7 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/wait.h> 16#include <linux/wait.h>
17#include <linux/completion.h>
17#include <asm/prom.h> 18#include <asm/prom.h>
18#include <asm/machdep.h> 19#include <asm/machdep.h>
19#include <asm/io.h> 20#include <asm/io.h>
diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c
index b558cc209d49..1a00d9c75a23 100644
--- a/drivers/macintosh/windfarm_smu_sensors.c
+++ b/drivers/macintosh/windfarm_smu_sensors.c
@@ -14,6 +14,7 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/wait.h> 16#include <linux/wait.h>
17#include <linux/completion.h>
17#include <asm/prom.h> 18#include <asm/prom.h>
18#include <asm/machdep.h> 19#include <asm/machdep.h>
19#include <asm/io.h> 20#include <asm/io.h>
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 1b76fb29fb70..e423a16ba3c9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3598,12 +3598,21 @@ static int set_disk_faulty(mddev_t *mddev, dev_t dev)
3598 return 0; 3598 return 0;
3599} 3599}
3600 3600
3601static int md_getgeo(struct block_device *bdev, struct hd_geometry *geo)
3602{
3603 mddev_t *mddev = bdev->bd_disk->private_data;
3604
3605 geo->heads = 2;
3606 geo->sectors = 4;
3607 geo->cylinders = get_capacity(mddev->gendisk) / 8;
3608 return 0;
3609}
3610
3601static int md_ioctl(struct inode *inode, struct file *file, 3611static int md_ioctl(struct inode *inode, struct file *file,
3602 unsigned int cmd, unsigned long arg) 3612 unsigned int cmd, unsigned long arg)
3603{ 3613{
3604 int err = 0; 3614 int err = 0;
3605 void __user *argp = (void __user *)arg; 3615 void __user *argp = (void __user *)arg;
3606 struct hd_geometry __user *loc = argp;
3607 mddev_t *mddev = NULL; 3616 mddev_t *mddev = NULL;
3608 3617
3609 if (!capable(CAP_SYS_ADMIN)) 3618 if (!capable(CAP_SYS_ADMIN))
@@ -3765,24 +3774,6 @@ static int md_ioctl(struct inode *inode, struct file *file,
3765 * 4 sectors (with a BIG number of cylinders...). This drives 3774 * 4 sectors (with a BIG number of cylinders...). This drives
3766 * dosfs just mad... ;-) 3775 * dosfs just mad... ;-)
3767 */ 3776 */
3768 case HDIO_GETGEO:
3769 if (!loc) {
3770 err = -EINVAL;
3771 goto abort_unlock;
3772 }
3773 err = put_user (2, (char __user *) &loc->heads);
3774 if (err)
3775 goto abort_unlock;
3776 err = put_user (4, (char __user *) &loc->sectors);
3777 if (err)
3778 goto abort_unlock;
3779 err = put_user(get_capacity(mddev->gendisk)/8,
3780 (short __user *) &loc->cylinders);
3781 if (err)
3782 goto abort_unlock;
3783 err = put_user (get_start_sect(inode->i_bdev),
3784 (long __user *) &loc->start);
3785 goto done_unlock;
3786 } 3777 }
3787 3778
3788 /* 3779 /*
@@ -3911,6 +3902,7 @@ static struct block_device_operations md_fops =
3911 .open = md_open, 3902 .open = md_open,
3912 .release = md_release, 3903 .release = md_release,
3913 .ioctl = md_ioctl, 3904 .ioctl = md_ioctl,
3905 .getgeo = md_getgeo,
3914 .media_changed = md_media_changed, 3906 .media_changed = md_media_changed,
3915 .revalidate_disk= md_revalidate, 3907 .revalidate_disk= md_revalidate,
3916}; 3908};
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index abbca150202b..d03f99cf4b7d 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -306,9 +306,6 @@ static int raid0_run (mddev_t *mddev)
306 printk("raid0 : conf->hash_spacing is %llu blocks.\n", 306 printk("raid0 : conf->hash_spacing is %llu blocks.\n",
307 (unsigned long long)conf->hash_spacing); 307 (unsigned long long)conf->hash_spacing);
308 { 308 {
309#if __GNUC__ < 3
310 volatile
311#endif
312 sector_t s = mddev->array_size; 309 sector_t s = mddev->array_size;
313 sector_t space = conf->hash_spacing; 310 sector_t space = conf->hash_spacing;
314 int round; 311 int round;
@@ -439,9 +436,6 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
439 436
440 437
441 { 438 {
442#if __GNUC__ < 3
443 volatile
444#endif
445 sector_t x = block >> conf->preshift; 439 sector_t x = block >> conf->preshift;
446 sector_div(x, (u32)conf->hash_spacing); 440 sector_div(x, (u32)conf->hash_spacing);
447 zone = conf->hash_table[x]; 441 zone = conf->hash_table[x];
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 09ec964dec5c..b614612be7b4 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -253,7 +253,10 @@ static int fops_open(struct inode *inode, struct file *file)
253 253
254 if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 254 if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
255 DEB_S(("initializing vbi...\n")); 255 DEB_S(("initializing vbi...\n"));
256 result = saa7146_vbi_uops.open(dev,file); 256 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
257 result = saa7146_vbi_uops.open(dev,file);
258 if (dev->ext_vv_data->vbi_fops.open)
259 dev->ext_vv_data->vbi_fops.open(inode, file);
257 } else { 260 } else {
258 DEB_S(("initializing video...\n")); 261 DEB_S(("initializing video...\n"));
259 result = saa7146_video_uops.open(dev,file); 262 result = saa7146_video_uops.open(dev,file);
@@ -289,7 +292,10 @@ static int fops_release(struct inode *inode, struct file *file)
289 return -ERESTARTSYS; 292 return -ERESTARTSYS;
290 293
291 if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 294 if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
292 saa7146_vbi_uops.release(dev,file); 295 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
296 saa7146_vbi_uops.release(dev,file);
297 if (dev->ext_vv_data->vbi_fops.release)
298 dev->ext_vv_data->vbi_fops.release(inode, file);
293 } else { 299 } else {
294 saa7146_video_uops.release(dev,file); 300 saa7146_video_uops.release(dev,file);
295 } 301 }
@@ -332,6 +338,7 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma)
332 BUG(); 338 BUG();
333 return 0; 339 return 0;
334 } 340 }
341
335 return videobuf_mmap_mapper(q,vma); 342 return videobuf_mmap_mapper(q,vma);
336} 343}
337 344
@@ -381,7 +388,10 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof
381 } 388 }
382 case V4L2_BUF_TYPE_VBI_CAPTURE: { 389 case V4L2_BUF_TYPE_VBI_CAPTURE: {
383// DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count)); 390// DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count));
384 return saa7146_vbi_uops.read(file,data,count,ppos); 391 if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
392 return saa7146_vbi_uops.read(file,data,count,ppos);
393 else
394 return -EINVAL;
385 } 395 }
386 break; 396 break;
387 default: 397 default:
@@ -390,12 +400,31 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof
390 } 400 }
391} 401}
392 402
403static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
404{
405 struct saa7146_fh *fh = file->private_data;
406
407 switch (fh->type) {
408 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
409 return -EINVAL;
410 case V4L2_BUF_TYPE_VBI_CAPTURE:
411 if (fh->dev->ext_vv_data->vbi_fops.write)
412 return fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos);
413 else
414 return -EINVAL;
415 default:
416 BUG();
417 return -EINVAL;
418 }
419}
420
393static struct file_operations video_fops = 421static struct file_operations video_fops =
394{ 422{
395 .owner = THIS_MODULE, 423 .owner = THIS_MODULE,
396 .open = fops_open, 424 .open = fops_open,
397 .release = fops_release, 425 .release = fops_release,
398 .read = fops_read, 426 .read = fops_read,
427 .write = fops_write,
399 .poll = fops_poll, 428 .poll = fops_poll,
400 .mmap = fops_mmap, 429 .mmap = fops_mmap,
401 .ioctl = fops_ioctl, 430 .ioctl = fops_ioctl,
@@ -467,7 +496,8 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
467 memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM); 496 memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM);
468 497
469 saa7146_video_uops.init(dev,vv); 498 saa7146_video_uops.init(dev,vv);
470 saa7146_vbi_uops.init(dev,vv); 499 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
500 saa7146_vbi_uops.init(dev,vv);
471 501
472 dev->vv_data = vv; 502 dev->vv_data = vv;
473 dev->vv_callback = &vv_callback; 503 dev->vv_callback = &vv_callback;
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c
index ec52dff8cb69..33bec8a6843b 100644
--- a/drivers/media/common/saa7146_hlp.c
+++ b/drivers/media/common/saa7146_hlp.c
@@ -562,19 +562,26 @@ static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int
562 562
563 int b_depth = vv->ov_fmt->depth; 563 int b_depth = vv->ov_fmt->depth;
564 int b_bpl = vv->ov_fb.fmt.bytesperline; 564 int b_bpl = vv->ov_fb.fmt.bytesperline;
565 u32 base = (u32)vv->ov_fb.base; 565 /* The unsigned long cast is to remove a 64-bit compile warning since
566 it looks like a 64-bit address is cast to a 32-bit value, even
567 though the base pointer is really a 32-bit physical address that
568 goes into a 32-bit DMA register.
569 FIXME: might not work on some 64-bit platforms, but see the FIXME
570 in struct v4l2_framebuffer (videodev2.h) for that.
571 */
572 u32 base = (u32)(unsigned long)vv->ov_fb.base;
566 573
567 struct saa7146_video_dma vdma1; 574 struct saa7146_video_dma vdma1;
568 575
569 /* calculate memory offsets for picture, look if we shall top-down-flip */ 576 /* calculate memory offsets for picture, look if we shall top-down-flip */
570 vdma1.pitch = 2*b_bpl; 577 vdma1.pitch = 2*b_bpl;
571 if ( 0 == vv->vflip ) { 578 if ( 0 == vv->vflip ) {
572 vdma1.base_even = (u32)base + (w_y * (vdma1.pitch/2)) + (w_x * (b_depth / 8)); 579 vdma1.base_even = base + (w_y * (vdma1.pitch/2)) + (w_x * (b_depth / 8));
573 vdma1.base_odd = vdma1.base_even + (vdma1.pitch / 2); 580 vdma1.base_odd = vdma1.base_even + (vdma1.pitch / 2);
574 vdma1.prot_addr = vdma1.base_even + (w_height * (vdma1.pitch / 2)); 581 vdma1.prot_addr = vdma1.base_even + (w_height * (vdma1.pitch / 2));
575 } 582 }
576 else { 583 else {
577 vdma1.base_even = (u32)base + ((w_y+w_height) * (vdma1.pitch/2)) + (w_x * (b_depth / 8)); 584 vdma1.base_even = base + ((w_y+w_height) * (vdma1.pitch/2)) + (w_x * (b_depth / 8));
578 vdma1.base_odd = vdma1.base_even - (vdma1.pitch / 2); 585 vdma1.base_odd = vdma1.base_even - (vdma1.pitch / 2);
579 vdma1.prot_addr = vdma1.base_odd - (w_height * (vdma1.pitch / 2)); 586 vdma1.prot_addr = vdma1.base_odd - (w_height * (vdma1.pitch / 2));
580 } 587 }
diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c
index 063986ec16b5..468d3c959075 100644
--- a/drivers/media/common/saa7146_vbi.c
+++ b/drivers/media/common/saa7146_vbi.c
@@ -500,9 +500,9 @@ static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff
500} 500}
501 501
502struct saa7146_use_ops saa7146_vbi_uops = { 502struct saa7146_use_ops saa7146_vbi_uops = {
503 .init = vbi_init, 503 .init = vbi_init,
504 .open = vbi_open, 504 .open = vbi_open,
505 .release = vbi_close, 505 .release = vbi_close,
506 .irq_done = vbi_irq_done, 506 .irq_done = vbi_irq_done,
507 .read = vbi_read, 507 .read = vbi_read,
508}; 508};
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 1d961023b837..7ebac7949df3 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -151,8 +151,8 @@ static int try_win(struct saa7146_dev *dev, struct v4l2_window *win)
151 151
152 if (V4L2_FIELD_ANY == field) { 152 if (V4L2_FIELD_ANY == field) {
153 field = (win->w.height > maxh/2) 153 field = (win->w.height > maxh/2)
154 ? V4L2_FIELD_INTERLACED 154 ? V4L2_FIELD_INTERLACED
155 : V4L2_FIELD_TOP; 155 : V4L2_FIELD_TOP;
156 } 156 }
157 switch (field) { 157 switch (field) {
158 case V4L2_FIELD_TOP: 158 case V4L2_FIELD_TOP:
@@ -1114,10 +1114,6 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
1114 return 0; 1114 return 0;
1115 } 1115 }
1116 case VIDIOC_OVERLAY: 1116 case VIDIOC_OVERLAY:
1117
1118
1119
1120
1121 { 1117 {
1122 int on = *(int *)arg; 1118 int on = *(int *)arg;
1123 int err = 0; 1119 int err = 0;
@@ -1359,7 +1355,6 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1359 saa7146_buffer_queue(fh->dev,&vv->video_q,buf); 1355 saa7146_buffer_queue(fh->dev,&vv->video_q,buf);
1360} 1356}
1361 1357
1362
1363static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) 1358static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1364{ 1359{
1365 struct file *file = q->priv_data; 1360 struct file *file = q->priv_data;
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 21a9045b3ef6..0b940e152b79 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -298,7 +298,7 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir
298} 298}
299 299
300static int lgdt3303_pll_set(struct dvb_frontend* fe, 300static int lgdt3303_pll_set(struct dvb_frontend* fe,
301 struct dvb_frontend_parameters* params) 301 struct dvb_frontend_parameters* params)
302{ 302{
303 struct flexcop_device *fc = fe->dvb->priv; 303 struct flexcop_device *fc = fe->dvb->priv;
304 u8 buf[4]; 304 u8 buf[4];
@@ -485,12 +485,16 @@ static struct stv0297_config alps_tdee4_stv0297_config = {
485/* try to figure out the frontend, each card/box can have on of the following list */ 485/* try to figure out the frontend, each card/box can have on of the following list */
486int flexcop_frontend_init(struct flexcop_device *fc) 486int flexcop_frontend_init(struct flexcop_device *fc)
487{ 487{
488 struct dvb_frontend_ops *ops;
489
488 /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ 490 /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
489 if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { 491 if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) {
490 fc->fe->ops->set_voltage = flexcop_set_voltage; 492 ops = fc->fe->ops;
493
494 ops->set_voltage = flexcop_set_voltage;
491 495
492 fc->fe_sleep = fc->fe->ops->sleep; 496 fc->fe_sleep = ops->sleep;
493 fc->fe->ops->sleep = flexcop_sleep; 497 ops->sleep = flexcop_sleep;
494 498
495 fc->dev_type = FC_SKY; 499 fc->dev_type = FC_SKY;
496 info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address); 500 info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address);
@@ -522,15 +526,17 @@ int flexcop_frontend_init(struct flexcop_device *fc)
522 } else 526 } else
523 /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ 527 /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
524 if ((fc->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { 528 if ((fc->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
525 fc->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; 529 ops = fc->fe->ops;
526 fc->fe->ops->diseqc_send_burst = flexcop_diseqc_send_burst; 530
527 fc->fe->ops->set_tone = flexcop_set_tone; 531 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
528 fc->fe->ops->set_voltage = flexcop_set_voltage; 532 ops->diseqc_send_burst = flexcop_diseqc_send_burst;
533 ops->set_tone = flexcop_set_tone;
534 ops->set_voltage = flexcop_set_voltage;
529 535
530 fc->fe_sleep = fc->fe->ops->sleep; 536 fc->fe_sleep = ops->sleep;
531 fc->fe->ops->sleep = flexcop_sleep; 537 ops->sleep = flexcop_sleep;
532 538
533 fc->dev_type = FC_SKY_OLD; 539 fc->dev_type = FC_SKY_OLD;
534 info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address); 540 info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address);
535 } 541 }
536 542
@@ -540,8 +546,9 @@ int flexcop_frontend_init(struct flexcop_device *fc)
540 } else { 546 } else {
541 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { 547 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
542 err("frontend registration failed!"); 548 err("frontend registration failed!");
543 if (fc->fe->ops->release != NULL) 549 ops = fc->fe->ops;
544 fc->fe->ops->release(fc->fe); 550 if (ops->release != NULL)
551 ops->release(fc->fe);
545 fc->fe = NULL; 552 fc->fe = NULL;
546 return -EINVAL; 553 return -EINVAL;
547 } 554 }
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 23cc6431e2b8..3153f9513c63 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -39,11 +39,13 @@ extern const char *flexcop_device_names[];
39/* FlexCop IBI Registers */ 39/* FlexCop IBI Registers */
40#if defined(__LITTLE_ENDIAN) 40#if defined(__LITTLE_ENDIAN)
41 #include "flexcop_ibi_value_le.h" 41 #include "flexcop_ibi_value_le.h"
42#elif defined(__BIG_ENDIAN) 42#else
43#if defined(__BIG_ENDIAN)
43 #include "flexcop_ibi_value_be.h" 44 #include "flexcop_ibi_value_be.h"
44#else 45#else
45 #error no endian defined 46 #error no endian defined
46#endif 47#endif
48#endif
47 49
48#define fc_data_Tag_ID_DVB 0x3e 50#define fc_data_Tag_ID_DVB 0x3e
49#define fc_data_Tag_ID_ATSC 0x3f 51#define fc_data_Tag_ID_ATSC 0x3f
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 8977c7a313df..3a2ff1cc24b7 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1341,30 +1341,40 @@ static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
1341 return 0; 1341 return 0;
1342} 1342}
1343 1343
1344static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) 1344static int dst_set_frontend(struct dvb_frontend* fe,
1345 struct dvb_frontend_parameters* p,
1346 unsigned int mode_flags,
1347 int *delay,
1348 fe_status_t *status)
1345{ 1349{
1346 struct dst_state *state = fe->demodulator_priv; 1350 struct dst_state *state = fe->demodulator_priv;
1347 1351
1348 dst_set_freq(state, p->frequency); 1352 if (p != NULL) {
1349 dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); 1353 dst_set_freq(state, p->frequency);
1354 dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
1350 1355
1351 if (state->dst_type == DST_TYPE_IS_SAT) { 1356 if (state->dst_type == DST_TYPE_IS_SAT) {
1352 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) 1357 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1353 dst_set_inversion(state, p->inversion); 1358 dst_set_inversion(state, p->inversion);
1354 dst_set_fec(state, p->u.qpsk.fec_inner); 1359 dst_set_fec(state, p->u.qpsk.fec_inner);
1355 dst_set_symbolrate(state, p->u.qpsk.symbol_rate); 1360 dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
1356 dst_set_polarization(state); 1361 dst_set_polarization(state);
1357 dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); 1362 dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate);
1358 1363
1359 } else if (state->dst_type == DST_TYPE_IS_TERR) 1364 } else if (state->dst_type == DST_TYPE_IS_TERR)
1360 dst_set_bandwidth(state, p->u.ofdm.bandwidth); 1365 dst_set_bandwidth(state, p->u.ofdm.bandwidth);
1361 else if (state->dst_type == DST_TYPE_IS_CABLE) { 1366 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1362 dst_set_fec(state, p->u.qam.fec_inner); 1367 dst_set_fec(state, p->u.qam.fec_inner);
1363 dst_set_symbolrate(state, p->u.qam.symbol_rate); 1368 dst_set_symbolrate(state, p->u.qam.symbol_rate);
1364 dst_set_modulation(state, p->u.qam.modulation); 1369 dst_set_modulation(state, p->u.qam.modulation);
1370 }
1371 dst_write_tuna(fe);
1365 } 1372 }
1366 dst_write_tuna(fe);
1367 1373
1374 if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
1375 dst_read_status(fe, status);
1376
1377 *delay = HZ/10;
1368 return 0; 1378 return 0;
1369} 1379}
1370 1380
@@ -1445,7 +1455,7 @@ static struct dvb_frontend_ops dst_dvbt_ops = {
1445 1455
1446 .release = dst_release, 1456 .release = dst_release,
1447 .init = dst_init, 1457 .init = dst_init,
1448 .set_frontend = dst_set_frontend, 1458 .tune = dst_set_frontend,
1449 .get_frontend = dst_get_frontend, 1459 .get_frontend = dst_get_frontend,
1450 .read_status = dst_read_status, 1460 .read_status = dst_read_status,
1451 .read_signal_strength = dst_read_signal_strength, 1461 .read_signal_strength = dst_read_signal_strength,
@@ -1469,7 +1479,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = {
1469 1479
1470 .release = dst_release, 1480 .release = dst_release,
1471 .init = dst_init, 1481 .init = dst_init,
1472 .set_frontend = dst_set_frontend, 1482 .tune = dst_set_frontend,
1473 .get_frontend = dst_get_frontend, 1483 .get_frontend = dst_get_frontend,
1474 .read_status = dst_read_status, 1484 .read_status = dst_read_status,
1475 .read_signal_strength = dst_read_signal_strength, 1485 .read_signal_strength = dst_read_signal_strength,
@@ -1496,7 +1506,7 @@ static struct dvb_frontend_ops dst_dvbc_ops = {
1496 1506
1497 .release = dst_release, 1507 .release = dst_release,
1498 .init = dst_init, 1508 .init = dst_init,
1499 .set_frontend = dst_set_frontend, 1509 .tune = dst_set_frontend,
1500 .get_frontend = dst_get_frontend, 1510 .get_frontend = dst_get_frontend,
1501 .read_status = dst_read_status, 1511 .read_status = dst_read_status,
1502 .read_signal_strength = dst_read_signal_strength, 1512 .read_signal_strength = dst_read_signal_strength,
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 2239651969c8..c650b4bf7f5f 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -283,16 +283,17 @@ static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message,
283 hw_buffer->msg[4] = 0x03; 283 hw_buffer->msg[4] = 0x03;
284 hw_buffer->msg[5] = length & 0xff; 284 hw_buffer->msg[5] = length & 0xff;
285 hw_buffer->msg[6] = 0x00; 285 hw_buffer->msg[6] = 0x00;
286
286 /* 287 /*
287 * Need to compute length for EN50221 section 8.3.2, for the time being 288 * Need to compute length for EN50221 section 8.3.2, for the time being
288 * assuming 8.3.2 is not applicable 289 * assuming 8.3.2 is not applicable
289 */ 290 */
290 memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length); 291 memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length);
291 } 292 }
293
292 return 0; 294 return 0;
293} 295}
294 296
295
296static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply) 297static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply)
297{ 298{
298 if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) { 299 if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) {
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index 77977e9c013e..01b4e0aac049 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -600,7 +600,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
600 struct dst_state* state = NULL; 600 struct dst_state* state = NULL;
601 601
602 switch(type) { 602 switch(type) {
603#ifdef BTTV_BOARD_DVICO_DVBT_LITE
604 case BTTV_BOARD_DVICO_DVBT_LITE: 603 case BTTV_BOARD_DVICO_DVBT_LITE:
605 card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); 604 card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter);
606 if (card->fe != NULL) { 605 if (card->fe != NULL) {
@@ -608,22 +607,15 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
608 card->fe->ops->info.frequency_max = 862000000; 607 card->fe->ops->info.frequency_max = 862000000;
609 } 608 }
610 break; 609 break;
611#endif
612 610
613#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
614 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: 611 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
615 lgdt330x_reset(card); 612 lgdt330x_reset(card);
616 card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); 613 card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter);
617 if (card->fe != NULL) 614 if (card->fe != NULL)
618 dprintk ("dvb_bt8xx: lgdt330x detected\n"); 615 dprintk ("dvb_bt8xx: lgdt330x detected\n");
619 break; 616 break;
620#endif
621 617
622#ifdef BTTV_BOARD_TWINHAN_VP3021
623 case BTTV_BOARD_TWINHAN_VP3021:
624#else
625 case BTTV_BOARD_NEBULA_DIGITV: 618 case BTTV_BOARD_NEBULA_DIGITV:
626#endif
627 /* 619 /*
628 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); 620 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
629 * this would be a cleaner solution than trying each frontend in turn. 621 * this would be a cleaner solution than trying each frontend in turn.
@@ -812,9 +804,7 @@ static int dvb_bt8xx_probe(struct device *dev)
812 card->irq_err_ignore = 0; 804 card->irq_err_ignore = 0;
813 break; 805 break;
814 806
815#ifdef BTTV_BOARD_DVICO_DVBT_LITE
816 case BTTV_BOARD_DVICO_DVBT_LITE: 807 case BTTV_BOARD_DVICO_DVBT_LITE:
817#endif
818 card->gpio_mode = 0x0400C060; 808 card->gpio_mode = 0x0400C060;
819 card->op_sync_orin = 0; 809 card->op_sync_orin = 0;
820 card->irq_err_ignore = 0; 810 card->irq_err_ignore = 0;
@@ -823,19 +813,13 @@ static int dvb_bt8xx_probe(struct device *dev)
823 * DA_APP(parallel) */ 813 * DA_APP(parallel) */
824 break; 814 break;
825 815
826#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
827 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: 816 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
828#endif
829 card->gpio_mode = 0x0400c060; 817 card->gpio_mode = 0x0400c060;
830 card->op_sync_orin = BT878_RISC_SYNC_MASK; 818 card->op_sync_orin = BT878_RISC_SYNC_MASK;
831 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; 819 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
832 break; 820 break;
833 821
834#ifdef BTTV_BOARD_TWINHAN_VP3021
835 case BTTV_BOARD_TWINHAN_VP3021:
836#else
837 case BTTV_BOARD_NEBULA_DIGITV: 822 case BTTV_BOARD_NEBULA_DIGITV:
838#endif
839 case BTTV_BOARD_AVDVBT_761: 823 case BTTV_BOARD_AVDVBT_761:
840 card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); 824 card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
841 card->op_sync_orin = 0; 825 card->op_sync_orin = 0;
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig
index 7cf4c4a888ec..6018fcdba1e6 100644
--- a/drivers/media/dvb/cinergyT2/Kconfig
+++ b/drivers/media/dvb/cinergyT2/Kconfig
@@ -21,35 +21,35 @@ config DVB_CINERGYT2_TUNING
21config DVB_CINERGYT2_STREAM_URB_COUNT 21config DVB_CINERGYT2_STREAM_URB_COUNT
22 int "Number of queued USB Request Blocks for Highspeed Stream Transfers" 22 int "Number of queued USB Request Blocks for Highspeed Stream Transfers"
23 depends on DVB_CINERGYT2_TUNING 23 depends on DVB_CINERGYT2_TUNING
24 default "32" 24 default "32"
25 help 25 help
26 USB Request Blocks for Highspeed Stream transfers are scheduled in 26 USB Request Blocks for Highspeed Stream transfers are scheduled in
27 a queue for the Host Controller. 27 a queue for the Host Controller.
28 28
29 Usually the default value is a safe choice. 29 Usually the default value is a safe choice.
30 30
31 You may increase this number if you are using this device in a 31 You may increase this number if you are using this device in a
32 Server Environment with many high-traffic USB Highspeed devices 32 Server Environment with many high-traffic USB Highspeed devices
33 sharing the same USB bus. 33 sharing the same USB bus.
34 34
35 35
36config DVB_CINERGYT2_STREAM_BUF_SIZE 36config DVB_CINERGYT2_STREAM_BUF_SIZE
37 int "Size of URB Stream Buffers for Highspeed Transfers" 37 int "Size of URB Stream Buffers for Highspeed Transfers"
38 depends on DVB_CINERGYT2_TUNING 38 depends on DVB_CINERGYT2_TUNING
39 default "512" 39 default "512"
40 help 40 help
41 Should be a multiple of native buffer size of 512 bytes. 41 Should be a multiple of native buffer size of 512 bytes.
42 Default value is a safe choice. 42 Default value is a safe choice.
43 43
44 You may increase this number if you are using this device in a 44 You may increase this number if you are using this device in a
45 Server Environment with many high-traffic USB Highspeed devices 45 Server Environment with many high-traffic USB Highspeed devices
46 sharing the same USB bus. 46 sharing the same USB bus.
47 47
48 48
49config DVB_CINERGYT2_QUERY_INTERVAL 49config DVB_CINERGYT2_QUERY_INTERVAL
50 int "Status update interval [milliseconds]" 50 int "Status update interval [milliseconds]"
51 depends on DVB_CINERGYT2_TUNING 51 depends on DVB_CINERGYT2_TUNING
52 default "250" 52 default "250"
53 help 53 help
54 This is the interval for status readouts from the demodulator. 54 This is the interval for status readouts from the demodulator.
55 You may try lower values if you need more responsive signal quality 55 You may try lower values if you need more responsive signal quality
@@ -64,9 +64,9 @@ config DVB_CINERGYT2_QUERY_INTERVAL
64config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE 64config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
65 bool "Register the onboard IR Remote Control Receiver as Input Device" 65 bool "Register the onboard IR Remote Control Receiver as Input Device"
66 depends on DVB_CINERGYT2_TUNING 66 depends on DVB_CINERGYT2_TUNING
67 default "yes" 67 default "yes"
68 help 68 help
69 Enable this option if you want to use the onboard Infrared Remote 69 Enable this option if you want to use the onboard Infrared Remote
70 Control Receiver as Linux-Input device. 70 Control Receiver as Linux-Input device.
71 71
72 Right now only the keycode table for the default Remote Control 72 Right now only the keycode table for the default Remote Control
@@ -77,7 +77,7 @@ config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
77config DVB_CINERGYT2_RC_QUERY_INTERVAL 77config DVB_CINERGYT2_RC_QUERY_INTERVAL
78 int "Infrared Remote Controller update interval [milliseconds]" 78 int "Infrared Remote Controller update interval [milliseconds]"
79 depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE 79 depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
80 default "50" 80 default "50"
81 help 81 help
82 If you have a very fast-repeating remote control you can try lower 82 If you have a very fast-repeating remote control you can try lower
83 values, for normal consumer receivers the default value should be 83 values, for normal consumer receivers the default value should be
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 1d69bf031fb9..c4b4c5b6b7c8 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -131,6 +131,8 @@ struct cinergyt2 {
131 131
132 wait_queue_head_t poll_wq; 132 wait_queue_head_t poll_wq;
133 int pending_fe_events; 133 int pending_fe_events;
134 int disconnect_pending;
135 atomic_t inuse;
134 136
135 void *streambuf; 137 void *streambuf;
136 dma_addr_t streambuf_dmahandle; 138 dma_addr_t streambuf_dmahandle;
@@ -343,7 +345,7 @@ static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed)
343 struct dvb_demux *demux = dvbdmxfeed->demux; 345 struct dvb_demux *demux = dvbdmxfeed->demux;
344 struct cinergyt2 *cinergyt2 = demux->priv; 346 struct cinergyt2 *cinergyt2 = demux->priv;
345 347
346 if (down_interruptible(&cinergyt2->sem)) 348 if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
347 return -ERESTARTSYS; 349 return -ERESTARTSYS;
348 350
349 if (cinergyt2->streaming == 0) 351 if (cinergyt2->streaming == 0)
@@ -359,7 +361,7 @@ static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
359 struct dvb_demux *demux = dvbdmxfeed->demux; 361 struct dvb_demux *demux = dvbdmxfeed->demux;
360 struct cinergyt2 *cinergyt2 = demux->priv; 362 struct cinergyt2 *cinergyt2 = demux->priv;
361 363
362 if (down_interruptible(&cinergyt2->sem)) 364 if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
363 return -ERESTARTSYS; 365 return -ERESTARTSYS;
364 366
365 if (--cinergyt2->streaming == 0) 367 if (--cinergyt2->streaming == 0)
@@ -479,23 +481,37 @@ static int cinergyt2_open (struct inode *inode, struct file *file)
479{ 481{
480 struct dvb_device *dvbdev = file->private_data; 482 struct dvb_device *dvbdev = file->private_data;
481 struct cinergyt2 *cinergyt2 = dvbdev->priv; 483 struct cinergyt2 *cinergyt2 = dvbdev->priv;
482 int err; 484 int err = -ERESTARTSYS;
483 485
484 if ((err = dvb_generic_open(inode, file))) 486 if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
487 return -ERESTARTSYS;
488
489 if ((err = dvb_generic_open(inode, file))) {
490 up(&cinergyt2->sem);
485 return err; 491 return err;
492 }
486 493
487 if (down_interruptible(&cinergyt2->sem))
488 return -ERESTARTSYS;
489 494
490 if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 495 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
491 cinergyt2_sleep(cinergyt2, 0); 496 cinergyt2_sleep(cinergyt2, 0);
492 schedule_delayed_work(&cinergyt2->query_work, HZ/2); 497 schedule_delayed_work(&cinergyt2->query_work, HZ/2);
493 } 498 }
494 499
500 atomic_inc(&cinergyt2->inuse);
501
495 up(&cinergyt2->sem); 502 up(&cinergyt2->sem);
496 return 0; 503 return 0;
497} 504}
498 505
506static void cinergyt2_unregister(struct cinergyt2 *cinergyt2)
507{
508 dvb_unregister_device(cinergyt2->fedev);
509 dvb_unregister_adapter(&cinergyt2->adapter);
510
511 cinergyt2_free_stream_urbs(cinergyt2);
512 kfree(cinergyt2);
513}
514
499static int cinergyt2_release (struct inode *inode, struct file *file) 515static int cinergyt2_release (struct inode *inode, struct file *file)
500{ 516{
501 struct dvb_device *dvbdev = file->private_data; 517 struct dvb_device *dvbdev = file->private_data;
@@ -504,7 +520,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file)
504 if (down_interruptible(&cinergyt2->sem)) 520 if (down_interruptible(&cinergyt2->sem))
505 return -ERESTARTSYS; 521 return -ERESTARTSYS;
506 522
507 if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 523 if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) {
508 cancel_delayed_work(&cinergyt2->query_work); 524 cancel_delayed_work(&cinergyt2->query_work);
509 flush_scheduled_work(); 525 flush_scheduled_work();
510 cinergyt2_sleep(cinergyt2, 1); 526 cinergyt2_sleep(cinergyt2, 1);
@@ -512,6 +528,11 @@ static int cinergyt2_release (struct inode *inode, struct file *file)
512 528
513 up(&cinergyt2->sem); 529 up(&cinergyt2->sem);
514 530
531 if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) {
532 warn("delayed unregister in release");
533 cinergyt2_unregister(cinergyt2);
534 }
535
515 return dvb_generic_release(inode, file); 536 return dvb_generic_release(inode, file);
516} 537}
517 538
@@ -519,7 +540,14 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct
519{ 540{
520 struct dvb_device *dvbdev = file->private_data; 541 struct dvb_device *dvbdev = file->private_data;
521 struct cinergyt2 *cinergyt2 = dvbdev->priv; 542 struct cinergyt2 *cinergyt2 = dvbdev->priv;
543
544 if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
545 return -ERESTARTSYS;
546
522 poll_wait(file, &cinergyt2->poll_wq, wait); 547 poll_wait(file, &cinergyt2->poll_wq, wait);
548
549 up(&cinergyt2->sem);
550
523 return (POLLIN | POLLRDNORM | POLLPRI); 551 return (POLLIN | POLLRDNORM | POLLPRI);
524} 552}
525 553
@@ -564,10 +592,15 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file,
564 (__u16 __user *) arg); 592 (__u16 __user *) arg);
565 593
566 case FE_READ_UNCORRECTED_BLOCKS: 594 case FE_READ_UNCORRECTED_BLOCKS:
567 /* UNC are already converted to host byte order... */ 595 {
568 return put_user(stat->uncorrected_block_count, 596 uint32_t unc_count;
569 (__u32 __user *) arg); 597
598 unc_count = stat->uncorrected_block_count;
599 stat->uncorrected_block_count = 0;
570 600
601 /* UNC are already converted to host byte order... */
602 return put_user(unc_count,(__u32 __user *) arg);
603 }
571 case FE_SET_FRONTEND: 604 case FE_SET_FRONTEND:
572 { 605 {
573 struct dvbt_set_parameters_msg *param = &cinergyt2->param; 606 struct dvbt_set_parameters_msg *param = &cinergyt2->param;
@@ -580,7 +613,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file,
580 if (copy_from_user(&p, (void __user*) arg, sizeof(p))) 613 if (copy_from_user(&p, (void __user*) arg, sizeof(p)))
581 return -EFAULT; 614 return -EFAULT;
582 615
583 if (down_interruptible(&cinergyt2->sem)) 616 if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
584 return -ERESTARTSYS; 617 return -ERESTARTSYS;
585 618
586 param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; 619 param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
@@ -691,7 +724,7 @@ static void cinergyt2_query_rc (void *data)
691 struct cinergyt2_rc_event rc_events[12]; 724 struct cinergyt2_rc_event rc_events[12];
692 int n, len, i; 725 int n, len, i;
693 726
694 if (down_interruptible(&cinergyt2->sem)) 727 if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
695 return; 728 return;
696 729
697 len = cinergyt2_command(cinergyt2, buf, sizeof(buf), 730 len = cinergyt2_command(cinergyt2, buf, sizeof(buf),
@@ -786,7 +819,6 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
786static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) 819static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2)
787{ 820{
788 cancel_delayed_work(&cinergyt2->rc_query_work); 821 cancel_delayed_work(&cinergyt2->rc_query_work);
789 flush_scheduled_work();
790 input_unregister_device(cinergyt2->rc_input_dev); 822 input_unregister_device(cinergyt2->rc_input_dev);
791} 823}
792 824
@@ -817,7 +849,7 @@ static void cinergyt2_query (void *data)
817 uint8_t lock_bits; 849 uint8_t lock_bits;
818 uint32_t unc; 850 uint32_t unc;
819 851
820 if (down_interruptible(&cinergyt2->sem)) 852 if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
821 return; 853 return;
822 854
823 unc = s->uncorrected_block_count; 855 unc = s->uncorrected_block_count;
@@ -917,28 +949,25 @@ static void cinergyt2_disconnect (struct usb_interface *intf)
917{ 949{
918 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); 950 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
919 951
920 if (down_interruptible(&cinergyt2->sem)) 952 flush_scheduled_work();
921 return;
922 953
923 cinergyt2_unregister_rc(cinergyt2); 954 cinergyt2_unregister_rc(cinergyt2);
924 955
956 cancel_delayed_work(&cinergyt2->query_work);
957 wake_up_interruptible(&cinergyt2->poll_wq);
958
925 cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx); 959 cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx);
926 dvb_net_release(&cinergyt2->dvbnet); 960 cinergyt2->disconnect_pending = 1;
927 dvb_dmxdev_release(&cinergyt2->dmxdev);
928 dvb_dmx_release(&cinergyt2->demux);
929 dvb_unregister_device(cinergyt2->fedev);
930 dvb_unregister_adapter(&cinergyt2->adapter);
931 961
932 cinergyt2_free_stream_urbs(cinergyt2); 962 if (!atomic_read(&cinergyt2->inuse))
933 up(&cinergyt2->sem); 963 cinergyt2_unregister(cinergyt2);
934 kfree(cinergyt2);
935} 964}
936 965
937static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) 966static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
938{ 967{
939 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); 968 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
940 969
941 if (down_interruptible(&cinergyt2->sem)) 970 if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
942 return -ERESTARTSYS; 971 return -ERESTARTSYS;
943 972
944 if (state.event > PM_EVENT_ON) { 973 if (state.event > PM_EVENT_ON) {
@@ -961,7 +990,7 @@ static int cinergyt2_resume (struct usb_interface *intf)
961 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); 990 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
962 struct dvbt_set_parameters_msg *param = &cinergyt2->param; 991 struct dvbt_set_parameters_msg *param = &cinergyt2->param;
963 992
964 if (down_interruptible(&cinergyt2->sem)) 993 if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
965 return -ERESTARTSYS; 994 return -ERESTARTSYS;
966 995
967 if (!cinergyt2->sleeping) { 996 if (!cinergyt2->sleeping) {
@@ -1014,4 +1043,3 @@ module_exit (cinergyt2_exit);
1014 1043
1015MODULE_LICENSE("GPL"); 1044MODULE_LICENSE("GPL");
1016MODULE_AUTHOR("Holger Waechtler, Daniel Mack"); 1045MODULE_AUTHOR("Holger Waechtler, Daniel Mack");
1017
diff --git a/drivers/media/dvb/dvb-core/Kconfig b/drivers/media/dvb/dvb-core/Kconfig
index a9a7b3421048..12ee912a5705 100644
--- a/drivers/media/dvb/dvb-core/Kconfig
+++ b/drivers/media/dvb/dvb-core/Kconfig
@@ -5,7 +5,7 @@ config DVB_CORE
5 help 5 help
6 DVB core utility functions for device handling, software fallbacks etc. 6 DVB core utility functions for device handling, software fallbacks etc.
7 Say Y when you have a DVB card and want to use it. Say Y if your want 7 Say Y when you have a DVB card and want to use it. Say Y if your want
8 to build your drivers outside the kernel, but need the DVB core. All 8 to build your drivers outside the kernel, but need the DVB core. All
9 in-kernel drivers will select this automatically if needed. 9 in-kernel drivers will select this automatically if needed.
10 If unsure say N. 10 If unsure say N.
11 11
diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile
index c6baac20f529..7adb50c1e8eb 100644
--- a/drivers/media/dvb/dvb-core/Makefile
+++ b/drivers/media/dvb/dvb-core/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ 5dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
6 dvb_ca_en50221.o dvb_frontend.o \ 6 dvb_ca_en50221.o dvb_frontend.o \
7 dvb_net.o dvb_ringbuffer.o 7 dvb_net.o dvb_ringbuffer.o
8 8
9obj-$(CONFIG_DVB_CORE) += dvb-core.o 9obj-$(CONFIG_DVB_CORE) += dvb-core.o
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 5956c35d34ac..4bb779aeff6a 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -1745,9 +1745,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
1745 1745
1746 for (i = 0; i < ca->slot_count; i++) { 1746 for (i = 0; i < ca->slot_count; i++) {
1747 dvb_ca_en50221_slot_shutdown(ca, i); 1747 dvb_ca_en50221_slot_shutdown(ca, i);
1748 if (ca->slot_info[i].rx_buffer.data != NULL) { 1748 vfree(ca->slot_info[i].rx_buffer.data);
1749 vfree(ca->slot_info[i].rx_buffer.data);
1750 }
1751 } 1749 }
1752 kfree(ca->slot_info); 1750 kfree(ca->slot_info);
1753 dvb_unregister_device(ca->dvbdev); 1751 dvb_unregister_device(ca->dvbdev);
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.c b/drivers/media/dvb/dvb-core/dvb_filter.c
index c49fd0bd7181..772003fb1821 100644
--- a/drivers/media/dvb/dvb-core/dvb_filter.c
+++ b/drivers/media/dvb/dvb-core/dvb_filter.c
@@ -409,16 +409,16 @@ static u8 *skip_pes_header(u8 **bufp)
409 409
410 if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */ 410 if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */
411 if (buf[7] & PTS_ONLY) 411 if (buf[7] & PTS_ONLY)
412 pts = buf+9; 412 pts = buf+9;
413 else pts = NULL; 413 else pts = NULL;
414 buf = inbuf + 9 + inbuf[8]; 414 buf = inbuf + 9 + inbuf[8];
415 } else { /* mpeg1 */ 415 } else { /* mpeg1 */
416 for (buf = inbuf + 6; *buf == 0xff; buf++) 416 for (buf = inbuf + 6; *buf == 0xff; buf++)
417 if (buf == inbuf + 6 + 16) { 417 if (buf == inbuf + 6 + 16) {
418 break; 418 break;
419 } 419 }
420 if ((*buf & 0xc0) == 0x40) 420 if ((*buf & 0xc0) == 0x40)
421 buf += 2; 421 buf += 2;
422 skip = mpeg1_skip_table [*buf >> 4]; 422 skip = mpeg1_skip_table [*buf >> 4];
423 if (skip == 5 || skip == 10) pts = buf; 423 if (skip == 5 || skip == 10) pts = buf;
424 else pts = NULL; 424 else pts = NULL;
@@ -529,9 +529,9 @@ static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_t
529 pic->picture_header = 0; 529 pic->picture_header = 0;
530 pic->sequence_header_data 530 pic->sequence_header_data
531 = ( INIT_HORIZONTAL_SIZE << 20 ) 531 = ( INIT_HORIZONTAL_SIZE << 20 )
532 | ( INIT_VERTICAL_SIZE << 8 ) 532 | ( INIT_VERTICAL_SIZE << 8 )
533 | ( INIT_ASPECT_RATIO << 4 ) 533 | ( INIT_ASPECT_RATIO << 4 )
534 | ( INIT_FRAME_RATE ); 534 | ( INIT_FRAME_RATE );
535 pic->mpeg1_flag = 0; 535 pic->mpeg1_flag = 0;
536 pic->vinfo.horizontal_size 536 pic->vinfo.horizontal_size
537 = INIT_DISP_HORIZONTAL_SIZE; 537 = INIT_DISP_HORIZONTAL_SIZE;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 95ea5095e07e..4a08c4ab6730 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -92,6 +92,7 @@ static DECLARE_MUTEX(frontend_mutex);
92 92
93struct dvb_frontend_private { 93struct dvb_frontend_private {
94 94
95 /* thread/frontend values */
95 struct dvb_device *dvbdev; 96 struct dvb_device *dvbdev;
96 struct dvb_frontend_parameters parameters; 97 struct dvb_frontend_parameters parameters;
97 struct dvb_fe_events events; 98 struct dvb_fe_events events;
@@ -100,20 +101,25 @@ struct dvb_frontend_private {
100 wait_queue_head_t wait_queue; 101 wait_queue_head_t wait_queue;
101 pid_t thread_pid; 102 pid_t thread_pid;
102 unsigned long release_jiffies; 103 unsigned long release_jiffies;
103 int state; 104 unsigned int exit;
104 int bending; 105 unsigned int wakeup;
105 int lnb_drift;
106 int inversion;
107 int auto_step;
108 int auto_sub_step;
109 int started_auto_step;
110 int min_delay;
111 int max_drift;
112 int step_size;
113 int exit;
114 int wakeup;
115 fe_status_t status; 106 fe_status_t status;
116 fe_sec_tone_mode_t tone; 107 unsigned long tune_mode_flags;
108 unsigned int delay;
109
110 /* swzigzag values */
111 unsigned int state;
112 unsigned int bending;
113 int lnb_drift;
114 unsigned int inversion;
115 unsigned int auto_step;
116 unsigned int auto_sub_step;
117 unsigned int started_auto_step;
118 unsigned int min_delay;
119 unsigned int max_drift;
120 unsigned int step_size;
121 int quality;
122 unsigned int check_wrapped;
117}; 123};
118 124
119 125
@@ -208,21 +214,21 @@ static void dvb_frontend_init(struct dvb_frontend *fe)
208 fe->ops->init(fe); 214 fe->ops->init(fe);
209} 215}
210 216
211static void update_delay(int *quality, int *delay, int min_delay, int locked) 217static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked)
212{ 218{
213 int q2; 219 int q2;
214 220
215 dprintk ("%s\n", __FUNCTION__); 221 dprintk ("%s\n", __FUNCTION__);
216 222
217 if (locked) 223 if (locked)
218 (*quality) = (*quality * 220 + 36*256) / 256; 224 (fepriv->quality) = (fepriv->quality * 220 + 36*256) / 256;
219 else 225 else
220 (*quality) = (*quality * 220 + 0) / 256; 226 (fepriv->quality) = (fepriv->quality * 220 + 0) / 256;
221 227
222 q2 = *quality - 128; 228 q2 = fepriv->quality - 128;
223 q2 *= q2; 229 q2 *= q2;
224 230
225 *delay = min_delay + q2 * HZ / (128*128); 231 fepriv->delay = fepriv->min_delay + q2 * HZ / (128*128);
226} 232}
227 233
228/** 234/**
@@ -232,7 +238,7 @@ static void update_delay(int *quality, int *delay, int min_delay, int locked)
232 * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT 238 * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT
233 * @returns Number of complete iterations that have been performed. 239 * @returns Number of complete iterations that have been performed.
234 */ 240 */
235static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped) 241static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wrapped)
236{ 242{
237 int autoinversion; 243 int autoinversion;
238 int ready = 0; 244 int ready = 0;
@@ -321,6 +327,129 @@ static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped)
321 return 0; 327 return 0;
322} 328}
323 329
330static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
331{
332 fe_status_t s;
333 struct dvb_frontend_private *fepriv = fe->frontend_priv;
334
335 /* if we've got no parameters, just keep idling */
336 if (fepriv->state & FESTATE_IDLE) {
337 fepriv->delay = 3*HZ;
338 fepriv->quality = 0;
339 return;
340 }
341
342 /* in SCAN mode, we just set the frontend when asked and leave it alone */
343 if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) {
344 if (fepriv->state & FESTATE_RETUNE) {
345 if (fe->ops->set_frontend)
346 fe->ops->set_frontend(fe, &fepriv->parameters);
347 fepriv->state = FESTATE_TUNED;
348 }
349 fepriv->delay = 3*HZ;
350 fepriv->quality = 0;
351 return;
352 }
353
354 /* get the frontend status */
355 if (fepriv->state & FESTATE_RETUNE) {
356 s = 0;
357 } else {
358 if (fe->ops->read_status)
359 fe->ops->read_status(fe, &s);
360 if (s != fepriv->status) {
361 dvb_frontend_add_event(fe, s);
362 fepriv->status = s;
363 }
364 }
365
366 /* if we're not tuned, and we have a lock, move to the TUNED state */
367 if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) {
368 dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
369 fepriv->state = FESTATE_TUNED;
370
371 /* if we're tuned, then we have determined the correct inversion */
372 if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) &&
373 (fepriv->parameters.inversion == INVERSION_AUTO)) {
374 fepriv->parameters.inversion = fepriv->inversion;
375 }
376 return;
377 }
378
379 /* if we are tuned already, check we're still locked */
380 if (fepriv->state & FESTATE_TUNED) {
381 dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
382
383 /* we're tuned, and the lock is still good... */
384 if (s & FE_HAS_LOCK) {
385 return;
386 } else { /* if we _WERE_ tuned, but now don't have a lock */
387 fepriv->state = FESTATE_ZIGZAG_FAST;
388 fepriv->started_auto_step = fepriv->auto_step;
389 fepriv->check_wrapped = 0;
390 }
391 }
392
393 /* don't actually do anything if we're in the LOSTLOCK state,
394 * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */
395 if ((fepriv->state & FESTATE_LOSTLOCK) &&
396 (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) {
397 dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
398 return;
399 }
400
401 /* don't do anything if we're in the DISEQC state, since this
402 * might be someone with a motorized dish controlled by DISEQC.
403 * If its actually a re-tune, there will be a SET_FRONTEND soon enough. */
404 if (fepriv->state & FESTATE_DISEQC) {
405 dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
406 return;
407 }
408
409 /* if we're in the RETUNE state, set everything up for a brand
410 * new scan, keeping the current inversion setting, as the next
411 * tune is _very_ likely to require the same */
412 if (fepriv->state & FESTATE_RETUNE) {
413 fepriv->lnb_drift = 0;
414 fepriv->auto_step = 0;
415 fepriv->auto_sub_step = 0;
416 fepriv->started_auto_step = 0;
417 fepriv->check_wrapped = 0;
418 }
419
420 /* fast zigzag. */
421 if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) {
422 fepriv->delay = fepriv->min_delay;
423
424 /* peform a tune */
425 if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) {
426 /* OK, if we've run out of trials at the fast speed.
427 * Drop back to slow for the _next_ attempt */
428 fepriv->state = FESTATE_SEARCHING_SLOW;
429 fepriv->started_auto_step = fepriv->auto_step;
430 return;
431 }
432 fepriv->check_wrapped = 1;
433
434 /* if we've just retuned, enter the ZIGZAG_FAST state.
435 * This ensures we cannot return from an
436 * FE_SET_FRONTEND ioctl before the first frontend tune
437 * occurs */
438 if (fepriv->state & FESTATE_RETUNE) {
439 fepriv->state = FESTATE_TUNING_FAST;
440 }
441 }
442
443 /* slow zigzag */
444 if (fepriv->state & FESTATE_SEARCHING_SLOW) {
445 dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
446
447 /* Note: don't bother checking for wrapping; we stay in this
448 * state until we get a lock */
449 dvb_frontend_swzigzag_autotune(fe, 0);
450 }
451}
452
324static int dvb_frontend_is_exiting(struct dvb_frontend *fe) 453static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
325{ 454{
326 struct dvb_frontend_private *fepriv = fe->frontend_priv; 455 struct dvb_frontend_private *fepriv = fe->frontend_priv;
@@ -330,7 +459,7 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
330 459
331 if (fepriv->dvbdev->writers == 1) 460 if (fepriv->dvbdev->writers == 1)
332 if (time_after(jiffies, fepriv->release_jiffies + 461 if (time_after(jiffies, fepriv->release_jiffies +
333 dvb_shutdown_timeout * HZ)) 462 dvb_shutdown_timeout * HZ))
334 return 1; 463 return 1;
335 464
336 return 0; 465 return 0;
@@ -355,18 +484,14 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe)
355 wake_up_interruptible(&fepriv->wait_queue); 484 wake_up_interruptible(&fepriv->wait_queue);
356} 485}
357 486
358/*
359 * FIXME: use linux/kthread.h
360 */
361static int dvb_frontend_thread(void *data) 487static int dvb_frontend_thread(void *data)
362{ 488{
363 struct dvb_frontend *fe = data; 489 struct dvb_frontend *fe = data;
364 struct dvb_frontend_private *fepriv = fe->frontend_priv; 490 struct dvb_frontend_private *fepriv = fe->frontend_priv;
365 unsigned long timeout; 491 unsigned long timeout;
366 char name [15]; 492 char name [15];
367 int quality = 0, delay = 3*HZ;
368 fe_status_t s; 493 fe_status_t s;
369 int check_wrapped = 0; 494 struct dvb_frontend_parameters *params;
370 495
371 dprintk("%s\n", __FUNCTION__); 496 dprintk("%s\n", __FUNCTION__);
372 497
@@ -377,6 +502,9 @@ static int dvb_frontend_thread(void *data)
377 sigfillset(&current->blocked); 502 sigfillset(&current->blocked);
378 unlock_kernel(); 503 unlock_kernel();
379 504
505 fepriv->check_wrapped = 0;
506 fepriv->quality = 0;
507 fepriv->delay = 3*HZ;
380 fepriv->status = 0; 508 fepriv->status = 0;
381 dvb_frontend_init(fe); 509 dvb_frontend_init(fe);
382 fepriv->wakeup = 0; 510 fepriv->wakeup = 0;
@@ -386,7 +514,7 @@ static int dvb_frontend_thread(void *data)
386 514
387 timeout = wait_event_interruptible_timeout(fepriv->wait_queue, 515 timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
388 dvb_frontend_should_wakeup(fe), 516 dvb_frontend_should_wakeup(fe),
389 delay); 517 fepriv->delay);
390 if (0 != dvb_frontend_is_exiting(fe)) { 518 if (0 != dvb_frontend_is_exiting(fe)) {
391 /* got signal or quitting */ 519 /* got signal or quitting */
392 break; 520 break;
@@ -397,108 +525,22 @@ static int dvb_frontend_thread(void *data)
397 if (down_interruptible(&fepriv->sem)) 525 if (down_interruptible(&fepriv->sem))
398 break; 526 break;
399 527
400 /* if we've got no parameters, just keep idling */ 528 /* do an iteration of the tuning loop */
401 if (fepriv->state & FESTATE_IDLE) { 529 if (fe->ops->tune) {
402 delay = 3*HZ; 530 /* have we been asked to retune? */
403 quality = 0; 531 params = NULL;
404 continue; 532 if (fepriv->state & FESTATE_RETUNE) {
405 } 533 params = &fepriv->parameters;
534 fepriv->state = FESTATE_TUNED;
535 }
406 536
407 /* get the frontend status */ 537 fe->ops->tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
408 if (fepriv->state & FESTATE_RETUNE) {
409 s = 0;
410 } else {
411 if (fe->ops->read_status)
412 fe->ops->read_status(fe, &s);
413 if (s != fepriv->status) { 538 if (s != fepriv->status) {
414 dvb_frontend_add_event(fe, s); 539 dvb_frontend_add_event(fe, s);
415 fepriv->status = s; 540 fepriv->status = s;
416 } 541 }
417 } 542 } else {
418 /* if we're not tuned, and we have a lock, move to the TUNED state */ 543 dvb_frontend_swzigzag(fe);
419 if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) {
420 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
421 fepriv->state = FESTATE_TUNED;
422
423 /* if we're tuned, then we have determined the correct inversion */
424 if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) &&
425 (fepriv->parameters.inversion == INVERSION_AUTO)) {
426 fepriv->parameters.inversion = fepriv->inversion;
427 }
428 continue;
429 }
430
431 /* if we are tuned already, check we're still locked */
432 if (fepriv->state & FESTATE_TUNED) {
433 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
434
435 /* we're tuned, and the lock is still good... */
436 if (s & FE_HAS_LOCK)
437 continue;
438 else { /* if we _WERE_ tuned, but now don't have a lock */
439 fepriv->state = FESTATE_ZIGZAG_FAST;
440 fepriv->started_auto_step = fepriv->auto_step;
441 check_wrapped = 0;
442 }
443 }
444
445 /* don't actually do anything if we're in the LOSTLOCK state,
446 * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */
447 if ((fepriv->state & FESTATE_LOSTLOCK) &&
448 (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) {
449 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
450 continue;
451 }
452
453 /* don't do anything if we're in the DISEQC state, since this
454 * might be someone with a motorized dish controlled by DISEQC.
455 * If its actually a re-tune, there will be a SET_FRONTEND soon enough. */
456 if (fepriv->state & FESTATE_DISEQC) {
457 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
458 continue;
459 }
460
461 /* if we're in the RETUNE state, set everything up for a brand
462 * new scan, keeping the current inversion setting, as the next
463 * tune is _very_ likely to require the same */
464 if (fepriv->state & FESTATE_RETUNE) {
465 fepriv->lnb_drift = 0;
466 fepriv->auto_step = 0;
467 fepriv->auto_sub_step = 0;
468 fepriv->started_auto_step = 0;
469 check_wrapped = 0;
470 }
471
472 /* fast zigzag. */
473 if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) {
474 delay = fepriv->min_delay;
475
476 /* peform a tune */
477 if (dvb_frontend_autotune(fe, check_wrapped)) {
478 /* OK, if we've run out of trials at the fast speed.
479 * Drop back to slow for the _next_ attempt */
480 fepriv->state = FESTATE_SEARCHING_SLOW;
481 fepriv->started_auto_step = fepriv->auto_step;
482 continue;
483 }
484 check_wrapped = 1;
485
486 /* if we've just retuned, enter the ZIGZAG_FAST state.
487 * This ensures we cannot return from an
488 * FE_SET_FRONTEND ioctl before the first frontend tune
489 * occurs */
490 if (fepriv->state & FESTATE_RETUNE) {
491 fepriv->state = FESTATE_TUNING_FAST;
492 }
493 }
494
495 /* slow zigzag */
496 if (fepriv->state & FESTATE_SEARCHING_SLOW) {
497 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
498
499 /* Note: don't bother checking for wrapping; we stay in this
500 * state until we get a lock */
501 dvb_frontend_autotune(fe, 0);
502 } 544 }
503 } 545 }
504 546
@@ -733,7 +775,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
733 err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); 775 err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg);
734 fepriv->state = FESTATE_DISEQC; 776 fepriv->state = FESTATE_DISEQC;
735 fepriv->status = 0; 777 fepriv->status = 0;
736 fepriv->tone = (fe_sec_tone_mode_t) parg;
737 } 778 }
738 break; 779 break;
739 780
@@ -747,7 +788,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
747 788
748 case FE_DISHNETWORK_SEND_LEGACY_CMD: 789 case FE_DISHNETWORK_SEND_LEGACY_CMD:
749 if (fe->ops->dishnetwork_send_legacy_command) { 790 if (fe->ops->dishnetwork_send_legacy_command) {
750 err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg); 791 err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned long) parg);
751 fepriv->state = FESTATE_DISEQC; 792 fepriv->state = FESTATE_DISEQC;
752 fepriv->status = 0; 793 fepriv->status = 0;
753 } else if (fe->ops->set_voltage) { 794 } else if (fe->ops->set_voltage) {
@@ -767,13 +808,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
767 * initialization, so parg is 8 bits and does not 808 * initialization, so parg is 8 bits and does not
768 * include the initialization or start bit 809 * include the initialization or start bit
769 */ 810 */
770 unsigned int cmd = ((unsigned int) parg) << 1; 811 unsigned long cmd = ((unsigned long) parg) << 1;
771 struct timeval nexttime; 812 struct timeval nexttime;
772 struct timeval tv[10]; 813 struct timeval tv[10];
773 int i; 814 int i;
774 u8 last = 1; 815 u8 last = 1;
775 if (dvb_frontend_debug) 816 if (dvb_frontend_debug)
776 printk("%s switch command: 0x%04x\n", __FUNCTION__, cmd); 817 printk("%s switch command: 0x%04lx\n", __FUNCTION__, cmd);
777 do_gettimeofday(&nexttime); 818 do_gettimeofday(&nexttime);
778 if (dvb_frontend_debug) 819 if (dvb_frontend_debug)
779 memcpy(&tv[0], &nexttime, sizeof(struct timeval)); 820 memcpy(&tv[0], &nexttime, sizeof(struct timeval));
@@ -814,7 +855,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
814 855
815 case FE_ENABLE_HIGH_LNB_VOLTAGE: 856 case FE_ENABLE_HIGH_LNB_VOLTAGE:
816 if (fe->ops->enable_high_lnb_voltage) 857 if (fe->ops->enable_high_lnb_voltage)
817 err = fe->ops->enable_high_lnb_voltage(fe, (int) parg); 858 err = fe->ops->enable_high_lnb_voltage(fe, (long) parg);
818 break; 859 break;
819 860
820 case FE_SET_FRONTEND: { 861 case FE_SET_FRONTEND: {
@@ -891,6 +932,10 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
891 err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg); 932 err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg);
892 } 933 }
893 break; 934 break;
935
936 case FE_SET_FRONTEND_TUNE_MODE:
937 fepriv->tune_mode_flags = (unsigned long) parg;
938 break;
894 }; 939 };
895 940
896 up (&fepriv->sem); 941 up (&fepriv->sem);
@@ -932,6 +977,9 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
932 977
933 /* empty event queue */ 978 /* empty event queue */
934 fepriv->events.eventr = fepriv->events.eventw = 0; 979 fepriv->events.eventr = fepriv->events.eventw = 0;
980
981 /* normal tune mode when opened R/W */
982 fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT;
935 } 983 }
936 984
937 return ret; 985 return ret;
@@ -990,7 +1038,6 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
990 init_MUTEX (&fepriv->events.sem); 1038 init_MUTEX (&fepriv->events.sem);
991 fe->dvb = dvb; 1039 fe->dvb = dvb;
992 fepriv->inversion = INVERSION_OFF; 1040 fepriv->inversion = INVERSION_OFF;
993 fepriv->tone = SEC_TONE_OFF;
994 1041
995 printk ("DVB: registering frontend %i (%s)...\n", 1042 printk ("DVB: registering frontend %i (%s)...\n",
996 fe->dvb->num, 1043 fe->dvb->num,
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 1e0840d02f1f..70a6d14efda7 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -58,10 +58,19 @@ struct dvb_frontend_ops {
58 int (*init)(struct dvb_frontend* fe); 58 int (*init)(struct dvb_frontend* fe);
59 int (*sleep)(struct dvb_frontend* fe); 59 int (*sleep)(struct dvb_frontend* fe);
60 60
61 /* if this is set, it overrides the default swzigzag */
62 int (*tune)(struct dvb_frontend* fe,
63 struct dvb_frontend_parameters* params,
64 unsigned int mode_flags,
65 int *delay,
66 fe_status_t *status);
67
68 /* these two are only used for the swzigzag code */
61 int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); 69 int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
62 int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
63 int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings); 70 int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings);
64 71
72 int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
73
65 int (*read_status)(struct dvb_frontend* fe, fe_status_t* status); 74 int (*read_status)(struct dvb_frontend* fe, fe_status_t* status);
66 int (*read_ber)(struct dvb_frontend* fe, u32* ber); 75 int (*read_ber)(struct dvb_frontend* fe, u32* ber);
67 int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength); 76 int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength);
@@ -74,8 +83,9 @@ struct dvb_frontend_ops {
74 int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); 83 int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd);
75 int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); 84 int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone);
76 int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); 85 int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
77 int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, int arg); 86 int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg);
78 int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd); 87 int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
88 int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
79}; 89};
80 90
81#define MAX_EVENT 8 91#define MAX_EVENT 8
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 86bba81e851e..6711eb6a058c 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1222,7 +1222,7 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype)
1222 return if_num; 1222 return if_num;
1223} 1223}
1224 1224
1225static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned int num) 1225static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num)
1226{ 1226{
1227 struct net_device *net = dvbnet->device[num]; 1227 struct net_device *net = dvbnet->device[num];
1228 struct dvb_net_priv *priv; 1228 struct dvb_net_priv *priv;
@@ -1296,9 +1296,9 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
1296 1296
1297 if (!capable(CAP_SYS_ADMIN)) 1297 if (!capable(CAP_SYS_ADMIN))
1298 return -EPERM; 1298 return -EPERM;
1299 if ((unsigned int) parg >= DVB_NET_DEVICES_MAX) 1299 if ((unsigned long) parg >= DVB_NET_DEVICES_MAX)
1300 return -EINVAL; 1300 return -EINVAL;
1301 ret = dvb_net_remove_if(dvbnet, (unsigned int) parg); 1301 ret = dvb_net_remove_if(dvbnet, (unsigned long) parg);
1302 if (!ret) 1302 if (!ret)
1303 module_put(dvbdev->adapter->module); 1303 module_put(dvbdev->adapter->module);
1304 return ret; 1304 return ret;
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
index 283c6e9339a4..77ad2410f4d3 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
@@ -112,10 +112,10 @@ ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, in
112 split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; 112 split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
113 if (split > 0) { 113 if (split > 0) {
114 if (!usermem) 114 if (!usermem)
115 memcpy(buf, rbuf->data+rbuf->pread, split); 115 memcpy(buf, rbuf->data+rbuf->pread, split);
116 else 116 else
117 if (copy_to_user(buf, rbuf->data+rbuf->pread, split)) 117 if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
118 return -EFAULT; 118 return -EFAULT;
119 buf += split; 119 buf += split;
120 todo -= split; 120 todo -= split;
121 rbuf->pread = 0; 121 rbuf->pread = 0;
@@ -124,7 +124,7 @@ ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, in
124 memcpy(buf, rbuf->data+rbuf->pread, todo); 124 memcpy(buf, rbuf->data+rbuf->pread, todo);
125 else 125 else
126 if (copy_to_user(buf, rbuf->data+rbuf->pread, todo)) 126 if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
127 return -EFAULT; 127 return -EFAULT;
128 128
129 rbuf->pread = (rbuf->pread + todo) % rbuf->size; 129 rbuf->pread = (rbuf->pread + todo) % rbuf->size;
130 130
@@ -167,7 +167,7 @@ ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t le
167} 167}
168 168
169ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, 169ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
170 int offset, u8* buf, size_t len, int usermem) 170 int offset, u8* buf, size_t len, int usermem)
171{ 171{
172 size_t todo; 172 size_t todo;
173 size_t split; 173 size_t split;
@@ -183,10 +183,10 @@ ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
183 split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; 183 split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
184 if (split > 0) { 184 if (split > 0) {
185 if (!usermem) 185 if (!usermem)
186 memcpy(buf, rbuf->data+idx, split); 186 memcpy(buf, rbuf->data+idx, split);
187 else 187 else
188 if (copy_to_user(buf, rbuf->data+idx, split)) 188 if (copy_to_user(buf, rbuf->data+idx, split))
189 return -EFAULT; 189 return -EFAULT;
190 buf += split; 190 buf += split;
191 todo -= split; 191 todo -= split;
192 idx = 0; 192 idx = 0;
@@ -195,7 +195,7 @@ ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
195 memcpy(buf, rbuf->data+idx, todo); 195 memcpy(buf, rbuf->data+idx, todo);
196 else 196 else
197 if (copy_to_user(buf, rbuf->data+idx, todo)) 197 if (copy_to_user(buf, rbuf->data+idx, todo))
198 return -EFAULT; 198 return -EFAULT;
199 199
200 return len; 200 return len;
201} 201}
@@ -209,12 +209,12 @@ void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx)
209 // clean up disposed packets 209 // clean up disposed packets
210 while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) { 210 while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) {
211 if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) { 211 if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) {
212 pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8; 212 pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8;
213 pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1); 213 pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1);
214 DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE); 214 DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE);
215 } else { 215 } else {
216 // first packet is not disposed, so we stop cleaning now 216 // first packet is not disposed, so we stop cleaning now
217 break; 217 break;
218 } 218 }
219 } 219 }
220} 220}
@@ -242,8 +242,8 @@ ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t*
242 curpktstatus = rbuf->data[(idx + 2) % rbuf->size]; 242 curpktstatus = rbuf->data[(idx + 2) % rbuf->size];
243 243
244 if (curpktstatus == PKT_READY) { 244 if (curpktstatus == PKT_READY) {
245 *pktlen = curpktlen; 245 *pktlen = curpktlen;
246 return idx; 246 return idx;
247 } 247 }
248 248
249 consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE; 249 consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE;
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
index fa476f662f82..6d2560972771 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
@@ -106,7 +106,7 @@ extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf);
106** returns number of bytes transferred or -EFAULT 106** returns number of bytes transferred or -EFAULT
107*/ 107*/
108extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, 108extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf,
109 size_t len, int usermem); 109 size_t len, int usermem);
110 110
111 111
112/* write routines & macros */ 112/* write routines & macros */
@@ -121,7 +121,7 @@ extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf,
121** returns number of bytes transferred or -EFAULT 121** returns number of bytes transferred or -EFAULT
122*/ 122*/
123extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, 123extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
124 size_t len); 124 size_t len);
125 125
126 126
127/** 127/**
@@ -133,7 +133,7 @@ extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
133 * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL. 133 * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL.
134 */ 134 */
135extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, 135extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf,
136 size_t len); 136 size_t len);
137 137
138/** 138/**
139 * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this 139 * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this
@@ -149,7 +149,7 @@ extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf,
149 * returns Number of bytes read, or -EFAULT. 149 * returns Number of bytes read, or -EFAULT.
150 */ 150 */
151extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, 151extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
152 int offset, u8* buf, size_t len, int usermem); 152 int offset, u8* buf, size_t len, int usermem);
153 153
154/** 154/**
155 * Dispose of a packet in the ring buffer. 155 * Dispose of a packet in the ring buffer.
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index a4aee8665854..06b696e9acbd 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -92,10 +92,10 @@ static int dvb_device_open(struct inode *inode, struct file *file)
92 old_fops = file->f_op; 92 old_fops = file->f_op;
93 file->f_op = fops_get(dvbdev->fops); 93 file->f_op = fops_get(dvbdev->fops);
94 if(file->f_op->open) 94 if(file->f_op->open)
95 err = file->f_op->open(inode,file); 95 err = file->f_op->open(inode,file);
96 if (err) { 96 if (err) {
97 fops_put(file->f_op); 97 fops_put(file->f_op);
98 file->f_op = fops_get(old_fops); 98 file->f_op = fops_get(old_fops);
99 } 99 }
100 fops_put(old_fops); 100 fops_put(old_fops);
101 return err; 101 return err;
@@ -356,18 +356,18 @@ int dvb_usercopy(struct inode *inode, struct file *file,
356 case _IOC_WRITE: 356 case _IOC_WRITE:
357 case (_IOC_WRITE | _IOC_READ): 357 case (_IOC_WRITE | _IOC_READ):
358 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { 358 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
359 parg = sbuf; 359 parg = sbuf;
360 } else { 360 } else {
361 /* too big to allocate from stack */ 361 /* too big to allocate from stack */
362 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); 362 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
363 if (NULL == mbuf) 363 if (NULL == mbuf)
364 return -ENOMEM; 364 return -ENOMEM;
365 parg = mbuf; 365 parg = mbuf;
366 } 366 }
367 367
368 err = -EFAULT; 368 err = -EFAULT;
369 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) 369 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
370 goto out; 370 goto out;
371 break; 371 break;
372 } 372 }
373 373
@@ -384,7 +384,7 @@ int dvb_usercopy(struct inode *inode, struct file *file,
384 case _IOC_READ: 384 case _IOC_READ:
385 case (_IOC_WRITE | _IOC_READ): 385 case (_IOC_WRITE | _IOC_READ):
386 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) 386 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
387 err = -EFAULT; 387 err = -EFAULT;
388 break; 388 break;
389 } 389 }
390 390
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 0cc6e4a0e27c..74ed5853f0fb 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -97,7 +97,7 @@ we simply define out own dvb_usercopy(), which will hopefully become
97generic_usercopy() someday... */ 97generic_usercopy() someday... */
98 98
99extern int dvb_usercopy(struct inode *inode, struct file *file, 99extern int dvb_usercopy(struct inode *inode, struct file *file,
100 unsigned int cmd, unsigned long arg, 100 unsigned int cmd, unsigned long arg,
101 int (*func)(struct inode *inode, struct file *file, 101 int (*func)(struct inode *inode, struct file *file,
102 unsigned int cmd, void *arg)); 102 unsigned int cmd, void *arg));
103 103
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 54e2b29076b1..90a69d343b79 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -37,16 +37,16 @@ config DVB_USB_DIBUSB_MB
37 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator. 37 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
38 38
39 Devices supported by this driver: 39 Devices supported by this driver:
40 TwinhanDTV USB-Ter (VP7041) 40 Artec T1 USB1.1 boxes
41 TwinhanDTV Magic Box (VP7041e) 41 Avermedia AverTV DVBT USB1.1
42 KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
43 Hama DVB-T USB1.1-Box
44 DiBcom USB1.1 reference devices (non-public)
45 Ultima Electronic/Artec T1 USB TVBOX
46 Compro Videomate DVB-U2000 - DVB-T USB 42 Compro Videomate DVB-U2000 - DVB-T USB
43 DiBcom USB1.1 reference devices (non-public)
47 Grandtec DVB-T USB 44 Grandtec DVB-T USB
48 Avermedia AverTV DVBT USB1.1 45 Hama DVB-T USB1.1-Box
49 Artec T1 USB1.1 boxes 46 KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
47 TwinhanDTV Magic Box (VP7041e)
48 TwinhanDTV USB-Ter (VP7041)
49 Ultima Electronic/Artec T1 USB TVBOX
50 50
51 The VP7041 seems to be identical to "CTS Portable" (Chinese 51 The VP7041 seems to be identical to "CTS Portable" (Chinese
52 Television System). 52 Television System).
@@ -54,6 +54,12 @@ config DVB_USB_DIBUSB_MB
54 Say Y if you own such a device and want to use it. You should build it as 54 Say Y if you own such a device and want to use it. You should build it as
55 a module. 55 a module.
56 56
57config DVB_USB_DIBUSB_MB_FAULTY
58 bool "Support faulty USB IDs"
59 depends on DVB_USB_DIBUSB_MB
60 help
61 Support for faulty USB IDs due to an invalid EEPROM on some Artec devices.
62
57config DVB_USB_DIBUSB_MC 63config DVB_USB_DIBUSB_MC
58 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" 64 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
59 depends on DVB_USB 65 depends on DVB_USB
@@ -63,8 +69,8 @@ config DVB_USB_DIBUSB_MC
63 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator. 69 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
64 70
65 Devices supported by this driver: 71 Devices supported by this driver:
66 DiBcom USB2.0 reference devices (non-public)
67 Artec T1 USB2.0 boxes 72 Artec T1 USB2.0 boxes
73 DiBcom USB2.0 reference devices (non-public)
68 74
69 Say Y if you own such a device and want to use it. You should build it as 75 Say Y if you own such a device and want to use it. You should build it as
70 a module. 76 a module.
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index d05fab01cccd..358ed153865f 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -11,10 +11,11 @@
11 * design, so it can be reused for the "analogue-only" device (if it will 11 * design, so it can be reused for the "analogue-only" device (if it will
12 * appear at all). 12 * appear at all).
13 * 13 *
14 * TODO: check if the cx25840-driver (from ivtv) can be used for the analogue 14 * TODO: Use the cx25840-driver for the analogue part
15 * part
16 * 15 *
17 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) 16 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
17 * Copyright (C) 2005 Michael Krufky (mkrufky@m1k.net)
18 * Copyright (C) 2006 Chris Pascoe (c.pascoe@itee.uq.edu.au)
18 * 19 *
19 * This program is free software; you can redistribute it and/or modify it 20 * This program is free software; you can redistribute it and/or modify it
20 * under the terms of the GNU General Public License as published by the Free 21 * under the terms of the GNU General Public License as published by the Free
@@ -25,6 +26,9 @@
25#include "cxusb.h" 26#include "cxusb.h"
26 27
27#include "cx22702.h" 28#include "cx22702.h"
29#include "lgdt330x.h"
30#include "mt352.h"
31#include "mt352_priv.h"
28 32
29/* debug */ 33/* debug */
30int dvb_usb_cxusb_debug; 34int dvb_usb_cxusb_debug;
@@ -156,6 +160,99 @@ static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
156 return 0; 160 return 0;
157} 161}
158 162
163static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
164{
165 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
166 u8 ircode[4];
167 int i;
168
169 cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
170
171 *event = 0;
172 *state = REMOTE_NO_KEY_PRESSED;
173
174 for (i = 0; i < d->props.rc_key_map_size; i++) {
175 if (keymap[i].custom == ircode[2] &&
176 keymap[i].data == ircode[3]) {
177 *event = keymap[i].event;
178 *state = REMOTE_KEY_PRESSED;
179
180 return 0;
181 }
182 }
183
184 return 0;
185}
186
187struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
188 { 0xfe, 0x02, KEY_TV },
189 { 0xfe, 0x0e, KEY_MP3 },
190 { 0xfe, 0x1a, KEY_DVD },
191 { 0xfe, 0x1e, KEY_FAVORITES },
192 { 0xfe, 0x16, KEY_SETUP },
193 { 0xfe, 0x46, KEY_POWER2 },
194 { 0xfe, 0x0a, KEY_EPG },
195 { 0xfe, 0x49, KEY_BACK },
196 { 0xfe, 0x4d, KEY_MENU },
197 { 0xfe, 0x51, KEY_UP },
198 { 0xfe, 0x5b, KEY_LEFT },
199 { 0xfe, 0x5f, KEY_RIGHT },
200 { 0xfe, 0x53, KEY_DOWN },
201 { 0xfe, 0x5e, KEY_OK },
202 { 0xfe, 0x59, KEY_INFO },
203 { 0xfe, 0x55, KEY_TAB },
204 { 0xfe, 0x0f, KEY_PREVIOUSSONG },/* Replay */
205 { 0xfe, 0x12, KEY_NEXTSONG }, /* Skip */
206 { 0xfe, 0x42, KEY_ENTER }, /* Windows/Start */
207 { 0xfe, 0x15, KEY_VOLUMEUP },
208 { 0xfe, 0x05, KEY_VOLUMEDOWN },
209 { 0xfe, 0x11, KEY_CHANNELUP },
210 { 0xfe, 0x09, KEY_CHANNELDOWN },
211 { 0xfe, 0x52, KEY_CAMERA },
212 { 0xfe, 0x5a, KEY_TUNER }, /* Live */
213 { 0xfe, 0x19, KEY_OPEN },
214 { 0xfe, 0x0b, KEY_1 },
215 { 0xfe, 0x17, KEY_2 },
216 { 0xfe, 0x1b, KEY_3 },
217 { 0xfe, 0x07, KEY_4 },
218 { 0xfe, 0x50, KEY_5 },
219 { 0xfe, 0x54, KEY_6 },
220 { 0xfe, 0x48, KEY_7 },
221 { 0xfe, 0x4c, KEY_8 },
222 { 0xfe, 0x58, KEY_9 },
223 { 0xfe, 0x13, KEY_ANGLE }, /* Aspect */
224 { 0xfe, 0x03, KEY_0 },
225 { 0xfe, 0x1f, KEY_ZOOM },
226 { 0xfe, 0x43, KEY_REWIND },
227 { 0xfe, 0x47, KEY_PLAYPAUSE },
228 { 0xfe, 0x4f, KEY_FASTFORWARD },
229 { 0xfe, 0x57, KEY_MUTE },
230 { 0xfe, 0x0d, KEY_STOP },
231 { 0xfe, 0x01, KEY_RECORD },
232 { 0xfe, 0x4e, KEY_POWER },
233};
234
235static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
236{
237 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
238 static u8 reset [] = { RESET, 0x80 };
239 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
240 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
241 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
242 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
243
244 mt352_write(fe, clock_config, sizeof(clock_config));
245 udelay(200);
246 mt352_write(fe, reset, sizeof(reset));
247 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
248
249 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
250 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
251 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
252
253 return 0;
254}
255
159struct cx22702_config cxusb_cx22702_config = { 256struct cx22702_config cxusb_cx22702_config = {
160 .demod_address = 0x63, 257 .demod_address = 0x63,
161 258
@@ -165,17 +262,47 @@ struct cx22702_config cxusb_cx22702_config = {
165 .pll_set = dvb_usb_pll_set_i2c, 262 .pll_set = dvb_usb_pll_set_i2c,
166}; 263};
167 264
265struct lgdt330x_config cxusb_lgdt330x_config = {
266 .demod_address = 0x0e,
267 .demod_chip = LGDT3303,
268 .pll_set = dvb_usb_pll_set_i2c,
269};
270
271struct mt352_config cxusb_dee1601_config = {
272 .demod_address = 0x0f,
273 .demod_init = cxusb_dee1601_demod_init,
274 .pll_set = dvb_usb_pll_set,
275};
276
168/* Callbacks for DVB USB */ 277/* Callbacks for DVB USB */
169static int cxusb_tuner_attach(struct dvb_usb_device *d) 278static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_device *d)
170{ 279{
171 u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 }; 280 u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 };
172 d->pll_addr = 0x61; 281 d->pll_addr = 0x61;
173 memcpy(d->pll_init,bpll,4); 282 memcpy(d->pll_init, bpll, 4);
174 d->pll_desc = &dvb_pll_fmd1216me; 283 d->pll_desc = &dvb_pll_fmd1216me;
175 return 0; 284 return 0;
176} 285}
177 286
178static int cxusb_frontend_attach(struct dvb_usb_device *d) 287static int cxusb_lgh064f_tuner_attach(struct dvb_usb_device *d)
288{
289 u8 bpll[4] = { 0x00, 0x00, 0x18, 0x50 };
290 /* bpll[2] : unset bit 3, set bits 4&5
291 bpll[3] : 0x50 - digital, 0x20 - analog */
292 d->pll_addr = 0x61;
293 memcpy(d->pll_init, bpll, 4);
294 d->pll_desc = &dvb_pll_tdvs_tua6034;
295 return 0;
296}
297
298static int cxusb_dee1601_tuner_attach(struct dvb_usb_device *d)
299{
300 d->pll_addr = 0x61;
301 d->pll_desc = &dvb_pll_thomson_dtt7579;
302 return 0;
303}
304
305static int cxusb_cx22702_frontend_attach(struct dvb_usb_device *d)
179{ 306{
180 u8 b; 307 u8 b;
181 if (usb_set_interface(d->udev,0,6) < 0) 308 if (usb_set_interface(d->udev,0,6) < 0)
@@ -189,22 +316,84 @@ static int cxusb_frontend_attach(struct dvb_usb_device *d)
189 return -EIO; 316 return -EIO;
190} 317}
191 318
319static int cxusb_lgdt330x_frontend_attach(struct dvb_usb_device *d)
320{
321 if (usb_set_interface(d->udev,0,7) < 0)
322 err("set interface failed");
323
324 cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
325
326 if ((d->fe = lgdt330x_attach(&cxusb_lgdt330x_config, &d->i2c_adap)) != NULL)
327 return 0;
328
329 return -EIO;
330}
331
332static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d)
333{
334 if (usb_set_interface(d->udev,0,0) < 0)
335 err("set interface failed");
336
337 cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
338
339 if ((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL)
340 return 0;
341
342 return -EIO;
343}
344
345/*
346 * DViCO bluebird firmware needs the "warm" product ID to be patched into the
347 * firmware file before download.
348 */
349
350#define BLUEBIRD_01_ID_OFFSET 6638
351static int bluebird_patch_dvico_firmware_download(struct usb_device *udev, const struct firmware *fw)
352{
353 if (fw->size < BLUEBIRD_01_ID_OFFSET + 4)
354 return -EINVAL;
355
356 if (fw->data[BLUEBIRD_01_ID_OFFSET] == (USB_VID_DVICO & 0xff) &&
357 fw->data[BLUEBIRD_01_ID_OFFSET + 1] == USB_VID_DVICO >> 8) {
358
359 /* FIXME: are we allowed to change the fw-data ? */
360 fw->data[BLUEBIRD_01_ID_OFFSET + 2] = udev->descriptor.idProduct + 1;
361 fw->data[BLUEBIRD_01_ID_OFFSET + 3] = udev->descriptor.idProduct >> 8;
362
363 return usb_cypress_load_firmware(udev,fw,CYPRESS_FX2);
364 }
365
366 return -EINVAL;
367}
368
192/* DVB USB Driver stuff */ 369/* DVB USB Driver stuff */
193static struct dvb_usb_properties cxusb_properties; 370static struct dvb_usb_properties cxusb_medion_properties;
371static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties;
372static struct dvb_usb_properties cxusb_bluebird_dee1601_properties;
194 373
195static int cxusb_probe(struct usb_interface *intf, 374static int cxusb_probe(struct usb_interface *intf,
196 const struct usb_device_id *id) 375 const struct usb_device_id *id)
197{ 376{
198 return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE,NULL); 377 if (dvb_usb_device_init(intf,&cxusb_medion_properties,THIS_MODULE,NULL) == 0 ||
378 dvb_usb_device_init(intf,&cxusb_bluebird_lgh064f_properties,THIS_MODULE,NULL) == 0 ||
379 dvb_usb_device_init(intf,&cxusb_bluebird_dee1601_properties,THIS_MODULE,NULL) == 0) {
380 return 0;
381 }
382
383 return -EINVAL;
199} 384}
200 385
201static struct usb_device_id cxusb_table [] = { 386static struct usb_device_id cxusb_table [] = {
202 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) }, 387 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
388 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
389 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
390 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DEE1601_COLD) },
391 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DEE1601_WARM) },
203 {} /* Terminating entry */ 392 {} /* Terminating entry */
204}; 393};
205MODULE_DEVICE_TABLE (usb, cxusb_table); 394MODULE_DEVICE_TABLE (usb, cxusb_table);
206 395
207static struct dvb_usb_properties cxusb_properties = { 396static struct dvb_usb_properties cxusb_medion_properties = {
208 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 397 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
209 398
210 .usb_ctrl = CYPRESS_FX2, 399 .usb_ctrl = CYPRESS_FX2,
@@ -213,8 +402,8 @@ static struct dvb_usb_properties cxusb_properties = {
213 402
214 .streaming_ctrl = cxusb_streaming_ctrl, 403 .streaming_ctrl = cxusb_streaming_ctrl,
215 .power_ctrl = cxusb_power_ctrl, 404 .power_ctrl = cxusb_power_ctrl,
216 .frontend_attach = cxusb_frontend_attach, 405 .frontend_attach = cxusb_cx22702_frontend_attach,
217 .tuner_attach = cxusb_tuner_attach, 406 .tuner_attach = cxusb_fmd1216me_tuner_attach,
218 407
219 .i2c_algo = &cxusb_i2c_algo, 408 .i2c_algo = &cxusb_i2c_algo,
220 409
@@ -240,6 +429,91 @@ static struct dvb_usb_properties cxusb_properties = {
240 } 429 }
241}; 430};
242 431
432static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = {
433 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
434
435 .usb_ctrl = DEVICE_SPECIFIC,
436 .firmware = "dvb-usb-bluebird-01.fw",
437 .download_firmware = bluebird_patch_dvico_firmware_download,
438 /* use usb alt setting 0 for EP4 transfer (dvb-t),
439 use usb alt setting 7 for EP2 transfer (atsc) */
440
441 .size_of_priv = sizeof(struct cxusb_state),
442
443 .streaming_ctrl = cxusb_streaming_ctrl,
444 .power_ctrl = cxusb_power_ctrl,
445 .frontend_attach = cxusb_lgdt330x_frontend_attach,
446 .tuner_attach = cxusb_lgh064f_tuner_attach,
447
448 .i2c_algo = &cxusb_i2c_algo,
449
450 .generic_bulk_ctrl_endpoint = 0x01,
451 /* parameter for the MPEG2-data transfer */
452 .urb = {
453 .type = DVB_USB_BULK,
454 .count = 5,
455 .endpoint = 0x02,
456 .u = {
457 .bulk = {
458 .buffersize = 8192,
459 }
460 }
461 },
462
463 .num_device_descs = 1,
464 .devices = {
465 { "DViCO FusionHDTV5 USB Gold",
466 { &cxusb_table[1], NULL },
467 { &cxusb_table[2], NULL },
468 },
469 }
470};
471
472static struct dvb_usb_properties cxusb_bluebird_dee1601_properties = {
473 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
474
475 .usb_ctrl = DEVICE_SPECIFIC,
476 .firmware = "dvb-usb-bluebird-01.fw",
477 .download_firmware = bluebird_patch_dvico_firmware_download,
478 /* use usb alt setting 0 for EP4 transfer (dvb-t),
479 use usb alt setting 7 for EP2 transfer (atsc) */
480
481 .size_of_priv = sizeof(struct cxusb_state),
482
483 .streaming_ctrl = cxusb_streaming_ctrl,
484 .power_ctrl = cxusb_power_ctrl,
485 .frontend_attach = cxusb_dee1601_frontend_attach,
486 .tuner_attach = cxusb_dee1601_tuner_attach,
487
488 .i2c_algo = &cxusb_i2c_algo,
489
490 .rc_interval = 150,
491 .rc_key_map = dvico_mce_rc_keys,
492 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys),
493 .rc_query = cxusb_rc_query,
494
495 .generic_bulk_ctrl_endpoint = 0x01,
496 /* parameter for the MPEG2-data transfer */
497 .urb = {
498 .type = DVB_USB_BULK,
499 .count = 5,
500 .endpoint = 0x04,
501 .u = {
502 .bulk = {
503 .buffersize = 8192,
504 }
505 }
506 },
507
508 .num_device_descs = 1,
509 .devices = {
510 { "DViCO FusionHDTV DVB-T Dual USB",
511 { &cxusb_table[3], NULL },
512 { &cxusb_table[4], NULL },
513 },
514 }
515};
516
243static struct usb_driver cxusb_driver = { 517static struct usb_driver cxusb_driver = {
244 .name = "dvb_usb_cxusb", 518 .name = "dvb_usb_cxusb",
245 .probe = cxusb_probe, 519 .probe = cxusb_probe,
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h
index 135c2a81f581..087c99427853 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.h
+++ b/drivers/media/dvb/dvb-usb/cxusb.h
@@ -21,6 +21,8 @@ extern int dvb_usb_cxusb_debug;
21#define CMD_STREAMING_ON 0x36 21#define CMD_STREAMING_ON 0x36
22#define CMD_STREAMING_OFF 0x37 22#define CMD_STREAMING_OFF 0x37
23 23
24#define CMD_GET_IR_CODE 0x47
25
24#define CMD_ANALOG 0x50 26#define CMD_ANALOG 0x50
25#define CMD_DIGITAL 0x51 27#define CMD_DIGITAL 0x51
26 28
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index 52ac3e5adf5d..dd5a13195886 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -65,11 +65,11 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d)
65 d->tuner_pass_ctrl(d->fe,0,msg[0].addr); 65 d->tuner_pass_ctrl(d->fe,0,msg[0].addr);
66 66
67 if (b2[0] == 0xfe) { 67 if (b2[0] == 0xfe) {
68 info("this device has the Thomson Cable onboard. Which is default."); 68 info("This device has the Thomson Cable onboard. Which is default.");
69 dibusb_thomson_tuner_attach(d); 69 dibusb_thomson_tuner_attach(d);
70 } else { 70 } else {
71 u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab }; 71 u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab };
72 info("this device has the Panasonic ENV77H11D5 onboard."); 72 info("This device has the Panasonic ENV77H11D5 onboard.");
73 d->pll_addr = 0x60; 73 d->pll_addr = 0x60;
74 memcpy(d->pll_init,bpll,4); 74 memcpy(d->pll_init,bpll,4);
75 d->pll_desc = &dvb_pll_tda665x; 75 d->pll_desc = &dvb_pll_tda665x;
@@ -98,15 +98,15 @@ static int dibusb_probe(struct usb_interface *intf,
98 98
99/* do not change the order of the ID table */ 99/* do not change the order of the ID table */
100static struct usb_device_id dibusb_dib3000mb_table [] = { 100static struct usb_device_id dibusb_dib3000mb_table [] = {
101/* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD)}, 101/* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD) },
102/* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM)}, 102/* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM) },
103/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) }, 103/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
104/* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) }, 104/* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) },
105/* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) }, 105/* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) },
106/* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) }, 106/* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) },
107/* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) }, 107/* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) },
108/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) }, 108/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) },
109/* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) }, 109/* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) },
110/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) }, 110/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) },
111/* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) }, 111/* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) },
112/* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) }, 112/* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) },
@@ -117,27 +117,34 @@ static struct usb_device_id dibusb_dib3000mb_table [] = {
117/* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) }, 117/* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) },
118/* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) }, 118/* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) },
119/* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) }, 119/* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) },
120/* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) }, 120/* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
121/* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) }, 121/* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
122/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) }, 122/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
123/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) }, 123/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
124/* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) }, 124/* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) },
125 125
126/* device ID with default DIBUSB2_0-firmware and with the hacked firmware */ 126/* device ID with default DIBUSB2_0-firmware and with the hacked firmware */
127/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, 127/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) },
128/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) }, 128/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) },
129/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) }, 129/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) },
130 130
131/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, 131/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) },
132 132
133/* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, 133/* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
134/* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, 134/* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) },
135 135
136// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 136/*
137 * XXX: As Artec just 'forgot' to program the EEPROM on some Artec T1 devices
138 * we don't catch these faulty IDs (namely 'Cypress FX1 USB controller') that
139 * have been left on the device. If you don't have such a device but an Artec
140 * device that's supposed to work with this driver but is not detected by it,
141 * free to enable CONFIG_DVB_USB_DIBUSB_MB_FAULTY via your kernel config.
142 */
137 143
138#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 144#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
139/* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, 145/* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
140#endif 146#endif
147
141 { } /* Terminating entry */ 148 { } /* Terminating entry */
142}; 149};
143MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table); 150MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
@@ -257,7 +264,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
257 } 264 }
258 }, 265 },
259 266
260#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 267#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
261 .num_device_descs = 2, 268 .num_device_descs = 2,
262#else 269#else
263 .num_device_descs = 1, 270 .num_device_descs = 1,
@@ -267,11 +274,12 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
267 { &dibusb_dib3000mb_table[20], NULL }, 274 { &dibusb_dib3000mb_table[20], NULL },
268 { &dibusb_dib3000mb_table[21], NULL }, 275 { &dibusb_dib3000mb_table[21], NULL },
269 }, 276 },
270#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 277#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
271 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", 278 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
272 { &dibusb_dib3000mb_table[30], NULL }, 279 { &dibusb_dib3000mb_table[30], NULL },
273 { NULL }, 280 { NULL },
274 }, 281 },
282 { NULL },
275#endif 283#endif
276 } 284 }
277}; 285};
@@ -323,6 +331,7 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
323 { &dibusb_dib3000mb_table[27], NULL }, 331 { &dibusb_dib3000mb_table[27], NULL },
324 { NULL } 332 { NULL }
325 }, 333 },
334 { NULL },
326 } 335 }
327}; 336};
328 337
@@ -369,6 +378,7 @@ static struct dvb_usb_properties artec_t1_usb2_properties = {
369 { &dibusb_dib3000mb_table[28], NULL }, 378 { &dibusb_dib3000mb_table[28], NULL },
370 { &dibusb_dib3000mb_table[29], NULL }, 379 { &dibusb_dib3000mb_table[29], NULL },
371 }, 380 },
381 { NULL },
372 } 382 }
373}; 383};
374 384
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index 450417a9e64b..e6c55c9c9417 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -32,7 +32,7 @@ static int digitv_ctrl_msg(struct dvb_usb_device *d,
32 sndbuf[1] = vv; 32 sndbuf[1] = vv;
33 sndbuf[2] = wo ? wlen : rlen; 33 sndbuf[2] = wo ? wlen : rlen;
34 34
35 if (!wo) { 35 if (wo) {
36 memcpy(&sndbuf[3],wbuf,wlen); 36 memcpy(&sndbuf[3],wbuf,wlen);
37 dvb_usb_generic_write(d,sndbuf,7); 37 dvb_usb_generic_write(d,sndbuf,7);
38 } else { 38 } else {
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index 6e2bac873445..130ea7f21f5e 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = {
151 .cold_ids = { &dtt200u_usb_table[0], NULL }, 151 .cold_ids = { &dtt200u_usb_table[0], NULL },
152 .warm_ids = { &dtt200u_usb_table[1], NULL }, 152 .warm_ids = { &dtt200u_usb_table[1], NULL },
153 }, 153 },
154 { NULL }, 154 { 0 },
155 } 155 }
156}; 156};
157 157
@@ -160,7 +160,7 @@ static struct dvb_usb_properties wt220u_properties = {
160 .pid_filter_count = 15, 160 .pid_filter_count = 15,
161 161
162 .usb_ctrl = CYPRESS_FX2, 162 .usb_ctrl = CYPRESS_FX2,
163 .firmware = "dvb-usb-wt220u-01.fw", 163 .firmware = "dvb-usb-wt220u-02.fw",
164 164
165 .power_ctrl = dtt200u_power_ctrl, 165 .power_ctrl = dtt200u_power_ctrl,
166 .streaming_ctrl = dtt200u_streaming_ctrl, 166 .streaming_ctrl = dtt200u_streaming_ctrl,
@@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_properties = {
192 .cold_ids = { &dtt200u_usb_table[2], NULL }, 192 .cold_ids = { &dtt200u_usb_table[2], NULL },
193 .warm_ids = { &dtt200u_usb_table[3], NULL }, 193 .warm_ids = { &dtt200u_usb_table[3], NULL },
194 }, 194 },
195 { NULL }, 195 { 0 },
196 } 196 }
197}; 197};
198 198
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h
index 6f1f3042e21a..005b0a7df358 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.h
+++ b/drivers/media/dvb/dvb-usb/dtt200u.h
@@ -13,6 +13,7 @@
13#define _DVB_USB_DTT200U_H_ 13#define _DVB_USB_DTT200U_H_
14 14
15#define DVB_USB_LOG_PREFIX "dtt200u" 15#define DVB_USB_LOG_PREFIX "dtt200u"
16
16#include "dvb-usb.h" 17#include "dvb-usb.h"
17 18
18extern int dvb_usb_dtt200u_debug; 19extern int dvb_usb_dtt200u_debug;
@@ -25,15 +26,15 @@ extern int dvb_usb_dtt200u_debug;
25 * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal) 26 * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
26 */ 27 */
27 28
28#define GET_SPEED 0x00 29#define GET_SPEED 0x00
29#define GET_TUNE_STATUS 0x81 30#define GET_TUNE_STATUS 0x81
30#define GET_RC_CODE 0x84 31#define GET_RC_CODE 0x84
31#define GET_CONFIGURATION 0x88 32#define GET_CONFIGURATION 0x88
32#define GET_AGC 0x89 33#define GET_AGC 0x89
33#define GET_SNR 0x8a 34#define GET_SNR 0x8a
34#define GET_VIT_ERR_CNT 0x8c 35#define GET_VIT_ERR_CNT 0x8c
35#define GET_RS_ERR_CNT 0x8d 36#define GET_RS_ERR_CNT 0x8d
36#define GET_RS_UNCOR_BLK_CNT 0x8e 37#define GET_RS_UNCOR_BLK_CNT 0x8e
37 38
38/* write 39/* write
39 * 01 - init 40 * 01 - init
@@ -44,12 +45,12 @@ extern int dvb_usb_dtt200u_debug;
44 * 08 - transfer switch 45 * 08 - transfer switch
45 */ 46 */
46 47
47#define SET_INIT 0x01 48#define SET_INIT 0x01
48#define SET_RF_FREQ 0x02 49#define SET_RF_FREQ 0x02
49#define SET_BANDWIDTH 0x03 50#define SET_BANDWIDTH 0x03
50#define SET_PID_FILTER 0x04 51#define SET_PID_FILTER 0x04
51#define RESET_PID_FILTER 0x05 52#define RESET_PID_FILTER 0x05
52#define SET_STREAMING 0x08 53#define SET_STREAMING 0x08
53 54
54extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d); 55extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d);
55 56
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
index 7300489d3e24..a3460bf2d9fa 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-common.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
@@ -24,7 +24,7 @@ extern int dvb_usb_disable_rc_polling;
24#define deb_mem(args...) dprintk(dvb_usb_debug,0x80,args) 24#define deb_mem(args...) dprintk(dvb_usb_debug,0x80,args)
25 25
26/* commonly used methods */ 26/* commonly used methods */
27extern int usb_cypress_load_firmware(struct usb_device *, const char *, int); 27extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_properties *);
28 28
29extern int dvb_usb_urb_submit(struct dvb_usb_device *); 29extern int dvb_usb_urb_submit(struct dvb_usb_device *);
30extern int dvb_usb_urb_kill(struct dvb_usb_device *); 30extern int dvb_usb_urb_kill(struct dvb_usb_device *);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
index 5244e39770a0..8535895819fb 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
@@ -9,7 +9,6 @@
9 */ 9 */
10#include "dvb-usb-common.h" 10#include "dvb-usb-common.h"
11 11
12#include <linux/firmware.h>
13#include <linux/usb.h> 12#include <linux/usb.h>
14 13
15struct usb_cypress_controller { 14struct usb_cypress_controller {
@@ -19,9 +18,10 @@ struct usb_cypress_controller {
19}; 18};
20 19
21static struct usb_cypress_controller cypress[] = { 20static struct usb_cypress_controller cypress[] = {
22 { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 }, 21 { .id = DEVICE_SPECIFIC, .name = "Device specific", .cpu_cs_register = 0 },
23 { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 }, 22 { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
24 { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, 23 { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
24 { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 },
25}; 25};
26 26
27/* 27/*
@@ -30,71 +30,117 @@ static struct usb_cypress_controller cypress[] = {
30static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len) 30static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
31{ 31{
32 return usb_control_msg(udev, usb_sndctrlpipe(udev,0), 32 return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
33 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5*HZ); 33 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
34} 34}
35 35
36int usb_cypress_load_firmware(struct usb_device *udev, const char *filename, int type) 36int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type)
37{ 37{
38 const struct firmware *fw = NULL; 38 struct hexline hx;
39 u16 addr; 39 u8 reset;
40 u8 *b,*p; 40 int ret,pos=0;
41 int ret = 0,i;
42 41
43 if ((ret = request_firmware(&fw, filename, &udev->dev)) != 0) { 42 /* stop the CPU */
44 err("did not find the firmware file. (%s) " 43 reset = 1;
45 "Please see linux/Documentation/dvb/ for more details on firmware-problems.", 44 if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
46 filename); 45 err("could not stop the USB controller CPU.");
46
47 while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) {
48 deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk);
49 ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len);
50
51 if (ret != hx.len) {
52 err("error while transferring firmware "
53 "(transferred size: %d, block size: %d)",
54 ret,hx.len);
55 ret = -EINVAL;
56 break;
57 }
58 }
59 if (ret < 0) {
60 err("firmware download failed at %d with %d",pos,ret);
47 return ret; 61 return ret;
48 } 62 }
49 63
50 info("downloading firmware from file '%s' to the '%s'",filename,cypress[type].name); 64 if (ret == 0) {
51
52 p = kmalloc(fw->size,GFP_KERNEL);
53 if (p != NULL) {
54 u8 reset;
55 /*
56 * you cannot use the fw->data as buffer for
57 * usb_control_msg, a new buffer has to be
58 * created
59 */
60 memcpy(p,fw->data,fw->size);
61
62 /* stop the CPU */
63 reset = 1;
64 if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
65 err("could not stop the USB controller CPU.");
66 for(i = 0; p[i+3] == 0 && i < fw->size; ) {
67 b = (u8 *) &p[i];
68 addr = cpu_to_le16( *((u16 *) &b[1]) );
69
70 deb_fw("writing to address 0x%04x (buffer: 0x%02x%02x)\n",addr,b[1],b[2]);
71
72 ret = usb_cypress_writemem(udev,addr,&b[4],b[0]);
73
74 if (ret != b[0]) {
75 err("error while transferring firmware "
76 "(transferred size: %d, block size: %d)",
77 ret,b[0]);
78 ret = -EINVAL;
79 break;
80 }
81 i += 5 + b[0];
82 }
83 /* length in ret */
84 if (ret > 0)
85 ret = 0;
86 /* restart the CPU */ 65 /* restart the CPU */
87 reset = 0; 66 reset = 0;
88 if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) { 67 if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
89 err("could not restart the USB controller CPU."); 68 err("could not restart the USB controller CPU.");
90 ret = -EINVAL; 69 ret = -EINVAL;
91 } 70 }
71 } else
72 ret = -EIO;
92 73
93 kfree(p); 74 return ret;
94 } else { 75}
95 ret = -ENOMEM; 76EXPORT_SYMBOL(usb_cypress_load_firmware);
77
78int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_properties *props)
79{
80 int ret;
81 const struct firmware *fw = NULL;
82
83 if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) {
84 err("did not find the firmware file. (%s) "
85 "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
86 props->firmware,ret);
87 return ret;
96 } 88 }
97 release_firmware(fw);
98 89
90 info("downloading firmware from file '%s'",props->firmware);
91
92 switch (props->usb_ctrl) {
93 case CYPRESS_AN2135:
94 case CYPRESS_AN2235:
95 case CYPRESS_FX2:
96 ret = usb_cypress_load_firmware(udev, fw, props->usb_ctrl);
97 break;
98 case DEVICE_SPECIFIC:
99 if (props->download_firmware)
100 ret = props->download_firmware(udev,fw);
101 else {
102 err("BUG: driver didn't specified a download_firmware-callback, although it claims to have a DEVICE_SPECIFIC one.");
103 ret = -EINVAL;
104 }
105 break;
106 default:
107 ret = -EINVAL;
108 break;
109 }
110
111 release_firmware(fw);
99 return ret; 112 return ret;
100} 113}
114
115int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos)
116{
117 u8 *b = (u8 *) &fw->data[*pos];
118 int data_offs = 4;
119 if (*pos >= fw->size)
120 return 0;
121
122 memset(hx,0,sizeof(struct hexline));
123
124 hx->len = b[0];
125
126 if ((*pos + hx->len + 4) >= fw->size)
127 return -EINVAL;
128
129 hx->addr = le16_to_cpu( *((u16 *) &b[1]) );
130 hx->type = b[3];
131
132 if (hx->type == 0x04) {
133 /* b[4] and b[5] are the Extended linear address record data field */
134 hx->addr |= (b[4] << 24) | (b[5] << 16);
135/* hx->len -= 2;
136 data_offs += 2; */
137 }
138 memcpy(hx->data,&b[data_offs],hx->len);
139 hx->chk = b[hx->len + data_offs];
140
141 *pos += hx->len + 5;
142
143 return *pos;
144}
145EXPORT_SYMBOL(dvb_usb_get_hexline);
146
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
index da970947dfc7..9b254532af4d 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -52,9 +52,8 @@ int dvb_usb_pll_init_i2c(struct dvb_frontend *fe)
52 struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 }; 52 struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 };
53 int ret = 0; 53 int ret = 0;
54 54
55 /* if there is nothing to initialize */ 55 /* if pll_desc is not used */
56 if (d->pll_init[0] == 0x00 && d->pll_init[1] == 0x00 && 56 if (d->pll_desc == NULL)
57 d->pll_init[2] == 0x00 && d->pll_init[3] == 0x00)
58 return 0; 57 return 0;
59 58
60 if (d->tuner_pass_ctrl) 59 if (d->tuner_pass_ctrl)
@@ -80,6 +79,9 @@ int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep
80{ 79{
81 struct dvb_usb_device *d = fe->dvb->priv; 80 struct dvb_usb_device *d = fe->dvb->priv;
82 81
82 if (d->pll_desc == NULL)
83 return 0;
84
83 deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc); 85 deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc);
84 86
85 b[0] = d->pll_addr << 1; 87 b[0] = d->pll_addr << 1;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 6be99e537e12..d22934383226 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -86,11 +86,15 @@
86#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300 86#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
87#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 87#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
88#define USB_PID_NEBULA_DIGITV 0x0201 88#define USB_PID_NEBULA_DIGITV 0x0201
89#define USB_PID_DVICO_BLUEBIRD_LGZ201 0xdb00
90#define USB_PID_DVICO_BLUEBIRD_TH7579 0xdb10
91#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820 89#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820
92#define USB_PID_DVICO_BLUEBIRD_LGZ201_1 0xdb01 90#define USB_PID_DVICO_BLUEBIRD_LG064F_COLD 0xd500
93#define USB_PID_DVICO_BLUEBIRD_TH7579_2 0xdb11 91#define USB_PID_DVICO_BLUEBIRD_LG064F_WARM 0xd501
92#define USB_PID_DVICO_BLUEBIRD_LGZ201_COLD 0xdb00
93#define USB_PID_DVICO_BLUEBIRD_LGZ201_WARM 0xdb01
94#define USB_PID_DVICO_BLUEBIRD_TH7579_COLD 0xdb10
95#define USB_PID_DVICO_BLUEBIRD_TH7579_WARM 0xdb11
96#define USB_PID_DVICO_BLUEBIRD_DEE1601_COLD 0xdb50
97#define USB_PID_DVICO_BLUEBIRD_DEE1601_WARM 0xdb51
94#define USB_PID_MEDION_MD95700 0x0932 98#define USB_PID_MEDION_MD95700 0x0932
95#define USB_PID_KYE_DVB_T_COLD 0x701e 99#define USB_PID_KYE_DVB_T_COLD 0x701e
96#define USB_PID_KYE_DVB_T_WARM 0x701f 100#define USB_PID_KYE_DVB_T_WARM 0x701f
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
index dd8e0b94edba..2e23060cbbca 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -138,6 +138,9 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties
138 138
139 int ret = -ENOMEM,cold=0; 139 int ret = -ENOMEM,cold=0;
140 140
141 if (du != NULL)
142 *du = NULL;
143
141 if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) { 144 if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) {
142 deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); 145 deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n");
143 return -ENODEV; 146 return -ENODEV;
@@ -145,38 +148,40 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties
145 148
146 if (cold) { 149 if (cold) {
147 info("found a '%s' in cold state, will try to load a firmware",desc->name); 150 info("found a '%s' in cold state, will try to load a firmware",desc->name);
148 ret = usb_cypress_load_firmware(udev,props->firmware,props->usb_ctrl); 151 ret = dvb_usb_download_firmware(udev,props);
149 } else { 152 if (!props->no_reconnect)
150 info("found a '%s' in warm state.",desc->name);
151 d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL);
152 if (d == NULL) {
153 err("no memory for 'struct dvb_usb_device'");
154 return ret; 153 return ret;
154 }
155
156 info("found a '%s' in warm state.",desc->name);
157 d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL);
158 if (d == NULL) {
159 err("no memory for 'struct dvb_usb_device'");
160 return ret;
161 }
162 memset(d,0,sizeof(struct dvb_usb_device));
163
164 d->udev = udev;
165 memcpy(&d->props,props,sizeof(struct dvb_usb_properties));
166 d->desc = desc;
167 d->owner = owner;
168
169 if (d->props.size_of_priv > 0) {
170 d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL);
171 if (d->priv == NULL) {
172 err("no memory for priv in 'struct dvb_usb_device'");
173 kfree(d);
174 return -ENOMEM;
155 } 175 }
156 memset(d,0,sizeof(struct dvb_usb_device)); 176 memset(d->priv,0,d->props.size_of_priv);
157 177 }
158 d->udev = udev;
159 memcpy(&d->props,props,sizeof(struct dvb_usb_properties));
160 d->desc = desc;
161 d->owner = owner;
162
163 if (d->props.size_of_priv > 0) {
164 d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL);
165 if (d->priv == NULL) {
166 err("no memory for priv in 'struct dvb_usb_device'");
167 kfree(d);
168 return -ENOMEM;
169 }
170 memset(d->priv,0,d->props.size_of_priv);
171 }
172 178
173 usb_set_intfdata(intf, d); 179 usb_set_intfdata(intf, d);
174 180
175 if (du != NULL) 181 if (du != NULL)
176 *du = d; 182 *du = d;
177 183
178 ret = dvb_usb_init(d); 184 ret = dvb_usb_init(d);
179 }
180 185
181 if (ret == 0) 186 if (ret == 0)
182 info("%s successfully initialized and connected.",desc->name); 187 info("%s successfully initialized and connected.",desc->name);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index b4a1a98006c7..dd568396e594 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -10,8 +10,8 @@
10 10
11#include <linux/config.h> 11#include <linux/config.h>
12#include <linux/input.h> 12#include <linux/input.h>
13#include <linux/module.h>
14#include <linux/usb.h> 13#include <linux/usb.h>
14#include <linux/firmware.h>
15 15
16#include "dvb_frontend.h" 16#include "dvb_frontend.h"
17#include "dvb_demux.h" 17#include "dvb_demux.h"
@@ -94,7 +94,11 @@ struct dvb_usb_device;
94 * @usb_ctrl: which USB device-side controller is in use. Needed for firmware 94 * @usb_ctrl: which USB device-side controller is in use. Needed for firmware
95 * download. 95 * download.
96 * @firmware: name of the firmware file. 96 * @firmware: name of the firmware file.
97 * 97 * @download_firmware: called to download the firmware when the usb_ctrl is
98 * DEVICE_SPECIFIC.
99 * @no_reconnect: device doesn't do a reconnect after downloading the firmware,
100 so do the warm initialization right after it
101
98 * @size_of_priv: how many bytes shall be allocated for the private field 102 * @size_of_priv: how many bytes shall be allocated for the private field
99 * of struct dvb_usb_device. 103 * of struct dvb_usb_device.
100 * 104 *
@@ -142,11 +146,14 @@ struct dvb_usb_properties {
142 int caps; 146 int caps;
143 int pid_filter_count; 147 int pid_filter_count;
144 148
145#define CYPRESS_AN2135 0 149#define DEVICE_SPECIFIC 0
146#define CYPRESS_AN2235 1 150#define CYPRESS_AN2135 1
147#define CYPRESS_FX2 2 151#define CYPRESS_AN2235 2
152#define CYPRESS_FX2 3
148 int usb_ctrl; 153 int usb_ctrl;
149 const char *firmware; 154 const char firmware[FIRMWARE_NAME_MAX];
155 int (*download_firmware) (struct usb_device *, const struct firmware *);
156 int no_reconnect;
150 157
151 int size_of_priv; 158 int size_of_priv;
152 159
@@ -326,5 +333,15 @@ extern int dvb_usb_pll_init_i2c(struct dvb_frontend *);
326extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]); 333extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]);
327extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); 334extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *);
328 335
336/* commonly used firmware download types and function */
337struct hexline {
338 u8 len;
339 u32 addr;
340 u8 type;
341 u8 data[255];
342 u8 chk;
343};
344extern int dvb_usb_get_hexline(const struct firmware *, struct hexline *, int *);
345extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type);
329 346
330#endif 347#endif
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index fac48fc7a4ac..412039d8dbae 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -129,10 +129,6 @@ static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6])
129 dibusb_read_eeprom_byte(d,i, &b); 129 dibusb_read_eeprom_byte(d,i, &b);
130 130
131 mac[5 - (i - 136)] = b; 131 mac[5 - (i - 136)] = b;
132
133/* deb_ee("%02x ",b);
134 if ((i+1) % 16 == 0)
135 deb_ee("\n");*/
136 } 132 }
137 133
138 return 0; 134 return 0;
@@ -153,7 +149,7 @@ static struct usb_device_id nova_t_table [] = {
153/* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) }, 149/* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) },
154 { } /* Terminating entry */ 150 { } /* Terminating entry */
155}; 151};
156MODULE_DEVICE_TABLE (usb, nova_t_table); 152MODULE_DEVICE_TABLE(usb, nova_t_table);
157 153
158static struct dvb_usb_properties nova_t_properties = { 154static struct dvb_usb_properties nova_t_properties = {
159 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, 155 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
@@ -198,6 +194,7 @@ static struct dvb_usb_properties nova_t_properties = {
198 { &nova_t_table[0], NULL }, 194 { &nova_t_table[0], NULL },
199 { &nova_t_table[1], NULL }, 195 { &nova_t_table[1], NULL },
200 }, 196 },
197 { NULL },
201 } 198 }
202}; 199};
203 200
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c
index 104b5d016c7b..0885d9fb2bf2 100644
--- a/drivers/media/dvb/dvb-usb/vp702x-fe.c
+++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c
@@ -190,7 +190,7 @@ static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
190} 190}
191 191
192static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, 192static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
193 struct dvb_diseqc_master_cmd *m) 193 struct dvb_diseqc_master_cmd *m)
194{ 194{
195 struct vp702x_fe_state *st = fe->demodulator_priv; 195 struct vp702x_fe_state *st = fe->demodulator_priv;
196 u8 cmd[8],ibuf[10]; 196 u8 cmd[8],ibuf[10];
diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h
index 4a3e8c7eca2b..a808d48e7bf2 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.h
+++ b/drivers/media/dvb/dvb-usb/vp702x.h
@@ -13,47 +13,47 @@ extern int dvb_usb_vp702x_debug;
13/* commands are read and written with USB control messages */ 13/* commands are read and written with USB control messages */
14 14
15/* consecutive read/write operation */ 15/* consecutive read/write operation */
16#define REQUEST_OUT 0xB2 16#define REQUEST_OUT 0xB2
17#define REQUEST_IN 0xB3 17#define REQUEST_IN 0xB3
18 18
19/* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0 19/* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0
20 * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer 20 * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer
21 * the returning buffer looks as follows 21 * the returning buffer looks as follows
22 * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */ 22 * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */
23 23
24#define GET_TUNER_STATUS 0x05 24#define GET_TUNER_STATUS 0x05
25/* additional in buffer: 25/* additional in buffer:
26 * 0 1 2 3 4 5 6 7 8 26 * 0 1 2 3 4 5 6 7 8
27 * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */ 27 * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */
28 28
29#define GET_SYSTEM_STRING 0x06 29#define GET_SYSTEM_STRING 0x06
30/* additional in buffer: 30/* additional in buffer:
31 * 0 1 2 3 4 5 6 7 8 31 * 0 1 2 3 4 5 6 7 8
32 * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */ 32 * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */
33 33
34#define SET_DISEQC_CMD 0x08 34#define SET_DISEQC_CMD 0x08
35/* additional out buffer: 35/* additional out buffer:
36 * 0 1 2 3 4 36 * 0 1 2 3 4
37 * len X1 X2 X3 X4 37 * len X1 X2 X3 X4
38 * additional in buffer: 38 * additional in buffer:
39 * 0 1 2 39 * 0 1 2
40 * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */ 40 * N/A 0 0 b[1] == b[2] == 0 -> success, failure otherwise */
41 41
42#define SET_LNB_POWER 0x09 42#define SET_LNB_POWER 0x09
43/* additional out buffer: 43/* additional out buffer:
44 * 0 1 2 44 * 0 1 2
45 * 0x00 0xff 1 = on, 0 = off 45 * 0x00 0xff 1 = on, 0 = off
46 * additional in buffer: 46 * additional in buffer:
47 * 0 1 2 47 * 0 1 2
48 * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */ 48 * N/A 0 0 b[1] == b[2] == 0 -> success failure otherwise */
49 49
50#define GET_MAC_ADDRESS 0x0A 50#define GET_MAC_ADDRESS 0x0A
51/* #define GET_MAC_ADDRESS 0x0B */ 51/* #define GET_MAC_ADDRESS 0x0B */
52/* additional in buffer: 52/* additional in buffer:
53 * 0 1 2 3 4 5 6 7 8 53 * 0 1 2 3 4 5 6 7 8
54 * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */ 54 * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */
55 55
56#define SET_PID_FILTER 0x11 56#define SET_PID_FILTER 0x11
57/* additional in buffer: 57/* additional in buffer:
58 * 0 1 ... 14 15 16 58 * 0 1 ... 14 15 16
59 * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */ 59 * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */
@@ -64,39 +64,38 @@ extern int dvb_usb_vp702x_debug;
64 * freq0 freq1 divstep srate0 srate1 srate2 flag chksum 64 * freq0 freq1 divstep srate0 srate1 srate2 flag chksum
65 */ 65 */
66 66
67
68/* one direction requests */ 67/* one direction requests */
69#define READ_REMOTE_REQ 0xB4 68#define READ_REMOTE_REQ 0xB4
70/* IN i: 0; v: 0; b[0] == request, b[1] == key */ 69/* IN i: 0; v: 0; b[0] == request, b[1] == key */
71 70
72#define READ_PID_NUMBER_REQ 0xB5 71#define READ_PID_NUMBER_REQ 0xB5
73/* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */ 72/* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */
74 73
75#define WRITE_EEPROM_REQ 0xB6 74#define WRITE_EEPROM_REQ 0xB6
76/* OUT i: offset; v: value to write; no extra buffer */ 75/* OUT i: offset; v: value to write; no extra buffer */
77 76
78#define READ_EEPROM_REQ 0xB7 77#define READ_EEPROM_REQ 0xB7
79/* IN i: bufferlen; v: offset; buffer with bufferlen bytes */ 78/* IN i: bufferlen; v: offset; buffer with bufferlen bytes */
80 79
81#define READ_STATUS 0xB8 80#define READ_STATUS 0xB8
82/* IN i: 0; v: 0; bufferlen 10 */ 81/* IN i: 0; v: 0; bufferlen 10 */
83 82
84#define READ_TUNER_REG_REQ 0xB9 83#define READ_TUNER_REG_REQ 0xB9
85/* IN i: 0; v: register; b[0] = value */ 84/* IN i: 0; v: register; b[0] = value */
86 85
87#define READ_FX2_REG_REQ 0xBA 86#define READ_FX2_REG_REQ 0xBA
88/* IN i: offset; v: 0; b[0] = value */ 87/* IN i: offset; v: 0; b[0] = value */
89 88
90#define WRITE_FX2_REG_REQ 0xBB 89#define WRITE_FX2_REG_REQ 0xBB
91/* OUT i: offset; v: value to write; 1 byte extra buffer */ 90/* OUT i: offset; v: value to write; 1 byte extra buffer */
92 91
93#define SET_TUNER_POWER_REQ 0xBC 92#define SET_TUNER_POWER_REQ 0xBC
94/* IN i: 0 = power off, 1 = power on */ 93/* IN i: 0 = power off, 1 = power on */
95 94
96#define WRITE_TUNER_REG_REQ 0xBD 95#define WRITE_TUNER_REG_REQ 0xBD
97/* IN i: register, v: value to write, no extra buffer */ 96/* IN i: register, v: value to write, no extra buffer */
98 97
99#define RESET_TUNER 0xBE 98#define RESET_TUNER 0xBE
100/* IN i: 0, v: 0, no extra buffer */ 99/* IN i: 0, v: 0, no extra buffer */
101 100
102extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d); 101extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index 3835235b68df..028204956bb0 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = {
247 .cold_ids = { &vp7045_usb_table[2], NULL }, 247 .cold_ids = { &vp7045_usb_table[2], NULL },
248 .warm_ids = { &vp7045_usb_table[3], NULL }, 248 .warm_ids = { &vp7045_usb_table[3], NULL },
249 }, 249 },
250 { NULL }, 250 { 0 },
251 } 251 }
252}; 252};
253 253
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 8e269e1c1f9d..db3a8b40031e 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -16,6 +16,12 @@ config DVB_CX24110
16 help 16 help
17 A DVB-S tuner module. Say Y when you want to support this frontend. 17 A DVB-S tuner module. Say Y when you want to support this frontend.
18 18
19config DVB_CX24123
20 tristate "Conexant CX24123 based"
21 depends on DVB_CORE
22 help
23 A DVB-S tuner module. Say Y when you want to support this frontend.
24
19config DVB_TDA8083 25config DVB_TDA8083
20 tristate "Philips TDA8083 based" 26 tristate "Philips TDA8083 based"
21 depends on DVB_CORE 27 depends on DVB_CORE
@@ -50,18 +56,19 @@ comment "DVB-T (terrestrial) frontends"
50 depends on DVB_CORE 56 depends on DVB_CORE
51 57
52config DVB_SP8870 58config DVB_SP8870
53 tristate "Spase sp8870 based" 59 tristate "Spase sp8870 based"
54 depends on DVB_CORE 60 depends on DVB_CORE
55 select FW_LOADER 61 select FW_LOADER
56 help 62 help
57 A DVB-T tuner module. Say Y when you want to support this frontend. 63 A DVB-T tuner module. Say Y when you want to support this frontend.
58 64
59 This driver needs external firmware. Please use the command 65 This driver needs external firmware. Please use the command
60 "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to 66 "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to
61 download/extract it, and then copy it to /usr/lib/hotplug/firmware. 67 download/extract it, and then copy it to /usr/lib/hotplug/firmware
68 or /lib/firmware (depending on configuration of firmware hotplug).
62 69
63config DVB_SP887X 70config DVB_SP887X
64 tristate "Spase sp887x based" 71 tristate "Spase sp887x based"
65 depends on DVB_CORE 72 depends on DVB_CORE
66 select FW_LOADER 73 select FW_LOADER
67 help 74 help
@@ -69,7 +76,8 @@ config DVB_SP887X
69 76
70 This driver needs external firmware. Please use the command 77 This driver needs external firmware. Please use the command
71 "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to 78 "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
72 download/extract it, and then copy it to /usr/lib/hotplug/firmware. 79 download/extract it, and then copy it to /usr/lib/hotplug/firmware
80 or /lib/firmware (depending on configuration of firmware hotplug).
73 81
74config DVB_CX22700 82config DVB_CX22700
75 tristate "Conexant CX22700 based" 83 tristate "Conexant CX22700 based"
@@ -78,10 +86,10 @@ config DVB_CX22700
78 A DVB-T tuner module. Say Y when you want to support this frontend. 86 A DVB-T tuner module. Say Y when you want to support this frontend.
79 87
80config DVB_CX22702 88config DVB_CX22702
81 tristate "Conexant cx22702 demodulator (OFDM)" 89 tristate "Conexant cx22702 demodulator (OFDM)"
82 depends on DVB_CORE 90 depends on DVB_CORE
83 help 91 help
84 A DVB-T tuner module. Say Y when you want to support this frontend. 92 A DVB-T tuner module. Say Y when you want to support this frontend.
85 93
86config DVB_L64781 94config DVB_L64781
87 tristate "LSI L64781" 95 tristate "LSI L64781"
@@ -98,8 +106,9 @@ config DVB_TDA1004X
98 106
99 This driver needs external firmware. Please use the commands 107 This driver needs external firmware. Please use the commands
100 "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", 108 "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
101 "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to 109 "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
102 download/extract them, and then copy them to /usr/lib/hotplug/firmware. 110 download/extract them, and then copy them to /usr/lib/hotplug/firmware
111 or /lib/firmware (depending on configuration of firmware hotplug).
103 112
104config DVB_NXT6000 113config DVB_NXT6000
105 tristate "NxtWave Communications NXT6000 based" 114 tristate "NxtWave Communications NXT6000 based"
@@ -140,13 +149,13 @@ config DVB_VES1820
140 tristate "VLSI VES1820 based" 149 tristate "VLSI VES1820 based"
141 depends on DVB_CORE 150 depends on DVB_CORE
142 help 151 help
143 A DVB-C tuner module. Say Y when you want to support this frontend. 152 A DVB-C tuner module. Say Y when you want to support this frontend.
144 153
145config DVB_TDA10021 154config DVB_TDA10021
146 tristate "Philips TDA10021 based" 155 tristate "Philips TDA10021 based"
147 depends on DVB_CORE 156 depends on DVB_CORE
148 help 157 help
149 A DVB-C tuner module. Say Y when you want to support this frontend. 158 A DVB-C tuner module. Say Y when you want to support this frontend.
150 159
151config DVB_STV0297 160config DVB_STV0297
152 tristate "ST STV0297 based" 161 tristate "ST STV0297 based"
@@ -164,6 +173,11 @@ config DVB_NXT2002
164 help 173 help
165 An ATSC 8VSB tuner module. Say Y when you want to support this frontend. 174 An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
166 175
176 This driver needs external firmware. Please use the command
177 "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to
178 download/extract it, and then copy it to /usr/lib/hotplug/firmware
179 or /lib/firmware (depending on configuration of firmware hotplug).
180
167config DVB_NXT200X 181config DVB_NXT200X
168 tristate "Nextwave NXT2002/NXT2004 based" 182 tristate "Nextwave NXT2002/NXT2004 based"
169 depends on DVB_CORE 183 depends on DVB_CORE
@@ -172,6 +186,12 @@ config DVB_NXT200X
172 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 186 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
173 to support this frontend. 187 to support this frontend.
174 188
189 This driver needs external firmware. Please use the commands
190 "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" and
191 "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
192 download/extract them, and then copy them to /usr/lib/hotplug/firmware
193 or /lib/firmware (depending on configuration of firmware hotplug).
194
175config DVB_OR51211 195config DVB_OR51211
176 tristate "or51211 based (pcHDTV HD2000 card)" 196 tristate "or51211 based (pcHDTV HD2000 card)"
177 depends on DVB_CORE 197 depends on DVB_CORE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index a98760fe08a1..615ec830e1c9 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -32,3 +32,4 @@ obj-$(CONFIG_DVB_OR51132) += or51132.o
32obj-$(CONFIG_DVB_BCM3510) += bcm3510.o 32obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
33obj-$(CONFIG_DVB_S5H1420) += s5h1420.o 33obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
34obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o 34obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
35obj-$(CONFIG_DVB_CX24123) += cx24123.o
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
index 8ceb9a33c7af..3b132bafd4de 100644
--- a/drivers/media/dvb/frontends/bcm3510.c
+++ b/drivers/media/dvb/frontends/bcm3510.c
@@ -255,7 +255,7 @@ static int bcm3510_bert_reset(struct bcm3510_state *st)
255 bcm3510_register_value b; 255 bcm3510_register_value b;
256 int ret; 256 int ret;
257 257
258 if ((ret < bcm3510_readB(st,0xfa,&b)) < 0) 258 if ((ret = bcm3510_readB(st,0xfa,&b)) < 0)
259 return ret; 259 return ret;
260 260
261 b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b); 261 b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
@@ -623,13 +623,13 @@ static int bcm3510_download_firmware(struct dvb_frontend* fe)
623 err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret); 623 err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
624 return ret; 624 return ret;
625 } 625 }
626 deb_info("got firmware: %d\n",fw->size); 626 deb_info("got firmware: %zd\n",fw->size);
627 627
628 b = fw->data; 628 b = fw->data;
629 for (i = 0; i < fw->size;) { 629 for (i = 0; i < fw->size;) {
630 addr = le16_to_cpu( *( (u16 *)&b[i] ) ); 630 addr = le16_to_cpu( *( (u16 *)&b[i] ) );
631 len = le16_to_cpu( *( (u16 *)&b[i+2] ) ); 631 len = le16_to_cpu( *( (u16 *)&b[i+2] ) );
632 deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04x\n",addr,len,fw->size); 632 deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
633 if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) { 633 if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
634 err("firmware download failed: %d\n",ret); 634 err("firmware download failed: %d\n",ret);
635 return ret; 635 return ret;
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index 5de0e6d350b1..0fc899f81c5e 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -195,6 +195,16 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet
195 return 0; 195 return 0;
196} 196}
197 197
198static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
199{
200 struct cx22702_state* state = fe->demodulator_priv;
201 dprintk ("%s(%d)\n", __FUNCTION__, enable);
202 if (enable)
203 return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe);
204 else
205 return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) | 1);
206}
207
198/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ 208/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
199static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) 209static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
200{ 210{
@@ -202,7 +212,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
202 struct cx22702_state* state = fe->demodulator_priv; 212 struct cx22702_state* state = fe->demodulator_priv;
203 213
204 /* set PLL */ 214 /* set PLL */
205 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); 215 cx22702_i2c_gate_ctrl(fe, 1);
206 if (state->config->pll_set) { 216 if (state->config->pll_set) {
207 state->config->pll_set(fe, p); 217 state->config->pll_set(fe, p);
208 } else if (state->config->pll_desc) { 218 } else if (state->config->pll_desc) {
@@ -216,7 +226,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
216 } else { 226 } else {
217 BUG(); 227 BUG();
218 } 228 }
219 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); 229 cx22702_i2c_gate_ctrl(fe, 0);
220 230
221 /* set inversion */ 231 /* set inversion */
222 cx22702_set_inversion (state, p->inversion); 232 cx22702_set_inversion (state, p->inversion);
@@ -349,11 +359,10 @@ static int cx22702_init (struct dvb_frontend* fe)
349 cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); 359 cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02);
350 360
351 /* init PLL */ 361 /* init PLL */
352 if (state->config->pll_init) { 362 if (state->config->pll_init)
353 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) & 0xfe);
354 state->config->pll_init(fe); 363 state->config->pll_init(fe);
355 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); 364
356 } 365 cx22702_i2c_gate_ctrl(fe, 0);
357 366
358 return 0; 367 return 0;
359} 368}
@@ -531,6 +540,7 @@ static struct dvb_frontend_ops cx22702_ops = {
531 .read_signal_strength = cx22702_read_signal_strength, 540 .read_signal_strength = cx22702_read_signal_strength,
532 .read_snr = cx22702_read_snr, 541 .read_snr = cx22702_read_snr,
533 .read_ucblocks = cx22702_read_ucblocks, 542 .read_ucblocks = cx22702_read_ucblocks,
543 .i2c_gate_ctrl = cx22702_i2c_gate_ctrl,
534}; 544};
535 545
536module_param(debug, int, 0644); 546module_param(debug, int, 0644);
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index 0c4db80ec332..d15d32c51dc5 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -27,7 +27,6 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/jiffies.h>
31 30
32#include "dvb_frontend.h" 31#include "dvb_frontend.h"
33#include "cx24110.h" 32#include "cx24110.h"
@@ -56,7 +55,7 @@ static int debug;
56 55
57static struct {u8 reg; u8 data;} cx24110_regdata[]= 56static struct {u8 reg; u8 data;} cx24110_regdata[]=
58 /* Comments beginning with @ denote this value should 57 /* Comments beginning with @ denote this value should
59 be the default */ 58 be the default */
60 {{0x09,0x01}, /* SoftResetAll */ 59 {{0x09,0x01}, /* SoftResetAll */
61 {0x09,0x00}, /* release reset */ 60 {0x09,0x00}, /* release reset */
62 {0x01,0xe8}, /* MSB of code rate 27.5MS/s */ 61 {0x01,0xe8}, /* MSB of code rate 27.5MS/s */
@@ -67,26 +66,26 @@ static struct {u8 reg; u8 data;} cx24110_regdata[]=
67 {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */ 66 {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */
68 {0x0a,0x00}, /* @ partial chip disables, do not set */ 67 {0x0a,0x00}, /* @ partial chip disables, do not set */
69 {0x0b,0x01}, /* set output clock in gapped mode, start signal low 68 {0x0b,0x01}, /* set output clock in gapped mode, start signal low
70 active for first byte */ 69 active for first byte */
71 {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */ 70 {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */
72 {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */ 71 {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */
73 {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1 72 {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1
74 to avoid starting the BER counter. Reset the 73 to avoid starting the BER counter. Reset the
75 CRC test bit. Finite counting selected */ 74 CRC test bit. Finite counting selected */
76 {0x15,0xff}, /* @ size of the limited time window for RS BER 75 {0x15,0xff}, /* @ size of the limited time window for RS BER
77 estimation. It is <value>*256 RS blocks, this 76 estimation. It is <value>*256 RS blocks, this
78 gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */ 77 gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */
79 {0x16,0x00}, /* @ enable all RS output ports */ 78 {0x16,0x00}, /* @ enable all RS output ports */
80 {0x17,0x04}, /* @ time window allowed for the RS to sync */ 79 {0x17,0x04}, /* @ time window allowed for the RS to sync */
81 {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned 80 {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned
82 for automatically */ 81 for automatically */
83 /* leave the current code rate and normalization 82 /* leave the current code rate and normalization
84 registers as they are after reset... */ 83 registers as they are after reset... */
85 {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting 84 {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting
86 only once */ 85 only once */
87 {0x23,0x18}, /* @ size of the limited time window for Viterbi BER 86 {0x23,0x18}, /* @ size of the limited time window for Viterbi BER
88 estimation. It is <value>*65536 channel bits, i.e. 87 estimation. It is <value>*65536 channel bits, i.e.
89 approx. 38ms at 27.5MS/s, rate 3/4 */ 88 approx. 38ms at 27.5MS/s, rate 3/4 */
90 {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */ 89 {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */
91 /* leave front-end AGC parameters at default values */ 90 /* leave front-end AGC parameters at default values */
92 /* leave decimation AGC parameters at default values */ 91 /* leave decimation AGC parameters at default values */
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
new file mode 100644
index 000000000000..d661c6f9cbe5
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -0,0 +1,889 @@
1/*
2 Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
3
4 Copyright (C) 2005 Steven Toth <stoth@hauppauge.com>
5
6 Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#include <linux/slab.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28
29#include "dvb_frontend.h"
30#include "cx24123.h"
31
32static int debug;
33#define dprintk(args...) \
34 do { \
35 if (debug) printk (KERN_DEBUG "cx24123: " args); \
36 } while (0)
37
38struct cx24123_state
39{
40 struct i2c_adapter* i2c;
41 struct dvb_frontend_ops ops;
42 const struct cx24123_config* config;
43
44 struct dvb_frontend frontend;
45
46 u32 lastber;
47 u16 snr;
48 u8 lnbreg;
49
50 /* Some PLL specifics for tuning */
51 u32 VCAarg;
52 u32 VGAarg;
53 u32 bandselectarg;
54 u32 pllarg;
55
56 /* The Demod/Tuner can't easily provide these, we cache them */
57 u32 currentfreq;
58 u32 currentsymbolrate;
59};
60
61/* Various tuner defaults need to be established for a given symbol rate Sps */
62static struct
63{
64 u32 symbolrate_low;
65 u32 symbolrate_high;
66 u32 VCAslope;
67 u32 VCAoffset;
68 u32 VGA1offset;
69 u32 VGA2offset;
70 u32 VCAprogdata;
71 u32 VGAprogdata;
72} cx24123_AGC_vals[] =
73{
74 {
75 .symbolrate_low = 1000000,
76 .symbolrate_high = 4999999,
77 .VCAslope = 0x07,
78 .VCAoffset = 0x0f,
79 .VGA1offset = 0x1f8,
80 .VGA2offset = 0x1f8,
81 .VGAprogdata = (2 << 18) | (0x1f8 << 9) | 0x1f8,
82 .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x07,
83 },
84 {
85 .symbolrate_low = 5000000,
86 .symbolrate_high = 14999999,
87 .VCAslope = 0x1f,
88 .VCAoffset = 0x1f,
89 .VGA1offset = 0x1e0,
90 .VGA2offset = 0x180,
91 .VGAprogdata = (2 << 18) | (0x180 << 9) | 0x1e0,
92 .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x1f,
93 },
94 {
95 .symbolrate_low = 15000000,
96 .symbolrate_high = 45000000,
97 .VCAslope = 0x3f,
98 .VCAoffset = 0x3f,
99 .VGA1offset = 0x180,
100 .VGA2offset = 0x100,
101 .VGAprogdata = (2 << 18) | (0x100 << 9) | 0x180,
102 .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x3f,
103 },
104};
105
106/*
107 * Various tuner defaults need to be established for a given frequency kHz.
108 * fixme: The bounds on the bands do not match the doc in real life.
109 * fixme: Some of them have been moved, other might need adjustment.
110 */
111static struct
112{
113 u32 freq_low;
114 u32 freq_high;
115 u32 bandselect;
116 u32 VCOdivider;
117 u32 VCOnumber;
118 u32 progdata;
119} cx24123_bandselect_vals[] =
120{
121 {
122 .freq_low = 950000,
123 .freq_high = 1018999,
124 .bandselect = 0x40,
125 .VCOdivider = 4,
126 .VCOnumber = 7,
127 .progdata = (0 << 18) | (0 << 9) | 0x40,
128 },
129 {
130 .freq_low = 1019000,
131 .freq_high = 1074999,
132 .bandselect = 0x80,
133 .VCOdivider = 4,
134 .VCOnumber = 8,
135 .progdata = (0 << 18) | (0 << 9) | 0x80,
136 },
137 {
138 .freq_low = 1075000,
139 .freq_high = 1227999,
140 .bandselect = 0x01,
141 .VCOdivider = 2,
142 .VCOnumber = 1,
143 .progdata = (0 << 18) | (1 << 9) | 0x01,
144 },
145 {
146 .freq_low = 1228000,
147 .freq_high = 1349999,
148 .bandselect = 0x02,
149 .VCOdivider = 2,
150 .VCOnumber = 2,
151 .progdata = (0 << 18) | (1 << 9) | 0x02,
152 },
153 {
154 .freq_low = 1350000,
155 .freq_high = 1481999,
156 .bandselect = 0x04,
157 .VCOdivider = 2,
158 .VCOnumber = 3,
159 .progdata = (0 << 18) | (1 << 9) | 0x04,
160 },
161 {
162 .freq_low = 1482000,
163 .freq_high = 1595999,
164 .bandselect = 0x08,
165 .VCOdivider = 2,
166 .VCOnumber = 4,
167 .progdata = (0 << 18) | (1 << 9) | 0x08,
168 },
169 {
170 .freq_low = 1596000,
171 .freq_high = 1717999,
172 .bandselect = 0x10,
173 .VCOdivider = 2,
174 .VCOnumber = 5,
175 .progdata = (0 << 18) | (1 << 9) | 0x10,
176 },
177 {
178 .freq_low = 1718000,
179 .freq_high = 1855999,
180 .bandselect = 0x20,
181 .VCOdivider = 2,
182 .VCOnumber = 6,
183 .progdata = (0 << 18) | (1 << 9) | 0x20,
184 },
185 {
186 .freq_low = 1856000,
187 .freq_high = 2035999,
188 .bandselect = 0x40,
189 .VCOdivider = 2,
190 .VCOnumber = 7,
191 .progdata = (0 << 18) | (1 << 9) | 0x40,
192 },
193 {
194 .freq_low = 2036000,
195 .freq_high = 2149999,
196 .bandselect = 0x80,
197 .VCOdivider = 2,
198 .VCOnumber = 8,
199 .progdata = (0 << 18) | (1 << 9) | 0x80,
200 },
201};
202
203static struct {
204 u8 reg;
205 u8 data;
206} cx24123_regdata[] =
207{
208 {0x00, 0x03}, /* Reset system */
209 {0x00, 0x00}, /* Clear reset */
210 {0x01, 0x3b}, /* Apply sensible defaults, from an i2c sniffer */
211 {0x03, 0x07},
212 {0x04, 0x10},
213 {0x05, 0x04},
214 {0x06, 0x31},
215 {0x0d, 0x02},
216 {0x0e, 0x03},
217 {0x0f, 0xfe},
218 {0x10, 0x01},
219 {0x14, 0x01},
220 {0x15, 0x98},
221 {0x16, 0x00},
222 {0x17, 0x01},
223 {0x1b, 0x05},
224 {0x1c, 0x80},
225 {0x1d, 0x00},
226 {0x1e, 0x00},
227 {0x20, 0x41},
228 {0x21, 0x15},
229 {0x27, 0x14},
230 {0x28, 0x46},
231 {0x29, 0x00},
232 {0x2a, 0xb0},
233 {0x2b, 0x73},
234 {0x2c, 0x00},
235 {0x2d, 0x00},
236 {0x2e, 0x00},
237 {0x2f, 0x00},
238 {0x30, 0x00},
239 {0x31, 0x00},
240 {0x32, 0x8c},
241 {0x33, 0x00},
242 {0x34, 0x00},
243 {0x35, 0x03},
244 {0x36, 0x02},
245 {0x37, 0x3a},
246 {0x3a, 0x00}, /* Enable AGC accumulator */
247 {0x44, 0x00},
248 {0x45, 0x00},
249 {0x46, 0x05},
250 {0x56, 0x41},
251 {0x57, 0xff},
252 {0x67, 0x83},
253};
254
255static int cx24123_writereg(struct cx24123_state* state, int reg, int data)
256{
257 u8 buf[] = { reg, data };
258 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
259 int err;
260
261 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
262 printk("%s: writereg error(err == %i, reg == 0x%02x,"
263 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
264 return -EREMOTEIO;
265 }
266
267 return 0;
268}
269
270static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data)
271{
272 u8 buf[] = { reg, data };
273 /* fixme: put the intersil addr int the config */
274 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 };
275 int err;
276
277 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
278 printk("%s: writelnbreg error (err == %i, reg == 0x%02x,"
279 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
280 return -EREMOTEIO;
281 }
282
283 /* cache the write, no way to read back */
284 state->lnbreg = data;
285
286 return 0;
287}
288
289static int cx24123_readreg(struct cx24123_state* state, u8 reg)
290{
291 int ret;
292 u8 b0[] = { reg };
293 u8 b1[] = { 0 };
294 struct i2c_msg msg[] = {
295 { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
296 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 }
297 };
298
299 ret = i2c_transfer(state->i2c, msg, 2);
300
301 if (ret != 2) {
302 printk("%s: reg=0x%x (error=%d)\n", __FUNCTION__, reg, ret);
303 return ret;
304 }
305
306 return b1[0];
307}
308
309static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg)
310{
311 return state->lnbreg;
312}
313
314static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion)
315{
316 switch (inversion) {
317 case INVERSION_OFF:
318 cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) & 0x7f);
319 cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80);
320 break;
321 case INVERSION_ON:
322 cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) | 0x80);
323 cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80);
324 break;
325 case INVERSION_AUTO:
326 cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) & 0x7f);
327 break;
328 default:
329 return -EINVAL;
330 }
331
332 return 0;
333}
334
335static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_inversion_t *inversion)
336{
337 u8 val;
338
339 val = cx24123_readreg(state, 0x1b) >> 7;
340
341 if (val == 0)
342 *inversion = INVERSION_OFF;
343 else
344 *inversion = INVERSION_ON;
345
346 return 0;
347}
348
349static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
350{
351 if ( (fec < FEC_NONE) || (fec > FEC_AUTO) )
352 fec = FEC_AUTO;
353
354 /* Hardware has 5/11 and 3/5 but are never unused */
355 switch (fec) {
356 case FEC_NONE:
357 return cx24123_writereg(state, 0x0f, 0x01);
358 case FEC_1_2:
359 return cx24123_writereg(state, 0x0f, 0x02);
360 case FEC_2_3:
361 return cx24123_writereg(state, 0x0f, 0x04);
362 case FEC_3_4:
363 return cx24123_writereg(state, 0x0f, 0x08);
364 case FEC_5_6:
365 return cx24123_writereg(state, 0x0f, 0x20);
366 case FEC_7_8:
367 return cx24123_writereg(state, 0x0f, 0x80);
368 case FEC_AUTO:
369 return cx24123_writereg(state, 0x0f, 0xae);
370 default:
371 return -EOPNOTSUPP;
372 }
373}
374
375static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec)
376{
377 int ret;
378 u8 val;
379
380 ret = cx24123_readreg (state, 0x1b);
381 if (ret < 0)
382 return ret;
383 val = ret & 0x07;
384 switch (val) {
385 case 1:
386 *fec = FEC_1_2;
387 break;
388 case 3:
389 *fec = FEC_2_3;
390 break;
391 case 4:
392 *fec = FEC_3_4;
393 break;
394 case 5:
395 *fec = FEC_4_5;
396 break;
397 case 6:
398 *fec = FEC_5_6;
399 break;
400 case 7:
401 *fec = FEC_7_8;
402 break;
403 case 2: /* *fec = FEC_3_5; break; */
404 case 0: /* *fec = FEC_5_11; break; */
405 *fec = FEC_AUTO;
406 break;
407 default:
408 *fec = FEC_NONE; // can't happen
409 }
410
411 return 0;
412}
413
414/* fixme: Symbol rates < 3MSps may not work because of precision loss */
415static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
416{
417 u32 val;
418
419 val = (srate / 1185) * 100;
420
421 /* Compensate for scaling up, by removing 17 symbols per 1Msps */
422 val = val - (17 * (srate / 1000000));
423
424 cx24123_writereg(state, 0x08, (val >> 16) & 0xff );
425 cx24123_writereg(state, 0x09, (val >> 8) & 0xff );
426 cx24123_writereg(state, 0x0a, (val ) & 0xff );
427
428 return 0;
429}
430
431/*
432 * Based on the required frequency and symbolrate, the tuner AGC has to be configured
433 * and the correct band selected. Calculate those values
434 */
435static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
436{
437 struct cx24123_state *state = fe->demodulator_priv;
438 u32 ndiv = 0, adiv = 0, vco_div = 0;
439 int i = 0;
440
441 /* Defaults for low freq, low rate */
442 state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
443 state->VGAarg = cx24123_AGC_vals[0].VGAprogdata;
444 state->bandselectarg = cx24123_bandselect_vals[0].progdata;
445 vco_div = cx24123_bandselect_vals[0].VCOdivider;
446
447 /* For the given symbolerate, determine the VCA and VGA programming bits */
448 for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++)
449 {
450 if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) &&
451 (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) {
452 state->VCAarg = cx24123_AGC_vals[i].VCAprogdata;
453 state->VGAarg = cx24123_AGC_vals[i].VGAprogdata;
454 }
455 }
456
457 /* For the given frequency, determine the bandselect programming bits */
458 for (i = 0; i < sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); i++)
459 {
460 if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) &&
461 (cx24123_bandselect_vals[i].freq_high >= p->frequency) ) {
462 state->bandselectarg = cx24123_bandselect_vals[i].progdata;
463 vco_div = cx24123_bandselect_vals[i].VCOdivider;
464 }
465 }
466
467 /* Determine the N/A dividers for the requested lband freq (in kHz). */
468 /* Note: 10111 (kHz) is the Crystal Freq and divider of 10. */
469 ndiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) / 32) & 0x1ff;
470 adiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) % 32) & 0x1f;
471
472 if (adiv == 0)
473 adiv++;
474
475 /* determine the correct pll frequency values. */
476 /* Command 11, refdiv 11, cpump polarity 1, cpump current 3mA 10. */
477 state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (2 << 14);
478 state->pllarg |= (ndiv << 5) | adiv;
479
480 return 0;
481}
482
483/*
484 * Tuner data is 21 bits long, must be left-aligned in data.
485 * Tuner cx24109 is written through a dedicated 3wire interface on the demod chip.
486 */
487static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_parameters *p, u32 data)
488{
489 struct cx24123_state *state = fe->demodulator_priv;
490 unsigned long timeout;
491
492 /* align the 21 bytes into to bit23 boundary */
493 data = data << 3;
494
495 /* Reset the demod pll word length to 0x15 bits */
496 cx24123_writereg(state, 0x21, 0x15);
497
498 /* write the msb 8 bits, wait for the send to be completed */
499 timeout = jiffies + msecs_to_jiffies(40);
500 cx24123_writereg(state, 0x22, (data >> 16) & 0xff);
501 while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
502 if (time_after(jiffies, timeout)) {
503 printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
504 return -EREMOTEIO;
505 }
506 msleep(10);
507 }
508
509 /* send another 8 bytes, wait for the send to be completed */
510 timeout = jiffies + msecs_to_jiffies(40);
511 cx24123_writereg(state, 0x22, (data>>8) & 0xff );
512 while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
513 if (time_after(jiffies, timeout)) {
514 printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
515 return -EREMOTEIO;
516 }
517 msleep(10);
518 }
519
520 /* send the lower 5 bits of this byte, padded with 3 LBB, wait for the send to be completed */
521 timeout = jiffies + msecs_to_jiffies(40);
522 cx24123_writereg(state, 0x22, (data) & 0xff );
523 while ((cx24123_readreg(state, 0x20) & 0x80)) {
524 if (time_after(jiffies, timeout)) {
525 printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
526 return -EREMOTEIO;
527 }
528 msleep(10);
529 }
530
531 /* Trigger the demod to configure the tuner */
532 cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2);
533 cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd);
534
535 return 0;
536}
537
538static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
539{
540 struct cx24123_state *state = fe->demodulator_priv;
541
542 if (cx24123_pll_calculate(fe, p) != 0) {
543 printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__);
544 return -EINVAL;
545 }
546
547 /* Write the new VCO/VGA */
548 cx24123_pll_writereg(fe, p, state->VCAarg);
549 cx24123_pll_writereg(fe, p, state->VGAarg);
550
551 /* Write the new bandselect and pll args */
552 cx24123_pll_writereg(fe, p, state->bandselectarg);
553 cx24123_pll_writereg(fe, p, state->pllarg);
554
555 return 0;
556}
557
558static int cx24123_initfe(struct dvb_frontend* fe)
559{
560 struct cx24123_state *state = fe->demodulator_priv;
561 int i;
562
563 /* Configure the demod to a good set of defaults */
564 for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
565 cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
566
567 if (state->config->pll_init)
568 state->config->pll_init(fe);
569
570 /* Configure the LNB for 14V */
571 if (state->config->use_isl6421)
572 cx24123_writelnbreg(state, 0x0, 0x2a);
573
574 return 0;
575}
576
577static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
578{
579 struct cx24123_state *state = fe->demodulator_priv;
580 u8 val;
581
582 switch (state->config->use_isl6421) {
583
584 case 1:
585
586 val = cx24123_readlnbreg(state, 0x0);
587
588 switch (voltage) {
589 case SEC_VOLTAGE_13:
590 return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */
591 case SEC_VOLTAGE_18:
592 return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */
593 case SEC_VOLTAGE_OFF:
594 return cx24123_writelnbreg(state, 0x0, val & 0x30);
595 default:
596 return -EINVAL;
597 };
598
599 case 0:
600
601 val = cx24123_readreg(state, 0x29);
602
603 switch (voltage) {
604 case SEC_VOLTAGE_13:
605 dprintk("%s: setting voltage 13V\n", __FUNCTION__);
606 if (state->config->enable_lnb_voltage)
607 state->config->enable_lnb_voltage(fe, 1);
608 return cx24123_writereg(state, 0x29, val | 0x80);
609 case SEC_VOLTAGE_18:
610 dprintk("%s: setting voltage 18V\n", __FUNCTION__);
611 if (state->config->enable_lnb_voltage)
612 state->config->enable_lnb_voltage(fe, 1);
613 return cx24123_writereg(state, 0x29, val & 0x7f);
614 case SEC_VOLTAGE_OFF:
615 dprintk("%s: setting voltage off\n", __FUNCTION__);
616 if (state->config->enable_lnb_voltage)
617 state->config->enable_lnb_voltage(fe, 0);
618 return 0;
619 default:
620 return -EINVAL;
621 };
622 }
623
624 return 0;
625}
626
627static int cx24123_send_diseqc_msg(struct dvb_frontend* fe,
628 struct dvb_diseqc_master_cmd *cmd)
629{
630 /* fixme: Implement diseqc */
631 printk("%s: No support yet\n",__FUNCTION__);
632
633 return -ENOTSUPP;
634}
635
636static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
637{
638 struct cx24123_state *state = fe->demodulator_priv;
639
640 int sync = cx24123_readreg(state, 0x14);
641 int lock = cx24123_readreg(state, 0x20);
642
643 *status = 0;
644 if (lock & 0x01)
645 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
646 if (sync & 0x04)
647 *status |= FE_HAS_VITERBI;
648 if (sync & 0x08)
649 *status |= FE_HAS_CARRIER;
650 if (sync & 0x80)
651 *status |= FE_HAS_SYNC | FE_HAS_LOCK;
652
653 return 0;
654}
655
656/*
657 * Configured to return the measurement of errors in blocks, because no UCBLOCKS value
658 * is available, so this value doubles up to satisfy both measurements
659 */
660static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
661{
662 struct cx24123_state *state = fe->demodulator_priv;
663
664 state->lastber =
665 ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
666 (cx24123_readreg(state, 0x1d) << 8 |
667 cx24123_readreg(state, 0x1e));
668
669 /* Do the signal quality processing here, it's derived from the BER. */
670 /* Scale the BER from a 24bit to a SNR 16 bit where higher = better */
671 if (state->lastber < 5000)
672 state->snr = 655*100;
673 else if ( (state->lastber >= 5000) && (state->lastber < 55000) )
674 state->snr = 655*90;
675 else if ( (state->lastber >= 55000) && (state->lastber < 150000) )
676 state->snr = 655*80;
677 else if ( (state->lastber >= 150000) && (state->lastber < 250000) )
678 state->snr = 655*70;
679 else if ( (state->lastber >= 250000) && (state->lastber < 450000) )
680 state->snr = 655*65;
681 else
682 state->snr = 0;
683
684 *ber = state->lastber;
685
686 return 0;
687}
688
689static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
690{
691 struct cx24123_state *state = fe->demodulator_priv;
692 *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */
693
694 return 0;
695}
696
697static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr)
698{
699 struct cx24123_state *state = fe->demodulator_priv;
700 *snr = state->snr;
701
702 return 0;
703}
704
705static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
706{
707 struct cx24123_state *state = fe->demodulator_priv;
708 *ucblocks = state->lastber;
709
710 return 0;
711}
712
713static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
714{
715 struct cx24123_state *state = fe->demodulator_priv;
716
717 if (state->config->set_ts_params)
718 state->config->set_ts_params(fe, 0);
719
720 state->currentfreq=p->frequency;
721 state->currentsymbolrate = p->u.qpsk.symbol_rate;
722
723 cx24123_set_inversion(state, p->inversion);
724 cx24123_set_fec(state, p->u.qpsk.fec_inner);
725 cx24123_set_symbolrate(state, p->u.qpsk.symbol_rate);
726 cx24123_pll_tune(fe, p);
727
728 /* Enable automatic aquisition and reset cycle */
729 cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07));
730 cx24123_writereg(state, 0x00, 0x10);
731 cx24123_writereg(state, 0x00, 0);
732
733 return 0;
734}
735
736static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
737{
738 struct cx24123_state *state = fe->demodulator_priv;
739
740 if (cx24123_get_inversion(state, &p->inversion) != 0) {
741 printk("%s: Failed to get inversion status\n",__FUNCTION__);
742 return -EREMOTEIO;
743 }
744 if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) {
745 printk("%s: Failed to get fec status\n",__FUNCTION__);
746 return -EREMOTEIO;
747 }
748 p->frequency = state->currentfreq;
749 p->u.qpsk.symbol_rate = state->currentsymbolrate;
750
751 return 0;
752}
753
754static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
755{
756 struct cx24123_state *state = fe->demodulator_priv;
757 u8 val;
758
759 switch (state->config->use_isl6421) {
760 case 1:
761
762 val = cx24123_readlnbreg(state, 0x0);
763
764 switch (tone) {
765 case SEC_TONE_ON:
766 return cx24123_writelnbreg(state, 0x0, val | 0x10);
767 case SEC_TONE_OFF:
768 return cx24123_writelnbreg(state, 0x0, val & 0x2f);
769 default:
770 printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
771 return -EINVAL;
772 }
773
774 case 0:
775
776 val = cx24123_readreg(state, 0x29);
777
778 switch (tone) {
779 case SEC_TONE_ON:
780 dprintk("%s: setting tone on\n", __FUNCTION__);
781 return cx24123_writereg(state, 0x29, val | 0x10);
782 case SEC_TONE_OFF:
783 dprintk("%s: setting tone off\n",__FUNCTION__);
784 return cx24123_writereg(state, 0x29, val & 0xef);
785 default:
786 printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
787 return -EINVAL;
788 }
789 }
790
791 return 0;
792}
793
794static void cx24123_release(struct dvb_frontend* fe)
795{
796 struct cx24123_state* state = fe->demodulator_priv;
797 dprintk("%s\n",__FUNCTION__);
798 kfree(state);
799}
800
801static struct dvb_frontend_ops cx24123_ops;
802
803struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
804 struct i2c_adapter* i2c)
805{
806 struct cx24123_state* state = NULL;
807 int ret;
808
809 dprintk("%s\n",__FUNCTION__);
810
811 /* allocate memory for the internal state */
812 state = kmalloc(sizeof(struct cx24123_state), GFP_KERNEL);
813 if (state == NULL) {
814 printk("Unable to kmalloc\n");
815 goto error;
816 }
817
818 /* setup the state */
819 state->config = config;
820 state->i2c = i2c;
821 memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops));
822 state->lastber = 0;
823 state->snr = 0;
824 state->lnbreg = 0;
825 state->VCAarg = 0;
826 state->VGAarg = 0;
827 state->bandselectarg = 0;
828 state->pllarg = 0;
829 state->currentfreq = 0;
830 state->currentsymbolrate = 0;
831
832 /* check if the demod is there */
833 ret = cx24123_readreg(state, 0x00);
834 if ((ret != 0xd1) && (ret != 0xe1)) {
835 printk("Version != d1 or e1\n");
836 goto error;
837 }
838
839 /* create dvb_frontend */
840 state->frontend.ops = &state->ops;
841 state->frontend.demodulator_priv = state;
842 return &state->frontend;
843
844error:
845 kfree(state);
846
847 return NULL;
848}
849
850static struct dvb_frontend_ops cx24123_ops = {
851
852 .info = {
853 .name = "Conexant CX24123/CX24109",
854 .type = FE_QPSK,
855 .frequency_min = 950000,
856 .frequency_max = 2150000,
857 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
858 .frequency_tolerance = 29500,
859 .symbol_rate_min = 1000000,
860 .symbol_rate_max = 45000000,
861 .caps = FE_CAN_INVERSION_AUTO |
862 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
863 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
864 FE_CAN_QPSK | FE_CAN_RECOVER
865 },
866
867 .release = cx24123_release,
868
869 .init = cx24123_initfe,
870 .set_frontend = cx24123_set_frontend,
871 .get_frontend = cx24123_get_frontend,
872 .read_status = cx24123_read_status,
873 .read_ber = cx24123_read_ber,
874 .read_signal_strength = cx24123_read_signal_strength,
875 .read_snr = cx24123_read_snr,
876 .read_ucblocks = cx24123_read_ucblocks,
877 .diseqc_send_master_cmd = cx24123_send_diseqc_msg,
878 .set_tone = cx24123_set_tone,
879 .set_voltage = cx24123_set_voltage,
880};
881
882module_param(debug, int, 0644);
883MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
884
885MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24123/cx24109 hardware");
886MODULE_AUTHOR("Steven Toth");
887MODULE_LICENSE("GPL");
888
889EXPORT_SYMBOL(cx24123_attach);
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h
new file mode 100644
index 000000000000..0c922b5e9263
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24123.h
@@ -0,0 +1,51 @@
1/*
2 Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
3
4 Copyright (C) 2005 Steven Toth <stoth@hauppauge.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef CX24123_H
22#define CX24123_H
23
24#include <linux/dvb/frontend.h>
25
26struct cx24123_config
27{
28 /* the demodulator's i2c address */
29 u8 demod_address;
30
31 /*
32 cards like Hauppauge Nova-S Plus/Nova-SE2 use an Intersil ISL6421 chip
33 for LNB control, while KWorld DVB-S 100 use the LNBDC and LNBTone bits
34 from register 0x29 of the CX24123 demodulator
35 */
36 int use_isl6421;
37
38 /* PLL maintenance */
39 int (*pll_init)(struct dvb_frontend* fe);
40 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
41
42 /* Need to set device param for start_dma */
43 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
44
45 void (*enable_lnb_voltage)(struct dvb_frontend* fe, int on);
46};
47
48extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
49 struct i2c_adapter* i2c);
50
51#endif /* CX24123_H */
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index f857b869616c..a3d57ce9dd12 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -107,18 +107,19 @@ struct dvb_pll_desc dvb_pll_microtune_4042 = {
107}; 107};
108EXPORT_SYMBOL(dvb_pll_microtune_4042); 108EXPORT_SYMBOL(dvb_pll_microtune_4042);
109 109
110struct dvb_pll_desc dvb_pll_thomson_dtt7611 = { 110struct dvb_pll_desc dvb_pll_thomson_dtt761x = {
111 .name = "Thomson dtt7611", 111 /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
112 .min = 44000000, 112 .name = "Thomson dtt761x",
113 .max = 958000000, 113 .min = 57000000,
114 .max = 863000000,
114 .count = 3, 115 .count = 3,
115 .entries = { 116 .entries = {
116 { 157250000, 44000000, 62500, 0x8e, 0x39 }, 117 { 147000000, 44000000, 62500, 0x8e, 0x39 },
117 { 454000000, 44000000, 62500, 0x8e, 0x3a }, 118 { 417000000, 44000000, 62500, 0x8e, 0x3a },
118 { 999999999, 44000000, 62500, 0x8e, 0x3c }, 119 { 999999999, 44000000, 62500, 0x8e, 0x3c },
119 }, 120 },
120}; 121};
121EXPORT_SYMBOL(dvb_pll_thomson_dtt7611); 122EXPORT_SYMBOL(dvb_pll_thomson_dtt761x);
122 123
123struct dvb_pll_desc dvb_pll_unknown_1 = { 124struct dvb_pll_desc dvb_pll_unknown_1 = {
124 .name = "unknown 1", /* used by dntv live dvb-t */ 125 .name = "unknown 1", /* used by dntv live dvb-t */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 497d31dcf41e..24d4d2e9acd8 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -25,7 +25,7 @@ extern struct dvb_pll_desc dvb_pll_thomson_dtt759x;
25extern struct dvb_pll_desc dvb_pll_thomson_dtt7610; 25extern struct dvb_pll_desc dvb_pll_thomson_dtt7610;
26extern struct dvb_pll_desc dvb_pll_lg_z201; 26extern struct dvb_pll_desc dvb_pll_lg_z201;
27extern struct dvb_pll_desc dvb_pll_microtune_4042; 27extern struct dvb_pll_desc dvb_pll_microtune_4042;
28extern struct dvb_pll_desc dvb_pll_thomson_dtt7611; 28extern struct dvb_pll_desc dvb_pll_thomson_dtt761x;
29extern struct dvb_pll_desc dvb_pll_unknown_1; 29extern struct dvb_pll_desc dvb_pll_unknown_1;
30 30
31extern struct dvb_pll_desc dvb_pll_tua6010xs; 31extern struct dvb_pll_desc dvb_pll_tua6010xs;
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index cb5301865d07..9d214643b87a 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -27,6 +27,7 @@
27 * DViCO FusionHDTV 3 Gold-T 27 * DViCO FusionHDTV 3 Gold-T
28 * DViCO FusionHDTV 5 Gold 28 * DViCO FusionHDTV 5 Gold
29 * DViCO FusionHDTV 5 Lite 29 * DViCO FusionHDTV 5 Lite
30 * DViCO FusionHDTV 5 USB Gold
30 * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) 31 * Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
31 * 32 *
32 * TODO: 33 * TODO:
@@ -402,6 +403,8 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe,
402 state->config->pll_set(fe, param); 403 state->config->pll_set(fe, param);
403 404
404 /* Keep track of the new frequency */ 405 /* Keep track of the new frequency */
406 /* FIXME this is the wrong way to do this... */
407 /* The tuner is shared with the video4linux analog API */
405 state->current_frequency = param->frequency; 408 state->current_frequency = param->frequency;
406 409
407 lgdt330x_SwReset(state); 410 lgdt330x_SwReset(state);
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index 8d672283c93d..ec4e641acc64 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -501,7 +501,8 @@ static int mt312_set_frontend(struct dvb_frontend* fe,
501 case ID_VP310: 501 case ID_VP310:
502 // For now we will do this only for the VP310. 502 // For now we will do this only for the VP310.
503 // It should be better for the mt312 as well, but tunning will be slower. ACCJr 09/29/03 503 // It should be better for the mt312 as well, but tunning will be slower. ACCJr 09/29/03
504 if ((ret = mt312_readreg(state, CONFIG, &config_val) < 0)) 504 ret = mt312_readreg(state, CONFIG, &config_val);
505 if (ret < 0)
505 return ret; 506 return ret;
506 if (p->u.qpsk.symbol_rate >= 30000000) //Note that 30MS/s should use 90MHz 507 if (p->u.qpsk.symbol_rate >= 30000000) //Note that 30MS/s should use 90MHz
507 { 508 {
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
index 52c416043a62..4f263e65ba14 100644
--- a/drivers/media/dvb/frontends/nxt2002.c
+++ b/drivers/media/dvb/frontends/nxt2002.c
@@ -22,7 +22,8 @@
22/* 22/*
23 * This driver needs external firmware. Please use the command 23 * This driver needs external firmware. Please use the command
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to 24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to
25 * download/extract it, and then copy it to /usr/lib/hotplug/firmware. 25 * download/extract it, and then copy it to /usr/lib/hotplug/firmware
26 * or /lib/firmware (depending on configuration of firmware hotplug).
26 */ 27 */
27#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw" 28#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
28#define CRC_CCIT_MASK 0x1021 29#define CRC_CCIT_MASK 0x1021
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c
index a458a3bfff70..a16eeba0020d 100644
--- a/drivers/media/dvb/frontends/nxt6000.c
+++ b/drivers/media/dvb/frontends/nxt6000.c
@@ -574,11 +574,11 @@ static struct dvb_frontend_ops nxt6000_ops = {
574 .symbol_rate_max = 9360000, /* FIXME */ 574 .symbol_rate_max = 9360000, /* FIXME */
575 .symbol_rate_tolerance = 4000, 575 .symbol_rate_tolerance = 4000,
576 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 576 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
577 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | 577 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
578 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | 578 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
579 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | 579 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
580 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | 580 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
581 FE_CAN_HIERARCHY_AUTO, 581 FE_CAN_HIERARCHY_AUTO,
582 }, 582 },
583 583
584 .release = nxt6000_release, 584 .release = nxt6000_release,
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
index 531f76246e5f..7c3aed1f546b 100644
--- a/drivers/media/dvb/frontends/or51211.c
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -25,7 +25,8 @@
25/* 25/*
26 * This driver needs external firmware. Please use the command 26 * This driver needs external firmware. Please use the command
27 * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to 27 * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
28 * download/extract it, and then copy it to /usr/lib/hotplug/firmware. 28 * download/extract it, and then copy it to /usr/lib/hotplug/firmware
29 * or /lib/firmware (depending on configuration of firmware hotplug).
29 */ 30 */
30#define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw" 31#define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw"
31 32
@@ -112,7 +113,7 @@ static int or51211_load_firmware (struct dvb_frontend* fe,
112 u8 tudata[585]; 113 u8 tudata[585];
113 int i; 114 int i;
114 115
115 dprintk("Firmware is %d bytes\n",fw->size); 116 dprintk("Firmware is %zd bytes\n",fw->size);
116 117
117 /* Get eprom data */ 118 /* Get eprom data */
118 tudata[0] = 17; 119 tudata[0] = 17;
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index 18715091aed8..d69477596921 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -521,8 +521,8 @@ static void s5h1420_setfec_inversion(struct s5h1420_state* state,
521 521
522 case FEC_3_4: 522 case FEC_3_4:
523 s5h1420_writereg(state, 0x30, 0x04); 523 s5h1420_writereg(state, 0x30, 0x04);
524 s5h1420_writereg(state, 0x31, 0x12 | inversion); 524 s5h1420_writereg(state, 0x31, 0x12 | inversion);
525 break; 525 break;
526 526
527 case FEC_5_6: 527 case FEC_5_6:
528 s5h1420_writereg(state, 0x30, 0x08); 528 s5h1420_writereg(state, 0x30, 0x08);
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
index fc06cd6b46c3..73829e647e50 100644
--- a/drivers/media/dvb/frontends/sp8870.c
+++ b/drivers/media/dvb/frontends/sp8870.c
@@ -22,7 +22,8 @@
22/* 22/*
23 * This driver needs external firmware. Please use the command 23 * This driver needs external firmware. Please use the command
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to 24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to
25 * download/extract it, and then copy it to /usr/lib/hotplug/firmware. 25 * download/extract it, and then copy it to /usr/lib/hotplug/firmware
26 * or /lib/firmware (depending on configuration of firmware hotplug).
26 */ 27 */
27#define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw" 28#define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw"
28 29
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
index e3b665782243..eb8a602198ca 100644
--- a/drivers/media/dvb/frontends/sp887x.c
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -5,7 +5,8 @@
5/* 5/*
6 * This driver needs external firmware. Please use the command 6 * This driver needs external firmware. Please use the command
7 * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to 7 * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
8 * download/extract it, and then copy it to /usr/lib/hotplug/firmware. 8 * download/extract it, and then copy it to /usr/lib/hotplug/firmware
9 * or /lib/firmware (depending on configuration of firmware hotplug).
9 */ 10 */
10#define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw" 11#define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw"
11 12
@@ -581,7 +582,7 @@ static struct dvb_frontend_ops sp887x_ops = {
581 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 582 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
582 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 583 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
583 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | 584 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
584 FE_CAN_RECOVER 585 FE_CAN_RECOVER
585 }, 586 },
586 587
587 .release = sp887x_release, 588 .release = sp887x_release,
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 177d71d56b67..5bcd00f792e6 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -131,6 +131,13 @@ static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len
131 return ret == 2 ? 0 : ret; 131 return ret == 2 ? 0 : ret;
132} 132}
133 133
134int stv0299_enable_plli2c (struct dvb_frontend* fe)
135{
136 struct stv0299_state* state = fe->demodulator_priv;
137
138 return stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
139}
140
134static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) 141static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec)
135{ 142{
136 dprintk ("%s\n", __FUNCTION__); 143 dprintk ("%s\n", __FUNCTION__);
@@ -387,7 +394,7 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
387 }; 394 };
388} 395}
389 396
390static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) 397static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd)
391{ 398{
392 struct stv0299_state* state = fe->demodulator_priv; 399 struct stv0299_state* state = fe->demodulator_priv;
393 u8 reg0x08; 400 u8 reg0x08;
@@ -407,7 +414,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
407 414
408 cmd = cmd << 1; 415 cmd = cmd << 1;
409 if (debug_legacy_dish_switch) 416 if (debug_legacy_dish_switch)
410 printk ("%s switch command: 0x%04x\n",__FUNCTION__, cmd); 417 printk ("%s switch command: 0x%04lx\n",__FUNCTION__, cmd);
411 418
412 do_gettimeofday (&nexttime); 419 do_gettimeofday (&nexttime);
413 if (debug_legacy_dish_switch) 420 if (debug_legacy_dish_switch)
@@ -717,5 +724,6 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, "
717 "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy"); 724 "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy");
718MODULE_LICENSE("GPL"); 725MODULE_LICENSE("GPL");
719 726
727EXPORT_SYMBOL(stv0299_enable_plli2c);
720EXPORT_SYMBOL(stv0299_writereg); 728EXPORT_SYMBOL(stv0299_writereg);
721EXPORT_SYMBOL(stv0299_attach); 729EXPORT_SYMBOL(stv0299_attach);
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index 9af3d71c89db..32c87b4c2f13 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -94,6 +94,7 @@ struct stv0299_config
94}; 94};
95 95
96extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); 96extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data);
97extern int stv0299_enable_plli2c (struct dvb_frontend* fe);
97 98
98extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, 99extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
99 struct i2c_adapter* i2c); 100 struct i2c_adapter* i2c);
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index 425cd19136fe..21255cac9793 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -95,7 +95,7 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
95 u8 b0 [] = { reg }; 95 u8 b0 [] = { reg };
96 u8 b1 [] = { 0 }; 96 u8 b1 [] = { 0 };
97 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, 97 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
98 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; 98 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
99 int ret; 99 int ret;
100 100
101 ret = i2c_transfer (state->i2c, msg, 2); 101 ret = i2c_transfer (state->i2c, msg, 2);
@@ -434,7 +434,7 @@ static struct dvb_frontend_ops tda10021_ops = {
434 .frequency_max = 858000000, 434 .frequency_max = 858000000,
435 .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ 435 .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */
436 .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ 436 .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */
437 #if 0 437#if 0
438 .frequency_tolerance = ???, 438 .frequency_tolerance = ???,
439 .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ 439 .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */
440 #endif 440 #endif
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index dd02aff467fe..c63e9a5084eb 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -23,7 +23,8 @@
23 * This driver needs external firmware. Please use the commands 23 * This driver needs external firmware. Please use the commands
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", 24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
25 * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to 25 * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
26 * download/extract them, and then copy them to /usr/lib/hotplug/firmware. 26 * download/extract them, and then copy them to /usr/lib/hotplug/firmware
27 * or /lib/firmware (depending on configuration of firmware hotplug).
27 */ 28 */
28#define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw" 29#define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw"
29#define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw" 30#define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw"
@@ -271,32 +272,57 @@ static int tda10045h_set_bandwidth(struct tda1004x_state *state,
271static int tda10046h_set_bandwidth(struct tda1004x_state *state, 272static int tda10046h_set_bandwidth(struct tda1004x_state *state,
272 fe_bandwidth_t bandwidth) 273 fe_bandwidth_t bandwidth)
273{ 274{
274 static u8 bandwidth_6mhz[] = { 0x80, 0x15, 0xfe, 0xab, 0x8e }; 275 static u8 bandwidth_6mhz_53M[] = { 0x7b, 0x2e, 0x11, 0xf0, 0xd2 };
275 static u8 bandwidth_7mhz[] = { 0x6e, 0x02, 0x53, 0xc8, 0x25 }; 276 static u8 bandwidth_7mhz_53M[] = { 0x6a, 0x02, 0x6a, 0x43, 0x9f };
276 static u8 bandwidth_8mhz[] = { 0x60, 0x12, 0xa8, 0xe4, 0xbd }; 277 static u8 bandwidth_8mhz_53M[] = { 0x5c, 0x32, 0xc2, 0x96, 0x6d };
277 278
279 static u8 bandwidth_6mhz_48M[] = { 0x70, 0x02, 0x49, 0x24, 0x92 };
280 static u8 bandwidth_7mhz_48M[] = { 0x60, 0x02, 0xaa, 0xaa, 0xab };
281 static u8 bandwidth_8mhz_48M[] = { 0x54, 0x03, 0x0c, 0x30, 0xc3 };
282 int tda10046_clk53m;
283
284 if ((state->config->if_freq == TDA10046_FREQ_045) ||
285 (state->config->if_freq == TDA10046_FREQ_052))
286 tda10046_clk53m = 0;
287 else
288 tda10046_clk53m = 1;
278 switch (bandwidth) { 289 switch (bandwidth) {
279 case BANDWIDTH_6_MHZ: 290 case BANDWIDTH_6_MHZ:
280 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz)); 291 if (tda10046_clk53m)
292 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_53M,
293 sizeof(bandwidth_6mhz_53M));
294 else
295 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_48M,
296 sizeof(bandwidth_6mhz_48M));
281 if (state->config->if_freq == TDA10046_FREQ_045) { 297 if (state->config->if_freq == TDA10046_FREQ_045) {
282 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x09); 298 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a);
283 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x4f); 299 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xab);
284 } 300 }
285 break; 301 break;
286 302
287 case BANDWIDTH_7_MHZ: 303 case BANDWIDTH_7_MHZ:
288 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz)); 304 if (tda10046_clk53m)
305 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_53M,
306 sizeof(bandwidth_7mhz_53M));
307 else
308 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_48M,
309 sizeof(bandwidth_7mhz_48M));
289 if (state->config->if_freq == TDA10046_FREQ_045) { 310 if (state->config->if_freq == TDA10046_FREQ_045) {
290 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a); 311 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
291 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x79); 312 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00);
292 } 313 }
293 break; 314 break;
294 315
295 case BANDWIDTH_8_MHZ: 316 case BANDWIDTH_8_MHZ:
296 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz)); 317 if (tda10046_clk53m)
318 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_53M,
319 sizeof(bandwidth_8mhz_53M));
320 else
321 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_48M,
322 sizeof(bandwidth_8mhz_48M));
297 if (state->config->if_freq == TDA10046_FREQ_045) { 323 if (state->config->if_freq == TDA10046_FREQ_045) {
298 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b); 324 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d);
299 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3); 325 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x55);
300 } 326 }
301 break; 327 break;
302 328
@@ -418,9 +444,22 @@ static int tda10045_fwupload(struct dvb_frontend* fe)
418static void tda10046_init_plls(struct dvb_frontend* fe) 444static void tda10046_init_plls(struct dvb_frontend* fe)
419{ 445{
420 struct tda1004x_state* state = fe->demodulator_priv; 446 struct tda1004x_state* state = fe->demodulator_priv;
447 int tda10046_clk53m;
448
449 if ((state->config->if_freq == TDA10046_FREQ_045) ||
450 (state->config->if_freq == TDA10046_FREQ_052))
451 tda10046_clk53m = 0;
452 else
453 tda10046_clk53m = 1;
421 454
422 tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); 455 tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
423 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x0a); // PLL M = 10 456 if(tda10046_clk53m) {
457 printk(KERN_INFO "tda1004x: setting up plls for 53MHz sampling clock\n");
458 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x08); // PLL M = 8
459 } else {
460 printk(KERN_INFO "tda1004x: setting up plls for 48MHz sampling clock\n");
461 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3
462 }
424 if (state->config->xtal_freq == TDA10046_XTAL_4M ) { 463 if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
425 dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); 464 dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__);
426 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 465 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
@@ -428,26 +467,32 @@ static void tda10046_init_plls(struct dvb_frontend* fe)
428 dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__); 467 dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__);
429 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3 468 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3
430 } 469 }
431 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); 470 if(tda10046_clk53m)
471 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x67);
472 else
473 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x72);
474 /* Note clock frequency is handled implicitly */
432 switch (state->config->if_freq) { 475 switch (state->config->if_freq) {
433 case TDA10046_FREQ_3617:
434 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
435 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
436 break;
437 case TDA10046_FREQ_3613:
438 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
439 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x13);
440 break;
441 case TDA10046_FREQ_045: 476 case TDA10046_FREQ_045:
442 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b); 477 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
443 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3); 478 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00);
444 break; 479 break;
445 case TDA10046_FREQ_052: 480 case TDA10046_FREQ_052:
446 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); 481 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d);
447 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x06); 482 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xc7);
483 break;
484 case TDA10046_FREQ_3617:
485 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7);
486 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x59);
487 break;
488 case TDA10046_FREQ_3613:
489 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7);
490 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x3f);
448 break; 491 break;
449 } 492 }
450 tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz 493 tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
494 /* let the PLLs settle */
495 msleep(120);
451} 496}
452 497
453static int tda10046_fwupload(struct dvb_frontend* fe) 498static int tda10046_fwupload(struct dvb_frontend* fe)
@@ -462,13 +507,13 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
462 /* let the clocks recover from sleep */ 507 /* let the clocks recover from sleep */
463 msleep(5); 508 msleep(5);
464 509
510 /* The PLLs need to be reprogrammed after sleep */
511 tda10046_init_plls(fe);
512
465 /* don't re-upload unless necessary */ 513 /* don't re-upload unless necessary */
466 if (tda1004x_check_upload_ok(state) == 0) 514 if (tda1004x_check_upload_ok(state) == 0)
467 return 0; 515 return 0;
468 516
469 /* set parameters */
470 tda10046_init_plls(fe);
471
472 if (state->config->request_firmware != NULL) { 517 if (state->config->request_firmware != NULL) {
473 /* request the firmware, this will block until someone uploads it */ 518 /* request the firmware, this will block until someone uploads it */
474 printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); 519 printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
@@ -484,7 +529,6 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
484 return ret; 529 return ret;
485 } else { 530 } else {
486 /* boot from firmware eeprom */ 531 /* boot from firmware eeprom */
487 /* Hac Note: we might need to do some GPIO Magic here */
488 printk(KERN_INFO "tda1004x: booting from eeprom\n"); 532 printk(KERN_INFO "tda1004x: booting from eeprom\n");
489 tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); 533 tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
490 msleep(300); 534 msleep(300);
@@ -606,10 +650,9 @@ static int tda10046_init(struct dvb_frontend* fe)
606 650
607 // tda setup 651 // tda setup
608 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer 652 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
609 tda1004x_write_byteI(state, TDA1004X_AUTO, 7); // select HP stream 653 tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream
610 tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer 654 tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer
611 655
612 tda10046_init_plls(fe);
613 switch (state->config->agc_config) { 656 switch (state->config->agc_config) {
614 case TDA10046_AGC_DEFAULT: 657 case TDA10046_AGC_DEFAULT:
615 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup 658 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
@@ -626,25 +669,22 @@ static int tda10046_init(struct dvb_frontend* fe)
626 case TDA10046_AGC_TDA827X: 669 case TDA10046_AGC_TDA827X:
627 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup 670 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
628 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold 671 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
629 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x0E); // Gain Renormalize 672 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
630 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities 673 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities
631 break; 674 break;
632 } 675 }
676 tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
633 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on 677 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on
634 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } 678 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // }
635 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values 679 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
636 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } 680 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // }
637 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // } 681 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // }
638 tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1 682 tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 0x12); // IF gain 2, TUN gain 1
639 tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits 683 tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
640 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config 684 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
641 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config 685 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
642 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); 686 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
643 687
644 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup
645 tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config
646 tda1004x_write_byteI(state, TDA10046H_GPIO_SELECT, 8); // GPIO select
647
648 state->initialised = 1; 688 state->initialised = 1;
649 return 0; 689 return 0;
650} 690}
@@ -686,9 +726,9 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
686 726
687 // Set standard params.. or put them to auto 727 // Set standard params.. or put them to auto
688 if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) || 728 if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) ||
689 (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) || 729 (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) ||
690 (fe_params->u.ofdm.constellation == QAM_AUTO) || 730 (fe_params->u.ofdm.constellation == QAM_AUTO) ||
691 (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) { 731 (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) {
692 tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto 732 tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto
693 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits 733 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits
694 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits 734 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits
@@ -851,6 +891,7 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
851static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) 891static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params)
852{ 892{
853 struct tda1004x_state* state = fe->demodulator_priv; 893 struct tda1004x_state* state = fe->demodulator_priv;
894
854 dprintk("%s\n", __FUNCTION__); 895 dprintk("%s\n", __FUNCTION__);
855 896
856 // inversion status 897 // inversion status
@@ -875,16 +916,18 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete
875 break; 916 break;
876 } 917 }
877 break; 918 break;
878
879 case TDA1004X_DEMOD_TDA10046: 919 case TDA1004X_DEMOD_TDA10046:
880 switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) { 920 switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) {
881 case 0x60: 921 case 0x5c:
922 case 0x54:
882 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; 923 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
883 break; 924 break;
884 case 0x6e: 925 case 0x6a:
926 case 0x60:
885 fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; 927 fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
886 break; 928 break;
887 case 0x80: 929 case 0x7b:
930 case 0x70:
888 fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; 931 fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
889 break; 932 break;
890 } 933 }
diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/dvb/pluto2/Kconfig
index f02842be0d60..84f8f9f52869 100644
--- a/drivers/media/dvb/pluto2/Kconfig
+++ b/drivers/media/dvb/pluto2/Kconfig
@@ -8,7 +8,7 @@ config DVB_PLUTO2
8 Support for PCI cards based on the Pluto2 FPGA like the Satelco 8 Support for PCI cards based on the Pluto2 FPGA like the Satelco
9 Easywatch Mobile Terrestrial DVB-T Receiver. 9 Easywatch Mobile Terrestrial DVB-T Receiver.
10 10
11 Since these cards have no MPEG decoder onboard, they transmit 11 Since these cards have no MPEG decoder onboard, they transmit
12 only compressed MPEG data over the PCI bus, so you need 12 only compressed MPEG data over the PCI bus, so you need
13 an external software decoder to watch TV on your computer. 13 an external software decoder to watch TV on your computer.
14 14
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index fa5034a9ecf5..5b2aadb8385c 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -18,9 +18,10 @@ config DVB_AV7110
18 This driver only supports the fullfeatured cards with 18 This driver only supports the fullfeatured cards with
19 onboard MPEG2 decoder. 19 onboard MPEG2 decoder.
20 20
21 This driver needs an external firmware. Please use the script 21 This driver needs an external firmware. Please use the script
22 "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to 22 "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to
23 download/extract it, and then copy it to /usr/lib/hotplug/firmware. 23 download/extract it, and then copy it to /usr/lib/hotplug/firmware
24 or /lib/firmware (depending on configuration of firmware hotplug).
24 25
25 Say Y if you own such a card and want to use it. 26 Say Y if you own such a card and want to use it.
26 27
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile
index 825ab1c38a4f..a690730ac39d 100644
--- a/drivers/media/dvb/ttpci/Makefile
+++ b/drivers/media/dvb/ttpci/Makefile
@@ -16,7 +16,7 @@ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
16hostprogs-y := fdump 16hostprogs-y := fdump
17 17
18ifdef CONFIG_DVB_AV7110_FIRMWARE 18ifdef CONFIG_DVB_AV7110_FIRMWARE
19$(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h 19$(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h
20 20
21$(obj)/av7110_firm.h: 21$(obj)/av7110_firm.h:
22 $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ 22 $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 7dae91e5863c..8ce4146f55f1 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -133,7 +133,13 @@ static void init_av7110_av(struct av7110 *av7110)
133 /* remaining inits according to card and frontend type */ 133 /* remaining inits according to card and frontend type */
134 av7110->analog_tuner_flags = 0; 134 av7110->analog_tuner_flags = 0;
135 av7110->current_input = 0; 135 av7110->current_input = 0;
136 if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { 136 if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a) {
137 printk("dvb-ttpci: MSP3415 audio DAC @ card %d\n",
138 av7110->dvb_adapter.num);
139 av7110->adac_type = DVB_ADAC_MSP34x5;
140 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on
141 }
142 else if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
137 printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n", 143 printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
138 av7110->dvb_adapter.num); 144 av7110->dvb_adapter.num);
139 av7110->adac_type = DVB_ADAC_CRYSTAL; 145 av7110->adac_type = DVB_ADAC_CRYSTAL;
@@ -156,10 +162,10 @@ static void init_av7110_av(struct av7110 *av7110)
156 else { 162 else {
157 av7110->adac_type = adac; 163 av7110->adac_type = adac;
158 printk("dvb-ttpci: adac type set to %d @ card %d\n", 164 printk("dvb-ttpci: adac type set to %d @ card %d\n",
159 av7110->dvb_adapter.num, av7110->adac_type); 165 av7110->adac_type, av7110->dvb_adapter.num);
160 } 166 }
161 167
162 if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) { 168 if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP34x0) {
163 // switch DVB SCART on 169 // switch DVB SCART on
164 ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); 170 ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
165 if (ret < 0) 171 if (ret < 0)
@@ -190,17 +196,15 @@ static void recover_arm(struct av7110 *av7110)
190 196
191 av7110_bootarm(av7110); 197 av7110_bootarm(av7110);
192 msleep(100); 198 msleep(100);
193 restart_feeds(av7110);
194 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config);
195}
196 199
197static void arm_error(struct av7110 *av7110) 200 init_av7110_av(av7110);
198{ 201
199 dprintk(4, "%p\n",av7110); 202 /* card-specific recovery */
203 if (av7110->recover)
204 av7110->recover(av7110);
200 205
201 av7110->arm_errors++; 206 restart_feeds(av7110);
202 av7110->arm_ready = 0; 207 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config);
203 recover_arm(av7110);
204} 208}
205 209
206static void av7110_arm_sync(struct av7110 *av7110) 210static void av7110_arm_sync(struct av7110 *av7110)
@@ -240,26 +244,22 @@ static int arm_thread(void *data)
240 244
241 if (down_interruptible(&av7110->dcomlock)) 245 if (down_interruptible(&av7110->dcomlock))
242 break; 246 break;
243
244 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); 247 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
245 up(&av7110->dcomlock); 248 up(&av7110->dcomlock);
246 249
247 if (newloops == av7110->arm_loops) { 250 if (newloops == av7110->arm_loops || av7110->arm_errors > 3) {
248 printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n", 251 printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
249 av7110->dvb_adapter.num); 252 av7110->dvb_adapter.num);
250 253
251 arm_error(av7110); 254 recover_arm(av7110);
252 av7710_set_video_mode(av7110, vidmode);
253
254 init_av7110_av(av7110);
255 255
256 if (down_interruptible(&av7110->dcomlock)) 256 if (down_interruptible(&av7110->dcomlock))
257 break; 257 break;
258
259 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1; 258 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1;
260 up(&av7110->dcomlock); 259 up(&av7110->dcomlock);
261 } 260 }
262 av7110->arm_loops = newloops; 261 av7110->arm_loops = newloops;
262 av7110->arm_errors = 0;
263 } 263 }
264 264
265 av7110->arm_thread = NULL; 265 av7110->arm_thread = NULL;
@@ -510,10 +510,6 @@ static void gpioirq(unsigned long data)
510 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); 510 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
511 511
512 av7110->video_size.h = h_ar & 0xfff; 512 av7110->video_size.h = h_ar & 0xfff;
513 dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
514 av7110->video_size.w,
515 av7110->video_size.h,
516 av7110->video_size.aspect_ratio);
517 513
518 event.type = VIDEO_EVENT_SIZE_CHANGED; 514 event.type = VIDEO_EVENT_SIZE_CHANGED;
519 event.u.size.w = av7110->video_size.w; 515 event.u.size.w = av7110->video_size.w;
@@ -535,6 +531,11 @@ static void gpioirq(unsigned long data)
535 event.u.size.aspect_ratio = VIDEO_FORMAT_4_3; 531 event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;
536 av7110->videostate.video_format = VIDEO_FORMAT_4_3; 532 av7110->videostate.video_format = VIDEO_FORMAT_4_3;
537 } 533 }
534
535 dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
536 av7110->video_size.w, av7110->video_size.h,
537 av7110->video_size.aspect_ratio);
538
538 dvb_video_add_event(av7110, &event); 539 dvb_video_add_event(av7110, &event);
539 break; 540 break;
540 } 541 }
@@ -714,6 +715,8 @@ static struct dvb_device dvbdev_osd = {
714static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, 715static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
715 u16 subpid, u16 pcrpid) 716 u16 subpid, u16 pcrpid)
716{ 717{
718 u16 aflags = 0;
719
717 dprintk(4, "%p\n", av7110); 720 dprintk(4, "%p\n", av7110);
718 721
719 if (vpid == 0x1fff || apid == 0x1fff || 722 if (vpid == 0x1fff || apid == 0x1fff ||
@@ -725,8 +728,11 @@ static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
725 av7110->pids[DMX_PES_PCR] = 0; 728 av7110->pids[DMX_PES_PCR] = 0;
726 } 729 }
727 730
728 return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 5, 731 if (av7110->audiostate.bypass_mode)
729 pcrpid, vpid, apid, ttpid, subpid); 732 aflags |= 0x8000;
733
734 return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 6,
735 pcrpid, vpid, apid, ttpid, subpid, aflags);
730} 736}
731 737
732int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, 738int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
@@ -1043,7 +1049,7 @@ static void restart_feeds(struct av7110 *av7110)
1043 struct dvb_demux *dvbdmx = &av7110->demux; 1049 struct dvb_demux *dvbdmx = &av7110->demux;
1044 struct dvb_demux_feed *feed; 1050 struct dvb_demux_feed *feed;
1045 int mode; 1051 int mode;
1046 int i; 1052 int i, j;
1047 1053
1048 dprintk(4, "%p\n", av7110); 1054 dprintk(4, "%p\n", av7110);
1049 1055
@@ -1051,10 +1057,21 @@ static void restart_feeds(struct av7110 *av7110)
1051 av7110->playing = 0; 1057 av7110->playing = 0;
1052 av7110->rec_mode = 0; 1058 av7110->rec_mode = 0;
1053 1059
1054 for (i = 0; i < dvbdmx->filternum; i++) { 1060 for (i = 0; i < dvbdmx->feednum; i++) {
1055 feed = &dvbdmx->feed[i]; 1061 feed = &dvbdmx->feed[i];
1056 if (feed->state == DMX_STATE_GO) 1062 if (feed->state == DMX_STATE_GO) {
1063 if (feed->type == DMX_TYPE_SEC) {
1064 for (j = 0; j < dvbdmx->filternum; j++) {
1065 if (dvbdmx->filter[j].type != DMX_TYPE_SEC)
1066 continue;
1067 if (dvbdmx->filter[j].filter.parent != &feed->feed.sec)
1068 continue;
1069 if (dvbdmx->filter[j].state == DMX_STATE_GO)
1070 dvbdmx->filter[j].state = DMX_STATE_READY;
1071 }
1072 }
1057 av7110_start_feed(feed); 1073 av7110_start_feed(feed);
1074 }
1058 } 1075 }
1059 1076
1060 if (mode) 1077 if (mode)
@@ -1483,9 +1500,9 @@ static int get_firmware(struct av7110* av7110)
1483 if (ret == -ENOENT) { 1500 if (ret == -ENOENT) {
1484 printk(KERN_ERR "dvb-ttpci: could not load firmware," 1501 printk(KERN_ERR "dvb-ttpci: could not load firmware,"
1485 " file not found: dvb-ttpci-01.fw\n"); 1502 " file not found: dvb-ttpci-01.fw\n");
1486 printk(KERN_ERR "dvb-ttpci: usually this should be in" 1503 printk(KERN_ERR "dvb-ttpci: usually this should be in "
1487 " /usr/lib/hotplug/firmware\n"); 1504 "/usr/lib/hotplug/firmware or /lib/firmware\n");
1488 printk(KERN_ERR "dvb-ttpci: and can be downloaded here" 1505 printk(KERN_ERR "dvb-ttpci: and can be downloaded from"
1489 " http://www.linuxtv.org/download/dvb/firmware/\n"); 1506 " http://www.linuxtv.org/download/dvb/firmware/\n");
1490 } else 1507 } else
1491 printk(KERN_ERR "dvb-ttpci: cannot request firmware" 1508 printk(KERN_ERR "dvb-ttpci: cannot request firmware"
@@ -2110,8 +2127,10 @@ static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_p
2110 struct av7110* av7110 = fe->dvb->priv; 2127 struct av7110* av7110 = fe->dvb->priv;
2111 2128
2112 int ret = av7110_fe_lock_fix(av7110, 0); 2129 int ret = av7110_fe_lock_fix(av7110, 0);
2113 if (!ret) 2130 if (!ret) {
2131 av7110->saved_fe_params = *params;
2114 ret = av7110->fe_set_frontend(fe, params); 2132 ret = av7110->fe_set_frontend(fe, params);
2133 }
2115 return ret; 2134 return ret;
2116} 2135}
2117 2136
@@ -2153,8 +2172,10 @@ static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
2153 struct av7110* av7110 = fe->dvb->priv; 2172 struct av7110* av7110 = fe->dvb->priv;
2154 2173
2155 int ret = av7110_fe_lock_fix(av7110, 0); 2174 int ret = av7110_fe_lock_fix(av7110, 0);
2156 if (!ret) 2175 if (!ret) {
2176 av7110->saved_master_cmd = *cmd;
2157 ret = av7110->fe_diseqc_send_master_cmd(fe, cmd); 2177 ret = av7110->fe_diseqc_send_master_cmd(fe, cmd);
2178 }
2158 return ret; 2179 return ret;
2159} 2180}
2160 2181
@@ -2163,8 +2184,10 @@ static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_
2163 struct av7110* av7110 = fe->dvb->priv; 2184 struct av7110* av7110 = fe->dvb->priv;
2164 2185
2165 int ret = av7110_fe_lock_fix(av7110, 0); 2186 int ret = av7110_fe_lock_fix(av7110, 0);
2166 if (!ret) 2187 if (!ret) {
2188 av7110->saved_minicmd = minicmd;
2167 ret = av7110->fe_diseqc_send_burst(fe, minicmd); 2189 ret = av7110->fe_diseqc_send_burst(fe, minicmd);
2190 }
2168 return ret; 2191 return ret;
2169} 2192}
2170 2193
@@ -2173,8 +2196,10 @@ static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
2173 struct av7110* av7110 = fe->dvb->priv; 2196 struct av7110* av7110 = fe->dvb->priv;
2174 2197
2175 int ret = av7110_fe_lock_fix(av7110, 0); 2198 int ret = av7110_fe_lock_fix(av7110, 0);
2176 if (!ret) 2199 if (!ret) {
2200 av7110->saved_tone = tone;
2177 ret = av7110->fe_set_tone(fe, tone); 2201 ret = av7110->fe_set_tone(fe, tone);
2202 }
2178 return ret; 2203 return ret;
2179} 2204}
2180 2205
@@ -2183,12 +2208,14 @@ static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t volta
2183 struct av7110* av7110 = fe->dvb->priv; 2208 struct av7110* av7110 = fe->dvb->priv;
2184 2209
2185 int ret = av7110_fe_lock_fix(av7110, 0); 2210 int ret = av7110_fe_lock_fix(av7110, 0);
2186 if (!ret) 2211 if (!ret) {
2212 av7110->saved_voltage = voltage;
2187 ret = av7110->fe_set_voltage(fe, voltage); 2213 ret = av7110->fe_set_voltage(fe, voltage);
2214 }
2188 return ret; 2215 return ret;
2189} 2216}
2190 2217
2191static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd) 2218static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned long cmd)
2192{ 2219{
2193 struct av7110* av7110 = fe->dvb->priv; 2220 struct av7110* av7110 = fe->dvb->priv;
2194 2221
@@ -2198,6 +2225,23 @@ static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, un
2198 return ret; 2225 return ret;
2199} 2226}
2200 2227
2228static void dvb_s_recover(struct av7110* av7110)
2229{
2230 av7110_fe_init(av7110->fe);
2231
2232 av7110_fe_set_voltage(av7110->fe, av7110->saved_voltage);
2233 if (av7110->saved_master_cmd.msg_len) {
2234 msleep(20);
2235 av7110_fe_diseqc_send_master_cmd(av7110->fe, &av7110->saved_master_cmd);
2236 }
2237 msleep(20);
2238 av7110_fe_diseqc_send_burst(av7110->fe, av7110->saved_minicmd);
2239 msleep(20);
2240 av7110_fe_set_tone(av7110->fe, av7110->saved_tone);
2241
2242 av7110_fe_set_frontend(av7110->fe, &av7110->saved_fe_params);
2243}
2244
2201static u8 read_pwm(struct av7110* av7110) 2245static u8 read_pwm(struct av7110* av7110)
2202{ 2246{
2203 u8 b = 0xff; 2247 u8 b = 0xff;
@@ -2235,6 +2279,7 @@ static int frontend_init(struct av7110 *av7110)
2235 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; 2279 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2236 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; 2280 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2237 av7110->fe->ops->set_tone = av7110_set_tone; 2281 av7110->fe->ops->set_tone = av7110_set_tone;
2282 av7110->recover = dvb_s_recover;
2238 break; 2283 break;
2239 } 2284 }
2240 2285
@@ -2244,15 +2289,17 @@ static int frontend_init(struct av7110 *av7110)
2244 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; 2289 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2245 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; 2290 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2246 av7110->fe->ops->set_tone = av7110_set_tone; 2291 av7110->fe->ops->set_tone = av7110_set_tone;
2292 av7110->recover = dvb_s_recover;
2247 break; 2293 break;
2248 } 2294 }
2249 2295
2250 // Try the grundig 29504-451 2296 // Try the grundig 29504-451
2251 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); 2297 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
2252 if (av7110->fe) { 2298 if (av7110->fe) {
2253 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; 2299 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2254 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; 2300 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2255 av7110->fe->ops->set_tone = av7110_set_tone; 2301 av7110->fe->ops->set_tone = av7110_set_tone;
2302 av7110->recover = dvb_s_recover;
2256 break; 2303 break;
2257 } 2304 }
2258 2305
@@ -2274,12 +2321,12 @@ static int frontend_init(struct av7110 *av7110)
2274 case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X 2321 case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
2275 2322
2276 // ALPS TDLB7 2323 // ALPS TDLB7
2277 av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); 2324 av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
2278 break; 2325 break;
2279 2326
2280 case 0x0002: // Hauppauge/TT DVB-C premium rev2.X 2327 case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
2281 2328
2282 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); 2329 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
2283 break; 2330 break;
2284 2331
2285 case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */ 2332 case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
@@ -2289,6 +2336,7 @@ static int frontend_init(struct av7110 *av7110)
2289 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; 2336 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2290 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; 2337 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2291 av7110->fe->ops->set_tone = av7110_set_tone; 2338 av7110->fe->ops->set_tone = av7110_set_tone;
2339 av7110->recover = dvb_s_recover;
2292 } 2340 }
2293 break; 2341 break;
2294 2342
@@ -2314,8 +2362,11 @@ static int frontend_init(struct av7110 *av7110)
2314 case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */ 2362 case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */
2315 /* ALPS BSBE1 */ 2363 /* ALPS BSBE1 */
2316 av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); 2364 av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap);
2317 if (av7110->fe) 2365 if (av7110->fe) {
2318 av7110->fe->ops->set_voltage = lnbp21_set_voltage; 2366 av7110->fe->ops->set_voltage = lnbp21_set_voltage;
2367 av7110->fe->ops->dishnetwork_send_legacy_command = NULL;
2368 av7110->recover = dvb_s_recover;
2369 }
2319 break; 2370 break;
2320 } 2371 }
2321 } 2372 }
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
index cce00ef293e9..6ea30df2e823 100644
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -98,7 +98,8 @@ struct av7110 {
98 int adac_type; /* audio DAC type */ 98 int adac_type; /* audio DAC type */
99#define DVB_ADAC_TI 0 99#define DVB_ADAC_TI 0
100#define DVB_ADAC_CRYSTAL 1 100#define DVB_ADAC_CRYSTAL 1
101#define DVB_ADAC_MSP 2 101#define DVB_ADAC_MSP34x0 2
102#define DVB_ADAC_MSP34x5 3
102#define DVB_ADAC_NONE -1 103#define DVB_ADAC_NONE -1
103 104
104 105
@@ -228,6 +229,9 @@ struct av7110 {
228 struct dvb_video_events video_events; 229 struct dvb_video_events video_events;
229 video_size_t video_size; 230 video_size_t video_size;
230 231
232 u16 wssMode;
233 u16 wssData;
234
231 u32 ir_config; 235 u32 ir_config;
232 u32 ir_command; 236 u32 ir_command;
233 void (*ir_handler)(struct av7110 *av7110, u32 ircom); 237 void (*ir_handler)(struct av7110 *av7110, u32 ircom);
@@ -245,6 +249,15 @@ struct av7110 {
245 249
246 struct dvb_frontend* fe; 250 struct dvb_frontend* fe;
247 fe_status_t fe_status; 251 fe_status_t fe_status;
252
253 /* crash recovery */
254 void (*recover)(struct av7110* av7110);
255 struct dvb_frontend_parameters saved_fe_params;
256 fe_sec_voltage_t saved_voltage;
257 fe_sec_tone_mode_t saved_tone;
258 struct dvb_diseqc_master_cmd saved_master_cmd;
259 fe_sec_mini_cmd_t saved_minicmd;
260
248 int (*fe_init)(struct dvb_frontend* fe); 261 int (*fe_init)(struct dvb_frontend* fe);
249 int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status); 262 int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status);
250 int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe); 263 int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe);
@@ -252,7 +265,7 @@ struct av7110 {
252 int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); 265 int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd);
253 int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); 266 int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone);
254 int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); 267 int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
255 int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd); 268 int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
256 int (*fe_set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); 269 int (*fe_set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
257}; 270};
258 271
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index 0696a5a4f855..400facec7407 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -309,7 +309,7 @@ int av7110_set_volume(struct av7110 *av7110, int volleft, int volright)
309 i2c_writereg(av7110, 0x20, 0x04, volright); 309 i2c_writereg(av7110, 0x20, 0x04, volright);
310 return 0; 310 return 0;
311 311
312 case DVB_ADAC_MSP: 312 case DVB_ADAC_MSP34x0:
313 vol = (volleft > volright) ? volleft : volright; 313 vol = (volleft > volright) ? volleft : volright;
314 val = (vol * 0x73 / 255) << 8; 314 val = (vol * 0x73 / 255) << 8;
315 if (vol > 0) 315 if (vol > 0)
@@ -1256,7 +1256,9 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1256 break; 1256 break;
1257 1257
1258 case AUDIO_SET_BYPASS_MODE: 1258 case AUDIO_SET_BYPASS_MODE:
1259 ret = -EINVAL; 1259 if (FW_VERSION(av7110->arm_app) < 0x2621)
1260 ret = -EINVAL;
1261 av7110->audiostate.bypass_mode = (int)arg;
1260 break; 1262 break;
1261 1263
1262 case AUDIO_CHANNEL_SELECT: 1264 case AUDIO_CHANNEL_SELECT:
@@ -1295,7 +1297,11 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1295 break; 1297 break;
1296 1298
1297 case AUDIO_GET_CAPABILITIES: 1299 case AUDIO_GET_CAPABILITIES:
1298 *(int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; 1300 if (FW_VERSION(av7110->arm_app) < 0x2621)
1301 *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2;
1302 else
1303 *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_DTS | AUDIO_CAP_AC3 |
1304 AUDIO_CAP_MP1 | AUDIO_CAP_MP2;
1299 break; 1305 break;
1300 1306
1301 case AUDIO_CLEAR_BUFFER: 1307 case AUDIO_CLEAR_BUFFER:
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 87106e8bf35b..cb377452b57d 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -230,6 +230,8 @@ int av7110_bootarm(struct av7110 *av7110)
230 230
231 dprintk(4, "%p\n", av7110); 231 dprintk(4, "%p\n", av7110);
232 232
233 av7110->arm_ready = 0;
234
233 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); 235 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
234 236
235 /* Disable DEBI and GPIO irq */ 237 /* Disable DEBI and GPIO irq */
@@ -361,6 +363,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
361 break; 363 break;
362 if (err) { 364 if (err) {
363 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__); 365 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__);
366 av7110->arm_errors++;
364 return -ETIMEDOUT; 367 return -ETIMEDOUT;
365 } 368 }
366 msleep(1); 369 msleep(1);
@@ -1206,9 +1209,9 @@ int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap)
1206 switch (cap->cmd) { 1209 switch (cap->cmd) {
1207 case OSD_CAP_MEMSIZE: 1210 case OSD_CAP_MEMSIZE:
1208 if (FW_4M_SDRAM(av7110->arm_app)) 1211 if (FW_4M_SDRAM(av7110->arm_app))
1209 cap->val = 1000000; 1212 cap->val = 1000000;
1210 else 1213 else
1211 cap->val = 92000; 1214 cap->val = 92000;
1212 return 0; 1215 return 0;
1213 default: 1216 default:
1214 return -EINVAL; 1217 return -EINVAL;
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
index 2a5e87ba1052..84b83299b8be 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.h
+++ b/drivers/media/dvb/ttpci/av7110_hw.h
@@ -167,7 +167,8 @@ enum av7110_encoder_command {
167 LoadVidCode, 167 LoadVidCode,
168 SetMonitorType, 168 SetMonitorType,
169 SetPanScanType, 169 SetPanScanType,
170 SetFreezeMode 170 SetFreezeMode,
171 SetWSSConfig
171}; 172};
172 173
173enum av7110_rec_play_state { 174enum av7110_rec_play_state {
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index f5e59fc924af..9138132ad25f 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -17,6 +17,8 @@ static int av_cnt;
17static struct av7110 *av_list[4]; 17static struct av7110 *av_list[4];
18static struct input_dev *input_dev; 18static struct input_dev *input_dev;
19 19
20static u8 delay_timer_finished;
21
20static u16 key_map [256] = { 22static u16 key_map [256] = {
21 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, 23 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
22 KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, 24 KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO,
@@ -112,13 +114,16 @@ static void av7110_emit_key(unsigned long parm)
112 if (timer_pending(&keyup_timer)) { 114 if (timer_pending(&keyup_timer)) {
113 del_timer(&keyup_timer); 115 del_timer(&keyup_timer);
114 if (keyup_timer.data != keycode || new_toggle != old_toggle) { 116 if (keyup_timer.data != keycode || new_toggle != old_toggle) {
117 delay_timer_finished = 0;
115 input_event(input_dev, EV_KEY, keyup_timer.data, !!0); 118 input_event(input_dev, EV_KEY, keyup_timer.data, !!0);
116 input_event(input_dev, EV_KEY, keycode, !0); 119 input_event(input_dev, EV_KEY, keycode, !0);
117 } else 120 } else
118 input_event(input_dev, EV_KEY, keycode, 2); 121 if (delay_timer_finished)
119 122 input_event(input_dev, EV_KEY, keycode, 2);
120 } else 123 } else {
124 delay_timer_finished = 0;
121 input_event(input_dev, EV_KEY, keycode, !0); 125 input_event(input_dev, EV_KEY, keycode, !0);
126 }
122 127
123 keyup_timer.expires = jiffies + UP_TIMEOUT; 128 keyup_timer.expires = jiffies + UP_TIMEOUT;
124 keyup_timer.data = keycode; 129 keyup_timer.data = keycode;
@@ -145,7 +150,8 @@ static void input_register_keys(void)
145 150
146static void input_repeat_key(unsigned long data) 151static void input_repeat_key(unsigned long data)
147{ 152{
148 /* dummy routine to disable autorepeat in the input driver */ 153 /* called by the input driver after rep[REP_DELAY] ms */
154 delay_timer_finished = 1;
149} 155}
150 156
151 157
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index b5aea4129fa7..94cf38c7e8a8 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -490,6 +490,58 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
490 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); 490 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
491 break; 491 break;
492 } 492 }
493 case VIDIOC_G_SLICED_VBI_CAP:
494 {
495 struct v4l2_sliced_vbi_cap *cap = arg;
496 dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
497 memset(cap, 0, sizeof *cap);
498 if (FW_VERSION(av7110->arm_app) >= 0x2623) {
499 cap->service_set = V4L2_SLICED_WSS_625;
500 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
501 }
502 break;
503 }
504 case VIDIOC_G_FMT:
505 {
506 struct v4l2_format *f = arg;
507 dprintk(2, "VIDIOC_G_FMT:\n");
508 if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
509 FW_VERSION(av7110->arm_app) < 0x2623)
510 return -EAGAIN; /* handled by core driver */
511 memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
512 if (av7110->wssMode) {
513 f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
514 f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
515 f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
516 }
517 break;
518 }
519 case VIDIOC_S_FMT:
520 {
521 struct v4l2_format *f = arg;
522 dprintk(2, "VIDIOC_S_FMT\n");
523 if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
524 FW_VERSION(av7110->arm_app) < 0x2623)
525 return -EAGAIN; /* handled by core driver */
526 if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
527 f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
528 memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
529 /* WSS controlled by firmware */
530 av7110->wssMode = 0;
531 av7110->wssData = 0;
532 return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
533 SetWSSConfig, 1, 0);
534 } else {
535 memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
536 f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
537 f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
538 f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
539 /* WSS controlled by userspace */
540 av7110->wssMode = 1;
541 av7110->wssData = 0;
542 }
543 break;
544 }
493 default: 545 default:
494 printk("no such ioctl\n"); 546 printk("no such ioctl\n");
495 return -ENOIOCTLCMD; 547 return -ENOIOCTLCMD;
@@ -497,6 +549,46 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
497 return 0; 549 return 0;
498} 550}
499 551
552static int av7110_vbi_reset(struct inode *inode, struct file *file)
553{
554 struct saa7146_fh *fh = file->private_data;
555 struct saa7146_dev *dev = fh->dev;
556 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
557
558 dprintk(2, "%s\n", __FUNCTION__);
559 av7110->wssMode = 0;
560 av7110->wssData = 0;
561 if (FW_VERSION(av7110->arm_app) < 0x2623)
562 return 0;
563 else
564 return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0);
565}
566
567static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
568{
569 struct saa7146_fh *fh = file->private_data;
570 struct saa7146_dev *dev = fh->dev;
571 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
572 struct v4l2_sliced_vbi_data d;
573 int rc;
574
575 dprintk(2, "%s\n", __FUNCTION__);
576 if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d)
577 return -EINVAL;
578 if (copy_from_user(&d, data, count))
579 return -EFAULT;
580 if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23)
581 return -EINVAL;
582 if (d.id) {
583 av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0];
584 rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig,
585 2, 1, av7110->wssData);
586 } else {
587 av7110->wssData = 0;
588 rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0);
589 }
590 return (rc < 0) ? rc : count;
591}
500 592
501/**************************************************************************** 593/****************************************************************************
502 * INITIALIZATION 594 * INITIALIZATION
@@ -512,6 +604,9 @@ static struct saa7146_extension_ioctls ioctls[] = {
512 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE }, 604 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
513 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, 605 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
514 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, 606 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
607 { VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE },
608 { VIDIOC_G_FMT, SAA7146_BEFORE },
609 { VIDIOC_S_FMT, SAA7146_BEFORE },
515 { 0, 0 } 610 { 0, 0 }
516}; 611};
517 612
@@ -587,7 +682,7 @@ int av7110_init_analog_module(struct av7110 *av7110)
587 682
588 printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n", 683 printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n",
589 av7110->dvb_adapter.num); 684 av7110->dvb_adapter.num);
590 av7110->adac_type = DVB_ADAC_MSP; 685 av7110->adac_type = DVB_ADAC_MSP34x0;
591 msleep(100); // the probing above resets the msp... 686 msleep(100); // the probing above resets the msp...
592 msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); 687 msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
593 msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); 688 msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
@@ -692,12 +787,11 @@ int av7110_init_v4l(struct av7110 *av7110)
692 saa7146_vv_release(dev); 787 saa7146_vv_release(dev);
693 return -ENODEV; 788 return -ENODEV;
694 } 789 }
695 if (av7110->analog_tuner_flags) { 790 if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
696 if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) { 791 ERR(("cannot register vbi v4l2 device. skipping.\n"));
697 ERR(("cannot register vbi v4l2 device. skipping.\n")); 792 } else {
698 } else { 793 if (av7110->analog_tuner_flags)
699 av7110->analog_tuner_flags |= ANALOG_TUNER_VBI; 794 av7110->analog_tuner_flags |= ANALOG_TUNER_VBI;
700 }
701 } 795 }
702 return 0; 796 return 0;
703} 797}
@@ -778,7 +872,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
778static struct saa7146_ext_vv av7110_vv_data_st = { 872static struct saa7146_ext_vv av7110_vv_data_st = {
779 .inputs = 1, 873 .inputs = 1,
780 .audios = 1, 874 .audios = 1,
781 .capabilities = 0, 875 .capabilities = V4L2_CAP_SLICED_VBI_OUTPUT,
782 .flags = 0, 876 .flags = 0,
783 877
784 .stds = &standard[0], 878 .stds = &standard[0],
@@ -787,12 +881,16 @@ static struct saa7146_ext_vv av7110_vv_data_st = {
787 881
788 .ioctls = &ioctls[0], 882 .ioctls = &ioctls[0],
789 .ioctl = av7110_ioctl, 883 .ioctl = av7110_ioctl,
884
885 .vbi_fops.open = av7110_vbi_reset,
886 .vbi_fops.release = av7110_vbi_reset,
887 .vbi_fops.write = av7110_vbi_write,
790}; 888};
791 889
792static struct saa7146_ext_vv av7110_vv_data_c = { 890static struct saa7146_ext_vv av7110_vv_data_c = {
793 .inputs = 1, 891 .inputs = 1,
794 .audios = 1, 892 .audios = 1,
795 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE, 893 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT,
796 .flags = SAA7146_USE_PORT_B_FOR_VBI, 894 .flags = SAA7146_USE_PORT_B_FOR_VBI,
797 895
798 .stds = &standard[0], 896 .stds = &standard[0],
@@ -801,5 +899,9 @@ static struct saa7146_ext_vv av7110_vv_data_c = {
801 899
802 .ioctls = &ioctls[0], 900 .ioctls = &ioctls[0],
803 .ioctl = av7110_ioctl, 901 .ioctl = av7110_ioctl,
902
903 .vbi_fops.open = av7110_vbi_reset,
904 .vbi_fops.release = av7110_vbi_reset,
905 .vbi_fops.write = av7110_vbi_write,
804}; 906};
805 907
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 9f51bae7194c..f9d00452e639 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -127,7 +127,7 @@ static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int ad
127 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); 127 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
128 udelay(1); 128 udelay(1);
129 129
130 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 0); 130 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
131 131
132 if (result == -ETIMEDOUT) 132 if (result == -ETIMEDOUT)
133 budget_av->slot_status = 0; 133 budget_av->slot_status = 0;
@@ -145,7 +145,7 @@ static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int a
145 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); 145 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
146 udelay(1); 146 udelay(1);
147 147
148 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 0); 148 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
149 149
150 if (result == -ETIMEDOUT) 150 if (result == -ETIMEDOUT)
151 budget_av->slot_status = 0; 151 budget_av->slot_status = 0;
@@ -192,7 +192,7 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
192{ 192{
193 struct budget_av *budget_av = (struct budget_av *) ca->data; 193 struct budget_av *budget_av = (struct budget_av *) ca->data;
194 struct saa7146_dev *saa = budget_av->budget.dev; 194 struct saa7146_dev *saa = budget_av->budget.dev;
195 int timeout = 500; // 5 seconds (4.4.6 Ready) 195 int timeout = 50; // 5 seconds (4.4.6 Ready)
196 196
197 if (slot != 0) 197 if (slot != 0)
198 return -EINVAL; 198 return -EINVAL;
@@ -256,19 +256,37 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open
256{ 256{
257 struct budget_av *budget_av = (struct budget_av *) ca->data; 257 struct budget_av *budget_av = (struct budget_av *) ca->data;
258 struct saa7146_dev *saa = budget_av->budget.dev; 258 struct saa7146_dev *saa = budget_av->budget.dev;
259 int cam_present = 0;
259 260
260 if (slot != 0) 261 if (slot != 0)
261 return -EINVAL; 262 return -EINVAL;
262 263
263 if (!budget_av->slot_status) { 264 if (!budget_av->slot_status)
265 {
266 // first of all test the card detect line
264 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); 267 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
265 udelay(1); 268 udelay(1);
266 if (saa7146_read(saa, PSR) & MASK_06) 269 if (saa7146_read(saa, PSR) & MASK_06)
267 { 270 {
271 cam_present = 1;
272 }
273 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
274
275 // that is unreliable however, so try and read from IO memory
276 if (!cam_present)
277 {
278 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
279 if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) != -ETIMEDOUT)
280 {
281 cam_present = 1;
282 }
283 }
284
285 // did we find something?
286 if (cam_present) {
268 printk(KERN_INFO "budget-av: cam inserted\n"); 287 printk(KERN_INFO "budget-av: cam inserted\n");
269 budget_av->slot_status = 1; 288 budget_av->slot_status = 1;
270 } 289 }
271 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
272 } else if (!open) { 290 } else if (!open) {
273 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); 291 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
274 if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT) 292 if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT)
@@ -484,6 +502,140 @@ static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe,
484 return 0; 502 return 0;
485} 503}
486 504
505#define MIN2(a,b) ((a) < (b) ? (a) : (b))
506#define MIN3(a,b,c) MIN2(MIN2(a,b),c)
507
508static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe,
509 struct i2c_adapter *i2c,
510 struct dvb_frontend_parameters *params)
511{
512 u8 reg0 [2] = { 0x00, 0x00 };
513 u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 };
514 u8 reg2 [3] = { 0x02, 0x00, 0x00 };
515 int _fband;
516 int first_ZF;
517 int R, A, N, P, M;
518 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = NULL,.len = 0 };
519 int freq = params->frequency;
520
521 first_ZF = (freq) / 1000;
522
523 if (abs(MIN2(abs(first_ZF-1190),abs(first_ZF-1790))) <
524 abs(MIN3(abs(first_ZF-1202),abs(first_ZF-1542),abs(first_ZF-1890))))
525 _fband = 2;
526 else
527 _fband = 3;
528
529 if (_fband == 2) {
530 if (((first_ZF >= 950) && (first_ZF < 1350)) ||
531 ((first_ZF >= 1430) && (first_ZF < 1950)))
532 reg0[1] = 0x07;
533 else if (((first_ZF >= 1350) && (first_ZF < 1430)) ||
534 ((first_ZF >= 1950) && (first_ZF < 2150)))
535 reg0[1] = 0x0B;
536 }
537
538 if(_fband == 3) {
539 if (((first_ZF >= 950) && (first_ZF < 1350)) ||
540 ((first_ZF >= 1455) && (first_ZF < 1950)))
541 reg0[1] = 0x07;
542 else if (((first_ZF >= 1350) && (first_ZF < 1420)) ||
543 ((first_ZF >= 1950) && (first_ZF < 2150)))
544 reg0[1] = 0x0B;
545 else if ((first_ZF >= 1420) && (first_ZF < 1455))
546 reg0[1] = 0x0F;
547 }
548
549 if (first_ZF > 1525)
550 reg1[1] |= 0x80;
551 else
552 reg1[1] &= 0x7F;
553
554 if (_fband == 2) {
555 if (first_ZF > 1430) { /* 1430MHZ */
556 reg1[1] &= 0xCF; /* N2 */
557 reg2[1] &= 0xCF; /* R2 */
558 reg2[1] |= 0x10;
559 } else {
560 reg1[1] &= 0xCF; /* N2 */
561 reg1[1] |= 0x20;
562 reg2[1] &= 0xCF; /* R2 */
563 reg2[1] |= 0x10;
564 }
565 }
566
567 if (_fband == 3) {
568 if ((first_ZF >= 1455) &&
569 (first_ZF < 1630)) {
570 reg1[1] &= 0xCF; /* N2 */
571 reg1[1] |= 0x20;
572 reg2[1] &= 0xCF; /* R2 */
573 } else {
574 if (first_ZF < 1455) {
575 reg1[1] &= 0xCF; /* N2 */
576 reg1[1] |= 0x20;
577 reg2[1] &= 0xCF; /* R2 */
578 reg2[1] |= 0x10;
579 } else {
580 if (first_ZF >= 1630) {
581 reg1[1] &= 0xCF; /* N2 */
582 reg2[1] &= 0xCF; /* R2 */
583 reg2[1] |= 0x10;
584 }
585 }
586 }
587 }
588
589 /* set ports, enable P0 for symbol rates > 4Ms/s */
590 if (params->u.qpsk.symbol_rate >= 4000000)
591 reg1[1] |= 0x0c;
592 else
593 reg1[1] |= 0x04;
594
595 reg2[1] |= 0x0c;
596
597 R = 64;
598 A = 64;
599 P = 64; //32
600
601 M = (freq * R) / 4; /* in Mhz */
602 N = (M - A * 1000) / (P * 1000);
603
604 reg1[1] |= (N >> 9) & 0x03;
605 reg1[2] = (N >> 1) & 0xff;
606 reg1[3] = (N << 7) & 0x80;
607
608 reg2[1] |= (R >> 8) & 0x03;
609 reg2[2] = R & 0xFF; /* R */
610
611 reg1[3] |= A & 0x7f; /* A */
612
613 if (P == 64)
614 reg1[1] |= 0x40; /* Prescaler 64/65 */
615
616 reg0[1] |= 0x03;
617
618 /* already enabled - do not reenable i2c repeater or TX fails */
619 msg.buf = reg0;
620 msg.len = sizeof(reg0);
621 if (i2c_transfer(i2c, &msg, 1) != 1)
622 return -EIO;
623
624 stv0299_enable_plli2c(fe);
625 msg.buf = reg1;
626 msg.len = sizeof(reg1);
627 if (i2c_transfer(i2c, &msg, 1) != 1)
628 return -EIO;
629
630 stv0299_enable_plli2c(fe);
631 msg.buf = reg2;
632 msg.len = sizeof(reg2);
633 if (i2c_transfer(i2c, &msg, 1) != 1)
634 return -EIO;
635
636 return 0;
637}
638
487static u8 typhoon_cinergy1200s_inittab[] = { 639static u8 typhoon_cinergy1200s_inittab[] = {
488 0x01, 0x15, 640 0x01, 0x15,
489 0x02, 0x30, 641 0x02, 0x30,
@@ -553,6 +705,18 @@ static struct stv0299_config cinergy_1200s_config = {
553 .pll_set = philips_su1278_ty_ci_pll_set, 705 .pll_set = philips_su1278_ty_ci_pll_set,
554}; 706};
555 707
708static struct stv0299_config cinergy_1200s_1894_0010_config = {
709 .demod_address = 0x68,
710 .inittab = typhoon_cinergy1200s_inittab,
711 .mclk = 88000000UL,
712 .invert = 1,
713 .skip_reinit = 0,
714 .lock_output = STV0229_LOCKOUTPUT_1,
715 .volt13_op0_op1 = STV0299_VOLT13_OP0,
716 .min_delay_ms = 100,
717 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
718 .pll_set = philips_su1278sh2_tua6100_pll_set,
719};
556 720
557static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 721static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
558{ 722{
@@ -749,6 +913,15 @@ static void frontend_init(struct budget_av *budget_av)
749 switch (saa->pci->subsystem_device) { 913 switch (saa->pci->subsystem_device) {
750 914
751 case SUBID_DVBS_KNC1: 915 case SUBID_DVBS_KNC1:
916 if (saa->pci->subsystem_vendor == 0x1894) {
917 fe = stv0299_attach(&cinergy_1200s_1894_0010_config,
918 &budget_av->budget.i2c_adap);
919 } else {
920 fe = stv0299_attach(&typhoon_config,
921 &budget_av->budget.i2c_adap);
922 }
923 break;
924
752 case SUBID_DVBS_KNC1_PLUS: 925 case SUBID_DVBS_KNC1_PLUS:
753 case SUBID_DVBS_TYPHOON: 926 case SUBID_DVBS_TYPHOON:
754 fe = stv0299_attach(&typhoon_config, 927 fe = stv0299_attach(&typhoon_config,
@@ -1003,6 +1176,7 @@ MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
1003static struct pci_device_id pci_tbl[] = { 1176static struct pci_device_id pci_tbl[] = {
1004 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56), 1177 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
1005 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010), 1178 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
1179 MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
1006 MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), 1180 MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
1007 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), 1181 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
1008 MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), 1182 MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
index 017fcbccb8cc..633e68c341c8 100644
--- a/drivers/media/dvb/ttpci/budget-core.c
+++ b/drivers/media/dvb/ttpci/budget-core.c
@@ -404,9 +404,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
404 tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget); 404 tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget);
405 405
406 /* frontend power on */ 406 /* frontend power on */
407 if (bi->type == BUDGET_FS_ACTIVY) 407 if (bi->type != BUDGET_FS_ACTIVY)
408 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI);
409 else
410 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); 408 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
411 409
412 if (budget_register(budget) == 0) { 410 if (budget_register(budget) == 0) {
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index fafe6407b3d0..238c77b52f89 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -112,6 +112,7 @@ static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long
112 * Routines for the Fujitsu Siemens Activy budget card 112 * Routines for the Fujitsu Siemens Activy budget card
113 * 22 kHz tone and DiSEqC are handled by the frontend. 113 * 22 kHz tone and DiSEqC are handled by the frontend.
114 * Voltage must be set here. 114 * Voltage must be set here.
115 * GPIO 1: LNBP EN, GPIO 2: LNBP VSEL
115 */ 116 */
116static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage) 117static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage)
117{ 118{
@@ -121,11 +122,16 @@ static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage)
121 122
122 switch (voltage) { 123 switch (voltage) {
123 case SEC_VOLTAGE_13: 124 case SEC_VOLTAGE_13:
125 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI);
124 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO); 126 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO);
125 break; 127 break;
126 case SEC_VOLTAGE_18: 128 case SEC_VOLTAGE_18:
129 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI);
127 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); 130 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
128 break; 131 break;
132 case SEC_VOLTAGE_OFF:
133 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO);
134 break;
129 default: 135 default:
130 return -EINVAL; 136 return -EINVAL;
131 } 137 }
@@ -206,7 +212,7 @@ static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
206 return 0; 212 return 0;
207} 213}
208 214
209static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg) 215static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, long arg)
210{ 216{
211 struct budget* budget = (struct budget*) fe->dvb->priv; 217 struct budget* budget = (struct budget*) fe->dvb->priv;
212 u8 buf; 218 u8 buf;
@@ -580,6 +586,7 @@ static void frontend_init(struct budget *budget)
580 if (budget->dvb_frontend) { 586 if (budget->dvb_frontend) {
581 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; 587 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
582 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; 588 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
589 budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
583 if (lnbp21_init(budget)) { 590 if (lnbp21_init(budget)) {
584 printk("%s: No LNBP21 found!\n", __FUNCTION__); 591 printk("%s: No LNBP21 found!\n", __FUNCTION__);
585 goto error_out; 592 goto error_out;
@@ -624,7 +631,7 @@ static void frontend_init(struct budget *budget)
624 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); 631 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
625 if (budget->dvb_frontend) { 632 if (budget->dvb_frontend) {
626 budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; 633 budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage;
627 break; 634 budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
628 } 635 }
629 break; 636 break;
630 637
@@ -632,7 +639,7 @@ static void frontend_init(struct budget *budget)
632 budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); 639 budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap);
633 if (budget->dvb_frontend) { 640 if (budget->dvb_frontend) {
634 budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; 641 budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage;
635 break; 642 budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
636 } 643 }
637 break; 644 break;
638 645
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.c b/drivers/media/dvb/ttpci/ttpci-eeprom.c
index 18aa22b5478d..1f31e91195b0 100644
--- a/drivers/media/dvb/ttpci/ttpci-eeprom.c
+++ b/drivers/media/dvb/ttpci/ttpci-eeprom.c
@@ -13,7 +13,7 @@
13 Holger Waechtler Convergence 13 Holger Waechtler Convergence
14 14
15 Copyright (C) 2002-2003 Ralph Metzler <rjkm@metzlerbros.de> 15 Copyright (C) 2002-2003 Ralph Metzler <rjkm@metzlerbros.de>
16 Metzler Brothers Systementwicklung GbR 16 Metzler Brothers Systementwicklung GbR
17 17
18 This program is free software; you can redistribute it and/or modify 18 This program is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published by 19 it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig
index c6c1d41a2efb..914587d52b57 100644
--- a/drivers/media/dvb/ttusb-budget/Kconfig
+++ b/drivers/media/dvb/ttusb-budget/Kconfig
@@ -10,7 +10,7 @@ config DVB_TTUSB_BUDGET
10 Support for external USB adapters designed by Technotrend and 10 Support for external USB adapters designed by Technotrend and
11 produced by Hauppauge, shipped under the brand name 'Nova-USB'. 11 produced by Hauppauge, shipped under the brand name 'Nova-USB'.
12 12
13 These devices don't have a MPEG decoder built in, so you need 13 These devices don't have a MPEG decoder built in, so you need
14 an external software decoder to watch TV. 14 an external software decoder to watch TV.
15 15
16 Say Y if you own such a device and want to use it. 16 Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig
index c334526af66f..83611012ef34 100644
--- a/drivers/media/dvb/ttusb-dec/Kconfig
+++ b/drivers/media/dvb/ttusb-dec/Kconfig
@@ -8,14 +8,15 @@ config DVB_TTUSB_DEC
8 produced by Hauppauge, shipped under the brand name 'DEC2000-t' 8 produced by Hauppauge, shipped under the brand name 'DEC2000-t'
9 and 'DEC3000-s'. 9 and 'DEC3000-s'.
10 10
11 Even if these devices have a MPEG decoder built in, they transmit 11 Even if these devices have a MPEG decoder built in, they transmit
12 only compressed MPEG data over the USB bus, so you need 12 only compressed MPEG data over the USB bus, so you need
13 an external software decoder to watch TV on your computer. 13 an external software decoder to watch TV on your computer.
14 14
15 This driver needs external firmware. Please use the commands 15 This driver needs external firmware. Please use the commands
16 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t", 16 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t",
17 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t", 17 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t",
18 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s", 18 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s",
19 download/extract them, and then copy them to /usr/lib/hotplug/firmware. 19 download/extract them, and then copy them to /usr/lib/hotplug/firmware
20 or /lib/firmware (depending on configuration of firmware hotplug).
20 21
21 Say Y if you own such a device and want to use it. 22 Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 8abc21890129..d8966d1d25ee 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -369,7 +369,7 @@ static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode,
369 369
370static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) 370static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
371{ 371{
372 struct ttusb_dec *dec = (struct ttusb_dec *)priv; 372 struct ttusb_dec *dec = priv;
373 373
374 dec->audio_filter->feed->cb.ts(data, 188, NULL, 0, 374 dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
375 &dec->audio_filter->feed->feed.ts, 375 &dec->audio_filter->feed->feed.ts,
@@ -380,7 +380,7 @@ static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
380 380
381static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data) 381static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
382{ 382{
383 struct ttusb_dec *dec = (struct ttusb_dec *)priv; 383 struct ttusb_dec *dec = priv;
384 384
385 dec->video_filter->feed->cb.ts(data, 188, NULL, 0, 385 dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
386 &dec->video_filter->feed->feed.ts, 386 &dec->video_filter->feed->feed.ts,
@@ -965,8 +965,8 @@ static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
965 965
966 case DMX_TS_PES_TELETEXT: 966 case DMX_TS_PES_TELETEXT:
967 dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid; 967 dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid;
968 dprintk(" pes_type: DMX_TS_PES_TELETEXT\n"); 968 dprintk(" pes_type: DMX_TS_PES_TELETEXT(not supported)\n");
969 break; 969 return -ENOSYS;
970 970
971 case DMX_TS_PES_PCR: 971 case DMX_TS_PES_PCR:
972 dprintk(" pes_type: DMX_TS_PES_PCR\n"); 972 dprintk(" pes_type: DMX_TS_PES_PCR\n");
@@ -975,8 +975,8 @@ static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
975 break; 975 break;
976 976
977 case DMX_TS_PES_OTHER: 977 case DMX_TS_PES_OTHER:
978 dprintk(" pes_type: DMX_TS_PES_OTHER\n"); 978 dprintk(" pes_type: DMX_TS_PES_OTHER(not supported)\n");
979 break; 979 return -ENOSYS;
980 980
981 default: 981 default:
982 dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type); 982 dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);
@@ -1182,7 +1182,7 @@ static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
1182 (unsigned long)dec); 1182 (unsigned long)dec);
1183} 1183}
1184 1184
1185static int ttusb_init_rc(struct ttusb_dec *dec) 1185static int ttusb_init_rc( struct ttusb_dec *dec)
1186{ 1186{
1187 struct input_dev *input_dev; 1187 struct input_dev *input_dev;
1188 u8 b[] = { 0x00, 0x01 }; 1188 u8 b[] = { 0x00, 0x01 };
@@ -1203,13 +1203,12 @@ static int ttusb_init_rc(struct ttusb_dec *dec)
1203 input_dev->keycode = rc_keys; 1203 input_dev->keycode = rc_keys;
1204 1204
1205 for (i = 0; i < ARRAY_SIZE(rc_keys); i++) 1205 for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
1206 set_bit(rc_keys[i], input_dev->keybit); 1206 set_bit(rc_keys[i], input_dev->keybit);
1207 1207
1208 input_register_device(input_dev); 1208 input_register_device(input_dev);
1209 1209
1210 if (usb_submit_urb(dec->irq_urb, GFP_KERNEL)) 1210 if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
1211 printk("%s: usb_submit_urb failed\n",__FUNCTION__); 1211 printk("%s: usb_submit_urb failed\n",__FUNCTION__);
1212
1213 /* enable irq pipe */ 1212 /* enable irq pipe */
1214 ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL); 1213 ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
1215 1214
@@ -1395,6 +1394,7 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec)
1395 /* We can't trust the USB IDs that some firmwares 1394 /* We can't trust the USB IDs that some firmwares
1396 give the box */ 1395 give the box */
1397 switch (model) { 1396 switch (model) {
1397 case 0x00070001:
1398 case 0x00070008: 1398 case 0x00070008:
1399 case 0x0007000c: 1399 case 0x0007000c:
1400 ttusb_dec_set_model(dec, TTUSB_DEC3000S); 1400 ttusb_dec_set_model(dec, TTUSB_DEC3000S);
@@ -1588,7 +1588,7 @@ static int fe_send_command(struct dvb_frontend* fe, const u8 command,
1588 int param_length, const u8 params[], 1588 int param_length, const u8 params[],
1589 int *result_length, u8 cmd_result[]) 1589 int *result_length, u8 cmd_result[])
1590{ 1590{
1591 struct ttusb_dec* dec = (struct ttusb_dec*) fe->dvb->priv; 1591 struct ttusb_dec* dec = fe->dvb->priv;
1592 return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result); 1592 return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result);
1593} 1593}
1594 1594
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
index 725af3af5b27..a5a46175fa09 100644
--- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
+++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
@@ -42,8 +42,39 @@ struct ttusbdecfe_state {
42 42
43static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status) 43static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status)
44{ 44{
45 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | 45 struct ttusbdecfe_state* state = fe->demodulator_priv;
46 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; 46 u8 b[] = { 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00 };
48 u8 result[4];
49 int len, ret;
50
51 *status=0;
52
53 ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result);
54 if(ret)
55 return ret;
56
57 if(len != 4) {
58 printk(KERN_ERR "%s: unexpected reply\n", __FUNCTION__);
59 return -EIO;
60 }
61
62 switch(result[3]) {
63 case 1: /* not tuned yet */
64 case 2: /* no signal/no lock*/
65 break;
66 case 3: /* signal found and locked*/
67 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
68 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
69 break;
70 case 4:
71 *status = FE_TIMEDOUT;
72 break;
73 default:
74 pr_info("%s: returned unknown value: %d\n",
75 __FUNCTION__, result[3]);
76 return -EIO;
77 }
47 78
48 return 0; 79 return 0;
49} 80}
@@ -64,6 +95,16 @@ static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_fron
64 return 0; 95 return 0;
65} 96}
66 97
98static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
99 struct dvb_frontend_tune_settings* fesettings)
100{
101 fesettings->min_delay_ms = 1500;
102 /* Drift compensation makes no sense for DVB-T */
103 fesettings->step_size = 0;
104 fesettings->max_drift = 0;
105 return 0;
106}
107
67static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) 108static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
68{ 109{
69 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; 110 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
@@ -212,6 +253,8 @@ static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
212 253
213 .set_frontend = ttusbdecfe_dvbt_set_frontend, 254 .set_frontend = ttusbdecfe_dvbt_set_frontend,
214 255
256 .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
257
215 .read_status = ttusbdecfe_read_status, 258 .read_status = ttusbdecfe_read_status,
216}; 259};
217 260
@@ -223,11 +266,11 @@ static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
223 .frequency_min = 950000, 266 .frequency_min = 950000,
224 .frequency_max = 2150000, 267 .frequency_max = 2150000,
225 .frequency_stepsize = 125, 268 .frequency_stepsize = 125,
269 .symbol_rate_min = 1000000, /* guessed */
270 .symbol_rate_max = 45000000, /* guessed */
226 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 271 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
227 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 272 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
228 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | 273 FE_CAN_QPSK
229 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
230 FE_CAN_HIERARCHY_AUTO,
231 }, 274 },
232 275
233 .release = ttusbdecfe_release, 276 .release = ttusbdecfe_release,
diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c
index c2ebe8754a95..dc292da2605f 100644
--- a/drivers/media/radio/miropcm20-radio.c
+++ b/drivers/media/radio/miropcm20-radio.c
@@ -220,6 +220,7 @@ static struct file_operations pcm20_fops = {
220 .open = video_exclusive_open, 220 .open = video_exclusive_open,
221 .release = video_exclusive_release, 221 .release = video_exclusive_release,
222 .ioctl = pcm20_ioctl, 222 .ioctl = pcm20_ioctl,
223 .compat_ioctl = v4l_compat_ioctl32,
223 .llseek = no_llseek, 224 .llseek = no_llseek,
224}; 225};
225 226
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 877c770558e9..914deab4e044 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -299,6 +299,7 @@ static struct file_operations rtrack_fops = {
299 .open = video_exclusive_open, 299 .open = video_exclusive_open,
300 .release = video_exclusive_release, 300 .release = video_exclusive_release,
301 .ioctl = rt_ioctl, 301 .ioctl = rt_ioctl,
302 .compat_ioctl = v4l_compat_ioctl32,
302 .llseek = no_llseek, 303 .llseek = no_llseek,
303}; 304};
304 305
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 5319a9c9a979..523be820f9c6 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -256,6 +256,7 @@ static struct file_operations aztech_fops = {
256 .open = video_exclusive_open, 256 .open = video_exclusive_open,
257 .release = video_exclusive_release, 257 .release = video_exclusive_release,
258 .ioctl = az_ioctl, 258 .ioctl = az_ioctl,
259 .compat_ioctl = v4l_compat_ioctl32,
259 .llseek = no_llseek, 260 .llseek = no_llseek,
260}; 261};
261 262
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 9b0406318f2d..f1b5ac81e9d2 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -490,6 +490,7 @@ static struct file_operations cadet_fops = {
490 .release = cadet_release, 490 .release = cadet_release,
491 .read = cadet_read, 491 .read = cadet_read,
492 .ioctl = cadet_ioctl, 492 .ioctl = cadet_ioctl,
493 .compat_ioctl = v4l_compat_ioctl32,
493 .llseek = no_llseek, 494 .llseek = no_llseek,
494}; 495};
495 496
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 630cc786d0a4..42c8fce04aa2 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -301,6 +301,7 @@ static struct file_operations gemtek_pci_fops = {
301 .open = video_exclusive_open, 301 .open = video_exclusive_open,
302 .release = video_exclusive_release, 302 .release = video_exclusive_release,
303 .ioctl = gemtek_pci_ioctl, 303 .ioctl = gemtek_pci_ioctl,
304 .compat_ioctl = v4l_compat_ioctl32,
304 .llseek = no_llseek, 305 .llseek = no_llseek,
305}; 306};
306 307
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 6418f03b9ce4..47173be97b9f 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -233,6 +233,7 @@ static struct file_operations gemtek_fops = {
233 .open = video_exclusive_open, 233 .open = video_exclusive_open,
234 .release = video_exclusive_release, 234 .release = video_exclusive_release,
235 .ioctl = gemtek_ioctl, 235 .ioctl = gemtek_ioctl,
236 .compat_ioctl = v4l_compat_ioctl32,
236 .llseek = no_llseek, 237 .llseek = no_llseek,
237}; 238};
238 239
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index e5e2021a7312..c30effdf711f 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -72,6 +72,7 @@ static struct file_operations maestro_fops = {
72 .open = video_exclusive_open, 72 .open = video_exclusive_open,
73 .release = video_exclusive_release, 73 .release = video_exclusive_release,
74 .ioctl = radio_ioctl, 74 .ioctl = radio_ioctl,
75 .compat_ioctl = v4l_compat_ioctl32,
75 .llseek = no_llseek, 76 .llseek = no_llseek,
76}; 77};
77 78
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 02d39a50d5ed..30869308332a 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -80,6 +80,7 @@ static struct file_operations maxiradio_fops = {
80 .open = video_exclusive_open, 80 .open = video_exclusive_open,
81 .release = video_exclusive_release, 81 .release = video_exclusive_release,
82 .ioctl = radio_ioctl, 82 .ioctl = radio_ioctl,
83 .compat_ioctl = v4l_compat_ioctl32,
83 .llseek = no_llseek, 84 .llseek = no_llseek,
84}; 85};
85static struct video_device maxiradio_radio = 86static struct video_device maxiradio_radio =
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index b2256d675b44..28a47c9e7a81 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -199,6 +199,7 @@ static struct file_operations rtrack2_fops = {
199 .open = video_exclusive_open, 199 .open = video_exclusive_open,
200 .release = video_exclusive_release, 200 .release = video_exclusive_release,
201 .ioctl = rt_ioctl, 201 .ioctl = rt_ioctl,
202 .compat_ioctl = v4l_compat_ioctl32,
202 .llseek = no_llseek, 203 .llseek = no_llseek,
203}; 204};
204 205
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 6f03ce4dd7b0..0229f792a059 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -225,6 +225,7 @@ static struct file_operations fmi_fops = {
225 .open = video_exclusive_open, 225 .open = video_exclusive_open,
226 .release = video_exclusive_release, 226 .release = video_exclusive_release,
227 .ioctl = fmi_ioctl, 227 .ioctl = fmi_ioctl,
228 .compat_ioctl = v4l_compat_ioctl32,
228 .llseek = no_llseek, 229 .llseek = no_llseek,
229}; 230};
230 231
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 71971e9bb342..26632cead09a 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -356,6 +356,7 @@ static struct file_operations fmr2_fops = {
356 .open = video_exclusive_open, 356 .open = video_exclusive_open,
357 .release = video_exclusive_release, 357 .release = video_exclusive_release,
358 .ioctl = fmr2_ioctl, 358 .ioctl = fmr2_ioctl,
359 .compat_ioctl = v4l_compat_ioctl32,
359 .llseek = no_llseek, 360 .llseek = no_llseek,
360}; 361};
361 362
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index b03573c6840e..fcfde2e4f195 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -276,6 +276,7 @@ static struct file_operations terratec_fops = {
276 .open = video_exclusive_open, 276 .open = video_exclusive_open,
277 .release = video_exclusive_release, 277 .release = video_exclusive_release,
278 .ioctl = tt_ioctl, 278 .ioctl = tt_ioctl,
279 .compat_ioctl = v4l_compat_ioctl32,
279 .llseek = no_llseek, 280 .llseek = no_llseek,
280}; 281};
281 282
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index b300bedf7c74..5a099a50d4d0 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -255,6 +255,7 @@ static struct file_operations trust_fops = {
255 .open = video_exclusive_open, 255 .open = video_exclusive_open,
256 .release = video_exclusive_release, 256 .release = video_exclusive_release,
257 .ioctl = tr_ioctl, 257 .ioctl = tr_ioctl,
258 .compat_ioctl = v4l_compat_ioctl32,
258 .llseek = no_llseek, 259 .llseek = no_llseek,
259}; 260};
260 261
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index f304f3c14763..8ac9a8ef9094 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -261,6 +261,7 @@ static struct file_operations typhoon_fops = {
261 .open = video_exclusive_open, 261 .open = video_exclusive_open,
262 .release = video_exclusive_release, 262 .release = video_exclusive_release,
263 .ioctl = typhoon_ioctl, 263 .ioctl = typhoon_ioctl,
264 .compat_ioctl = v4l_compat_ioctl32,
264 .llseek = no_llseek, 265 .llseek = no_llseek,
265}; 266};
266 267
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 4c6d6fb49034..d590e80c922e 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -313,6 +313,7 @@ static struct file_operations zoltrix_fops =
313 .open = video_exclusive_open, 313 .open = video_exclusive_open,
314 .release = video_exclusive_release, 314 .release = video_exclusive_release,
315 .ioctl = zol_ioctl, 315 .ioctl = zol_ioctl,
316 .compat_ioctl = v4l_compat_ioctl32,
316 .llseek = no_llseek, 317 .llseek = no_llseek,
317}; 318};
318 319
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index fc87efc5049c..2fe260fff85d 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -7,6 +7,15 @@ menu "Video For Linux"
7 7
8comment "Video Adapters" 8comment "Video Adapters"
9 9
10config VIDEO_ADV_DEBUG
11 bool "Enable advanced debug functionality"
12 depends on VIDEO_DEV
13 default n
14 ---help---
15 Say Y here to enable advanced debugging functionality on some
16 V4L devices.
17 In doubt, say N.
18
10config VIDEO_BT848 19config VIDEO_BT848
11 tristate "BT848 Video For Linux" 20 tristate "BT848 Video For Linux"
12 depends on VIDEO_DEV && PCI && I2C 21 depends on VIDEO_DEV && PCI && I2C
@@ -342,6 +351,6 @@ config VIDEO_DECODER
342 depends on VIDEO_DEV && I2C && EXPERIMENTAL 351 depends on VIDEO_DEV && I2C && EXPERIMENTAL
343 ---help--- 352 ---help---
344 Say Y here to compile drivers for SAA7115, SAA7127 and CX25840 353 Say Y here to compile drivers for SAA7115, SAA7127 and CX25840
345 video decoders. 354 video decoders.
346 355
347endmenu 356endmenu
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 82060f9909d8..dd24896906fe 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -3,15 +3,19 @@
3# 3#
4 4
5bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ 5bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
6 bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o 6 bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \
7 bttv-input.o
7zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o 8zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
8zr36067-objs := zoran_procfs.o zoran_device.o \ 9zr36067-objs := zoran_procfs.o zoran_device.o \
9 zoran_driver.o zoran_card.o 10 zoran_driver.o zoran_card.o
10tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o 11tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o
11obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o 12
13msp3400-objs := msp3400-driver.o msp3400-kthreads.o
14
15obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o
12 16
13obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ 17obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
14 tda7432.o tda9875.o ir-kbd-i2c.o ir-kbd-gpio.o 18 tda7432.o tda9875.o ir-kbd-i2c.o
15obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o 19obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
16 20
17obj-$(CONFIG_VIDEO_ZR36120) += zoran.o 21obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 881cdcb1875d..7d5a068353f2 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -749,6 +749,7 @@ static struct file_operations ar_fops = {
749 .release = video_exclusive_release, 749 .release = video_exclusive_release,
750 .read = ar_read, 750 .read = ar_read,
751 .ioctl = ar_ioctl, 751 .ioctl = ar_ioctl,
752 .compat_ioctl = v4l_compat_ioctl32,
752 .llseek = no_llseek, 753 .llseek = no_llseek,
753}; 754};
754 755
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
index 1c3ff5f38a6d..dda4aa6bef27 100644
--- a/drivers/media/video/bt832.c
+++ b/drivers/media/video/bt832.c
@@ -30,8 +30,9 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/errno.h> 31#include <linux/errno.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33
34#include <media/audiochip.h> 33#include <media/audiochip.h>
34#include <media/v4l2-common.h>
35
35#include "bttv.h" 36#include "bttv.h"
36#include "bt832.h" 37#include "bt832.h"
37 38
@@ -42,9 +43,10 @@ static unsigned short normal_i2c[] = { I2C_BT832_ALT1>>1, I2C_BT832_ALT2>>1,
42 I2C_CLIENT_END }; 43 I2C_CLIENT_END };
43I2C_CLIENT_INSMOD; 44I2C_CLIENT_INSMOD;
44 45
45/* ---------------------------------------------------------------------- */ 46int debug = 0; /* debug output */
47module_param(debug, int, 0644);
46 48
47#define dprintk if (debug) printk 49/* ---------------------------------------------------------------------- */
48 50
49static int bt832_detach(struct i2c_client *client); 51static int bt832_detach(struct i2c_client *client);
50 52
@@ -61,23 +63,26 @@ int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf)
61 int i,rc; 63 int i,rc;
62 buf[0]=0x80; // start at register 0 with auto-increment 64 buf[0]=0x80; // start at register 0 with auto-increment
63 if (1 != (rc = i2c_master_send(i2c_client_s,buf,1))) 65 if (1 != (rc = i2c_master_send(i2c_client_s,buf,1)))
64 printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc); 66 v4l_err(i2c_client_s,"i2c i/o error: rc == %d (should be 1)\n",rc);
65 67
66 for(i=0;i<65;i++) 68 for(i=0;i<65;i++)
67 buf[i]=0; 69 buf[i]=0;
68 if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65))) 70 if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65)))
69 printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc); 71 v4l_err(i2c_client_s,"i2c i/o error: rc == %d (should be 65)\n",rc);
70 72
71 // Note: On READ the first byte is the current index 73 // Note: On READ the first byte is the current index
72 // (e.g. 0x80, what we just wrote) 74 // (e.g. 0x80, what we just wrote)
73 75
74 if(1) { 76 if(debug>1) {
75 int i; 77 int i;
76 printk("BT832 hexdump:\n"); 78 v4l_dbg(2,i2c_client_s,"hexdump:");
77 for(i=1;i<65;i++) { 79 for(i=1;i<65;i++) {
78 if(i!=1) { 80 if(i!=1) {
79 if(((i-1)%8)==0) printk(" "); 81 if(((i-1)%8)==0) printk(" ");
80 if(((i-1)%16)==0) printk("\n"); 82 if(((i-1)%16)==0) {
83 printk("\n");
84 v4l_dbg(2,i2c_client_s,"hexdump:");
85 }
81 } 86 }
82 printk(" %02x",buf[i]); 87 printk(" %02x",buf[i]);
83 } 88 }
@@ -96,56 +101,56 @@ int bt832_init(struct i2c_client *i2c_client_s)
96 bt832_hexdump(i2c_client_s,buf); 101 bt832_hexdump(i2c_client_s,buf);
97 102
98 if(buf[0x40] != 0x31) { 103 if(buf[0x40] != 0x31) {
99 printk("bt832: this i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]); 104 v4l_err(i2c_client_s,"This i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]);
100 kfree(buf); 105 kfree(buf);
101 return 0; 106 return 0;
102 } 107 }
103 108
104 printk("Write 0 tp VPSTATUS\n"); 109 v4l_err(i2c_client_s,"Write 0 tp VPSTATUS\n");
105 buf[0]=BT832_VP_STATUS; // Reg.52 110 buf[0]=BT832_VP_STATUS; // Reg.52
106 buf[1]= 0x00; 111 buf[1]= 0x00;
107 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 112 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
108 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); 113 v4l_err(i2c_client_s,"i2c i/o error VPS: rc == %d (should be 2)\n",rc);
109 114
110 bt832_hexdump(i2c_client_s,buf); 115 bt832_hexdump(i2c_client_s,buf);
111 116
112 117
113 // Leave low power mode: 118 // Leave low power mode:
114 printk("Bt832: leave low power mode.\n"); 119 v4l_err(i2c_client_s,"leave low power mode.\n");
115 buf[0]=BT832_CAM_SETUP0; //0x39 57 120 buf[0]=BT832_CAM_SETUP0; //0x39 57
116 buf[1]=0x08; 121 buf[1]=0x08;
117 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 122 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
118 printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc); 123 v4l_err(i2c_client_s,"i2c i/o error LLPM: rc == %d (should be 2)\n",rc);
119 124
120 bt832_hexdump(i2c_client_s,buf); 125 bt832_hexdump(i2c_client_s,buf);
121 126
122 printk("Write 0 tp VPSTATUS\n"); 127 v4l_info(i2c_client_s,"Write 0 tp VPSTATUS\n");
123 buf[0]=BT832_VP_STATUS; // Reg.52 128 buf[0]=BT832_VP_STATUS; // Reg.52
124 buf[1]= 0x00; 129 buf[1]= 0x00;
125 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 130 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
126 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); 131 v4l_err(i2c_client_s,"i2c i/o error VPS: rc == %d (should be 2)\n",rc);
127 132
128 bt832_hexdump(i2c_client_s,buf); 133 bt832_hexdump(i2c_client_s,buf);
129 134
130 135
131 // Enable Output 136 // Enable Output
132 printk("Enable Output\n"); 137 v4l_info(i2c_client_s,"Enable Output\n");
133 buf[0]=BT832_VP_CONTROL1; // Reg.40 138 buf[0]=BT832_VP_CONTROL1; // Reg.40
134 buf[1]= 0x27 & (~0x01); // Default | !skip 139 buf[1]= 0x27 & (~0x01); // Default | !skip
135 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 140 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
136 printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc); 141 v4l_err(i2c_client_s,"i2c i/o error EO: rc == %d (should be 2)\n",rc);
137 142
138 bt832_hexdump(i2c_client_s,buf); 143 bt832_hexdump(i2c_client_s,buf);
139 144
140 145
141 // for testing (even works when no camera attached) 146 // for testing (even works when no camera attached)
142 printk("bt832: *** Generate NTSC M Bars *****\n"); 147 v4l_info(i2c_client_s,"*** Generate NTSC M Bars *****\n");
143 buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42 148 buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42
144 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally 149 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally
145 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 150 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
146 printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc); 151 v4l_info(i2c_client_s,"i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
147 152
148 printk("Bt832: Camera Present: %s\n", 153 v4l_info(i2c_client_s,"Camera Present: %s\n",
149 (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no"); 154 (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no");
150 155
151 bt832_hexdump(i2c_client_s,buf); 156 bt832_hexdump(i2c_client_s,buf);
@@ -159,13 +164,9 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
159{ 164{
160 struct bt832 *t; 165 struct bt832 *t;
161 166
162 printk("bt832_attach\n");
163
164 client_template.adapter = adap; 167 client_template.adapter = adap;
165 client_template.addr = addr; 168 client_template.addr = addr;
166 169
167 printk("bt832: chip found @ 0x%x\n", addr<<1);
168
169 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) 170 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
170 return -ENOMEM; 171 return -ENOMEM;
171 memset(t,0,sizeof(*t)); 172 memset(t,0,sizeof(*t));
@@ -173,6 +174,9 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
173 i2c_set_clientdata(&t->client, t); 174 i2c_set_clientdata(&t->client, t);
174 i2c_attach_client(&t->client); 175 i2c_attach_client(&t->client);
175 176
177 v4l_info(&t->client,"chip found @ 0x%x\n", addr<<1);
178
179
176 if(! bt832_init(&t->client)) { 180 if(! bt832_init(&t->client)) {
177 bt832_detach(&t->client); 181 bt832_detach(&t->client);
178 return -1; 182 return -1;
@@ -183,13 +187,8 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
183 187
184static int bt832_probe(struct i2c_adapter *adap) 188static int bt832_probe(struct i2c_adapter *adap)
185{ 189{
186#ifdef I2C_CLASS_TV_ANALOG
187 if (adap->class & I2C_CLASS_TV_ANALOG) 190 if (adap->class & I2C_CLASS_TV_ANALOG)
188 return i2c_probe(adap, &addr_data, bt832_attach); 191 return i2c_probe(adap, &addr_data, bt832_attach);
189#else
190 if (adap->id == I2C_HW_B_BT848)
191 return i2c_probe(adap, &addr_data, bt832_attach);
192#endif
193 return 0; 192 return 0;
194} 193}
195 194
@@ -197,7 +196,7 @@ static int bt832_detach(struct i2c_client *client)
197{ 196{
198 struct bt832 *t = i2c_get_clientdata(client); 197 struct bt832 *t = i2c_get_clientdata(client);
199 198
200 printk("bt832: detach.\n"); 199 v4l_info(&t->client,"dettach\n");
201 i2c_detach_client(client); 200 i2c_detach_client(client);
202 kfree(t); 201 kfree(t);
203 return 0; 202 return 0;
@@ -208,7 +207,8 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
208{ 207{
209 struct bt832 *t = i2c_get_clientdata(client); 208 struct bt832 *t = i2c_get_clientdata(client);
210 209
211 printk("bt832: command %x\n",cmd); 210 if (debug>1)
211 v4l_i2c_print_ioctl(&t->client,cmd);
212 212
213 switch (cmd) { 213 switch (cmd) {
214 case BT832_HEXDUMP: { 214 case BT832_HEXDUMP: {
@@ -219,7 +219,7 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
219 } 219 }
220 break; 220 break;
221 case BT832_REATTACH: 221 case BT832_REATTACH:
222 printk("bt832: re-attach\n"); 222 v4l_info(&t->client,"re-attach\n");
223 i2c_del_driver(&driver); 223 i2c_del_driver(&driver);
224 i2c_add_driver(&driver); 224 i2c_add_driver(&driver);
225 break; 225 break;
@@ -231,9 +231,9 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
231 231
232static struct i2c_driver driver = { 232static struct i2c_driver driver = {
233 .driver = { 233 .driver = {
234 .name = "i2c bt832 driver", 234 .name = "bt832",
235 }, 235 },
236 .id = -1, /* FIXME */ 236 .id = 0, /* FIXME */
237 .attach_adapter = bt832_probe, 237 .attach_adapter = bt832_probe,
238 .detach_client = bt832_detach, 238 .detach_client = bt832_detach,
239 .command = bt832_command, 239 .command = bt832_command,
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 012be639aa18..1621ab133d23 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -38,6 +38,7 @@
38#include <asm/io.h> 38#include <asm/io.h>
39 39
40#include "bttvp.h" 40#include "bttvp.h"
41#include <media/v4l2-common.h>
41 42
42/* fwd decl */ 43/* fwd decl */
43static void boot_msp34xx(struct bttv *btv, int pin); 44static void boot_msp34xx(struct bttv *btv, int pin);
@@ -292,6 +293,9 @@ static struct CARD {
292 /* likely broken, vendor id doesn't match the other magic views ... 293 /* likely broken, vendor id doesn't match the other magic views ...
293 * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */ 294 * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
294 295
296 /* Duplicate PCI ID, reconfigure for this board during the eeprom read.
297 * { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB, "Hauppauge ImpactVCB" }, */
298
295 /* DVB cards (using pci function .1 for mpeg data xfer) */ 299 /* DVB cards (using pci function .1 for mpeg data xfer) */
296 { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, 300 { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
297 { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, 301 { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
@@ -2136,7 +2140,6 @@ struct tvcard bttv_tvcards[] = {
2136 .has_remote = 1, 2140 .has_remote = 1,
2137 .gpiomask = 0x1b, 2141 .gpiomask = 0x1b,
2138 .no_gpioirq = 1, 2142 .no_gpioirq = 1,
2139 .any_irq = 1,
2140 }, 2143 },
2141 [BTTV_BOARD_PV143] = { 2144 [BTTV_BOARD_PV143] = {
2142 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */ 2145 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */
@@ -2817,6 +2820,22 @@ struct tvcard bttv_tvcards[] = {
2817 .tuner_addr = ADDR_UNSET, 2820 .tuner_addr = ADDR_UNSET,
2818 .has_radio = 1, 2821 .has_radio = 1,
2819 }, 2822 },
2823 /* ---- card 0x8f ---------------------------------- */
2824 [BTTV_BOARD_HAUPPAUGE_IMPACTVCB] = {
2825 .name = "Hauppauge ImpactVCB (bt878)",
2826 .video_inputs = 4,
2827 .audio_inputs = 0,
2828 .tuner = -1,
2829 .svhs = -1,
2830 .gpiomask = 0x0f, /* old: 7 */
2831 .muxsel = { 0, 1, 3, 2}, /* Composite 0-3 */
2832 .no_msp34xx = 1,
2833 .no_tda9875 = 1,
2834 .no_tda7432 = 1,
2835 .tuner_type = -1,
2836 .tuner_addr = ADDR_UNSET,
2837 .radio_addr = ADDR_UNSET,
2838 },
2820}; 2839};
2821 2840
2822static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); 2841static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -3037,26 +3056,33 @@ static void miro_pinnacle_gpio(struct bttv *btv)
3037 switch (id) { 3056 switch (id) {
3038 case 1: 3057 case 1:
3039 info = "PAL / mono"; 3058 info = "PAL / mono";
3059 btv->tda9887_conf = TDA9887_INTERCARRIER;
3040 break; 3060 break;
3041 case 2: 3061 case 2:
3042 info = "PAL+SECAM / stereo"; 3062 info = "PAL+SECAM / stereo";
3043 btv->has_radio = 1; 3063 btv->has_radio = 1;
3064 btv->tda9887_conf = TDA9887_QSS;
3044 break; 3065 break;
3045 case 3: 3066 case 3:
3046 info = "NTSC / stereo"; 3067 info = "NTSC / stereo";
3047 btv->has_radio = 1; 3068 btv->has_radio = 1;
3069 btv->tda9887_conf = TDA9887_QSS;
3048 break; 3070 break;
3049 case 4: 3071 case 4:
3050 info = "PAL+SECAM / mono"; 3072 info = "PAL+SECAM / mono";
3073 btv->tda9887_conf = TDA9887_QSS;
3051 break; 3074 break;
3052 case 5: 3075 case 5:
3053 info = "NTSC / mono"; 3076 info = "NTSC / mono";
3077 btv->tda9887_conf = TDA9887_INTERCARRIER;
3054 break; 3078 break;
3055 case 6: 3079 case 6:
3056 info = "NTSC / stereo"; 3080 info = "NTSC / stereo";
3081 btv->tda9887_conf = TDA9887_INTERCARRIER;
3057 break; 3082 break;
3058 case 7: 3083 case 7:
3059 info = "PAL / stereo"; 3084 info = "PAL / stereo";
3085 btv->tda9887_conf = TDA9887_INTERCARRIER;
3060 break; 3086 break;
3061 default: 3087 default:
3062 info = "oops: unknown card"; 3088 info = "oops: unknown card";
@@ -3067,8 +3093,7 @@ static void miro_pinnacle_gpio(struct bttv *btv)
3067 printk(KERN_INFO 3093 printk(KERN_INFO
3068 "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n", 3094 "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n",
3069 btv->c.nr, id, info, btv->has_radio ? "yes" : "no"); 3095 btv->c.nr, id, info, btv->has_radio ? "yes" : "no");
3070 btv->tuner_type = 33; 3096 btv->tuner_type = TUNER_MT2032;
3071 btv->pinnacle_id = id;
3072 } 3097 }
3073} 3098}
3074 3099
@@ -3370,9 +3395,9 @@ void __devinit bttv_init_card2(struct bttv *btv)
3370 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); 3395 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
3371 } 3396 }
3372 3397
3373 if (btv->pinnacle_id != UNSET) { 3398 if (btv->tda9887_conf) {
3374 bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE, 3399 bttv_call_i2c_clients(btv, TDA9887_SET_CONFIG,
3375 &btv->pinnacle_id); 3400 &btv->tda9887_conf);
3376 } 3401 }
3377 3402
3378 btv->svhs = bttv_tvcards[btv->c.type].svhs; 3403 btv->svhs = bttv_tvcards[btv->c.type].svhs;
@@ -3387,8 +3412,6 @@ void __devinit bttv_init_card2(struct bttv *btv)
3387 btv->has_remote=1; 3412 btv->has_remote=1;
3388 if (!bttv_tvcards[btv->c.type].no_gpioirq) 3413 if (!bttv_tvcards[btv->c.type].no_gpioirq)
3389 btv->gpioirq=1; 3414 btv->gpioirq=1;
3390 if (bttv_tvcards[btv->c.type].any_irq)
3391 btv->any_irq = 1;
3392 if (bttv_tvcards[btv->c.type].audio_hook) 3415 if (bttv_tvcards[btv->c.type].audio_hook)
3393 btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook; 3416 btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook;
3394 3417
@@ -3424,7 +3447,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
3424 3447
3425 /* tuner modules */ 3448 /* tuner modules */
3426 tda9887 = 0; 3449 tda9887 = 0;
3427 if (btv->pinnacle_id != UNSET) 3450 if (btv->tda9887_conf)
3428 tda9887 = 1; 3451 tda9887 = 1;
3429 if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb && 3452 if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb &&
3430 bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0) 3453 bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0)
@@ -3471,6 +3494,21 @@ static void __devinit hauppauge_eeprom(struct bttv *btv)
3471 tveeprom_hauppauge_analog(&btv->i2c_client, &tv, eeprom_data); 3494 tveeprom_hauppauge_analog(&btv->i2c_client, &tv, eeprom_data);
3472 btv->tuner_type = tv.tuner_type; 3495 btv->tuner_type = tv.tuner_type;
3473 btv->has_radio = tv.has_radio; 3496 btv->has_radio = tv.has_radio;
3497
3498 printk("bttv%d: Hauppauge eeprom indicates model#%d\n",
3499 btv->c.nr, tv.model);
3500
3501 /*
3502 * Some of the 878 boards have duplicate PCI IDs. Switch the board
3503 * type based on model #.
3504 */
3505 if(tv.model == 64900) {
3506 printk("bttv%d: Switching board type from %s to %s\n",
3507 btv->c.nr,
3508 bttv_tvcards[btv->c.type].name,
3509 bttv_tvcards[BTTV_BOARD_HAUPPAUGE_IMPACTVCB].name);
3510 btv->c.type = BTTV_BOARD_HAUPPAUGE_IMPACTVCB;
3511 }
3474} 3512}
3475 3513
3476static int terratec_active_radio_upgrade(struct bttv *btv) 3514static int terratec_active_radio_upgrade(struct bttv *btv)
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 1ddf9ba613ef..0e6970346788 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -34,13 +34,14 @@
34#include <linux/sched.h> 34#include <linux/sched.h>
35#include <linux/interrupt.h> 35#include <linux/interrupt.h>
36#include <linux/kdev_t.h> 36#include <linux/kdev_t.h>
37#include "bttvp.h"
38#include <media/v4l2-common.h>
39
37#include <linux/dma-mapping.h> 40#include <linux/dma-mapping.h>
38 41
39#include <asm/io.h> 42#include <asm/io.h>
40#include <asm/byteorder.h> 43#include <asm/byteorder.h>
41 44
42#include "bttvp.h"
43
44#include "rds.h" 45#include "rds.h"
45 46
46 47
@@ -210,6 +211,9 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
210 .vdelay = 0x20, 211 .vdelay = 0x20,
211 .vbipack = 255, 212 .vbipack = 255,
212 .sram = 0, 213 .sram = 0,
214 /* ITU-R frame line number of the first VBI line
215 we can capture, of the first and second field. */
216 .vbistart = { 7,320 },
213 },{ 217 },{
214 .v4l2_id = V4L2_STD_NTSC_M, 218 .v4l2_id = V4L2_STD_NTSC_M,
215 .name = "NTSC", 219 .name = "NTSC",
@@ -226,6 +230,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
226 .vdelay = 0x1a, 230 .vdelay = 0x1a,
227 .vbipack = 144, 231 .vbipack = 144,
228 .sram = 1, 232 .sram = 1,
233 .vbistart = { 10, 273 },
229 },{ 234 },{
230 .v4l2_id = V4L2_STD_SECAM, 235 .v4l2_id = V4L2_STD_SECAM,
231 .name = "SECAM", 236 .name = "SECAM",
@@ -242,6 +247,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
242 .vdelay = 0x20, 247 .vdelay = 0x20,
243 .vbipack = 255, 248 .vbipack = 255,
244 .sram = 0, /* like PAL, correct? */ 249 .sram = 0, /* like PAL, correct? */
250 .vbistart = { 7, 320 },
245 },{ 251 },{
246 .v4l2_id = V4L2_STD_PAL_Nc, 252 .v4l2_id = V4L2_STD_PAL_Nc,
247 .name = "PAL-Nc", 253 .name = "PAL-Nc",
@@ -258,6 +264,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
258 .vdelay = 0x1a, 264 .vdelay = 0x1a,
259 .vbipack = 144, 265 .vbipack = 144,
260 .sram = -1, 266 .sram = -1,
267 .vbistart = { 7, 320 },
261 },{ 268 },{
262 .v4l2_id = V4L2_STD_PAL_M, 269 .v4l2_id = V4L2_STD_PAL_M,
263 .name = "PAL-M", 270 .name = "PAL-M",
@@ -274,6 +281,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
274 .vdelay = 0x1a, 281 .vdelay = 0x1a,
275 .vbipack = 144, 282 .vbipack = 144,
276 .sram = -1, 283 .sram = -1,
284 .vbistart = { 10, 273 },
277 },{ 285 },{
278 .v4l2_id = V4L2_STD_PAL_N, 286 .v4l2_id = V4L2_STD_PAL_N,
279 .name = "PAL-N", 287 .name = "PAL-N",
@@ -290,6 +298,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
290 .vdelay = 0x20, 298 .vdelay = 0x20,
291 .vbipack = 144, 299 .vbipack = 144,
292 .sram = -1, 300 .sram = -1,
301 .vbistart = { 7, 320},
293 },{ 302 },{
294 .v4l2_id = V4L2_STD_NTSC_M_JP, 303 .v4l2_id = V4L2_STD_NTSC_M_JP,
295 .name = "NTSC-JP", 304 .name = "NTSC-JP",
@@ -306,6 +315,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
306 .vdelay = 0x16, 315 .vdelay = 0x16,
307 .vbipack = 144, 316 .vbipack = 144,
308 .sram = -1, 317 .sram = -1,
318 .vbistart = {10, 273},
309 },{ 319 },{
310 /* that one hopefully works with the strange timing 320 /* that one hopefully works with the strange timing
311 * which video recorders produce when playing a NTSC 321 * which video recorders produce when playing a NTSC
@@ -326,6 +336,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
326 .vbipack = 255, 336 .vbipack = 255,
327 .vtotal = 524, 337 .vtotal = 524,
328 .sram = -1, 338 .sram = -1,
339 .vbistart = { 10, 273 },
329 } 340 }
330}; 341};
331static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms); 342static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms);
@@ -1510,14 +1521,6 @@ static struct videobuf_queue_ops bttv_video_qops = {
1510 .buf_release = buffer_release, 1521 .buf_release = buffer_release,
1511}; 1522};
1512 1523
1513static const char *v4l1_ioctls[] = {
1514 "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
1515 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
1516 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
1517 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
1518 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
1519#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
1520
1521static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) 1524static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1522{ 1525{
1523 switch (cmd) { 1526 switch (cmd) {
@@ -2206,22 +2209,9 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2206 unsigned long flags; 2209 unsigned long flags;
2207 int retval = 0; 2210 int retval = 0;
2208 2211
2209 if (bttv_debug > 1) { 2212 if (bttv_debug > 1)
2210 switch (_IOC_TYPE(cmd)) { 2213 v4l_print_ioctl(btv->c.name, cmd);
2211 case 'v': 2214
2212 printk("bttv%d: ioctl 0x%x (v4l1, VIDIOC%s)\n",
2213 btv->c.nr, cmd, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
2214 v4l1_ioctls[_IOC_NR(cmd)] : "???");
2215 break;
2216 case 'V':
2217 printk("bttv%d: ioctl 0x%x (v4l2, %s)\n",
2218 btv->c.nr, cmd, v4l2_ioctl_names[_IOC_NR(cmd)]);
2219 break;
2220 default:
2221 printk("bttv%d: ioctl 0x%x (???)\n",
2222 btv->c.nr, cmd);
2223 }
2224 }
2225 if (btv->errors) 2215 if (btv->errors)
2226 bttv_reinit_bt848(btv); 2216 bttv_reinit_bt848(btv);
2227 2217
@@ -2570,10 +2560,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2570 fmt->count[0] = fmt2.fmt.vbi.count[0]; 2560 fmt->count[0] = fmt2.fmt.vbi.count[0];
2571 fmt->start[1] = fmt2.fmt.vbi.start[1]; 2561 fmt->start[1] = fmt2.fmt.vbi.start[1];
2572 fmt->count[1] = fmt2.fmt.vbi.count[1]; 2562 fmt->count[1] = fmt2.fmt.vbi.count[1];
2573 if (fmt2.fmt.vbi.flags & VBI_UNSYNC) 2563 if (fmt2.fmt.vbi.flags & V4L2_VBI_UNSYNC)
2574 fmt->flags |= V4L2_VBI_UNSYNC; 2564 fmt->flags |= VBI_UNSYNC;
2575 if (fmt2.fmt.vbi.flags & VBI_INTERLACED) 2565 if (fmt2.fmt.vbi.flags & V4L2_VBI_INTERLACED)
2576 fmt->flags |= V4L2_VBI_INTERLACED; 2566 fmt->flags |= VBI_INTERLACED;
2577 return 0; 2567 return 0;
2578 } 2568 }
2579 case VIDIOCSVBIFMT: 2569 case VIDIOCSVBIFMT:
@@ -3120,6 +3110,7 @@ static struct file_operations bttv_fops =
3120 .open = bttv_open, 3110 .open = bttv_open,
3121 .release = bttv_release, 3111 .release = bttv_release,
3122 .ioctl = bttv_ioctl, 3112 .ioctl = bttv_ioctl,
3113 .compat_ioctl = v4l_compat_ioctl32,
3123 .llseek = no_llseek, 3114 .llseek = no_llseek,
3124 .read = bttv_read, 3115 .read = bttv_read,
3125 .mmap = bttv_mmap, 3116 .mmap = bttv_mmap,
@@ -3229,6 +3220,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
3229 case VIDIOCSFREQ: 3220 case VIDIOCSFREQ:
3230 case VIDIOCGAUDIO: 3221 case VIDIOCGAUDIO:
3231 case VIDIOCSAUDIO: 3222 case VIDIOCSAUDIO:
3223 case VIDIOC_LOG_STATUS:
3232 return bttv_common_ioctls(btv,cmd,arg); 3224 return bttv_common_ioctls(btv,cmd,arg);
3233 3225
3234 default: 3226 default:
@@ -3701,8 +3693,8 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3701 3693
3702 btv=(struct bttv *)dev_id; 3694 btv=(struct bttv *)dev_id;
3703 3695
3704 if (btv->any_irq) 3696 if (btv->custom_irq)
3705 handled = bttv_any_irq(&btv->c); 3697 handled = btv->custom_irq(btv);
3706 3698
3707 count=0; 3699 count=0;
3708 while (1) { 3700 while (1) {
@@ -3738,9 +3730,9 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3738 if (astat&BT848_INT_VSYNC) 3730 if (astat&BT848_INT_VSYNC)
3739 btv->field_count++; 3731 btv->field_count++;
3740 3732
3741 if (astat & BT848_INT_GPINT) { 3733 if ((astat & BT848_INT_GPINT) && btv->remote) {
3742 wake_up(&btv->gpioq); 3734 wake_up(&btv->gpioq);
3743 bttv_gpio_irq(&btv->c); 3735 bttv_input_irq(btv);
3744 } 3736 }
3745 3737
3746 if (astat & BT848_INT_I2CDONE) { 3738 if (astat & BT848_INT_I2CDONE) {
@@ -3946,7 +3938,6 @@ static int __devinit bttv_probe(struct pci_dev *dev,
3946 3938
3947 btv->i2c_rc = -1; 3939 btv->i2c_rc = -1;
3948 btv->tuner_type = UNSET; 3940 btv->tuner_type = UNSET;
3949 btv->pinnacle_id = UNSET;
3950 btv->new_input = UNSET; 3941 btv->new_input = UNSET;
3951 btv->has_radio=radio[btv->c.nr]; 3942 btv->has_radio=radio[btv->c.nr];
3952 3943
@@ -4065,11 +4056,11 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4065 } 4056 }
4066 4057
4067 /* add subdevices */ 4058 /* add subdevices */
4068 if (btv->has_remote)
4069 bttv_sub_add_device(&btv->c, "remote");
4070 if (bttv_tvcards[btv->c.type].has_dvb) 4059 if (bttv_tvcards[btv->c.type].has_dvb)
4071 bttv_sub_add_device(&btv->c, "dvb"); 4060 bttv_sub_add_device(&btv->c, "dvb");
4072 4061
4062 bttv_input_init(btv);
4063
4073 /* everything is fine */ 4064 /* everything is fine */
4074 bttv_num++; 4065 bttv_num++;
4075 return 0; 4066 return 0;
@@ -4104,6 +4095,7 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
4104 /* tell gpio modules we are leaving ... */ 4095 /* tell gpio modules we are leaving ... */
4105 btv->shutdown=1; 4096 btv->shutdown=1;
4106 wake_up(&btv->gpioq); 4097 wake_up(&btv->gpioq);
4098 bttv_input_fini(btv);
4107 bttv_sub_del_devices(&btv->c); 4099 bttv_sub_del_devices(&btv->c);
4108 4100
4109 /* unregister i2c_bus + input */ 4101 /* unregister i2c_bus + input */
@@ -4253,7 +4245,7 @@ static int bttv_init_module(void)
4253 bttv_check_chipset(); 4245 bttv_check_chipset();
4254 4246
4255 bus_register(&bttv_sub_bus_type); 4247 bus_register(&bttv_sub_bus_type);
4256 return pci_module_init(&bttv_pci_driver); 4248 return pci_register_driver(&bttv_pci_driver);
4257} 4249}
4258 4250
4259static void bttv_cleanup_module(void) 4251static void bttv_cleanup_module(void)
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c
index 616a5b7e510c..575ce8b8e714 100644
--- a/drivers/media/video/bttv-gpio.c
+++ b/drivers/media/video/bttv-gpio.c
@@ -113,24 +113,6 @@ void bttv_gpio_irq(struct bttv_core *core)
113 } 113 }
114} 114}
115 115
116int bttv_any_irq(struct bttv_core *core)
117{
118 struct bttv_sub_driver *drv;
119 struct bttv_sub_device *dev;
120 struct list_head *item;
121 int handled = 0;
122
123 list_for_each(item,&core->subs) {
124 dev = list_entry(item,struct bttv_sub_device,list);
125 drv = to_bttv_sub_drv(dev->dev.driver);
126 if (drv && drv->any_irq) {
127 if (drv->any_irq(dev))
128 handled = 1;
129 }
130 }
131 return handled;
132}
133
134/* ----------------------------------------------------------------------- */ 116/* ----------------------------------------------------------------------- */
135/* external: sub-driver register/unregister */ 117/* external: sub-driver register/unregister */
136 118
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index d6418c023d39..748d630c7fe4 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -28,10 +28,11 @@
28#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/jiffies.h>
32#include <asm/io.h>
33 31
34#include "bttvp.h" 32#include "bttvp.h"
33#include <media/v4l2-common.h>
34#include <linux/jiffies.h>
35#include <asm/io.h>
35 36
36static struct i2c_algo_bit_data bttv_i2c_algo_bit_template; 37static struct i2c_algo_bit_data bttv_i2c_algo_bit_template;
37static struct i2c_adapter bttv_i2c_adap_sw_template; 38static struct i2c_adapter bttv_i2c_adap_sw_template;
@@ -105,10 +106,8 @@ static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = {
105 106
106static struct i2c_adapter bttv_i2c_adap_sw_template = { 107static struct i2c_adapter bttv_i2c_adap_sw_template = {
107 .owner = THIS_MODULE, 108 .owner = THIS_MODULE,
108#ifdef I2C_CLASS_TV_ANALOG
109 .class = I2C_CLASS_TV_ANALOG, 109 .class = I2C_CLASS_TV_ANALOG,
110#endif 110 .name = "bttv",
111 .name = "bt848",
112 .id = I2C_HW_B_BT848, 111 .id = I2C_HW_B_BT848,
113 .client_register = attach_inform, 112 .client_register = attach_inform,
114}; 113};
@@ -275,10 +274,8 @@ static struct i2c_algorithm bttv_algo = {
275}; 274};
276 275
277static struct i2c_adapter bttv_i2c_adap_hw_template = { 276static struct i2c_adapter bttv_i2c_adap_hw_template = {
278 .owner = THIS_MODULE, 277 .owner = THIS_MODULE,
279#ifdef I2C_CLASS_TV_ANALOG
280 .class = I2C_CLASS_TV_ANALOG, 278 .class = I2C_CLASS_TV_ANALOG,
281#endif
282 .name = "bt878", 279 .name = "bt878",
283 .id = I2C_HW_B_BT848 /* FIXME */, 280 .id = I2C_HW_B_BT848 /* FIXME */,
284 .algo = &bttv_algo, 281 .algo = &bttv_algo,
@@ -441,12 +438,10 @@ int __devinit init_bttv_i2c(struct bttv *btv)
441 i2c_set_adapdata(&btv->c.i2c_adap, btv); 438 i2c_set_adapdata(&btv->c.i2c_adap, btv);
442 btv->i2c_client.adapter = &btv->c.i2c_adap; 439 btv->i2c_client.adapter = &btv->c.i2c_adap;
443 440
444#ifdef I2C_CLASS_TV_ANALOG
445 if (bttv_tvcards[btv->c.type].no_video) 441 if (bttv_tvcards[btv->c.type].no_video)
446 btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG; 442 btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG;
447 if (bttv_tvcards[btv->c.type].has_dvb) 443 if (bttv_tvcards[btv->c.type].has_dvb)
448 btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL; 444 btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
449#endif
450 445
451 if (btv->use_i2c_hw) { 446 if (btv->use_i2c_hw) {
452 btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap); 447 btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap);
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/bttv-input.c
index de1385e5d05e..12197f1b2757 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/bttv-input.c
@@ -24,11 +24,9 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/input.h> 26#include <linux/input.h>
27#include <linux/pci.h>
28
29#include <media/ir-common.h>
30 27
31#include "bttv.h" 28#include "bttv.h"
29#include "bttvp.h"
32 30
33/* ---------------------------------------------------------------------- */ 31/* ---------------------------------------------------------------------- */
34 32
@@ -156,9 +154,6 @@ static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
156 154
157/* ---------------------------------------------------------------------- */ 155/* ---------------------------------------------------------------------- */
158 156
159/* Ricardo Cerqueira <v4l@cerqueira.org> */
160/* Weird matching, since the remote has "uncommon" keys */
161
162static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = { 157static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = {
163 158
164 [ 30 ] = KEY_POWER, // power 159 [ 30 ] = KEY_POWER, // power
@@ -279,34 +274,6 @@ static IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = {
279 [0x36] = KEY_PC 274 [0x36] = KEY_PC
280}; 275};
281 276
282struct IR {
283 struct bttv_sub_device *sub;
284 struct input_dev *input;
285 struct ir_input_state ir;
286 char name[32];
287 char phys[32];
288
289 /* Usual gpio signalling */
290
291 u32 mask_keycode;
292 u32 mask_keydown;
293 u32 mask_keyup;
294 u32 polling;
295 u32 last_gpio;
296 struct work_struct work;
297 struct timer_list timer;
298
299 /* RC5 gpio */
300 u32 rc5_gpio;
301 struct timer_list timer_end; /* timer_end for code completion */
302 struct timer_list timer_keyup; /* timer_end for key release */
303 u32 last_rc5; /* last good rc5 code */
304 u32 last_bit; /* last raw bit seen */
305 u32 code; /* raw code under construction */
306 struct timeval base_time; /* time of last seen code */
307 int active; /* building raw code */
308};
309
310static int debug; 277static int debug;
311module_param(debug, int, 0644); /* debug level (0,1,2) */ 278module_param(debug, int, 0644); /* debug level (0,1,2) */
312static int repeat_delay = 500; 279static int repeat_delay = 500;
@@ -314,31 +281,17 @@ module_param(repeat_delay, int, 0644);
314static int repeat_period = 33; 281static int repeat_period = 33;
315module_param(repeat_period, int, 0644); 282module_param(repeat_period, int, 0644);
316 283
317#define DEVNAME "ir-kbd-gpio" 284#define DEVNAME "bttv-input"
318#define dprintk(fmt, arg...) if (debug) \
319 printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
320
321static void ir_irq(struct bttv_sub_device *sub);
322static int ir_probe(struct device *dev);
323static int ir_remove(struct device *dev);
324
325static struct bttv_sub_driver driver = {
326 .drv = {
327 .name = DEVNAME,
328 .probe = ir_probe,
329 .remove = ir_remove,
330 },
331 .gpio_irq = ir_irq,
332};
333 285
334/* ---------------------------------------------------------------------- */ 286/* ---------------------------------------------------------------------- */
335 287
336static void ir_handle_key(struct IR *ir) 288static void ir_handle_key(struct bttv *btv)
337{ 289{
290 struct bttv_ir *ir = btv->remote;
338 u32 gpio,data; 291 u32 gpio,data;
339 292
340 /* read gpio value */ 293 /* read gpio value */
341 gpio = bttv_gpio_read(ir->sub->core); 294 gpio = bttv_gpio_read(&btv->c);
342 if (ir->polling) { 295 if (ir->polling) {
343 if (ir->last_gpio == gpio) 296 if (ir->last_gpio == gpio)
344 return; 297 return;
@@ -347,56 +300,36 @@ static void ir_handle_key(struct IR *ir)
347 300
348 /* extract data */ 301 /* extract data */
349 data = ir_extract_bits(gpio, ir->mask_keycode); 302 data = ir_extract_bits(gpio, ir->mask_keycode);
350 dprintk(DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n", 303 dprintk(KERN_INFO DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n",
351 gpio, data, 304 gpio, data,
352 ir->polling ? "poll" : "irq", 305 ir->polling ? "poll" : "irq",
353 (gpio & ir->mask_keydown) ? " down" : "", 306 (gpio & ir->mask_keydown) ? " down" : "",
354 (gpio & ir->mask_keyup) ? " up" : ""); 307 (gpio & ir->mask_keyup) ? " up" : "");
355 308
356 if (ir->mask_keydown) { 309 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
357 /* bit set on keydown */ 310 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
358 if (gpio & ir->mask_keydown) { 311 ir_input_keydown(ir->dev,&ir->ir,data,data);
359 ir_input_keydown(ir->input, &ir->ir, data, data);
360 } else {
361 ir_input_nokey(ir->input, &ir->ir);
362 }
363
364 } else if (ir->mask_keyup) {
365 /* bit cleared on keydown */
366 if (0 == (gpio & ir->mask_keyup)) {
367 ir_input_keydown(ir->input, &ir->ir, data, data);
368 } else {
369 ir_input_nokey(ir->input, &ir->ir);
370 }
371
372 } else { 312 } else {
373 /* can't disturgissh keydown/up :-/ */ 313 ir_input_nokey(ir->dev,&ir->ir);
374 ir_input_keydown(ir->input, &ir->ir, data, data);
375 ir_input_nokey(ir->input, &ir->ir);
376 } 314 }
377}
378
379static void ir_irq(struct bttv_sub_device *sub)
380{
381 struct IR *ir = dev_get_drvdata(&sub->dev);
382 315
383 if (!ir->polling)
384 ir_handle_key(ir);
385} 316}
386 317
387static void ir_timer(unsigned long data) 318void bttv_input_irq(struct bttv *btv)
388{ 319{
389 struct IR *ir = (struct IR*)data; 320 struct bttv_ir *ir = btv->remote;
390 321
391 schedule_work(&ir->work); 322 if (!ir->polling)
323 ir_handle_key(btv);
392} 324}
393 325
394static void ir_work(void *data) 326static void bttv_input_timer(unsigned long data)
395{ 327{
396 struct IR *ir = data; 328 struct bttv *btv = (struct bttv*)data;
329 struct bttv_ir *ir = btv->remote;
397 unsigned long timeout; 330 unsigned long timeout;
398 331
399 ir_handle_key(ir); 332 ir_handle_key(btv);
400 timeout = jiffies + (ir->polling * HZ / 1000); 333 timeout = jiffies + (ir->polling * HZ / 1000);
401 mod_timer(&ir->timer, timeout); 334 mod_timer(&ir->timer, timeout);
402} 335}
@@ -435,26 +368,26 @@ static u32 rc5_decode(unsigned int code)
435 rc5 |= 1; 368 rc5 |= 1;
436 break; 369 break;
437 case 3: 370 case 3:
438 dprintk("bad code: %x\n", org_code); 371 dprintk(KERN_WARNING "bad code: %x\n", org_code);
439 return 0; 372 return 0;
440 } 373 }
441 } 374 }
442 dprintk("code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " 375 dprintk(KERN_WARNING "code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
443 "instr=%x\n", rc5, org_code, RC5_START(rc5), 376 "instr=%x\n", rc5, org_code, RC5_START(rc5),
444 RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); 377 RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
445 return rc5; 378 return rc5;
446} 379}
447 380
448static int ir_rc5_irq(struct bttv_sub_device *sub) 381static int bttv_rc5_irq(struct bttv *btv)
449{ 382{
450 struct IR *ir = dev_get_drvdata(&sub->dev); 383 struct bttv_ir *ir = btv->remote;
451 struct timeval tv; 384 struct timeval tv;
452 u32 gpio; 385 u32 gpio;
453 u32 gap; 386 u32 gap;
454 unsigned long current_jiffies, timeout; 387 unsigned long current_jiffies, timeout;
455 388
456 /* read gpio port */ 389 /* read gpio port */
457 gpio = bttv_gpio_read(ir->sub->core); 390 gpio = bttv_gpio_read(&btv->c);
458 391
459 /* remote IRQ? */ 392 /* remote IRQ? */
460 if (!(gpio & 0x20)) 393 if (!(gpio & 0x20))
@@ -493,14 +426,15 @@ static int ir_rc5_irq(struct bttv_sub_device *sub)
493 } 426 }
494 427
495 /* toggle GPIO pin 4 to reset the irq */ 428 /* toggle GPIO pin 4 to reset the irq */
496 bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4)); 429 bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
497 bttv_gpio_write(ir->sub->core, gpio | (1 << 4)); 430 bttv_gpio_write(&btv->c, gpio | (1 << 4));
498 return 1; 431 return 1;
499} 432}
500 433
501static void ir_rc5_timer_end(unsigned long data) 434
435static void bttv_rc5_timer_end(unsigned long data)
502{ 436{
503 struct IR *ir = (struct IR *)data; 437 struct bttv_ir *ir = (struct bttv_ir *)data;
504 struct timeval tv; 438 struct timeval tv;
505 unsigned long current_jiffies, timeout; 439 unsigned long current_jiffies, timeout;
506 u32 gap; 440 u32 gap;
@@ -519,20 +453,20 @@ static void ir_rc5_timer_end(unsigned long data)
519 453
520 /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */ 454 /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */
521 if (gap < 28000) { 455 if (gap < 28000) {
522 dprintk("spurious timer_end\n"); 456 dprintk(KERN_WARNING "spurious timer_end\n");
523 return; 457 return;
524 } 458 }
525 459
526 ir->active = 0; 460 ir->active = 0;
527 if (ir->last_bit < 20) { 461 if (ir->last_bit < 20) {
528 /* ignore spurious codes (caused by light/other remotes) */ 462 /* ignore spurious codes (caused by light/other remotes) */
529 dprintk("short code: %x\n", ir->code); 463 dprintk(KERN_WARNING "short code: %x\n", ir->code);
530 } else { 464 } else {
531 u32 rc5 = rc5_decode(ir->code); 465 u32 rc5 = rc5_decode(ir->code);
532 466
533 /* two start bits? */ 467 /* two start bits? */
534 if (RC5_START(rc5) != 3) { 468 if (RC5_START(rc5) != 3) {
535 dprintk("rc5 start bits invalid: %u\n", RC5_START(rc5)); 469 dprintk(KERN_WARNING "rc5 start bits invalid: %u\n", RC5_START(rc5));
536 470
537 /* right address? */ 471 /* right address? */
538 } else if (RC5_ADDR(rc5) == 0x0) { 472 } else if (RC5_ADDR(rc5) == 0x0) {
@@ -542,10 +476,10 @@ static void ir_rc5_timer_end(unsigned long data)
542 /* Good code, decide if repeat/repress */ 476 /* Good code, decide if repeat/repress */
543 if (toggle != RC5_TOGGLE(ir->last_rc5) || 477 if (toggle != RC5_TOGGLE(ir->last_rc5) ||
544 instr != RC5_INSTR(ir->last_rc5)) { 478 instr != RC5_INSTR(ir->last_rc5)) {
545 dprintk("instruction %x, toggle %x\n", instr, 479 dprintk(KERN_WARNING "instruction %x, toggle %x\n", instr,
546 toggle); 480 toggle);
547 ir_input_nokey(ir->input, &ir->ir); 481 ir_input_nokey(ir->dev, &ir->ir);
548 ir_input_keydown(ir->input, &ir->ir, instr, 482 ir_input_keydown(ir->dev, &ir->ir, instr,
549 instr); 483 instr);
550 } 484 }
551 485
@@ -560,34 +494,37 @@ static void ir_rc5_timer_end(unsigned long data)
560 } 494 }
561} 495}
562 496
563static void ir_rc5_timer_keyup(unsigned long data) 497static void bttv_rc5_timer_keyup(unsigned long data)
564{ 498{
565 struct IR *ir = (struct IR *)data; 499 struct bttv_ir *ir = (struct bttv_ir *)data;
566 500
567 dprintk("key released\n"); 501 dprintk(KERN_DEBUG "key released\n");
568 ir_input_nokey(ir->input, &ir->ir); 502 ir_input_nokey(ir->dev, &ir->ir);
569} 503}
570 504
571/* ---------------------------------------------------------------------- */ 505/* ---------------------------------------------------------------------- */
572 506
573static int ir_probe(struct device *dev) 507int bttv_input_init(struct bttv *btv)
574{ 508{
575 struct bttv_sub_device *sub = to_bttv_sub_dev(dev); 509 struct bttv_ir *ir;
576 struct IR *ir;
577 struct input_dev *input_dev;
578 IR_KEYTAB_TYPE *ir_codes = NULL; 510 IR_KEYTAB_TYPE *ir_codes = NULL;
511 struct input_dev *input_dev;
579 int ir_type = IR_TYPE_OTHER; 512 int ir_type = IR_TYPE_OTHER;
580 513
581 ir = kzalloc(sizeof(*ir), GFP_KERNEL); 514 if (!btv->has_remote)
515 return -ENODEV;
516
517 ir = kzalloc(sizeof(*ir),GFP_KERNEL);
582 input_dev = input_allocate_device(); 518 input_dev = input_allocate_device();
583 if (!ir || !input_dev) { 519 if (!ir || !input_dev) {
584 kfree(ir); 520 kfree(ir);
585 input_free_device(input_dev); 521 input_free_device(input_dev);
586 return -ENOMEM; 522 return -ENOMEM;
587 } 523 }
524 memset(ir,0,sizeof(*ir));
588 525
589 /* detect & configure */ 526 /* detect & configure */
590 switch (sub->core->type) { 527 switch (btv->c.type) {
591 case BTTV_BOARD_AVERMEDIA: 528 case BTTV_BOARD_AVERMEDIA:
592 case BTTV_BOARD_AVPHONE98: 529 case BTTV_BOARD_AVPHONE98:
593 case BTTV_BOARD_AVERMEDIA98: 530 case BTTV_BOARD_AVERMEDIA98:
@@ -643,12 +580,12 @@ static int ir_probe(struct device *dev)
643 break; 580 break;
644 case BTTV_BOARD_NEBULA_DIGITV: 581 case BTTV_BOARD_NEBULA_DIGITV:
645 ir_codes = ir_codes_nebula; 582 ir_codes = ir_codes_nebula;
646 driver.any_irq = ir_rc5_irq; 583 btv->custom_irq = bttv_rc5_irq;
647 driver.gpio_irq = NULL;
648 ir->rc5_gpio = 1; 584 ir->rc5_gpio = 1;
649 break; 585 break;
650 } 586 }
651 if (NULL == ir_codes) { 587 if (NULL == ir_codes) {
588 dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n",btv->c.type);
652 kfree(ir); 589 kfree(ir);
653 input_free_device(input_dev); 590 input_free_device(input_dev);
654 return -ENODEV; 591 return -ENODEV;
@@ -657,109 +594,92 @@ static int ir_probe(struct device *dev)
657 if (ir->rc5_gpio) { 594 if (ir->rc5_gpio) {
658 u32 gpio; 595 u32 gpio;
659 /* enable remote irq */ 596 /* enable remote irq */
660 bttv_gpio_inout(sub->core, (1 << 4), 1 << 4); 597 bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4);
661 gpio = bttv_gpio_read(sub->core); 598 gpio = bttv_gpio_read(&btv->c);
662 bttv_gpio_write(sub->core, gpio & ~(1 << 4)); 599 bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
663 bttv_gpio_write(sub->core, gpio | (1 << 4)); 600 bttv_gpio_write(&btv->c, gpio | (1 << 4));
664 } else { 601 } else {
665 /* init hardware-specific stuff */ 602 /* init hardware-specific stuff */
666 bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0); 603 bttv_gpio_inout(&btv->c, ir->mask_keycode | ir->mask_keydown, 0);
667 } 604 }
668 605
669 /* init input device */ 606 /* init input device */
607 ir->dev = input_dev;
608
670 snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)", 609 snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
671 sub->core->type); 610 btv->c.type);
672 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", 611 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
673 pci_name(sub->core->pci)); 612 pci_name(btv->c.pci));
674 613
675 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); 614 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
676 input_dev->name = ir->name; 615 input_dev->name = ir->name;
677 input_dev->phys = ir->phys; 616 input_dev->phys = ir->phys;
678 input_dev->id.bustype = BUS_PCI; 617 input_dev->id.bustype = BUS_PCI;
679 input_dev->id.version = 1; 618 input_dev->id.version = 1;
680 if (sub->core->pci->subsystem_vendor) { 619 if (btv->c.pci->subsystem_vendor) {
681 input_dev->id.vendor = sub->core->pci->subsystem_vendor; 620 input_dev->id.vendor = btv->c.pci->subsystem_vendor;
682 input_dev->id.product = sub->core->pci->subsystem_device; 621 input_dev->id.product = btv->c.pci->subsystem_device;
683 } else { 622 } else {
684 input_dev->id.vendor = sub->core->pci->vendor; 623 input_dev->id.vendor = btv->c.pci->vendor;
685 input_dev->id.product = sub->core->pci->device; 624 input_dev->id.product = btv->c.pci->device;
686 } 625 }
687 input_dev->cdev.dev = &sub->core->pci->dev; 626 input_dev->cdev.dev = &btv->c.pci->dev;
688
689 ir->input = input_dev;
690 ir->sub = sub;
691 627
628 btv->remote = ir;
692 if (ir->polling) { 629 if (ir->polling) {
693 INIT_WORK(&ir->work, ir_work, ir);
694 init_timer(&ir->timer); 630 init_timer(&ir->timer);
695 ir->timer.function = ir_timer; 631 ir->timer.function = bttv_input_timer;
696 ir->timer.data = (unsigned long)ir; 632 ir->timer.data = (unsigned long)btv;
697 schedule_work(&ir->work); 633 ir->timer.expires = jiffies + HZ;
634 add_timer(&ir->timer);
698 } else if (ir->rc5_gpio) { 635 } else if (ir->rc5_gpio) {
699 /* set timer_end for code completion */ 636 /* set timer_end for code completion */
700 init_timer(&ir->timer_end); 637 init_timer(&ir->timer_end);
701 ir->timer_end.function = ir_rc5_timer_end; 638 ir->timer_end.function = bttv_rc5_timer_end;
702 ir->timer_end.data = (unsigned long)ir; 639 ir->timer_end.data = (unsigned long)ir;
703 640
704 init_timer(&ir->timer_keyup); 641 init_timer(&ir->timer_keyup);
705 ir->timer_keyup.function = ir_rc5_timer_keyup; 642 ir->timer_keyup.function = bttv_rc5_timer_keyup;
706 ir->timer_keyup.data = (unsigned long)ir; 643 ir->timer_keyup.data = (unsigned long)ir;
707 } 644 }
708 645
709 /* all done */ 646 /* all done */
710 dev_set_drvdata(dev, ir); 647 input_register_device(btv->remote->dev);
711 input_register_device(ir->input); 648 printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys);
712 649
713 /* the remote isn't as bouncy as a keyboard */ 650 /* the remote isn't as bouncy as a keyboard */
714 ir->input->rep[REP_DELAY] = repeat_delay; 651 ir->dev->rep[REP_DELAY] = repeat_delay;
715 ir->input->rep[REP_PERIOD] = repeat_period; 652 ir->dev->rep[REP_PERIOD] = repeat_period;
716 653
717 return 0; 654 return 0;
718} 655}
719 656
720static int ir_remove(struct device *dev) 657void bttv_input_fini(struct bttv *btv)
721{ 658{
722 struct IR *ir = dev_get_drvdata(dev); 659 if (btv->remote == NULL)
660 return;
723 661
724 if (ir->polling) { 662 if (btv->remote->polling) {
725 del_timer(&ir->timer); 663 del_timer_sync(&btv->remote->timer);
726 flush_scheduled_work(); 664 flush_scheduled_work();
727 } 665 }
728 666
729 if (ir->rc5_gpio) { 667
668 if (btv->remote->rc5_gpio) {
730 u32 gpio; 669 u32 gpio;
731 670
732 del_timer(&ir->timer_end); 671 del_timer_sync(&btv->remote->timer_end);
733 flush_scheduled_work(); 672 flush_scheduled_work();
734 673
735 gpio = bttv_gpio_read(ir->sub->core); 674 gpio = bttv_gpio_read(&btv->c);
736 bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4)); 675 bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
737 } 676 }
738 677
739 input_unregister_device(ir->input); 678 input_unregister_device(btv->remote->dev);
740 kfree(ir); 679 kfree(btv->remote);
741 return 0; 680 btv->remote = NULL;
742}
743
744/* ---------------------------------------------------------------------- */
745
746MODULE_AUTHOR("Gerd Knorr, Pavel Machek");
747MODULE_DESCRIPTION("input driver for bt8x8 gpio IR remote controls");
748MODULE_LICENSE("GPL");
749
750static int ir_init(void)
751{
752 return bttv_sub_register(&driver, "remote");
753} 681}
754 682
755static void ir_fini(void)
756{
757 bttv_sub_unregister(&driver);
758}
759
760module_init(ir_init);
761module_exit(ir_fini);
762
763 683
764/* 684/*
765 * Local variables: 685 * Local variables:
diff --git a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c
index f4f58c60f152..72afdd64b882 100644
--- a/drivers/media/video/bttv-vbi.c
+++ b/drivers/media/video/bttv-vbi.c
@@ -31,6 +31,12 @@
31#include <asm/io.h> 31#include <asm/io.h>
32#include "bttvp.h" 32#include "bttvp.h"
33 33
34/* Offset from line sync pulse leading edge (0H) in 1 / sampling_rate:
35 bt8x8 /HRESET pulse starts at 0H and has length 64 / fCLKx1 (E|O_VTC
36 HSFMT = 0). VBI_HDELAY (always 0) is an offset from the trailing edge
37 of /HRESET in 1 / fCLKx1, and the sampling_rate tvnorm->Fsc is fCLKx2. */
38#define VBI_OFFSET ((64 + 0) * 2)
39
34#define VBI_DEFLINES 16 40#define VBI_DEFLINES 16
35#define VBI_MAXLINES 32 41#define VBI_MAXLINES 32
36 42
@@ -163,40 +169,30 @@ void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines)
163void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f) 169void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f)
164{ 170{
165 const struct bttv_tvnorm *tvnorm; 171 const struct bttv_tvnorm *tvnorm;
166 u32 start0,start1; 172 s64 count0,count1,count;
167 s32 count0,count1,count;
168 173
169 tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; 174 tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
170 f->type = V4L2_BUF_TYPE_VBI_CAPTURE; 175 f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
171 f->fmt.vbi.sampling_rate = tvnorm->Fsc; 176 f->fmt.vbi.sampling_rate = tvnorm->Fsc;
172 f->fmt.vbi.samples_per_line = 2048; 177 f->fmt.vbi.samples_per_line = 2048;
173 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; 178 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
174 f->fmt.vbi.offset = 244; 179 f->fmt.vbi.offset = VBI_OFFSET;
175 f->fmt.vbi.flags = 0; 180 f->fmt.vbi.flags = 0;
176 switch (fh->btv->tvnorm) {
177 case 1: /* NTSC */
178 start0 = 10;
179 start1 = 273;
180 break;
181 case 0: /* PAL */
182 case 2: /* SECAM */
183 default:
184 start0 = 7;
185 start1 = 320;
186 }
187 181
188 count0 = (f->fmt.vbi.start[0] + f->fmt.vbi.count[0]) - start0; 182 /* s64 to prevent overflow. */
189 count1 = (f->fmt.vbi.start[1] + f->fmt.vbi.count[1]) - start1; 183 count0 = (s64) f->fmt.vbi.start[0] + f->fmt.vbi.count[0]
190 count = max(count0,count1); 184 - tvnorm->vbistart[0];
191 if (count > VBI_MAXLINES) 185 count1 = (s64) f->fmt.vbi.start[1] + f->fmt.vbi.count[1]
192 count = VBI_MAXLINES; 186 - tvnorm->vbistart[1];
193 if (count < 1) 187 count = clamp (max (count0, count1), 1LL, (s64) VBI_MAXLINES);
194 count = 1;
195 188
196 f->fmt.vbi.start[0] = start0; 189 f->fmt.vbi.start[0] = tvnorm->vbistart[0];
197 f->fmt.vbi.start[1] = start1; 190 f->fmt.vbi.start[1] = tvnorm->vbistart[1];
198 f->fmt.vbi.count[0] = count; 191 f->fmt.vbi.count[0] = count;
199 f->fmt.vbi.count[1] = count; 192 f->fmt.vbi.count[1] = count;
193
194 f->fmt.vbi.reserved[0] = 0;
195 f->fmt.vbi.reserved[1] = 0;
200} 196}
201 197
202void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f) 198void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f)
@@ -209,21 +205,12 @@ void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f)
209 f->fmt.vbi.sampling_rate = tvnorm->Fsc; 205 f->fmt.vbi.sampling_rate = tvnorm->Fsc;
210 f->fmt.vbi.samples_per_line = 2048; 206 f->fmt.vbi.samples_per_line = 2048;
211 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; 207 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
212 f->fmt.vbi.offset = 244; 208 f->fmt.vbi.offset = VBI_OFFSET;
209 f->fmt.vbi.start[0] = tvnorm->vbistart[0];
210 f->fmt.vbi.start[1] = tvnorm->vbistart[1];
213 f->fmt.vbi.count[0] = fh->lines; 211 f->fmt.vbi.count[0] = fh->lines;
214 f->fmt.vbi.count[1] = fh->lines; 212 f->fmt.vbi.count[1] = fh->lines;
215 f->fmt.vbi.flags = 0; 213 f->fmt.vbi.flags = 0;
216 switch (fh->btv->tvnorm) {
217 case 1: /* NTSC */
218 f->fmt.vbi.start[0] = 10;
219 f->fmt.vbi.start[1] = 273;
220 break;
221 case 0: /* PAL */
222 case 2: /* SECAM */
223 default:
224 f->fmt.vbi.start[0] = 7;
225 f->fmt.vbi.start[1] = 319;
226 }
227} 214}
228 215
229/* ----------------------------------------------------------------------- */ 216/* ----------------------------------------------------------------------- */
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index 93298f06e019..9feaa6bab207 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -16,6 +16,8 @@
16 16
17#include <linux/videodev.h> 17#include <linux/videodev.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <media/ir-common.h>
20#include <media/ir-kbd-i2c.h>
19 21
20/* ---------------------------------------------------------- */ 22/* ---------------------------------------------------------- */
21/* exported by bttv-cards.c */ 23/* exported by bttv-cards.c */
@@ -163,6 +165,7 @@
163#define BTTV_BOARD_OSPREY440 0x8c 165#define BTTV_BOARD_OSPREY440 0x8c
164#define BTTV_BOARD_ASOUND_SKYEYE 0x8d 166#define BTTV_BOARD_ASOUND_SKYEYE 0x8d
165#define BTTV_BOARD_SABRENT_TVFM 0x8e 167#define BTTV_BOARD_SABRENT_TVFM 0x8e
168#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f
166 169
167/* i2c address list */ 170/* i2c address list */
168#define I2C_TSA5522 0xc2 171#define I2C_TSA5522 0xc2
@@ -210,6 +213,34 @@ struct bttv_core {
210 213
211struct bttv; 214struct bttv;
212 215
216
217struct bttv_ir {
218 struct input_dev *dev;
219 struct ir_input_state ir;
220 char name[32];
221 char phys[32];
222
223 /* Usual gpio signalling */
224
225 u32 mask_keycode;
226 u32 mask_keydown;
227 u32 mask_keyup;
228 u32 polling;
229 u32 last_gpio;
230 struct work_struct work;
231 struct timer_list timer;
232
233 /* RC5 gpio */
234 u32 rc5_gpio;
235 struct timer_list timer_end; /* timer_end for code completion */
236 struct timer_list timer_keyup; /* timer_end for key release */
237 u32 last_rc5; /* last good rc5 code */
238 u32 last_bit; /* last raw bit seen */
239 u32 code; /* raw code under construction */
240 struct timeval base_time; /* time of last seen code */
241 int active; /* building raw code */
242};
243
213struct tvcard 244struct tvcard
214{ 245{
215 char *name; 246 char *name;
@@ -235,7 +266,6 @@ struct tvcard
235 unsigned int has_dvb:1; 266 unsigned int has_dvb:1;
236 unsigned int has_remote:1; 267 unsigned int has_remote:1;
237 unsigned int no_gpioirq:1; 268 unsigned int no_gpioirq:1;
238 unsigned int any_irq:1;
239 269
240 /* other settings */ 270 /* other settings */
241 unsigned int pll; 271 unsigned int pll;
@@ -335,7 +365,6 @@ struct bttv_sub_driver {
335 struct device_driver drv; 365 struct device_driver drv;
336 char wanted[BUS_ID_SIZE]; 366 char wanted[BUS_ID_SIZE];
337 void (*gpio_irq)(struct bttv_sub_device *sub); 367 void (*gpio_irq)(struct bttv_sub_device *sub);
338 int (*any_irq)(struct bttv_sub_device *sub);
339}; 368};
340#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) 369#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv)
341 370
@@ -363,6 +392,10 @@ extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
363 unsigned char b2, int both); 392 unsigned char b2, int both);
364extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr); 393extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr);
365 394
395extern int bttv_input_init(struct bttv *dev);
396extern void bttv_input_fini(struct bttv *dev);
397extern void bttv_input_irq(struct bttv *dev);
398
366#endif /* _BTTV_H_ */ 399#endif /* _BTTV_H_ */
367/* 400/*
368 * Local variables: 401 * Local variables:
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index 1e6a5632c3c7..dd00c20ab95e 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -73,6 +73,8 @@
73 73
74#define UNSET (-1U) 74#define UNSET (-1U)
75 75
76#define clamp(x, low, high) min (max (low, x), high)
77
76/* ---------------------------------------------------------- */ 78/* ---------------------------------------------------------- */
77 79
78struct bttv_tvnorm { 80struct bttv_tvnorm {
@@ -88,6 +90,9 @@ struct bttv_tvnorm {
88 u8 vbipack; 90 u8 vbipack;
89 u16 vtotal; 91 u16 vtotal;
90 int sram; 92 int sram;
93 /* ITU-R frame line number of the first VBI line we can
94 capture, of the first and second field. */
95 u16 vbistart[2];
91}; 96};
92extern const struct bttv_tvnorm bttv_tvnorms[]; 97extern const struct bttv_tvnorm bttv_tvnorms[];
93 98
@@ -209,7 +214,6 @@ extern struct bus_type bttv_sub_bus_type;
209int bttv_sub_add_device(struct bttv_core *core, char *name); 214int bttv_sub_add_device(struct bttv_core *core, char *name);
210int bttv_sub_del_devices(struct bttv_core *core); 215int bttv_sub_del_devices(struct bttv_core *core);
211void bttv_gpio_irq(struct bttv_core *core); 216void bttv_gpio_irq(struct bttv_core *core);
212int bttv_any_irq(struct bttv_core *core);
213 217
214 218
215/* ---------------------------------------------------------- */ 219/* ---------------------------------------------------------- */
@@ -270,12 +274,13 @@ struct bttv {
270 /* card configuration info */ 274 /* card configuration info */
271 unsigned int cardid; /* pci subsystem id (bt878 based ones) */ 275 unsigned int cardid; /* pci subsystem id (bt878 based ones) */
272 unsigned int tuner_type; /* tuner chip type */ 276 unsigned int tuner_type; /* tuner chip type */
273 unsigned int pinnacle_id; 277 unsigned int tda9887_conf;
274 unsigned int svhs; 278 unsigned int svhs;
275 struct bttv_pll_info pll; 279 struct bttv_pll_info pll;
276 int triton1; 280 int triton1;
277 int gpioirq; 281 int gpioirq;
278 int any_irq; 282 int (*custom_irq)(struct bttv *btv);
283
279 int use_i2c_hw; 284 int use_i2c_hw;
280 285
281 /* old gpio interface */ 286 /* old gpio interface */
@@ -300,7 +305,7 @@ struct bttv {
300 305
301 /* infrared remote */ 306 /* infrared remote */
302 int has_remote; 307 int has_remote;
303 struct bttv_input *remote; 308 struct bttv_ir *remote;
304 309
305 /* locking */ 310 /* locking */
306 spinlock_t s_lock; 311 spinlock_t s_lock;
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index 0065d0c240d1..6bad93ef969f 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -875,6 +875,7 @@ static struct file_operations qcam_fops = {
875 .open = video_exclusive_open, 875 .open = video_exclusive_open,
876 .release = video_exclusive_release, 876 .release = video_exclusive_release,
877 .ioctl = qcam_ioctl, 877 .ioctl = qcam_ioctl,
878 .compat_ioctl = v4l_compat_ioctl32,
878 .read = qcam_read, 879 .read = qcam_read,
879 .llseek = no_llseek, 880 .llseek = no_llseek,
880}; 881};
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index 75442ec49f35..9976db4f6da8 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -687,6 +687,7 @@ static struct file_operations qcam_fops = {
687 .open = video_exclusive_open, 687 .open = video_exclusive_open,
688 .release = video_exclusive_release, 688 .release = video_exclusive_release,
689 .ioctl = qcam_ioctl, 689 .ioctl = qcam_ioctl,
690 .compat_ioctl = v4l_compat_ioctl32,
690 .read = qcam_read, 691 .read = qcam_read,
691 .llseek = no_llseek, 692 .llseek = no_llseek,
692}; 693};
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c
new file mode 100644
index 000000000000..6194b0125576
--- /dev/null
+++ b/drivers/media/video/compat_ioctl32.c
@@ -0,0 +1,732 @@
1/*
2 * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
3 * Separated from fs stuff by Arnd Bergmann <arnd@arndb.de>
4 *
5 * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
6 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
7 * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
8 * Copyright (C) 2003 Pavel Machek (pavel@suse.cz)
9 * Copyright (C) 2005 Philippe De Muyter (phdm@macqel.be)
10 *
11 * These routines maintain argument size conversion between 32bit and 64bit
12 * ioctls.
13 */
14
15#include <linux/config.h>
16#include <linux/compat.h>
17#include <linux/videodev.h>
18#include <linux/videodev2.h>
19#include <linux/module.h>
20#include <linux/smp_lock.h>
21
22#ifdef CONFIG_COMPAT
23struct video_tuner32 {
24 compat_int_t tuner;
25 char name[32];
26 compat_ulong_t rangelow, rangehigh;
27 u32 flags; /* It is really u32 in videodev.h */
28 u16 mode, signal;
29};
30
31static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
32{
33 if(get_user(kp->tuner, &up->tuner))
34 return -EFAULT;
35 __copy_from_user(kp->name, up->name, 32);
36 __get_user(kp->rangelow, &up->rangelow);
37 __get_user(kp->rangehigh, &up->rangehigh);
38 __get_user(kp->flags, &up->flags);
39 __get_user(kp->mode, &up->mode);
40 __get_user(kp->signal, &up->signal);
41 return 0;
42}
43
44static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
45{
46 if(put_user(kp->tuner, &up->tuner))
47 return -EFAULT;
48 __copy_to_user(up->name, kp->name, 32);
49 __put_user(kp->rangelow, &up->rangelow);
50 __put_user(kp->rangehigh, &up->rangehigh);
51 __put_user(kp->flags, &up->flags);
52 __put_user(kp->mode, &up->mode);
53 __put_user(kp->signal, &up->signal);
54 return 0;
55}
56
57struct video_buffer32 {
58 compat_caddr_t base;
59 compat_int_t height, width, depth, bytesperline;
60};
61
62static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
63{
64 u32 tmp;
65
66 if (get_user(tmp, &up->base))
67 return -EFAULT;
68
69 /* This is actually a physical address stored
70 * as a void pointer.
71 */
72 kp->base = (void *)(unsigned long) tmp;
73
74 __get_user(kp->height, &up->height);
75 __get_user(kp->width, &up->width);
76 __get_user(kp->depth, &up->depth);
77 __get_user(kp->bytesperline, &up->bytesperline);
78 return 0;
79}
80
81static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
82{
83 u32 tmp = (u32)((unsigned long)kp->base);
84
85 if(put_user(tmp, &up->base))
86 return -EFAULT;
87 __put_user(kp->height, &up->height);
88 __put_user(kp->width, &up->width);
89 __put_user(kp->depth, &up->depth);
90 __put_user(kp->bytesperline, &up->bytesperline);
91 return 0;
92}
93
94struct video_clip32 {
95 s32 x, y, width, height; /* Its really s32 in videodev.h */
96 compat_caddr_t next;
97};
98
99struct video_window32 {
100 u32 x, y, width, height, chromakey, flags;
101 compat_caddr_t clips;
102 compat_int_t clipcount;
103};
104
105static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
106{
107 int ret = -ENOIOCTLCMD;
108
109 if (file->f_op->unlocked_ioctl)
110 ret = file->f_op->unlocked_ioctl(file, cmd, arg);
111 else if (file->f_op->ioctl) {
112 lock_kernel();
113 ret = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, arg);
114 unlock_kernel();
115 }
116
117 return ret;
118}
119
120
121/* You get back everything except the clips... */
122static int put_video_window32(struct video_window *kp, struct video_window32 __user *up)
123{
124 if(put_user(kp->x, &up->x))
125 return -EFAULT;
126 __put_user(kp->y, &up->y);
127 __put_user(kp->width, &up->width);
128 __put_user(kp->height, &up->height);
129 __put_user(kp->chromakey, &up->chromakey);
130 __put_user(kp->flags, &up->flags);
131 __put_user(kp->clipcount, &up->clipcount);
132 return 0;
133}
134
135struct v4l2_clip32
136{
137 struct v4l2_rect c;
138 compat_caddr_t next;
139};
140
141struct v4l2_window32
142{
143 struct v4l2_rect w;
144 enum v4l2_field field;
145 __u32 chromakey;
146 compat_caddr_t clips; /* actually struct v4l2_clip32 * */
147 __u32 clipcount;
148 compat_caddr_t bitmap;
149};
150
151static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
152{
153 if (copy_from_user(&kp->w, &up->w, sizeof(up->w)))
154 return -EFAULT;
155 __get_user(kp->field, &up->field);
156 __get_user(kp->chromakey, &up->chromakey);
157 __get_user(kp->clipcount, &up->clipcount);
158 if (kp->clipcount > 2048)
159 return -EINVAL;
160 if (kp->clipcount) {
161 struct v4l2_clip32 *uclips = compat_ptr(up->clips);
162 struct v4l2_clip *kclips;
163 int n = kp->clipcount;
164
165 kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));
166 kp->clips = kclips;
167 while (--n >= 0) {
168 copy_from_user(&kclips->c, &uclips->c, sizeof(uclips->c));
169 kclips->next = n ? kclips + 1 : 0;
170 uclips += 1;
171 kclips += 1;
172 }
173 } else
174 kp->clips = 0;
175 return 0;
176}
177
178static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
179{
180 if (copy_to_user(&up->w, &kp->w, sizeof(up->w)))
181 return -EFAULT;
182 __put_user(kp->field, &up->field);
183 __put_user(kp->chromakey, &up->chromakey);
184 __put_user(kp->clipcount, &up->clipcount);
185 return 0;
186}
187
188static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
189{
190 return copy_from_user(kp, up, sizeof(struct v4l2_pix_format));
191}
192
193static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
194{
195 return copy_to_user(up, kp, sizeof(struct v4l2_pix_format));
196}
197
198static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
199{
200 return copy_from_user(kp, up, sizeof(struct v4l2_vbi_format));
201}
202
203static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
204{
205 return copy_to_user(up, kp, sizeof(struct v4l2_vbi_format));
206}
207
208struct v4l2_format32
209{
210 enum v4l2_buf_type type;
211 union
212 {
213 struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE
214 struct v4l2_window32 win; // V4L2_BUF_TYPE_VIDEO_OVERLAY
215 struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE
216 __u8 raw_data[200]; // user-defined
217 } fmt;
218};
219
220static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
221{
222 if(get_user(kp->type, &up->type))
223 return -EFAULT;
224 switch (kp->type) {
225 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
226 return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
227 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
228 return get_v4l2_window32(&kp->fmt.win, &up->fmt.win);
229 case V4L2_BUF_TYPE_VBI_CAPTURE:
230 return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
231 default:
232 printk("compat_ioctl : unexpected VIDIOC_FMT type %d\n",
233 kp->type);
234 return -ENXIO;
235 }
236}
237
238static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
239{
240 if(put_user(kp->type, &up->type))
241 return -EFAULT;
242 switch (kp->type) {
243 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
244 return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
245 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
246 return put_v4l2_window32(&kp->fmt.win, &up->fmt.win);
247 case V4L2_BUF_TYPE_VBI_CAPTURE:
248 return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
249 default:
250 return -ENXIO;
251 }
252}
253
254struct v4l2_standard32
255{
256 __u32 index;
257 __u32 id[2]; /* __u64 would get the alignment wrong */
258 __u8 name[24];
259 struct v4l2_fract frameperiod; /* Frames, not fields */
260 __u32 framelines;
261 __u32 reserved[4];
262};
263
264static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
265{
266 /* other fields are not set by the user, nor used by the driver */
267 return get_user(kp->index, &up->index);
268}
269
270static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
271{
272 if(put_user(kp->index, &up->index))
273 return -EFAULT;
274 __copy_to_user(up->id, &kp->id, sizeof(__u64));
275 __copy_to_user(up->name, kp->name, 24);
276 __put_user(kp->frameperiod, &up->frameperiod);
277 __put_user(kp->framelines, &up->framelines);
278 __copy_to_user(up->reserved, kp->reserved, 4 * sizeof(__u32));
279 return 0;
280}
281
282struct v4l2_buffer32
283{
284 __u32 index;
285 enum v4l2_buf_type type;
286 __u32 bytesused;
287 __u32 flags;
288 enum v4l2_field field;
289 struct compat_timeval timestamp;
290 struct v4l2_timecode timecode;
291 __u32 sequence;
292
293 /* memory location */
294 enum v4l2_memory memory;
295 union {
296 __u32 offset;
297 compat_long_t userptr;
298 } m;
299 __u32 length;
300 __u32 input;
301 __u32 reserved;
302};
303
304static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
305{
306
307 if (get_user(kp->index, &up->index))
308 return -EFAULT;
309 __get_user(kp->type, &up->type);
310 __get_user(kp->flags, &up->flags);
311 __get_user(kp->memory, &up->memory);
312 __get_user(kp->input, &up->input);
313 switch(kp->memory) {
314 case V4L2_MEMORY_MMAP:
315 break;
316 case V4L2_MEMORY_USERPTR:
317 {
318 unsigned long tmp = (unsigned long)compat_ptr(up->m.userptr);
319
320 __get_user(kp->length, &up->length);
321 __get_user(kp->m.userptr, &tmp);
322 }
323 break;
324 case V4L2_MEMORY_OVERLAY:
325 __get_user(kp->m.offset, &up->m.offset);
326 break;
327 }
328 return 0;
329}
330
331static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
332{
333 if (put_user(kp->index, &up->index))
334 return -EFAULT;
335 __put_user(kp->type, &up->type);
336 __put_user(kp->flags, &up->flags);
337 __put_user(kp->memory, &up->memory);
338 __put_user(kp->input, &up->input);
339 switch(kp->memory) {
340 case V4L2_MEMORY_MMAP:
341 __put_user(kp->length, &up->length);
342 __put_user(kp->m.offset, &up->m.offset);
343 break;
344 case V4L2_MEMORY_USERPTR:
345 __put_user(kp->length, &up->length);
346 __put_user(kp->m.userptr, &up->m.userptr);
347 break;
348 case V4L2_MEMORY_OVERLAY:
349 __put_user(kp->m.offset, &up->m.offset);
350 break;
351 }
352 __put_user(kp->bytesused, &up->bytesused);
353 __put_user(kp->field, &up->field);
354 __put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec);
355 __put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec);
356 __copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode));
357 __put_user(kp->sequence, &up->sequence);
358 __put_user(kp->reserved, &up->reserved);
359 return 0;
360}
361
362struct v4l2_framebuffer32
363{
364 __u32 capability;
365 __u32 flags;
366 compat_caddr_t base;
367 struct v4l2_pix_format fmt;
368};
369
370static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
371{
372 u32 tmp;
373
374 if (get_user(tmp, &up->base))
375 return -EFAULT;
376 kp->base = compat_ptr(tmp);
377 __get_user(kp->capability, &up->capability);
378 __get_user(kp->flags, &up->flags);
379 get_v4l2_pix_format(&kp->fmt, &up->fmt);
380 return 0;
381}
382
383static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
384{
385 u32 tmp = (u32)((unsigned long)kp->base);
386
387 if(put_user(tmp, &up->base))
388 return -EFAULT;
389 __put_user(kp->capability, &up->capability);
390 __put_user(kp->flags, &up->flags);
391 put_v4l2_pix_format(&kp->fmt, &up->fmt);
392 return 0;
393}
394
395struct v4l2_input32 /* identical layout, but different size */
396{
397 __u32 index; /* Which input */
398 __u8 name[32]; /* Label */
399 __u32 type; /* Type of input */
400 __u32 audioset; /* Associated audios (bitfield) */
401 __u32 tuner; /* Associated tuner */
402 __u32 std[2]; /* __u64 would get the padding wrong */
403 __u32 status;
404 __u32 reserved[4];
405};
406
407#define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32)
408#define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32)
409#define VIDIOCGWIN32 _IOR('v',9, struct video_window32)
410#define VIDIOCSWIN32 _IOW('v',10, struct video_window32)
411#define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32)
412#define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32)
413#define VIDIOCGFREQ32 _IOR('v',14, u32)
414#define VIDIOCSFREQ32 _IOW('v',15, u32)
415
416#define VIDIOC_G_FMT32 _IOWR ('V', 4, struct v4l2_format32)
417#define VIDIOC_S_FMT32 _IOWR ('V', 5, struct v4l2_format32)
418#define VIDIOC_QUERYBUF32 _IOWR ('V', 9, struct v4l2_buffer32)
419#define VIDIOC_G_FBUF32 _IOR ('V', 10, struct v4l2_framebuffer32)
420#define VIDIOC_S_FBUF32 _IOW ('V', 11, struct v4l2_framebuffer32)
421/* VIDIOC_OVERLAY is now _IOW, but was _IOWR */
422#define VIDIOC_OVERLAY32 _IOWR ('V', 14, compat_int_t)
423#define VIDIOC_QBUF32 _IOWR ('V', 15, struct v4l2_buffer32)
424#define VIDIOC_DQBUF32 _IOWR ('V', 17, struct v4l2_buffer32)
425#define VIDIOC_STREAMON32 _IOW ('V', 18, compat_int_t)
426#define VIDIOC_STREAMOFF32 _IOW ('V', 19, compat_int_t)
427#define VIDIOC_ENUMSTD32 _IOWR ('V', 25, struct v4l2_standard32)
428#define VIDIOC_ENUMINPUT32 _IOWR ('V', 26, struct v4l2_input32)
429/* VIDIOC_S_CTRL is now _IOWR, but was _IOW */
430#define VIDIOC_S_CTRL32 _IOW ('V', 28, struct v4l2_control)
431#define VIDIOC_G_INPUT32 _IOR ('V', 38, compat_int_t)
432#define VIDIOC_S_INPUT32 _IOWR ('V', 39, compat_int_t)
433#define VIDIOC_TRY_FMT32 _IOWR ('V', 64, struct v4l2_format32)
434
435enum {
436 MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip)
437};
438
439static int do_set_window(struct file *file, unsigned int cmd, unsigned long arg)
440{
441 struct video_window32 __user *up = compat_ptr(arg);
442 struct video_window __user *vw;
443 struct video_clip __user *p;
444 int nclips;
445 u32 n;
446
447 if (get_user(nclips, &up->clipcount))
448 return -EFAULT;
449
450 /* Peculiar interface... */
451 if (nclips < 0)
452 nclips = VIDEO_CLIPMAP_SIZE;
453
454 if (nclips > MaxClips)
455 return -ENOMEM;
456
457 vw = compat_alloc_user_space(sizeof(struct video_window) +
458 nclips * sizeof(struct video_clip));
459
460 p = nclips ? (struct video_clip __user *)(vw + 1) : NULL;
461
462 if (get_user(n, &up->x) || put_user(n, &vw->x) ||
463 get_user(n, &up->y) || put_user(n, &vw->y) ||
464 get_user(n, &up->width) || put_user(n, &vw->width) ||
465 get_user(n, &up->height) || put_user(n, &vw->height) ||
466 get_user(n, &up->chromakey) || put_user(n, &vw->chromakey) ||
467 get_user(n, &up->flags) || put_user(n, &vw->flags) ||
468 get_user(n, &up->clipcount) || put_user(n, &vw->clipcount) ||
469 get_user(n, &up->clips) || put_user(p, &vw->clips))
470 return -EFAULT;
471
472 if (nclips) {
473 struct video_clip32 __user *u = compat_ptr(n);
474 int i;
475 if (!u)
476 return -EINVAL;
477 for (i = 0; i < nclips; i++, u++, p++) {
478 s32 v;
479 if (get_user(v, &u->x) ||
480 put_user(v, &p->x) ||
481 get_user(v, &u->y) ||
482 put_user(v, &p->y) ||
483 get_user(v, &u->width) ||
484 put_user(v, &p->width) ||
485 get_user(v, &u->height) ||
486 put_user(v, &p->height) ||
487 put_user(NULL, &p->next))
488 return -EFAULT;
489 }
490 }
491
492 return native_ioctl(file, VIDIOCSWIN, (unsigned long)vw);
493}
494
495static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
496{
497 union {
498 struct video_tuner vt;
499 struct video_buffer vb;
500 struct video_window vw;
501 struct v4l2_format v2f;
502 struct v4l2_buffer v2b;
503 struct v4l2_framebuffer v2fb;
504 struct v4l2_standard v2s;
505 unsigned long vx;
506 } karg;
507 void __user *up = compat_ptr(arg);
508 int compatible_arg = 1;
509 int err = 0;
510
511 /* First, convert the command. */
512 switch(cmd) {
513 case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break;
514 case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break;
515 case VIDIOCGWIN32: cmd = VIDIOCGWIN; break;
516 case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break;
517 case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break;
518 case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break;
519 case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break;
520 case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break;
521 case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break;
522 case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break;
523 case VIDIOC_QBUF32: cmd = VIDIOC_QBUF; break;
524 case VIDIOC_DQBUF32: cmd = VIDIOC_DQBUF; break;
525 case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break;
526 case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break;
527 case VIDIOC_G_FBUF32: cmd = VIDIOC_G_FBUF; break;
528 case VIDIOC_S_FBUF32: cmd = VIDIOC_S_FBUF; break;
529 case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break;
530 case VIDIOC_ENUMSTD32: cmd = VIDIOC_ENUMSTD; break;
531 case VIDIOC_ENUMINPUT32: cmd = VIDIOC_ENUMINPUT; break;
532 case VIDIOC_S_CTRL32: cmd = VIDIOC_S_CTRL; break;
533 case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break;
534 case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
535 case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break;
536 };
537
538 switch(cmd) {
539 case VIDIOCSTUNER:
540 case VIDIOCGTUNER:
541 err = get_video_tuner32(&karg.vt, up);
542 compatible_arg = 0;
543
544 break;
545
546 case VIDIOCSFBUF:
547 err = get_video_buffer32(&karg.vb, up);
548 compatible_arg = 0;
549 break;
550
551 case VIDIOCSFREQ:
552 case VIDIOC_S_INPUT:
553 case VIDIOC_OVERLAY:
554 case VIDIOC_STREAMON:
555 case VIDIOC_STREAMOFF:
556 err = get_user(karg.vx, (u32 __user *)up);
557 compatible_arg = 0;
558 break;
559
560 case VIDIOC_S_FBUF:
561 err = get_v4l2_framebuffer32(&karg.v2fb, up);
562 compatible_arg = 0;
563 break;
564
565 case VIDIOC_G_FMT:
566 case VIDIOC_S_FMT:
567 case VIDIOC_TRY_FMT:
568 err = get_v4l2_format32(&karg.v2f, up);
569 compatible_arg = 0;
570 break;
571
572 case VIDIOC_QUERYBUF:
573 case VIDIOC_QBUF:
574 case VIDIOC_DQBUF:
575 err = get_v4l2_buffer32(&karg.v2b, up);
576 compatible_arg = 0;
577 break;
578
579 case VIDIOC_ENUMSTD:
580 err = get_v4l2_standard32(&karg.v2s, up);
581 compatible_arg = 0;
582 break;
583
584 case VIDIOCGWIN:
585 case VIDIOCGFBUF:
586 case VIDIOCGFREQ:
587 case VIDIOC_G_FBUF:
588 case VIDIOC_G_INPUT:
589 compatible_arg = 0;
590 };
591
592 if(err)
593 goto out;
594
595 if(compatible_arg)
596 err = native_ioctl(file, cmd, (unsigned long)up);
597 else {
598 mm_segment_t old_fs = get_fs();
599
600 set_fs(KERNEL_DS);
601 err = native_ioctl(file, cmd, (unsigned long)&karg);
602 set_fs(old_fs);
603 }
604 if(err == 0) {
605 switch(cmd) {
606 case VIDIOCGTUNER:
607 err = put_video_tuner32(&karg.vt, up);
608 break;
609
610 case VIDIOCGWIN:
611 err = put_video_window32(&karg.vw, up);
612 break;
613
614 case VIDIOCGFBUF:
615 err = put_video_buffer32(&karg.vb, up);
616 break;
617
618 case VIDIOC_G_FBUF:
619 err = put_v4l2_framebuffer32(&karg.v2fb, up);
620 break;
621
622 case VIDIOC_G_FMT:
623 case VIDIOC_S_FMT:
624 case VIDIOC_TRY_FMT:
625 err = put_v4l2_format32(&karg.v2f, up);
626 break;
627
628 case VIDIOC_QUERYBUF:
629 case VIDIOC_QBUF:
630 case VIDIOC_DQBUF:
631 err = put_v4l2_buffer32(&karg.v2b, up);
632 break;
633
634 case VIDIOC_ENUMSTD:
635 err = put_v4l2_standard32(&karg.v2s, up);
636 break;
637
638 case VIDIOCGFREQ:
639 case VIDIOC_G_INPUT:
640 err = put_user(((u32)karg.vx), (u32 __user *)up);
641 break;
642 };
643 }
644out:
645 return err;
646}
647
648long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
649{
650 int ret = -ENOIOCTLCMD;
651
652 if (!file->f_op->ioctl)
653 return ret;
654
655 switch (cmd) {
656 case VIDIOCSWIN32:
657 ret = do_set_window(file, cmd, arg);
658 break;
659 case VIDIOCGTUNER32:
660 case VIDIOCSTUNER32:
661 case VIDIOCGWIN32:
662 case VIDIOCGFBUF32:
663 case VIDIOCSFBUF32:
664 case VIDIOCGFREQ32:
665 case VIDIOCSFREQ32:
666 case VIDIOC_QUERYCAP:
667 case VIDIOC_ENUM_FMT:
668 case VIDIOC_G_FMT32:
669 case VIDIOC_S_FMT32:
670 case VIDIOC_REQBUFS:
671 case VIDIOC_QUERYBUF32:
672 case VIDIOC_G_FBUF32:
673 case VIDIOC_S_FBUF32:
674 case VIDIOC_OVERLAY32:
675 case VIDIOC_QBUF32:
676 case VIDIOC_DQBUF32:
677 case VIDIOC_STREAMON32:
678 case VIDIOC_STREAMOFF32:
679 case VIDIOC_G_PARM:
680 case VIDIOC_G_STD:
681 case VIDIOC_S_STD:
682 case VIDIOC_ENUMSTD32:
683 case VIDIOC_ENUMINPUT32:
684 case VIDIOC_G_CTRL:
685 case VIDIOC_S_CTRL32:
686 case VIDIOC_QUERYCTRL:
687 case VIDIOC_G_INPUT32:
688 case VIDIOC_S_INPUT32:
689 case VIDIOC_TRY_FMT32:
690 ret = do_video_ioctl(file, cmd, arg);
691 break;
692
693 /* Little v, the video4linux ioctls (conflict?) */
694 case VIDIOCGCAP:
695 case VIDIOCGCHAN:
696 case VIDIOCSCHAN:
697 case VIDIOCGPICT:
698 case VIDIOCSPICT:
699 case VIDIOCCAPTURE:
700 case VIDIOCKEY:
701 case VIDIOCGAUDIO:
702 case VIDIOCSAUDIO:
703 case VIDIOCSYNC:
704 case VIDIOCMCAPTURE:
705 case VIDIOCGMBUF:
706 case VIDIOCGUNIT:
707 case VIDIOCGCAPTURE:
708 case VIDIOCSCAPTURE:
709
710 /* BTTV specific... */
711 case _IOW('v', BASE_VIDIOCPRIVATE+0, char [256]):
712 case _IOR('v', BASE_VIDIOCPRIVATE+1, char [256]):
713 case _IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int):
714 case _IOW('v' , BASE_VIDIOCPRIVATE+3, char [16]): /* struct bttv_pll_info */
715 case _IOR('v' , BASE_VIDIOCPRIVATE+4, int):
716 case _IOR('v' , BASE_VIDIOCPRIVATE+5, int):
717 case _IOR('v' , BASE_VIDIOCPRIVATE+6, int):
718 case _IOR('v' , BASE_VIDIOCPRIVATE+7, int):
719 ret = native_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
720 break;
721 }
722 return ret;
723}
724#else
725long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
726{
727 return -ENOIOCTLCMD;
728}
729#endif
730EXPORT_SYMBOL_GPL(v4l_compat_ioctl32);
731
732MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index b7ec9bf45085..9f59541155d9 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -3807,6 +3807,7 @@ static struct file_operations cpia_fops = {
3807 .read = cpia_read, 3807 .read = cpia_read,
3808 .mmap = cpia_mmap, 3808 .mmap = cpia_mmap,
3809 .ioctl = cpia_ioctl, 3809 .ioctl = cpia_ioctl,
3810 .compat_ioctl = v4l_compat_ioctl32,
3810 .llseek = no_llseek, 3811 .llseek = no_llseek,
3811}; 3812};
3812 3813
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index 643ead1a87ee..b421068f7ea3 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -27,7 +27,7 @@
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/i2c-id.h> 28#include <linux/i2c-id.h>
29#include <linux/videodev.h> 29#include <linux/videodev.h>
30#include <media/audiochip.h> 30#include <media/v4l2-common.h>
31 31
32MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC"); 32MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
33MODULE_AUTHOR("Martin Vaughan"); 33MODULE_AUTHOR("Martin Vaughan");
@@ -39,21 +39,6 @@ module_param(debug, bool, 0644);
39 39
40MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On"); 40MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On");
41 41
42#define cs53l32a_dbg(fmt, arg...) \
43 do { \
44 if (debug) \
45 printk(KERN_INFO "%s debug %d-%04x: " fmt, \
46 client->driver->driver.name, \
47 i2c_adapter_id(client->adapter), client->addr , ## arg); \
48 } while (0)
49
50#define cs53l32a_err(fmt, arg...) do { \
51 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
52 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
53#define cs53l32a_info(fmt, arg...) do { \
54 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
55 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
56
57static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; 42static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
58 43
59 44
@@ -74,50 +59,59 @@ static int cs53l32a_read(struct i2c_client *client, u8 reg)
74static int cs53l32a_command(struct i2c_client *client, unsigned int cmd, 59static int cs53l32a_command(struct i2c_client *client, unsigned int cmd,
75 void *arg) 60 void *arg)
76{ 61{
77 int *input = arg; 62 struct v4l2_audio *input = arg;
63 struct v4l2_control *ctrl = arg;
78 64
79 switch (cmd) { 65 switch (cmd) {
80 case AUDC_SET_INPUT: 66 case VIDIOC_S_AUDIO:
81 switch (*input) { 67 /* There are 2 physical inputs, but the second input can be
82 case AUDIO_TUNER: 68 placed in two modes, the first mode bypasses the PGA (gain),
83 cs53l32a_write(client, 0x01, 0x01); 69 the second goes through the PGA. Hence there are three
84 break; 70 possible inputs to choose from. */
85 case AUDIO_EXTERN: 71 if (input->index > 2) {
86 cs53l32a_write(client, 0x01, 0x21); 72 v4l_err(client, "Invalid input %d.\n", input->index);
87 break;
88 case AUDIO_MUTE:
89 cs53l32a_write(client, 0x03, 0xF0);
90 break;
91 case AUDIO_UNMUTE:
92 cs53l32a_write(client, 0x03, 0x30);
93 break;
94 default:
95 cs53l32a_err("Invalid input %d.\n", *input);
96 return -EINVAL; 73 return -EINVAL;
97 } 74 }
75 cs53l32a_write(client, 0x01, 0x01 + (input->index << 4));
76 break;
77
78 case VIDIOC_G_AUDIO:
79 memset(input, 0, sizeof(*input));
80 input->index = (cs53l32a_read(client, 0x01) >> 4) & 3;
81 break;
82
83 case VIDIOC_G_CTRL:
84 if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
85 ctrl->value = (cs53l32a_read(client, 0x03) & 0xc0) != 0;
86 break;
87 }
88 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
89 return -EINVAL;
90 ctrl->value = (s8)cs53l32a_read(client, 0x04);
98 break; 91 break;
99 92
100 case VIDIOC_S_CTRL: 93 case VIDIOC_S_CTRL:
101 { 94 if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
102 struct v4l2_control *ctrl = arg; 95 cs53l32a_write(client, 0x03, ctrl->value ? 0xf0 : 0x30);
103
104 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
105 return -EINVAL;
106 if (ctrl->value > 12 || ctrl->value < -90)
107 return -EINVAL;
108 cs53l32a_write(client, 0x04, (u8) ctrl->value);
109 cs53l32a_write(client, 0x05, (u8) ctrl->value);
110 break; 96 break;
111 } 97 }
98 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
99 return -EINVAL;
100 if (ctrl->value > 12 || ctrl->value < -96)
101 return -EINVAL;
102 cs53l32a_write(client, 0x04, (u8) ctrl->value);
103 cs53l32a_write(client, 0x05, (u8) ctrl->value);
104 break;
112 105
113 case VIDIOC_LOG_STATUS: 106 case VIDIOC_LOG_STATUS:
114 { 107 {
115 u8 v = cs53l32a_read(client, 0x01); 108 u8 v = cs53l32a_read(client, 0x01);
116 u8 m = cs53l32a_read(client, 0x03); 109 u8 m = cs53l32a_read(client, 0x03);
110 s8 vol = cs53l32a_read(client, 0x04);
117 111
118 cs53l32a_info("Input: %s%s\n", 112 v4l_info(client, "Input: %d%s\n", (v >> 4) & 3,
119 v == 0x21 ? "external line in" : "tuner",
120 (m & 0xC0) ? " (muted)" : ""); 113 (m & 0xC0) ? " (muted)" : "");
114 v4l_info(client, "Volume: %d dB\n", vol);
121 break; 115 break;
122 } 116 }
123 117
@@ -157,12 +151,12 @@ static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind)
157 client->driver = &i2c_driver; 151 client->driver = &i2c_driver;
158 snprintf(client->name, sizeof(client->name) - 1, "cs53l32a"); 152 snprintf(client->name, sizeof(client->name) - 1, "cs53l32a");
159 153
160 cs53l32a_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name); 154 v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name);
161 155
162 for (i = 1; i <= 7; i++) { 156 for (i = 1; i <= 7; i++) {
163 u8 v = cs53l32a_read(client, i); 157 u8 v = cs53l32a_read(client, i);
164 158
165 cs53l32a_dbg("Read Reg %d %02x\n", i, v); 159 v4l_dbg(1, client, "Read Reg %d %02x\n", i, v);
166 } 160 }
167 161
168 /* Set cs53l32a internal register for Adaptec 2010/2410 setup */ 162 /* Set cs53l32a internal register for Adaptec 2010/2410 setup */
@@ -180,7 +174,7 @@ static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind)
180 for (i = 1; i <= 7; i++) { 174 for (i = 1; i <= 7; i++) {
181 u8 v = cs53l32a_read(client, i); 175 u8 v = cs53l32a_read(client, i);
182 176
183 cs53l32a_dbg("Read Reg %d %02x\n", i, v); 177 v4l_dbg(1, client, "Read Reg %d %02x\n", i, v);
184 } 178 }
185 179
186 i2c_attach_client(client); 180 i2c_attach_client(client);
@@ -190,11 +184,7 @@ static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind)
190 184
191static int cs53l32a_probe(struct i2c_adapter *adapter) 185static int cs53l32a_probe(struct i2c_adapter *adapter)
192{ 186{
193#ifdef I2C_CLASS_TV_ANALOG
194 if (adapter->class & I2C_CLASS_TV_ANALOG) 187 if (adapter->class & I2C_CLASS_TV_ANALOG)
195#else
196 if (adapter->id == I2C_HW_B_BT848)
197#endif
198 return i2c_probe(adapter, &addr_data, cs53l32a_attach); 188 return i2c_probe(adapter, &addr_data, cs53l32a_attach);
199 return 0; 189 return 0;
200} 190}
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index 740908f8027d..cb9a7981e408 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -23,11 +23,13 @@
23 23
24#include "cx25840.h" 24#include "cx25840.h"
25 25
26inline static int set_audclk_freq(struct i2c_client *client, 26static int set_audclk_freq(struct i2c_client *client, u32 freq)
27 enum v4l2_audio_clock_freq freq)
28{ 27{
29 struct cx25840_state *state = i2c_get_clientdata(client); 28 struct cx25840_state *state = i2c_get_clientdata(client);
30 29
30 if (freq != 32000 && freq != 44100 && freq != 48000)
31 return -EINVAL;
32
31 /* assert soft reset */ 33 /* assert soft reset */
32 cx25840_and_or(client, 0x810, ~0x1, 0x01); 34 cx25840_and_or(client, 0x810, ~0x1, 0x01);
33 35
@@ -35,10 +37,9 @@ inline static int set_audclk_freq(struct i2c_client *client,
35 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ 37 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
36 cx25840_write(client, 0x127, 0x50); 38 cx25840_write(client, 0x127, 0x50);
37 39
38 switch (state->audio_input) { 40 if (state->aud_input != CX25840_AUDIO_SERIAL) {
39 case AUDIO_TUNER:
40 switch (freq) { 41 switch (freq) {
41 case V4L2_AUDCLK_32_KHZ: 42 case 32000:
42 /* VID_PLL and AUX_PLL */ 43 /* VID_PLL and AUX_PLL */
43 cx25840_write4(client, 0x108, 0x0f040610); 44 cx25840_write4(client, 0x108, 0x0f040610);
44 45
@@ -51,7 +52,7 @@ inline static int set_audclk_freq(struct i2c_client *client,
51 cx25840_write4(client, 0x90c, 0x7ff70108); 52 cx25840_write4(client, 0x90c, 0x7ff70108);
52 break; 53 break;
53 54
54 case V4L2_AUDCLK_441_KHZ: 55 case 44100:
55 /* VID_PLL and AUX_PLL */ 56 /* VID_PLL and AUX_PLL */
56 cx25840_write4(client, 0x108, 0x0f040910); 57 cx25840_write4(client, 0x108, 0x0f040910);
57 58
@@ -64,7 +65,7 @@ inline static int set_audclk_freq(struct i2c_client *client,
64 cx25840_write4(client, 0x90c, 0x596d0108); 65 cx25840_write4(client, 0x90c, 0x596d0108);
65 break; 66 break;
66 67
67 case V4L2_AUDCLK_48_KHZ: 68 case 48000:
68 /* VID_PLL and AUX_PLL */ 69 /* VID_PLL and AUX_PLL */
69 cx25840_write4(client, 0x108, 0x0f040a10); 70 cx25840_write4(client, 0x108, 0x0f040a10);
70 71
@@ -77,14 +78,9 @@ inline static int set_audclk_freq(struct i2c_client *client,
77 cx25840_write4(client, 0x90c, 0xaa4f0108); 78 cx25840_write4(client, 0x90c, 0xaa4f0108);
78 break; 79 break;
79 } 80 }
80 break; 81 } else {
81
82 case AUDIO_EXTERN_1:
83 case AUDIO_EXTERN_2:
84 case AUDIO_INTERN:
85 case AUDIO_RADIO:
86 switch (freq) { 82 switch (freq) {
87 case V4L2_AUDCLK_32_KHZ: 83 case 32000:
88 /* VID_PLL and AUX_PLL */ 84 /* VID_PLL and AUX_PLL */
89 cx25840_write4(client, 0x108, 0x0f04081e); 85 cx25840_write4(client, 0x108, 0x0f04081e);
90 86
@@ -103,7 +99,7 @@ inline static int set_audclk_freq(struct i2c_client *client,
103 cx25840_write(client, 0x127, 0x54); 99 cx25840_write(client, 0x127, 0x54);
104 break; 100 break;
105 101
106 case V4L2_AUDCLK_441_KHZ: 102 case 44100:
107 /* VID_PLL and AUX_PLL */ 103 /* VID_PLL and AUX_PLL */
108 cx25840_write4(client, 0x108, 0x0f040918); 104 cx25840_write4(client, 0x108, 0x0f040918);
109 105
@@ -119,7 +115,7 @@ inline static int set_audclk_freq(struct i2c_client *client,
119 cx25840_write4(client, 0x90c, 0x85730108); 115 cx25840_write4(client, 0x90c, 0x85730108);
120 break; 116 break;
121 117
122 case V4L2_AUDCLK_48_KHZ: 118 case 48000:
123 /* VID_PLL and AUX_PLL */ 119 /* VID_PLL and AUX_PLL */
124 cx25840_write4(client, 0x108, 0x0f040a18); 120 cx25840_write4(client, 0x108, 0x0f040a18);
125 121
@@ -135,7 +131,6 @@ inline static int set_audclk_freq(struct i2c_client *client,
135 cx25840_write4(client, 0x90c, 0x55550108); 131 cx25840_write4(client, 0x90c, 0x55550108);
136 break; 132 break;
137 } 133 }
138 break;
139 } 134 }
140 135
141 /* deassert soft reset */ 136 /* deassert soft reset */
@@ -146,51 +141,36 @@ inline static int set_audclk_freq(struct i2c_client *client,
146 return 0; 141 return 0;
147} 142}
148 143
149static int set_input(struct i2c_client *client, int audio_input) 144void cx25840_audio_set_path(struct i2c_client *client)
150{ 145{
151 struct cx25840_state *state = i2c_get_clientdata(client); 146 struct cx25840_state *state = i2c_get_clientdata(client);
152 147
153 cx25840_dbg("set audio input (%d)\n", audio_input);
154
155 /* stop microcontroller */ 148 /* stop microcontroller */
156 cx25840_and_or(client, 0x803, ~0x10, 0); 149 cx25840_and_or(client, 0x803, ~0x10, 0);
157 150
158 /* Mute everything to prevent the PFFT! */ 151 /* Mute everything to prevent the PFFT! */
159 cx25840_write(client, 0x8d3, 0x1f); 152 cx25840_write(client, 0x8d3, 0x1f);
160 153
161 switch (audio_input) { 154 if (state->aud_input == CX25840_AUDIO_SERIAL) {
162 case AUDIO_TUNER:
163 /* Set Path1 to Analog Demod Main Channel */
164 cx25840_write4(client, 0x8d0, 0x7038061f);
165
166 /* When the microcontroller detects the
167 * audio format, it will unmute the lines */
168 cx25840_and_or(client, 0x803, ~0x10, 0x10);
169 break;
170
171 case AUDIO_EXTERN_1:
172 case AUDIO_EXTERN_2:
173 case AUDIO_INTERN:
174 case AUDIO_RADIO:
175 /* Set Path1 to Serial Audio Input */ 155 /* Set Path1 to Serial Audio Input */
176 cx25840_write4(client, 0x8d0, 0x12100101); 156 cx25840_write4(client, 0x8d0, 0x12100101);
177 157
178 /* The microcontroller should not be started for the 158 /* The microcontroller should not be started for the
179 * non-tuner inputs: autodetection is specific for 159 * non-tuner inputs: autodetection is specific for
180 * TV audio. */ 160 * TV audio. */
181 break; 161 } else {
162 /* Set Path1 to Analog Demod Main Channel */
163 cx25840_write4(client, 0x8d0, 0x7038061f);
182 164
183 default: 165 /* When the microcontroller detects the
184 cx25840_dbg("Invalid audio input selection %d\n", audio_input); 166 * audio format, it will unmute the lines */
185 return -EINVAL; 167 cx25840_and_or(client, 0x803, ~0x10, 0x10);
186 } 168 }
187 169
188 state->audio_input = audio_input; 170 set_audclk_freq(client, state->audclk_freq);
189
190 return set_audclk_freq(client, state->audclk_freq);
191} 171}
192 172
193inline static int get_volume(struct i2c_client *client) 173static int get_volume(struct i2c_client *client)
194{ 174{
195 /* Volume runs +18dB to -96dB in 1/2dB steps 175 /* Volume runs +18dB to -96dB in 1/2dB steps
196 * change to fit the msp3400 -114dB to +12dB range */ 176 * change to fit the msp3400 -114dB to +12dB range */
@@ -201,7 +181,7 @@ inline static int get_volume(struct i2c_client *client)
201 return vol << 9; 181 return vol << 9;
202} 182}
203 183
204inline static void set_volume(struct i2c_client *client, int volume) 184static void set_volume(struct i2c_client *client, int volume)
205{ 185{
206 /* First convert the volume to msp3400 values (0-127) */ 186 /* First convert the volume to msp3400 values (0-127) */
207 int vol = volume >> 9; 187 int vol = volume >> 9;
@@ -218,7 +198,7 @@ inline static void set_volume(struct i2c_client *client, int volume)
218 cx25840_write(client, 0x8d4, 228 - (vol * 2)); 198 cx25840_write(client, 0x8d4, 228 - (vol * 2));
219} 199}
220 200
221inline static int get_bass(struct i2c_client *client) 201static int get_bass(struct i2c_client *client)
222{ 202{
223 /* bass is 49 steps +12dB to -12dB */ 203 /* bass is 49 steps +12dB to -12dB */
224 204
@@ -228,13 +208,13 @@ inline static int get_bass(struct i2c_client *client)
228 return bass; 208 return bass;
229} 209}
230 210
231inline static void set_bass(struct i2c_client *client, int bass) 211static void set_bass(struct i2c_client *client, int bass)
232{ 212{
233 /* PATH1_EQ_BASS_VOL */ 213 /* PATH1_EQ_BASS_VOL */
234 cx25840_and_or(client, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff)); 214 cx25840_and_or(client, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
235} 215}
236 216
237inline static int get_treble(struct i2c_client *client) 217static int get_treble(struct i2c_client *client)
238{ 218{
239 /* treble is 49 steps +12dB to -12dB */ 219 /* treble is 49 steps +12dB to -12dB */
240 220
@@ -244,13 +224,13 @@ inline static int get_treble(struct i2c_client *client)
244 return treble; 224 return treble;
245} 225}
246 226
247inline static void set_treble(struct i2c_client *client, int treble) 227static void set_treble(struct i2c_client *client, int treble)
248{ 228{
249 /* PATH1_EQ_TREBLE_VOL */ 229 /* PATH1_EQ_TREBLE_VOL */
250 cx25840_and_or(client, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff)); 230 cx25840_and_or(client, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
251} 231}
252 232
253inline static int get_balance(struct i2c_client *client) 233static int get_balance(struct i2c_client *client)
254{ 234{
255 /* balance is 7 bit, 0 to -96dB */ 235 /* balance is 7 bit, 0 to -96dB */
256 236
@@ -264,7 +244,7 @@ inline static int get_balance(struct i2c_client *client)
264 return balance << 8; 244 return balance << 8;
265} 245}
266 246
267inline static void set_balance(struct i2c_client *client, int balance) 247static void set_balance(struct i2c_client *client, int balance)
268{ 248{
269 int bal = balance >> 8; 249 int bal = balance >> 8;
270 if (bal > 0x80) { 250 if (bal > 0x80) {
@@ -280,17 +260,17 @@ inline static void set_balance(struct i2c_client *client, int balance)
280 } 260 }
281} 261}
282 262
283inline static int get_mute(struct i2c_client *client) 263static int get_mute(struct i2c_client *client)
284{ 264{
285 /* check SRC1_MUTE_EN */ 265 /* check SRC1_MUTE_EN */
286 return cx25840_read(client, 0x8d3) & 0x2 ? 1 : 0; 266 return cx25840_read(client, 0x8d3) & 0x2 ? 1 : 0;
287} 267}
288 268
289inline static void set_mute(struct i2c_client *client, int mute) 269static void set_mute(struct i2c_client *client, int mute)
290{ 270{
291 struct cx25840_state *state = i2c_get_clientdata(client); 271 struct cx25840_state *state = i2c_get_clientdata(client);
292 272
293 if (state->audio_input == AUDIO_TUNER) { 273 if (state->aud_input != CX25840_AUDIO_SERIAL) {
294 /* Must turn off microcontroller in order to mute sound. 274 /* Must turn off microcontroller in order to mute sound.
295 * Not sure if this is the best method, but it does work. 275 * Not sure if this is the best method, but it does work.
296 * If the microcontroller is running, then it will undo any 276 * If the microcontroller is running, then it will undo any
@@ -314,10 +294,9 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
314 struct v4l2_control *ctrl = arg; 294 struct v4l2_control *ctrl = arg;
315 295
316 switch (cmd) { 296 switch (cmd) {
317 case AUDC_SET_INPUT:
318 return set_input(client, *(int *)arg);
319 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 297 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
320 return set_audclk_freq(client, *(enum v4l2_audio_clock_freq *)arg); 298 return set_audclk_freq(client, *(u32 *)arg);
299
321 case VIDIOC_G_CTRL: 300 case VIDIOC_G_CTRL:
322 switch (ctrl->id) { 301 switch (ctrl->id) {
323 case V4L2_CID_AUDIO_VOLUME: 302 case V4L2_CID_AUDIO_VOLUME:
@@ -339,6 +318,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
339 return -EINVAL; 318 return -EINVAL;
340 } 319 }
341 break; 320 break;
321
342 case VIDIOC_S_CTRL: 322 case VIDIOC_S_CTRL:
343 switch (ctrl->id) { 323 switch (ctrl->id) {
344 case V4L2_CID_AUDIO_VOLUME: 324 case V4L2_CID_AUDIO_VOLUME:
@@ -360,6 +340,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
360 return -EINVAL; 340 return -EINVAL;
361 } 341 }
362 break; 342 break;
343
363 default: 344 default:
364 return -EINVAL; 345 return -EINVAL;
365 } 346 }
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 3b09f46dddf6..d45237d508c4 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -43,11 +43,11 @@ MODULE_LICENSE("GPL");
43static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; 43static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
44 44
45 45
46int cx25840_debug = 0; 46int debug = 0;
47 47
48module_param(cx25840_debug, bool, 0644); 48module_param(debug, bool, 0644);
49 49
50MODULE_PARM_DESC(cx25840_debug, "Debugging messages [0=Off (default) 1=On]"); 50MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]");
51 51
52I2C_CLIENT_INSMOD; 52I2C_CLIENT_INSMOD;
53 53
@@ -115,13 +115,13 @@ int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask,
115 115
116/* ----------------------------------------------------------------------- */ 116/* ----------------------------------------------------------------------- */
117 117
118static int set_input(struct i2c_client *, enum cx25840_input); 118static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
119static void input_change(struct i2c_client *); 119 enum cx25840_audio_input aud_input);
120static void log_status(struct i2c_client *client); 120static void log_status(struct i2c_client *client);
121 121
122/* ----------------------------------------------------------------------- */ 122/* ----------------------------------------------------------------------- */
123 123
124static inline void init_dll1(struct i2c_client *client) 124static void init_dll1(struct i2c_client *client)
125{ 125{
126 /* This is the Hauppauge sequence used to 126 /* This is the Hauppauge sequence used to
127 * initialize the Delay Lock Loop 1 (ADC DLL). */ 127 * initialize the Delay Lock Loop 1 (ADC DLL). */
@@ -135,7 +135,7 @@ static inline void init_dll1(struct i2c_client *client)
135 cx25840_write(client, 0x15b, 0x10); 135 cx25840_write(client, 0x15b, 0x10);
136} 136}
137 137
138static inline void init_dll2(struct i2c_client *client) 138static void init_dll2(struct i2c_client *client)
139{ 139{
140 /* This is the Hauppauge sequence used to 140 /* This is the Hauppauge sequence used to
141 * initialize the Delay Lock Loop 2 (ADC DLL). */ 141 * initialize the Delay Lock Loop 2 (ADC DLL). */
@@ -195,10 +195,8 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw)
195 /* AC97 shift */ 195 /* AC97 shift */
196 cx25840_write(client, 0x8cf, 0x0f); 196 cx25840_write(client, 0x8cf, 0x0f);
197 197
198 /* (re)set video input */ 198 /* (re)set input */
199 set_input(client, state->input); 199 set_input(client, state->vid_input, state->aud_input);
200 /* (re)set audio input */
201 cx25840_audio(client, AUDC_SET_INPUT, &state->audio_input);
202 200
203 /* start microcontroller */ 201 /* start microcontroller */
204 cx25840_and_or(client, 0x803, ~0x10, 0x10); 202 cx25840_and_or(client, 0x803, ~0x10, 0x10);
@@ -223,7 +221,7 @@ static void input_change(struct i2c_client *client)
223 cx25840_write(client, 0x80b, 0x10); 221 cx25840_write(client, 0x80b, 0x10);
224 } else if (std & V4L2_STD_NTSC) { 222 } else if (std & V4L2_STD_NTSC) {
225 /* NTSC */ 223 /* NTSC */
226 if (state->cardtype == CARDTYPE_PVR150_WORKAROUND) { 224 if (state->pvr150_workaround) {
227 /* Certain Hauppauge PVR150 models have a hardware bug 225 /* Certain Hauppauge PVR150 models have a hardware bug
228 that causes audio to drop out. For these models the 226 that causes audio to drop out. For these models the
229 audio standard must be set explicitly. 227 audio standard must be set explicitly.
@@ -259,72 +257,68 @@ static void input_change(struct i2c_client *client)
259 } 257 }
260} 258}
261 259
262static int set_input(struct i2c_client *client, enum cx25840_input input) 260static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
261 enum cx25840_audio_input aud_input)
263{ 262{
264 struct cx25840_state *state = i2c_get_clientdata(client); 263 struct cx25840_state *state = i2c_get_clientdata(client);
264 u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&
265 vid_input <= CX25840_COMPOSITE8);
266 u8 reg;
265 267
266 cx25840_dbg("decoder set input (%d)\n", input); 268 v4l_dbg(1, client, "decoder set video input %d, audio input %d\n",
269 vid_input, aud_input);
267 270
268 switch (input) { 271 if (is_composite) {
269 case CX25840_TUNER: 272 reg = 0xf0 + (vid_input - CX25840_COMPOSITE1);
270 cx25840_dbg("now setting Tuner input\n"); 273 } else {
271 274 int luma = vid_input & 0xf0;
272 if (state->cardtype == CARDTYPE_PVR150 || 275 int chroma = vid_input & 0xf00;
273 state->cardtype == CARDTYPE_PVR150_WORKAROUND) {
274 /* CH_SEL_ADC2=1 */
275 cx25840_and_or(client, 0x102, ~0x2, 0x02);
276 }
277
278 /* Video Input Control */
279 if (state->cardtype == CARDTYPE_PG600) {
280 cx25840_write(client, 0x103, 0x11);
281 } else {
282 cx25840_write(client, 0x103, 0x46);
283 }
284
285 /* INPUT_MODE=0 */
286 cx25840_and_or(client, 0x401, ~0x6, 0x00);
287 break;
288
289 case CX25840_COMPOSITE0:
290 case CX25840_COMPOSITE1:
291 cx25840_dbg("now setting Composite input\n");
292 276
293 /* Video Input Control */ 277 if ((vid_input & ~0xff0) ||
294 if (state->cardtype == CARDTYPE_PG600) { 278 luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA4 ||
295 cx25840_write(client, 0x103, 0x00); 279 chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
296 } else { 280 v4l_err(client, "0x%04x is not a valid video input!\n", vid_input);
297 cx25840_write(client, 0x103, 0x02); 281 return -EINVAL;
298 } 282 }
299 283 reg = 0xf0 + ((luma - CX25840_SVIDEO_LUMA1) >> 4);
300 /* INPUT_MODE=0 */ 284 if (chroma >= CX25840_SVIDEO_CHROMA7) {
301 cx25840_and_or(client, 0x401, ~0x6, 0x00); 285 reg &= 0x3f;
302 break; 286 reg |= (chroma - CX25840_SVIDEO_CHROMA7) >> 2;
303
304 case CX25840_SVIDEO0:
305 case CX25840_SVIDEO1:
306 cx25840_dbg("now setting S-Video input\n");
307
308 /* CH_SEL_ADC2=0 */
309 cx25840_and_or(client, 0x102, ~0x2, 0x00);
310
311 /* Video Input Control */
312 if (state->cardtype == CARDTYPE_PG600) {
313 cx25840_write(client, 0x103, 0x02);
314 } else { 287 } else {
315 cx25840_write(client, 0x103, 0x10); 288 reg &= 0xcf;
289 reg |= (chroma - CX25840_SVIDEO_CHROMA4) >> 4;
316 } 290 }
291 }
317 292
318 /* INPUT_MODE=1 */ 293 switch (aud_input) {
319 cx25840_and_or(client, 0x401, ~0x6, 0x02); 294 case CX25840_AUDIO_SERIAL:
295 /* do nothing, use serial audio input */
320 break; 296 break;
297 case CX25840_AUDIO4: reg &= ~0x30; break;
298 case CX25840_AUDIO5: reg &= ~0x30; reg |= 0x10; break;
299 case CX25840_AUDIO6: reg &= ~0x30; reg |= 0x20; break;
300 case CX25840_AUDIO7: reg &= ~0xc0; break;
301 case CX25840_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
321 302
322 default: 303 default:
323 cx25840_err("%d is not a valid input!\n", input); 304 v4l_err(client, "0x%04x is not a valid audio input!\n", aud_input);
324 return -EINVAL; 305 return -EINVAL;
325 } 306 }
326 307
327 state->input = input; 308 cx25840_write(client, 0x103, reg);
309 /* Set INPUT_MODE to Composite (0) or S-Video (1) */
310 cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
311 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
312 cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
313 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
314 if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
315 cx25840_and_or(client, 0x102, ~0x4, 4);
316 else
317 cx25840_and_or(client, 0x102, ~0x4, 0);
318
319 state->vid_input = vid_input;
320 state->aud_input = aud_input;
321 cx25840_audio_set_path(client);
328 input_change(client); 322 input_change(client);
329 return 0; 323 return 0;
330} 324}
@@ -395,23 +389,14 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
395 struct cx25840_state *state = i2c_get_clientdata(client); 389 struct cx25840_state *state = i2c_get_clientdata(client);
396 390
397 switch (ctrl->id) { 391 switch (ctrl->id) {
398 case CX25840_CID_CARDTYPE: 392 case CX25840_CID_ENABLE_PVR150_WORKAROUND:
399 switch (ctrl->value) { 393 state->pvr150_workaround = ctrl->value;
400 case CARDTYPE_PVR150: 394 set_input(client, state->vid_input, state->aud_input);
401 case CARDTYPE_PVR150_WORKAROUND:
402 case CARDTYPE_PG600:
403 state->cardtype = ctrl->value;
404 break;
405 default:
406 return -ERANGE;
407 }
408
409 set_input(client, state->input);
410 break; 395 break;
411 396
412 case V4L2_CID_BRIGHTNESS: 397 case V4L2_CID_BRIGHTNESS:
413 if (ctrl->value < 0 || ctrl->value > 255) { 398 if (ctrl->value < 0 || ctrl->value > 255) {
414 cx25840_err("invalid brightness setting %d\n", 399 v4l_err(client, "invalid brightness setting %d\n",
415 ctrl->value); 400 ctrl->value);
416 return -ERANGE; 401 return -ERANGE;
417 } 402 }
@@ -421,7 +406,7 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
421 406
422 case V4L2_CID_CONTRAST: 407 case V4L2_CID_CONTRAST:
423 if (ctrl->value < 0 || ctrl->value > 127) { 408 if (ctrl->value < 0 || ctrl->value > 127) {
424 cx25840_err("invalid contrast setting %d\n", 409 v4l_err(client, "invalid contrast setting %d\n",
425 ctrl->value); 410 ctrl->value);
426 return -ERANGE; 411 return -ERANGE;
427 } 412 }
@@ -431,7 +416,7 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
431 416
432 case V4L2_CID_SATURATION: 417 case V4L2_CID_SATURATION:
433 if (ctrl->value < 0 || ctrl->value > 127) { 418 if (ctrl->value < 0 || ctrl->value > 127) {
434 cx25840_err("invalid saturation setting %d\n", 419 v4l_err(client, "invalid saturation setting %d\n",
435 ctrl->value); 420 ctrl->value);
436 return -ERANGE; 421 return -ERANGE;
437 } 422 }
@@ -442,7 +427,7 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
442 427
443 case V4L2_CID_HUE: 428 case V4L2_CID_HUE:
444 if (ctrl->value < -127 || ctrl->value > 127) { 429 if (ctrl->value < -127 || ctrl->value > 127) {
445 cx25840_err("invalid hue setting %d\n", ctrl->value); 430 v4l_err(client, "invalid hue setting %d\n", ctrl->value);
446 return -ERANGE; 431 return -ERANGE;
447 } 432 }
448 433
@@ -455,6 +440,9 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
455 case V4L2_CID_AUDIO_BALANCE: 440 case V4L2_CID_AUDIO_BALANCE:
456 case V4L2_CID_AUDIO_MUTE: 441 case V4L2_CID_AUDIO_MUTE:
457 return cx25840_audio(client, VIDIOC_S_CTRL, ctrl); 442 return cx25840_audio(client, VIDIOC_S_CTRL, ctrl);
443
444 default:
445 return -EINVAL;
458 } 446 }
459 447
460 return 0; 448 return 0;
@@ -465,11 +453,11 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
465 struct cx25840_state *state = i2c_get_clientdata(client); 453 struct cx25840_state *state = i2c_get_clientdata(client);
466 454
467 switch (ctrl->id) { 455 switch (ctrl->id) {
468 case CX25840_CID_CARDTYPE: 456 case CX25840_CID_ENABLE_PVR150_WORKAROUND:
469 ctrl->value = state->cardtype; 457 ctrl->value = state->pvr150_workaround;
470 break; 458 break;
471 case V4L2_CID_BRIGHTNESS: 459 case V4L2_CID_BRIGHTNESS:
472 ctrl->value = cx25840_read(client, 0x414) + 128; 460 ctrl->value = (s8)cx25840_read(client, 0x414) + 128;
473 break; 461 break;
474 case V4L2_CID_CONTRAST: 462 case V4L2_CID_CONTRAST:
475 ctrl->value = cx25840_read(client, 0x415) >> 1; 463 ctrl->value = cx25840_read(client, 0x415) >> 1;
@@ -478,7 +466,7 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
478 ctrl->value = cx25840_read(client, 0x420) >> 1; 466 ctrl->value = cx25840_read(client, 0x420) >> 1;
479 break; 467 break;
480 case V4L2_CID_HUE: 468 case V4L2_CID_HUE:
481 ctrl->value = cx25840_read(client, 0x422); 469 ctrl->value = (s8)cx25840_read(client, 0x422);
482 break; 470 break;
483 case V4L2_CID_AUDIO_VOLUME: 471 case V4L2_CID_AUDIO_VOLUME:
484 case V4L2_CID_AUDIO_BASS: 472 case V4L2_CID_AUDIO_BASS:
@@ -527,7 +515,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
527 515
528 if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || 516 if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
529 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { 517 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
530 cx25840_err("%dx%d is not a valid size!\n", 518 v4l_err(client, "%dx%d is not a valid size!\n",
531 pix->width, pix->height); 519 pix->width, pix->height);
532 return -ERANGE; 520 return -ERANGE;
533 } 521 }
@@ -545,7 +533,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
545 else 533 else
546 filter = 3; 534 filter = 3;
547 535
548 cx25840_dbg("decoder set size %dx%d -> scale %ux%u\n", 536 v4l_dbg(1, client, "decoder set size %dx%d -> scale %ux%u\n",
549 pix->width, pix->height, HSC, VSC); 537 pix->width, pix->height, HSC, VSC);
550 538
551 /* HSCALE=HSC */ 539 /* HSCALE=HSC */
@@ -574,17 +562,98 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
574 562
575/* ----------------------------------------------------------------------- */ 563/* ----------------------------------------------------------------------- */
576 564
565static struct v4l2_queryctrl cx25840_qctrl[] = {
566 {
567 .id = V4L2_CID_BRIGHTNESS,
568 .type = V4L2_CTRL_TYPE_INTEGER,
569 .name = "Brightness",
570 .minimum = 0,
571 .maximum = 255,
572 .step = 1,
573 .default_value = 128,
574 .flags = 0,
575 }, {
576 .id = V4L2_CID_CONTRAST,
577 .type = V4L2_CTRL_TYPE_INTEGER,
578 .name = "Contrast",
579 .minimum = 0,
580 .maximum = 255,
581 .step = 1,
582 .default_value = 64,
583 .flags = 0,
584 }, {
585 .id = V4L2_CID_SATURATION,
586 .type = V4L2_CTRL_TYPE_INTEGER,
587 .name = "Saturation",
588 .minimum = 0,
589 .maximum = 255,
590 .step = 1,
591 .default_value = 64,
592 .flags = 0,
593 }, {
594 .id = V4L2_CID_HUE,
595 .type = V4L2_CTRL_TYPE_INTEGER,
596 .name = "Hue",
597 .minimum = -128,
598 .maximum = 127,
599 .step = 1,
600 .default_value = 0,
601 .flags = 0,
602 }, {
603 .id = V4L2_CID_AUDIO_VOLUME,
604 .type = V4L2_CTRL_TYPE_INTEGER,
605 .name = "Volume",
606 .minimum = 0,
607 .maximum = 65535,
608 .step = 65535/100,
609 .default_value = 58880,
610 .flags = 0,
611 }, {
612 .id = V4L2_CID_AUDIO_BALANCE,
613 .type = V4L2_CTRL_TYPE_INTEGER,
614 .name = "Balance",
615 .minimum = 0,
616 .maximum = 65535,
617 .step = 65535/100,
618 .default_value = 32768,
619 .flags = 0,
620 }, {
621 .id = V4L2_CID_AUDIO_MUTE,
622 .type = V4L2_CTRL_TYPE_BOOLEAN,
623 .name = "Mute",
624 .minimum = 0,
625 .maximum = 1,
626 .step = 1,
627 .default_value = 1,
628 .flags = 0,
629 }, {
630 .id = V4L2_CID_AUDIO_BASS,
631 .type = V4L2_CTRL_TYPE_INTEGER,
632 .name = "Bass",
633 .minimum = 0,
634 .maximum = 65535,
635 .step = 65535/100,
636 .default_value = 32768,
637 }, {
638 .id = V4L2_CID_AUDIO_TREBLE,
639 .type = V4L2_CTRL_TYPE_INTEGER,
640 .name = "Treble",
641 .minimum = 0,
642 .maximum = 65535,
643 .step = 65535/100,
644 .default_value = 32768,
645 },
646};
647
648/* ----------------------------------------------------------------------- */
649
577static int cx25840_command(struct i2c_client *client, unsigned int cmd, 650static int cx25840_command(struct i2c_client *client, unsigned int cmd,
578 void *arg) 651 void *arg)
579{ 652{
580 struct cx25840_state *state = i2c_get_clientdata(client); 653 struct cx25840_state *state = i2c_get_clientdata(client);
581 struct v4l2_tuner *vt = arg; 654 struct v4l2_tuner *vt = arg;
582 int result = 0;
583 655
584 switch (cmd) { 656 switch (cmd) {
585 case 0:
586 break;
587
588#ifdef CONFIG_VIDEO_ADV_DEBUG 657#ifdef CONFIG_VIDEO_ADV_DEBUG
589 /* ioctls to allow direct access to the 658 /* ioctls to allow direct access to the
590 * cx25840 registers for testing */ 659 * cx25840 registers for testing */
@@ -615,18 +684,16 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
615 return cx25840_vbi(client, cmd, arg); 684 return cx25840_vbi(client, cmd, arg);
616 685
617 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 686 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
618 case AUDC_SET_INPUT: 687 return cx25840_audio(client, cmd, arg);
619 result = cx25840_audio(client, cmd, arg);
620 break;
621 688
622 case VIDIOC_STREAMON: 689 case VIDIOC_STREAMON:
623 cx25840_dbg("enable output\n"); 690 v4l_dbg(1, client, "enable output\n");
624 cx25840_write(client, 0x115, 0x8c); 691 cx25840_write(client, 0x115, 0x8c);
625 cx25840_write(client, 0x116, 0x07); 692 cx25840_write(client, 0x116, 0x07);
626 break; 693 break;
627 694
628 case VIDIOC_STREAMOFF: 695 case VIDIOC_STREAMOFF:
629 cx25840_dbg("disable output\n"); 696 v4l_dbg(1, client, "disable output\n");
630 cx25840_write(client, 0x115, 0x00); 697 cx25840_write(client, 0x115, 0x00);
631 cx25840_write(client, 0x116, 0x00); 698 cx25840_write(client, 0x116, 0x00);
632 break; 699 break;
@@ -636,28 +703,58 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
636 break; 703 break;
637 704
638 case VIDIOC_G_CTRL: 705 case VIDIOC_G_CTRL:
639 result = get_v4lctrl(client, (struct v4l2_control *)arg); 706 return get_v4lctrl(client, (struct v4l2_control *)arg);
640 break;
641 707
642 case VIDIOC_S_CTRL: 708 case VIDIOC_S_CTRL:
643 result = set_v4lctrl(client, (struct v4l2_control *)arg); 709 return set_v4lctrl(client, (struct v4l2_control *)arg);
644 break; 710
711 case VIDIOC_QUERYCTRL:
712 {
713 struct v4l2_queryctrl *qc = arg;
714 int i;
715
716 for (i = 0; i < ARRAY_SIZE(cx25840_qctrl); i++)
717 if (qc->id && qc->id == cx25840_qctrl[i].id) {
718 memcpy(qc, &cx25840_qctrl[i], sizeof(*qc));
719 return 0;
720 }
721 return -EINVAL;
722 }
645 723
646 case VIDIOC_G_STD: 724 case VIDIOC_G_STD:
647 *(v4l2_std_id *)arg = cx25840_get_v4lstd(client); 725 *(v4l2_std_id *)arg = cx25840_get_v4lstd(client);
648 break; 726 break;
649 727
650 case VIDIOC_S_STD: 728 case VIDIOC_S_STD:
651 result = set_v4lstd(client, *(v4l2_std_id *)arg); 729 state->radio = 0;
730 return set_v4lstd(client, *(v4l2_std_id *)arg);
731
732 case AUDC_SET_RADIO:
733 state->radio = 1;
652 break; 734 break;
653 735
654 case VIDIOC_G_INPUT: 736 case VIDIOC_G_INPUT:
655 *(int *)arg = state->input; 737 *(int *)arg = state->vid_input;
656 break; 738 break;
657 739
658 case VIDIOC_S_INPUT: 740 case VIDIOC_S_INPUT:
659 result = set_input(client, *(int *)arg); 741 return set_input(client, *(enum cx25840_video_input *)arg, state->aud_input);
742
743 case VIDIOC_S_AUDIO:
744 {
745 struct v4l2_audio *input = arg;
746
747 return set_input(client, state->vid_input, input->index);
748 }
749
750 case VIDIOC_G_AUDIO:
751 {
752 struct v4l2_audio *input = arg;
753
754 memset(input, 0, sizeof(*input));
755 input->index = state->aud_input;
660 break; 756 break;
757 }
661 758
662 case VIDIOC_S_FREQUENCY: 759 case VIDIOC_S_FREQUENCY:
663 input_change(client); 760 input_change(client);
@@ -670,6 +767,9 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
670 u8 vpres = cx25840_read(client, 0x80a) & 0x10; 767 u8 vpres = cx25840_read(client, 0x80a) & 0x10;
671 int val = 0; 768 int val = 0;
672 769
770 if (state->radio)
771 break;
772
673 vt->capability |= 773 vt->capability |=
674 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | 774 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
675 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; 775 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
@@ -724,12 +824,10 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
724 break; 824 break;
725 825
726 case VIDIOC_G_FMT: 826 case VIDIOC_G_FMT:
727 result = get_v4lfmt(client, (struct v4l2_format *)arg); 827 return get_v4lfmt(client, (struct v4l2_format *)arg);
728 break;
729 828
730 case VIDIOC_S_FMT: 829 case VIDIOC_S_FMT:
731 result = set_v4lfmt(client, (struct v4l2_format *)arg); 830 return set_v4lfmt(client, (struct v4l2_format *)arg);
732 break;
733 831
734 case VIDIOC_INT_RESET: 832 case VIDIOC_INT_RESET:
735 cx25840_initialize(client, 0); 833 cx25840_initialize(client, 0);
@@ -741,11 +839,10 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
741 break; 839 break;
742 840
743 default: 841 default:
744 cx25840_err("invalid ioctl %x\n", cmd);
745 return -EINVAL; 842 return -EINVAL;
746 } 843 }
747 844
748 return result; 845 return 0;
749} 846}
750 847
751/* ----------------------------------------------------------------------- */ 848/* ----------------------------------------------------------------------- */
@@ -775,7 +872,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
775 client->driver = &i2c_driver_cx25840; 872 client->driver = &i2c_driver_cx25840;
776 snprintf(client->name, sizeof(client->name) - 1, "cx25840"); 873 snprintf(client->name, sizeof(client->name) - 1, "cx25840");
777 874
778 cx25840_dbg("detecting cx25840 client on address 0x%x\n", address << 1); 875 v4l_dbg(1, client, "detecting cx25840 client on address 0x%x\n", address << 1);
779 876
780 device_id = cx25840_read(client, 0x101) << 8; 877 device_id = cx25840_read(client, 0x101) << 8;
781 device_id |= cx25840_read(client, 0x100); 878 device_id |= cx25840_read(client, 0x100);
@@ -783,12 +880,12 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
783 /* The high byte of the device ID should be 880 /* The high byte of the device ID should be
784 * 0x84 if chip is present */ 881 * 0x84 if chip is present */
785 if ((device_id & 0xff00) != 0x8400) { 882 if ((device_id & 0xff00) != 0x8400) {
786 cx25840_dbg("cx25840 not found\n"); 883 v4l_dbg(1, client, "cx25840 not found\n");
787 kfree(client); 884 kfree(client);
788 return 0; 885 return 0;
789 } 886 }
790 887
791 cx25840_info("cx25%3x-2%x found @ 0x%x (%s)\n", 888 v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
792 (device_id & 0xfff0) >> 4, 889 (device_id & 0xfff0) >> 4,
793 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3, 890 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3,
794 address << 1, adapter->name); 891 address << 1, adapter->name);
@@ -801,10 +898,10 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
801 898
802 i2c_set_clientdata(client, state); 899 i2c_set_clientdata(client, state);
803 memset(state, 0, sizeof(struct cx25840_state)); 900 memset(state, 0, sizeof(struct cx25840_state));
804 state->input = CX25840_TUNER; 901 state->vid_input = CX25840_COMPOSITE7;
805 state->audclk_freq = V4L2_AUDCLK_48_KHZ; 902 state->aud_input = CX25840_AUDIO8;
806 state->audio_input = AUDIO_TUNER; 903 state->audclk_freq = 48000;
807 state->cardtype = CARDTYPE_PVR150; 904 state->pvr150_workaround = 0;
808 905
809 cx25840_initialize(client, 1); 906 cx25840_initialize(client, 1);
810 907
@@ -815,11 +912,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
815 912
816static int cx25840_attach_adapter(struct i2c_adapter *adapter) 913static int cx25840_attach_adapter(struct i2c_adapter *adapter)
817{ 914{
818#ifdef I2C_CLASS_TV_ANALOG
819 if (adapter->class & I2C_CLASS_TV_ANALOG) 915 if (adapter->class & I2C_CLASS_TV_ANALOG)
820#else
821 if (adapter->id == I2C_HW_B_BT848)
822#endif
823 return i2c_probe(adapter, &addr_data, &cx25840_detect_client); 916 return i2c_probe(adapter, &addr_data, &cx25840_detect_client);
824 return 0; 917 return 0;
825} 918}
@@ -846,9 +939,7 @@ static struct i2c_driver i2c_driver_cx25840 = {
846 .driver = { 939 .driver = {
847 .name = "cx25840", 940 .name = "cx25840",
848 }, 941 },
849
850 .id = I2C_DRIVERID_CX25840, 942 .id = I2C_DRIVERID_CX25840,
851
852 .attach_adapter = cx25840_attach_adapter, 943 .attach_adapter = cx25840_attach_adapter,
853 .detach_client = cx25840_detach_client, 944 .detach_client = cx25840_detach_client,
854 .command = cx25840_command, 945 .command = cx25840_command,
@@ -892,11 +983,13 @@ static void log_status(struct i2c_client *client)
892 u8 pref_mode = cx25840_read(client, 0x809); 983 u8 pref_mode = cx25840_read(client, 0x809);
893 u8 afc0 = cx25840_read(client, 0x80b); 984 u8 afc0 = cx25840_read(client, 0x80b);
894 u8 mute_ctl = cx25840_read(client, 0x8d3); 985 u8 mute_ctl = cx25840_read(client, 0x8d3);
986 int vid_input = state->vid_input;
987 int aud_input = state->aud_input;
895 char *p; 988 char *p;
896 989
897 cx25840_info("Video signal: %spresent\n", 990 v4l_info(client, "Video signal: %spresent\n",
898 (microctrl_vidfmt & 0x10) ? "" : "not "); 991 (microctrl_vidfmt & 0x10) ? "" : "not ");
899 cx25840_info("Detected format: %s\n", 992 v4l_info(client, "Detected format: %s\n",
900 fmt_strs[gen_stat1 & 0xf]); 993 fmt_strs[gen_stat1 & 0xf]);
901 994
902 switch (mod_det_stat0) { 995 switch (mod_det_stat0) {
@@ -911,7 +1004,7 @@ static void log_status(struct i2c_client *client)
911 case 0xfe: p = "forced mode"; break; 1004 case 0xfe: p = "forced mode"; break;
912 default: p = "not defined"; 1005 default: p = "not defined";
913 } 1006 }
914 cx25840_info("Detected audio mode: %s\n", p); 1007 v4l_info(client, "Detected audio mode: %s\n", p);
915 1008
916 switch (mod_det_stat1) { 1009 switch (mod_det_stat1) {
917 case 0x00: p = "not defined"; break; 1010 case 0x00: p = "not defined"; break;
@@ -937,10 +1030,10 @@ static void log_status(struct i2c_client *client)
937 case 0xff: p = "no detected audio standard"; break; 1030 case 0xff: p = "no detected audio standard"; break;
938 default: p = "not defined"; 1031 default: p = "not defined";
939 } 1032 }
940 cx25840_info("Detected audio standard: %s\n", p); 1033 v4l_info(client, "Detected audio standard: %s\n", p);
941 cx25840_info("Audio muted: %s\n", 1034 v4l_info(client, "Audio muted: %s\n",
942 (mute_ctl & 0x2) ? "yes" : "no"); 1035 (mute_ctl & 0x2) ? "yes" : "no");
943 cx25840_info("Audio microcontroller: %s\n", 1036 v4l_info(client, "Audio microcontroller: %s\n",
944 (download_ctl & 0x10) ? "running" : "stopped"); 1037 (download_ctl & 0x10) ? "running" : "stopped");
945 1038
946 switch (audio_config >> 4) { 1039 switch (audio_config >> 4) {
@@ -962,7 +1055,7 @@ static void log_status(struct i2c_client *client)
962 case 0x0f: p = "automatic detection"; break; 1055 case 0x0f: p = "automatic detection"; break;
963 default: p = "undefined"; 1056 default: p = "undefined";
964 } 1057 }
965 cx25840_info("Configured audio standard: %s\n", p); 1058 v4l_info(client, "Configured audio standard: %s\n", p);
966 1059
967 if ((audio_config >> 4) < 0xF) { 1060 if ((audio_config >> 4) < 0xF) {
968 switch (audio_config & 0xF) { 1061 switch (audio_config & 0xF) {
@@ -979,7 +1072,7 @@ static void log_status(struct i2c_client *client)
979 case 0x0a: p = "SAP"; break; 1072 case 0x0a: p = "SAP"; break;
980 default: p = "undefined"; 1073 default: p = "undefined";
981 } 1074 }
982 cx25840_info("Configured audio mode: %s\n", p); 1075 v4l_info(client, "Configured audio mode: %s\n", p);
983 } else { 1076 } else {
984 switch (audio_config & 0xF) { 1077 switch (audio_config & 0xF) {
985 case 0x00: p = "BG"; break; 1078 case 0x00: p = "BG"; break;
@@ -995,30 +1088,27 @@ static void log_status(struct i2c_client *client)
995 case 0x0f: p = "automatic standard and mode detection"; break; 1088 case 0x0f: p = "automatic standard and mode detection"; break;
996 default: p = "undefined"; 1089 default: p = "undefined";
997 } 1090 }
998 cx25840_info("Configured audio system: %s\n", p); 1091 v4l_info(client, "Configured audio system: %s\n", p);
999 } 1092 }
1000 1093
1001 cx25840_info("Specified standard: %s\n", 1094 v4l_info(client, "Specified standard: %s\n",
1002 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); 1095 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
1003 1096
1004 switch (state->input) { 1097 if (vid_input >= CX25840_COMPOSITE1 &&
1005 case CX25840_COMPOSITE0: p = "Composite 0"; break; 1098 vid_input <= CX25840_COMPOSITE8) {
1006 case CX25840_COMPOSITE1: p = "Composite 1"; break; 1099 v4l_info(client, "Specified video input: Composite %d\n",
1007 case CX25840_SVIDEO0: p = "S-Video 0"; break; 1100 vid_input - CX25840_COMPOSITE1 + 1);
1008 case CX25840_SVIDEO1: p = "S-Video 1"; break; 1101 } else {
1009 case CX25840_TUNER: p = "Tuner"; break; 1102 v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
1103 (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
1010 } 1104 }
1011 cx25840_info("Specified input: %s\n", p); 1105 if (aud_input) {
1012 cx25840_info("Specified audio input: %s\n", 1106 v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input);
1013 state->audio_input == 0 ? "Tuner" : "External"); 1107 } else {
1014 1108 v4l_info(client, "Specified audio input: External\n");
1015 switch (state->audclk_freq) {
1016 case V4L2_AUDCLK_441_KHZ: p = "44.1 kHz"; break;
1017 case V4L2_AUDCLK_48_KHZ: p = "48 kHz"; break;
1018 case V4L2_AUDCLK_32_KHZ: p = "32 kHz"; break;
1019 default: p = "undefined";
1020 } 1109 }
1021 cx25840_info("Specified audioclock freq: %s\n", p); 1110
1111 v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq);
1022 1112
1023 switch (pref_mode & 0xf) { 1113 switch (pref_mode & 0xf) {
1024 case 0: p = "mono/language A"; break; 1114 case 0: p = "mono/language A"; break;
@@ -1031,7 +1121,7 @@ static void log_status(struct i2c_client *client)
1031 case 7: p = "language AB"; break; 1121 case 7: p = "language AB"; break;
1032 default: p = "undefined"; 1122 default: p = "undefined";
1033 } 1123 }
1034 cx25840_info("Preferred audio mode: %s\n", p); 1124 v4l_info(client, "Preferred audio mode: %s\n", p);
1035 1125
1036 if ((audio_config & 0xf) == 0xf) { 1126 if ((audio_config & 0xf) == 0xf) {
1037 switch ((afc0 >> 3) & 0x3) { 1127 switch ((afc0 >> 3) & 0x3) {
@@ -1040,7 +1130,7 @@ static void log_status(struct i2c_client *client)
1040 case 2: p = "autodetect"; break; 1130 case 2: p = "autodetect"; break;
1041 default: p = "undefined"; 1131 default: p = "undefined";
1042 } 1132 }
1043 cx25840_info("Selected 65 MHz format: %s\n", p); 1133 v4l_info(client, "Selected 65 MHz format: %s\n", p);
1044 1134
1045 switch (afc0 & 0x7) { 1135 switch (afc0 & 0x7) {
1046 case 0: p = "chroma"; break; 1136 case 0: p = "chroma"; break;
@@ -1050,6 +1140,6 @@ static void log_status(struct i2c_client *client)
1050 case 4: p = "autodetect"; break; 1140 case 4: p = "autodetect"; break;
1051 default: p = "undefined"; 1141 default: p = "undefined";
1052 } 1142 }
1053 cx25840_info("Selected 45 MHz format: %s\n", p); 1143 v4l_info(client, "Selected 45 MHz format: %s\n", p);
1054 } 1144 }
1055} 1145}
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
index df9d50a75542..e1a7823d82cd 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -15,7 +15,6 @@
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 */ 16 */
17 17
18
19#include <linux/module.h> 18#include <linux/module.h>
20#include <linux/i2c.h> 19#include <linux/i2c.h>
21#include <linux/i2c-algo-bit.h> 20#include <linux/i2c-algo-bit.h>
@@ -38,7 +37,7 @@ module_param(firmware, charp, 0444);
38MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]"); 37MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]");
39MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]"); 38MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]");
40 39
41static inline void set_i2c_delay(struct i2c_client *client, int delay) 40static void set_i2c_delay(struct i2c_client *client, int delay)
42{ 41{
43 struct i2c_algo_bit_data *algod = client->adapter->algo_data; 42 struct i2c_algo_bit_data *algod = client->adapter->algo_data;
44 43
@@ -52,7 +51,7 @@ static inline void set_i2c_delay(struct i2c_client *client, int delay)
52 } 51 }
53} 52}
54 53
55static inline void start_fw_load(struct i2c_client *client) 54static void start_fw_load(struct i2c_client *client)
56{ 55{
57 /* DL_ADDR_LB=0 DL_ADDR_HB=0 */ 56 /* DL_ADDR_LB=0 DL_ADDR_HB=0 */
58 cx25840_write(client, 0x800, 0x00); 57 cx25840_write(client, 0x800, 0x00);
@@ -66,7 +65,7 @@ static inline void start_fw_load(struct i2c_client *client)
66 set_i2c_delay(client, 3); 65 set_i2c_delay(client, 3);
67} 66}
68 67
69static inline void end_fw_load(struct i2c_client *client) 68static void end_fw_load(struct i2c_client *client)
70{ 69{
71 if (fastfw) 70 if (fastfw)
72 set_i2c_delay(client, 10); 71 set_i2c_delay(client, 10);
@@ -77,38 +76,47 @@ static inline void end_fw_load(struct i2c_client *client)
77 cx25840_write(client, 0x803, 0x03); 76 cx25840_write(client, 0x803, 0x03);
78} 77}
79 78
80static inline int check_fw_load(struct i2c_client *client, int size) 79static int check_fw_load(struct i2c_client *client, int size)
81{ 80{
82 /* DL_ADDR_HB DL_ADDR_LB */ 81 /* DL_ADDR_HB DL_ADDR_LB */
83 int s = cx25840_read(client, 0x801) << 8; 82 int s = cx25840_read(client, 0x801) << 8;
84 s |= cx25840_read(client, 0x800); 83 s |= cx25840_read(client, 0x800);
85 84
86 if (size != s) { 85 if (size != s) {
87 cx25840_err("firmware %s load failed\n", firmware); 86 v4l_err(client, "firmware %s load failed\n", firmware);
88 return -EINVAL; 87 return -EINVAL;
89 } 88 }
90 89
91 cx25840_info("loaded %s firmware (%d bytes)\n", firmware, size); 90 v4l_info(client, "loaded %s firmware (%d bytes)\n", firmware, size);
92 return 0; 91 return 0;
93} 92}
94 93
95static inline int fw_write(struct i2c_client *client, u8 * data, int size) 94static int fw_write(struct i2c_client *client, u8 * data, int size)
96{ 95{
97 if (i2c_master_send(client, data, size) < size) { 96 int sent;
97
98 if ((sent = i2c_master_send(client, data, size)) < size) {
98 99
99 if (fastfw) { 100 if (fastfw) {
100 cx25840_err("333MHz i2c firmware load failed\n"); 101 v4l_err(client, "333MHz i2c firmware load failed\n");
101 fastfw = 0; 102 fastfw = 0;
102 set_i2c_delay(client, 10); 103 set_i2c_delay(client, 10);
103 104
105 if (sent > 2) {
106 u16 dl_addr = cx25840_read(client, 0x801) << 8;
107 dl_addr |= cx25840_read(client, 0x800);
108 dl_addr -= sent - 2;
109 cx25840_write(client, 0x801, dl_addr >> 8);
110 cx25840_write(client, 0x800, dl_addr & 0xff);
111 }
112
104 if (i2c_master_send(client, data, size) < size) { 113 if (i2c_master_send(client, data, size) < size) {
105 cx25840_err 114 v4l_err(client, "100MHz i2c firmware load failed\n");
106 ("100MHz i2c firmware load failed\n");
107 return -ENOSYS; 115 return -ENOSYS;
108 } 116 }
109 117
110 } else { 118 } else {
111 cx25840_err("firmware load i2c failure\n"); 119 v4l_err(client, "firmware load i2c failure\n");
112 return -ENOSYS; 120 return -ENOSYS;
113 } 121 }
114 122
@@ -124,7 +132,7 @@ int cx25840_loadfw(struct i2c_client *client)
124 int size, send, retval; 132 int size, send, retval;
125 133
126 if (request_firmware(&fw, firmware, FWDEV(client)) != 0) { 134 if (request_firmware(&fw, firmware, FWDEV(client)) != 0) {
127 cx25840_err("unable to open firmware %s\n", firmware); 135 v4l_err(client, "unable to open firmware %s\n", firmware);
128 return -EINVAL; 136 return -EINVAL;
129 } 137 }
130 138
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c
index 13ba4e15ddea..04d879da7d63 100644
--- a/drivers/media/video/cx25840/cx25840-vbi.c
+++ b/drivers/media/video/cx25840/cx25840-vbi.c
@@ -22,7 +22,7 @@
22 22
23#include "cx25840.h" 23#include "cx25840.h"
24 24
25static inline int odd_parity(u8 c) 25static int odd_parity(u8 c)
26{ 26{
27 c ^= (c >> 4); 27 c ^= (c >> 4);
28 c ^= (c >> 2); 28 c ^= (c >> 2);
@@ -31,7 +31,7 @@ static inline int odd_parity(u8 c)
31 return c & 1; 31 return c & 1;
32} 32}
33 33
34static inline int decode_vps(u8 * dst, u8 * p) 34static int decode_vps(u8 * dst, u8 * p)
35{ 35{
36 static const u8 biphase_tbl[] = { 36 static const u8 biphase_tbl[] = {
37 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, 37 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
diff --git a/drivers/media/video/cx25840/cx25840.h b/drivers/media/video/cx25840/cx25840.h
index 40aa59f9c525..fd22f30dcc1b 100644
--- a/drivers/media/video/cx25840/cx25840.h
+++ b/drivers/media/video/cx25840/cx25840.h
@@ -24,48 +24,60 @@
24#include <linux/videodev2.h> 24#include <linux/videodev2.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26 26
27extern int cx25840_debug; 27/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
28 28 present in Hauppauge PVR-150 (and possibly PVR-500) cards that have
29#define cx25840_dbg(fmt, arg...) do { if (cx25840_debug) \ 29 certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The
30 printk(KERN_INFO "%s debug %d-%04x: " fmt, \
31 client->driver->driver.name, \
32 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
33
34#define cx25840_err(fmt, arg...) do { \
35 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
36 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
37
38#define cx25840_info(fmt, arg...) do { \
39 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
40 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
41
42#define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0)
43
44/* The CARDTYPE_PVR150_WORKAROUND cardtype activates a workaround for a
45 hardware bug that is present in PVR150 (and possible PVR500) cards that
46 have certain NTSC tuners (tveeprom model numbers 85, 99 and 112). The
47 audio autodetect fails on some channels for these models and the workaround 30 audio autodetect fails on some channels for these models and the workaround
48 is to select the audio standard explicitly. Many thanks to Hauppauge for 31 is to select the audio standard explicitly. Many thanks to Hauppauge for
49 providing this information. */ 32 providing this information. */
50enum cx25840_cardtype { 33#define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0)
51 CARDTYPE_PVR150, 34
52 CARDTYPE_PG600, 35enum cx25840_video_input {
53 CARDTYPE_PVR150_WORKAROUND, 36 /* Composite video inputs In1-In8 */
37 CX25840_COMPOSITE1 = 1,
38 CX25840_COMPOSITE2,
39 CX25840_COMPOSITE3,
40 CX25840_COMPOSITE4,
41 CX25840_COMPOSITE5,
42 CX25840_COMPOSITE6,
43 CX25840_COMPOSITE7,
44 CX25840_COMPOSITE8,
45
46 /* S-Video inputs consist of one luma input (In1-In4) ORed with one
47 chroma input (In5-In8) */
48 CX25840_SVIDEO_LUMA1 = 0x10,
49 CX25840_SVIDEO_LUMA2 = 0x20,
50 CX25840_SVIDEO_LUMA3 = 0x30,
51 CX25840_SVIDEO_LUMA4 = 0x40,
52 CX25840_SVIDEO_CHROMA4 = 0x400,
53 CX25840_SVIDEO_CHROMA5 = 0x500,
54 CX25840_SVIDEO_CHROMA6 = 0x600,
55 CX25840_SVIDEO_CHROMA7 = 0x700,
56 CX25840_SVIDEO_CHROMA8 = 0x800,
57
58 /* S-Video aliases for common luma/chroma combinations */
59 CX25840_SVIDEO1 = 0x510,
60 CX25840_SVIDEO2 = 0x620,
61 CX25840_SVIDEO3 = 0x730,
62 CX25840_SVIDEO4 = 0x840,
54}; 63};
55 64
56enum cx25840_input { 65enum cx25840_audio_input {
57 CX25840_TUNER, 66 /* Audio inputs: serial or In4-In8 */
58 CX25840_COMPOSITE0, 67 CX25840_AUDIO_SERIAL,
59 CX25840_COMPOSITE1, 68 CX25840_AUDIO4 = 4,
60 CX25840_SVIDEO0, 69 CX25840_AUDIO5,
61 CX25840_SVIDEO1 70 CX25840_AUDIO6,
71 CX25840_AUDIO7,
72 CX25840_AUDIO8,
62}; 73};
63 74
64struct cx25840_state { 75struct cx25840_state {
65 enum cx25840_cardtype cardtype; 76 int pvr150_workaround;
66 enum cx25840_input input; 77 int radio;
67 int audio_input; 78 enum cx25840_video_input vid_input;
68 enum v4l2_audio_clock_freq audclk_freq; 79 enum cx25840_audio_input aud_input;
80 u32 audclk_freq;
69}; 81};
70 82
71/* ----------------------------------------------------------------------- */ 83/* ----------------------------------------------------------------------- */
@@ -84,6 +96,7 @@ int cx25840_loadfw(struct i2c_client *client);
84/* ----------------------------------------------------------------------- */ 96/* ----------------------------------------------------------------------- */
85/* cx25850-audio.c */ 97/* cx25850-audio.c */
86int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg); 98int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg);
99void cx25840_audio_set_path(struct i2c_client *client);
87 100
88/* ----------------------------------------------------------------------- */ 101/* ----------------------------------------------------------------------- */
89/* cx25850-vbi.c */ 102/* cx25850-vbi.c */
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 85ba4106dc79..76fcb4e995c9 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -29,6 +29,21 @@ config VIDEO_CX88_DVB
29 You must also select one or more DVB/ATSC demodulators. 29 You must also select one or more DVB/ATSC demodulators.
30 If you are unsure which you need, choose all of them. 30 If you are unsure which you need, choose all of them.
31 31
32config VIDEO_CX88_ALSA
33 tristate "ALSA DMA audio support"
34 depends on VIDEO_CX88 && SND
35 select SND_PCM_OSS
36 ---help---
37 This is a video4linux driver for direct (DMA) audio on
38 Conexant 2388x based TV cards.
39 It only works with boards with function 01 enabled.
40 To check if your board supports, use lspci -n.
41 If supported, you should see 1471:8801 or 1471:8811
42 PCI device.
43
44 To compile this driver as a module, choose M here: the
45 module will be called cx88-alsa.
46
32config VIDEO_CX88_DVB_ALL_FRONTENDS 47config VIDEO_CX88_DVB_ALL_FRONTENDS
33 bool "Build all supported frontends for cx2388x based TV cards" 48 bool "Build all supported frontends for cx2388x based TV cards"
34 default y 49 default y
@@ -38,6 +53,7 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS
38 select DVB_CX22702 53 select DVB_CX22702
39 select DVB_LGDT330X 54 select DVB_LGDT330X
40 select DVB_NXT200X 55 select DVB_NXT200X
56 select DVB_CX24123
41 ---help--- 57 ---help---
42 This builds cx88-dvb with all currently supported frontend 58 This builds cx88-dvb with all currently supported frontend
43 demodulators. If you wish to tweak your configuration, and 59 demodulators. If you wish to tweak your configuration, and
@@ -89,3 +105,12 @@ config VIDEO_CX88_DVB_NXT200X
89 ---help--- 105 ---help---
90 This adds ATSC 8VSB and QAM64/256 support for cards based on the 106 This adds ATSC 8VSB and QAM64/256 support for cards based on the
91 Connexant 2388x chip and the NXT2002/NXT2004 demodulator. 107 Connexant 2388x chip and the NXT2002/NXT2004 demodulator.
108
109config VIDEO_CX88_DVB_CX24123
110 bool "Conexant CX24123 DVB-S Support"
111 default y
112 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
113 select DVB_CX24123
114 ---help---
115 This adds DVB-S support for cards based on the
116 Connexant 2388x chip and the CX24123 demodulator.
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 54401b02b7ce..e4b2134fe567 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -4,7 +4,7 @@ cx8800-objs := cx88-video.o cx88-vbi.o
4cx8802-objs := cx88-mpeg.o 4cx8802-objs := cx88-mpeg.o
5 5
6obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o 6obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o
7obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o 7obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o cx88-vp3054-i2c.o
8 8
9EXTRA_CFLAGS += -I$(src)/.. 9EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core 10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
@@ -16,5 +16,7 @@ extra-cflags-$(CONFIG_DVB_OR51132) += -DHAVE_OR51132=1
16extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1 16extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1
17extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 17extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1
18extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 18extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1
19extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1
20extra-cflags-$(CONFIG_VIDEO_CX88_DVB)+= -DHAVE_VP3054_I2C=1
19 21
20EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) 22EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
new file mode 100644
index 000000000000..7695b521eb35
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -0,0 +1,848 @@
1/*
2 *
3 * Support for audio capture
4 * PCI function #1 of the cx2388x.
5 *
6 * (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org>
7 * (c) 2005 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
8 * Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org>
9 * Based on dummy.c by Jaroslav Kysela <perex@suse.cz>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/module.h>
27#include <linux/init.h>
28#include <linux/device.h>
29#include <linux/interrupt.h>
30#include <asm/delay.h>
31#include <sound/driver.h>
32#include <sound/core.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/control.h>
36#include <sound/initval.h>
37
38#include "cx88.h"
39#include "cx88-reg.h"
40
41#define dprintk(level,fmt, arg...) if (debug >= level) \
42 printk(KERN_INFO "%s/1: " fmt, chip->core->name , ## arg)
43
44#define dprintk_core(level,fmt, arg...) if (debug >= level) \
45 printk(KERN_DEBUG "%s/1: " fmt, chip->core->name , ## arg)
46
47
48/****************************************************************************
49 Data type declarations - Can be moded to a header file later
50 ****************************************************************************/
51
52/* These can be replaced after done */
53#define MIXER_ADDR_LAST MAX_CX88_INPUT
54
55struct cx88_audio_dev {
56 struct cx88_core *core;
57 struct cx88_dmaqueue q;
58
59 /* pci i/o */
60 struct pci_dev *pci;
61 unsigned char pci_rev,pci_lat;
62
63 /* audio controls */
64 int irq;
65
66 snd_card_t *card;
67
68 spinlock_t reg_lock;
69
70 unsigned int dma_size;
71 unsigned int period_size;
72 unsigned int num_periods;
73
74 struct videobuf_dmabuf dma_risc;
75
76 int mixer_volume[MIXER_ADDR_LAST+1][2];
77 int capture_source[MIXER_ADDR_LAST+1][2];
78
79 long int read_count;
80 long int read_offset;
81
82 struct cx88_buffer *buf;
83
84 long opened;
85 snd_pcm_substream_t *substream;
86
87};
88typedef struct cx88_audio_dev snd_cx88_card_t;
89
90
91
92/****************************************************************************
93 Module global static vars
94 ****************************************************************************/
95
96static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
97static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
98static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
99static snd_card_t *snd_cx88_cards[SNDRV_CARDS];
100
101module_param_array(enable, bool, NULL, 0444);
102MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled.");
103
104module_param_array(index, int, NULL, 0444);
105MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s).");
106
107
108/****************************************************************************
109 Module macros
110 ****************************************************************************/
111
112MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards");
113MODULE_AUTHOR("Ricardo Cerqueira");
114MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@brturbo.com.br>");
115MODULE_LICENSE("GPL");
116MODULE_SUPPORTED_DEVICE("{{Conexant,23881},"
117 "{{Conexant,23882},"
118 "{{Conexant,23883}");
119static unsigned int debug = 0;
120module_param(debug,int,0644);
121MODULE_PARM_DESC(debug,"enable debug messages");
122
123/****************************************************************************
124 Module specific funtions
125 ****************************************************************************/
126
127/*
128 * BOARD Specific: Sets audio DMA
129 */
130
131int _cx88_start_audio_dma(snd_cx88_card_t *chip)
132{
133 struct cx88_buffer *buf = chip->buf;
134 struct cx88_core *core=chip->core;
135 struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25];
136
137
138 dprintk(1, "Starting audio DMA for %i bytes/line and %i (%i) lines at address %08x\n",buf->bpl, chip->num_periods, audio_ch->fifo_size / buf->bpl, audio_ch->fifo_start);
139
140 /* setup fifo + format - out channel */
141 cx88_sram_channel_setup(chip->core, &cx88_sram_channels[SRAM_CH25],
142 buf->bpl, buf->risc.dma);
143
144 /* sets bpl size */
145 cx_write(MO_AUDD_LNGTH, buf->bpl);
146
147 /* reset counter */
148 cx_write(MO_AUDD_GPCNTRL,GP_COUNT_CONTROL_RESET);
149
150 dprintk(1,"Enabling IRQ, setting mask from 0x%x to 0x%x\n",chip->core->pci_irqmask,(chip->core->pci_irqmask | 0x02));
151 /* enable irqs */
152 cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | 0x02);
153
154
155 /* Enables corresponding bits at AUD_INT_STAT */
156 cx_write(MO_AUD_INTMSK,
157 (1<<16)|
158 (1<<12)|
159 (1<<4)|
160 (1<<0)
161 );
162
163 /* start dma */
164 cx_set(MO_DEV_CNTRL2, (1<<5)); /* Enables Risc Processor */
165 cx_set(MO_AUD_DMACNTRL, 0x11); /* audio downstream FIFO and RISC enable */
166
167 if (debug)
168 cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]);
169
170 return 0;
171}
172
173/*
174 * BOARD Specific: Resets audio DMA
175 */
176int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
177{
178 struct cx88_core *core=chip->core;
179 dprintk(1, "Stopping audio DMA\n");
180
181 /* stop dma */
182 cx_clear(MO_AUD_DMACNTRL, 0x11);
183
184 /* disable irqs */
185 cx_clear(MO_PCI_INTMSK, 0x02);
186 cx_clear(MO_AUD_INTMSK,
187 (1<<16)|
188 (1<<12)|
189 (1<<4)|
190 (1<<0)
191 );
192
193 if (debug)
194 cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]);
195
196 return 0;
197}
198
199#define MAX_IRQ_LOOP 10
200
201/*
202 * BOARD Specific: IRQ dma bits
203 */
204static char *cx88_aud_irqs[32] = {
205 "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */
206 NULL, /* reserved */
207 "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */
208 NULL, /* reserved */
209 "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */
210 NULL, /* reserved */
211 "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */
212 NULL, /* reserved */
213 "opc_err", "par_err", "rip_err", /* 16-18 */
214 "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */
215};
216
217/*
218 * BOARD Specific: Threats IRQ audio specific calls
219 */
220static void cx8801_aud_irq(snd_cx88_card_t *chip)
221{
222 struct cx88_core *core = chip->core;
223 u32 status, mask;
224 u32 count;
225
226 status = cx_read(MO_AUD_INTSTAT);
227 mask = cx_read(MO_AUD_INTMSK);
228 if (0 == (status & mask)) {
229 spin_unlock(&chip->reg_lock);
230 return;
231 }
232 cx_write(MO_AUD_INTSTAT, status);
233 if (debug > 1 || (status & mask & ~0xff))
234 cx88_print_irqbits(core->name, "irq aud",
235 cx88_aud_irqs, status, mask);
236 /* risc op code error */
237 if (status & (1 << 16)) {
238 printk(KERN_WARNING "%s/0: audio risc op code error\n",core->name);
239 cx_clear(MO_AUD_DMACNTRL, 0x11);
240 cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH25]);
241 }
242
243 /* risc1 downstream */
244 if (status & 0x01) {
245 spin_lock(&chip->reg_lock);
246 count = cx_read(MO_AUDD_GPCNT);
247 spin_unlock(&chip->reg_lock);
248 if (chip->read_count == 0)
249 chip->read_count += chip->dma_size;
250 }
251
252 if (chip->read_count >= chip->period_size) {
253 dprintk(2, "Elapsing period\n");
254 snd_pcm_period_elapsed(chip->substream);
255 }
256
257 dprintk(3,"Leaving audio IRQ handler...\n");
258
259 /* FIXME: Any other status should deserve a special handling? */
260}
261
262/*
263 * BOARD Specific: Handles IRQ calls
264 */
265static irqreturn_t cx8801_irq(int irq, void *dev_id, struct pt_regs *regs)
266{
267 snd_cx88_card_t *chip = dev_id;
268 struct cx88_core *core = chip->core;
269 u32 status;
270 int loop, handled = 0;
271
272 for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
273 status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x02);
274 if (0 == status)
275 goto out;
276 dprintk( 3, "cx8801_irq\n" );
277 dprintk( 3, " loop: %d/%d\n", loop, MAX_IRQ_LOOP );
278 dprintk( 3, " status: %d\n", status );
279 handled = 1;
280 cx_write(MO_PCI_INTSTAT, status);
281
282 if (status & 0x02)
283 {
284 dprintk( 2, " ALSA IRQ handling\n" );
285 cx8801_aud_irq(chip);
286 }
287 };
288
289 if (MAX_IRQ_LOOP == loop) {
290 dprintk( 0, "clearing mask\n" );
291 dprintk(1,"%s/0: irq loop -- clearing mask\n",
292 core->name);
293 cx_clear(MO_PCI_INTMSK,0x02);
294 }
295
296 out:
297 return IRQ_RETVAL(handled);
298}
299
300
301static int dsp_buffer_free(snd_cx88_card_t *chip)
302{
303 BUG_ON(!chip->dma_size);
304
305 dprintk(2,"Freeing buffer\n");
306 videobuf_dma_pci_unmap(chip->pci, &chip->dma_risc);
307 videobuf_dma_free(&chip->dma_risc);
308 btcx_riscmem_free(chip->pci,&chip->buf->risc);
309 kfree(chip->buf);
310
311 chip->dma_size = 0;
312
313 return 0;
314}
315
316/****************************************************************************
317 ALSA PCM Interface
318 ****************************************************************************/
319
320/*
321 * Digital hardware definition
322 */
323static snd_pcm_hardware_t snd_cx88_digital_hw = {
324 .info = SNDRV_PCM_INFO_MMAP |
325 SNDRV_PCM_INFO_INTERLEAVED |
326 SNDRV_PCM_INFO_BLOCK_TRANSFER |
327 SNDRV_PCM_INFO_MMAP_VALID,
328 .formats = SNDRV_PCM_FMTBIT_S16_LE,
329
330 .rates = SNDRV_PCM_RATE_48000,
331 .rate_min = 48000,
332 .rate_max = 48000,
333 .channels_min = 1,
334 .channels_max = 2,
335 .buffer_bytes_max = (2*2048),
336 .period_bytes_min = 256,
337 .period_bytes_max = 2048,
338 .periods_min = 2,
339 .periods_max = 16,
340};
341
342/*
343 * audio pcm capture runtime free
344 */
345static void snd_card_cx88_runtime_free(snd_pcm_runtime_t *runtime)
346{
347}
348/*
349 * audio pcm capture open callback
350 */
351static int snd_cx88_pcm_open(snd_pcm_substream_t *substream)
352{
353 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
354 snd_pcm_runtime_t *runtime = substream->runtime;
355 int err;
356
357 if (test_and_set_bit(0, &chip->opened))
358 return -EBUSY;
359
360 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
361 if (err < 0)
362 goto _error;
363
364 chip->substream = substream;
365
366 chip->read_count = 0;
367 chip->read_offset = 0;
368
369 runtime->private_free = snd_card_cx88_runtime_free;
370 runtime->hw = snd_cx88_digital_hw;
371
372 return 0;
373_error:
374 dprintk(1,"Error opening PCM!\n");
375 clear_bit(0, &chip->opened);
376 smp_mb__after_clear_bit();
377 return err;
378}
379
380/*
381 * audio close callback
382 */
383static int snd_cx88_close(snd_pcm_substream_t *substream)
384{
385 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
386
387 clear_bit(0, &chip->opened);
388 smp_mb__after_clear_bit();
389
390 return 0;
391}
392
393/*
394 * hw_params callback
395 */
396static int snd_cx88_hw_params(snd_pcm_substream_t * substream,
397 snd_pcm_hw_params_t * hw_params)
398{
399 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
400 struct cx88_buffer *buf;
401
402 if (substream->runtime->dma_area) {
403 dsp_buffer_free(chip);
404 substream->runtime->dma_area = NULL;
405 }
406
407
408 chip->period_size = params_period_bytes(hw_params);
409 chip->num_periods = params_periods(hw_params);
410 chip->dma_size = chip->period_size * params_periods(hw_params);
411
412 BUG_ON(!chip->dma_size);
413
414 dprintk(1,"Setting buffer\n");
415
416 buf = kmalloc(sizeof(*buf),GFP_KERNEL);
417 if (NULL == buf)
418 return -ENOMEM;
419 memset(buf,0,sizeof(*buf));
420
421
422 buf->vb.memory = V4L2_MEMORY_MMAP;
423 buf->vb.width = chip->period_size;
424 buf->vb.height = chip->num_periods;
425 buf->vb.size = chip->dma_size;
426 buf->vb.field = V4L2_FIELD_NONE;
427
428 videobuf_dma_init(&buf->vb.dma);
429 videobuf_dma_init_kernel(&buf->vb.dma,PCI_DMA_FROMDEVICE,
430 (PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT));
431
432 videobuf_dma_pci_map(chip->pci,&buf->vb.dma);
433
434
435 cx88_risc_databuffer(chip->pci, &buf->risc,
436 buf->vb.dma.sglist,
437 buf->vb.width, buf->vb.height);
438
439 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
440 buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
441
442 buf->vb.state = STATE_PREPARED;
443
444 buf->bpl = chip->period_size;
445 chip->buf = buf;
446 chip->dma_risc = buf->vb.dma;
447
448 dprintk(1,"Buffer ready at %u\n",chip->dma_risc.nr_pages);
449 substream->runtime->dma_area = chip->dma_risc.vmalloc;
450 return 0;
451}
452
453/*
454 * hw free callback
455 */
456static int snd_cx88_hw_free(snd_pcm_substream_t * substream)
457{
458
459 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
460
461 if (substream->runtime->dma_area) {
462 dsp_buffer_free(chip);
463 substream->runtime->dma_area = NULL;
464 }
465
466 return 0;
467}
468
469/*
470 * prepare callback
471 */
472static int snd_cx88_prepare(snd_pcm_substream_t *substream)
473{
474 return 0;
475}
476
477
478/*
479 * trigger callback
480 */
481static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd)
482{
483 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
484 int err;
485
486 spin_lock(&chip->reg_lock);
487
488 switch (cmd) {
489 case SNDRV_PCM_TRIGGER_START:
490 err=_cx88_start_audio_dma(chip);
491 break;
492 case SNDRV_PCM_TRIGGER_STOP:
493 err=_cx88_stop_audio_dma(chip);
494 break;
495 default:
496 err=-EINVAL;
497 break;
498 }
499
500 spin_unlock(&chip->reg_lock);
501
502 return err;
503}
504
505/*
506 * pointer callback
507 */
508static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream)
509{
510 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
511 snd_pcm_runtime_t *runtime = substream->runtime;
512
513 if (chip->read_count) {
514 chip->read_count -= snd_pcm_lib_period_bytes(substream);
515 chip->read_offset += snd_pcm_lib_period_bytes(substream);
516 if (chip->read_offset == chip->dma_size)
517 chip->read_offset = 0;
518 }
519
520 dprintk(2, "Pointer time, will return %li, read %li\n",chip->read_offset,chip->read_count);
521 return bytes_to_frames(runtime, chip->read_offset);
522
523}
524
525/*
526 * operators
527 */
528static snd_pcm_ops_t snd_cx88_pcm_ops = {
529 .open = snd_cx88_pcm_open,
530 .close = snd_cx88_close,
531 .ioctl = snd_pcm_lib_ioctl,
532 .hw_params = snd_cx88_hw_params,
533 .hw_free = snd_cx88_hw_free,
534 .prepare = snd_cx88_prepare,
535 .trigger = snd_cx88_card_trigger,
536 .pointer = snd_cx88_pointer,
537};
538
539/*
540 * create a PCM device
541 */
542static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name)
543{
544 int err;
545 snd_pcm_t *pcm;
546
547 err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
548 if (err < 0)
549 return err;
550 pcm->private_data = chip;
551 strcpy(pcm->name, name);
552 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx88_pcm_ops);
553
554 return 0;
555}
556
557/****************************************************************************
558 CONTROL INTERFACE
559 ****************************************************************************/
560static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
561{
562 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
563 info->count = 1;
564 info->value.integer.min = 0;
565 info->value.integer.max = 0x3f;
566
567 return 0;
568}
569
570/* OK - TODO: test it */
571static int snd_cx88_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
572{
573 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
574 struct cx88_core *core=chip->core;
575
576 value->value.integer.value[0] = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f);
577
578 return 0;
579}
580
581/* OK - TODO: test it */
582static int snd_cx88_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
583{
584 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
585 struct cx88_core *core=chip->core;
586 int v;
587 u32 old_control;
588
589 spin_lock_irq(&chip->reg_lock);
590 old_control = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f);
591 v = 0x3f - (value->value.integer.value[0] & 0x3f);
592 cx_andor(AUD_VOL_CTL, 0x3f, v);
593 spin_unlock_irq(&chip->reg_lock);
594
595 return v != old_control;
596}
597
598static snd_kcontrol_new_t snd_cx88_capture_volume = {
599 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
600 .name = "Capture Volume",
601 .info = snd_cx88_capture_volume_info,
602 .get = snd_cx88_capture_volume_get,
603 .put = snd_cx88_capture_volume_put,
604};
605
606
607/****************************************************************************
608 Basic Flow for Sound Devices
609 ****************************************************************************/
610
611/*
612 * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio
613 * Only boards with eeprom and byte 1 at eeprom=1 have it
614 */
615
616struct pci_device_id cx88_audio_pci_tbl[] = {
617 {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
618 {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
619 {0, }
620};
621MODULE_DEVICE_TABLE(pci, cx88_audio_pci_tbl);
622
623/*
624 * Chip-specific destructor
625 */
626
627static int snd_cx88_free(snd_cx88_card_t *chip)
628{
629
630 if (chip->irq >= 0){
631 synchronize_irq(chip->irq);
632 free_irq(chip->irq, chip);
633 }
634
635 cx88_core_put(chip->core,chip->pci);
636
637 pci_disable_device(chip->pci);
638 return 0;
639}
640
641/*
642 * Component Destructor
643 */
644static void snd_cx88_dev_free(snd_card_t * card)
645{
646 snd_cx88_card_t *chip = card->private_data;
647
648 snd_cx88_free(chip);
649}
650
651
652/*
653 * Alsa Constructor - Component probe
654 */
655
656static int devno=0;
657static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
658 snd_cx88_card_t **rchip)
659{
660 snd_cx88_card_t *chip;
661 struct cx88_core *core;
662 int err;
663
664 *rchip = NULL;
665
666 err = pci_enable_device(pci);
667 if (err < 0)
668 return err;
669
670 pci_set_master(pci);
671
672 chip = (snd_cx88_card_t *) card->private_data;
673
674 core = cx88_core_get(pci);
675
676 if (!pci_dma_supported(pci,0xffffffff)) {
677 dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
678 err = -EIO;
679 cx88_core_put(core,pci);
680 return err;
681 }
682
683
684 /* pci init */
685 chip->card = card;
686 chip->pci = pci;
687 chip->irq = -1;
688 spin_lock_init(&chip->reg_lock);
689
690 cx88_reset(core);
691 if (NULL == core) {
692 err = -EINVAL;
693 kfree (chip);
694 return err;
695 }
696 chip->core = core;
697
698 /* get irq */
699 err = request_irq(chip->pci->irq, cx8801_irq,
700 SA_SHIRQ | SA_INTERRUPT, chip->core->name, chip);
701 if (err < 0) {
702 dprintk(0, "%s: can't get IRQ %d\n",
703 chip->core->name, chip->pci->irq);
704 return err;
705 }
706
707 /* print pci info */
708 pci_read_config_byte(pci, PCI_CLASS_REVISION, &chip->pci_rev);
709 pci_read_config_byte(pci, PCI_LATENCY_TIMER, &chip->pci_lat);
710
711 dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, "
712 "latency: %d, mmio: 0x%lx\n", core->name, devno,
713 pci_name(pci), chip->pci_rev, pci->irq,
714 chip->pci_lat,pci_resource_start(pci,0));
715
716 chip->irq = pci->irq;
717 synchronize_irq(chip->irq);
718
719 snd_card_set_dev(card, &pci->dev);
720
721 *rchip = chip;
722
723 return 0;
724}
725
726static int __devinit cx88_audio_initdev(struct pci_dev *pci,
727 const struct pci_device_id *pci_id)
728{
729 snd_card_t *card;
730 snd_cx88_card_t *chip;
731 int err;
732
733 if (devno >= SNDRV_CARDS)
734 return (-ENODEV);
735
736 if (!enable[devno]) {
737 ++devno;
738 return (-ENOENT);
739 }
740
741 card = snd_card_new(index[devno], id[devno], THIS_MODULE, sizeof(snd_cx88_card_t));
742 if (!card)
743 return (-ENOMEM);
744
745 card->private_free = snd_cx88_dev_free;
746
747 err = snd_cx88_create(card, pci, &chip);
748 if (err < 0)
749 return (err);
750
751 err = snd_cx88_pcm(chip, 0, "CX88 Digital");
752
753 if (err < 0) {
754 snd_card_free(card);
755 return (err);
756 }
757
758 err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_capture_volume, chip));
759 if (err < 0) {
760 snd_card_free(card);
761 return (err);
762 }
763
764 strcpy (card->driver, "CX88x");
765 sprintf(card->shortname, "Conexant CX%x", pci->device);
766 sprintf(card->longname, "%s at %#lx",
767 card->shortname, pci_resource_start(pci, 0));
768 strcpy (card->mixername, "CX88");
769
770 dprintk (0, "%s/%i: ALSA support for cx2388x boards\n",
771 card->driver,devno);
772
773 err = snd_card_register(card);
774 if (err < 0) {
775 snd_card_free(card);
776 return (err);
777 }
778 snd_cx88_cards[devno] = card;
779
780 pci_set_drvdata(pci,card);
781
782 devno++;
783 return 0;
784}
785/*
786 * ALSA destructor
787 */
788static void __devexit cx88_audio_finidev(struct pci_dev *pci)
789{
790 struct cx88_audio_dev *card = pci_get_drvdata(pci);
791
792 snd_card_free((void *)card);
793
794 pci_set_drvdata(pci, NULL);
795
796 devno--;
797}
798
799/*
800 * PCI driver definition
801 */
802
803static struct pci_driver cx88_audio_pci_driver = {
804 .name = "cx88_audio",
805 .id_table = cx88_audio_pci_tbl,
806 .probe = cx88_audio_initdev,
807 .remove = cx88_audio_finidev,
808 SND_PCI_PM_CALLBACKS
809};
810
811/****************************************************************************
812 LINUX MODULE INIT
813 ****************************************************************************/
814
815/*
816 * module init
817 */
818static int cx88_audio_init(void)
819{
820 printk(KERN_INFO "cx2388x alsa driver version %d.%d.%d loaded\n",
821 (CX88_VERSION_CODE >> 16) & 0xff,
822 (CX88_VERSION_CODE >> 8) & 0xff,
823 CX88_VERSION_CODE & 0xff);
824#ifdef SNAPSHOT
825 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
826 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
827#endif
828 return pci_register_driver(&cx88_audio_pci_driver);
829}
830
831/*
832 * module remove
833 */
834static void cx88_audio_fini(void)
835{
836
837 pci_unregister_driver(&cx88_audio_pci_driver);
838}
839
840module_init(cx88_audio_init);
841module_exit(cx88_audio_fini);
842
843/* ----------------------------------------------------------- */
844/*
845 * Local variables:
846 * c-basic-offset: 8
847 * End:
848 */
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 74e57a53116f..a49062119313 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -32,10 +32,10 @@
32#include <linux/firmware.h> 32#include <linux/firmware.h>
33 33
34#include "cx88.h" 34#include "cx88.h"
35#include <media/v4l2-common.h>
35 36
36MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards"); 37MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards");
37MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>"); 38MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>, Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
40 40
41static unsigned int mpegbufs = 32; 41static unsigned int mpegbufs = 32;
@@ -1375,7 +1375,7 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
1375 struct cx88_core *core = dev->core; 1375 struct cx88_core *core = dev->core;
1376 1376
1377 if (debug > 1) 1377 if (debug > 1)
1378 cx88_print_ioctl(core->name,cmd); 1378 v4l_print_ioctl(core->name,cmd);
1379 1379
1380 switch (cmd) { 1380 switch (cmd) {
1381 1381
@@ -1689,6 +1689,18 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1689 memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params)); 1689 memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params));
1690 memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params)); 1690 memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params));
1691 1691
1692 if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN) {
1693
1694 if (core->tuner_formats & V4L2_STD_525_60) {
1695 dev->height = 480;
1696 dev->params.vi_frame_rate = 30;
1697 } else {
1698 dev->height = 576;
1699 dev->params.vi_frame_rate = 25;
1700 }
1701
1702 }
1703
1692 err = cx8802_init_common(dev); 1704 err = cx8802_init_common(dev);
1693 if (0 != err) 1705 if (0 != err)
1694 goto fail_free; 1706 goto fail_free;
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 951709aa88ba..a76d54503b6f 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -611,12 +611,12 @@ struct cx88_board cx88_boards[] = {
611 .input = {{ 611 .input = {{
612 .type = CX88_VMUX_TELEVISION, 612 .type = CX88_VMUX_TELEVISION,
613 .vmux = 0, 613 .vmux = 0,
614 .gpio0 = 0xed12, /* internal decoder */ 614 .gpio0 = 0xed1a,
615 .gpio2 = 0x00ff, 615 .gpio2 = 0x00ff,
616 },{ 616 },{
617 .type = CX88_VMUX_DEBUG, 617 .type = CX88_VMUX_DEBUG,
618 .vmux = 0, 618 .vmux = 0,
619 .gpio0 = 0xff01, /* mono from tuner chip */ 619 .gpio0 = 0xff01,
620 },{ 620 },{
621 .type = CX88_VMUX_COMPOSITE1, 621 .type = CX88_VMUX_COMPOSITE1,
622 .vmux = 1, 622 .vmux = 1,
@@ -708,7 +708,7 @@ struct cx88_board cx88_boards[] = {
708 }, 708 },
709 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { 709 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
710 .name = "DViCO FusionHDTV 3 Gold-T", 710 .name = "DViCO FusionHDTV 3 Gold-T",
711 .tuner_type = TUNER_THOMSON_DTT7611, 711 .tuner_type = TUNER_THOMSON_DTT761X,
712 .radio_type = UNSET, 712 .radio_type = UNSET,
713 .tuner_addr = ADDR_UNSET, 713 .tuner_addr = ADDR_UNSET,
714 .radio_addr = ADDR_UNSET, 714 .radio_addr = ADDR_UNSET,
@@ -897,6 +897,158 @@ struct cx88_board cx88_boards[] = {
897 .gpio3 = 0x0000, 897 .gpio3 = 0x0000,
898 }}, 898 }},
899 }, 899 },
900 [CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1] = {
901 .name = "Hauppauge Nova-S-Plus DVB-S",
902 .tuner_type = TUNER_ABSENT,
903 .radio_type = UNSET,
904 .tuner_addr = ADDR_UNSET,
905 .radio_addr = ADDR_UNSET,
906 .input = {{
907 .type = CX88_VMUX_DVB,
908 .vmux = 0,
909 },{
910 .type = CX88_VMUX_COMPOSITE1,
911 .vmux = 1,
912 },{
913 .type = CX88_VMUX_SVIDEO,
914 .vmux = 2,
915 }},
916 .dvb = 1,
917 },
918 [CX88_BOARD_HAUPPAUGE_NOVASE2_S1] = {
919 .name = "Hauppauge Nova-SE2 DVB-S",
920 .tuner_type = TUNER_ABSENT,
921 .radio_type = UNSET,
922 .tuner_addr = ADDR_UNSET,
923 .radio_addr = ADDR_UNSET,
924 .input = {{
925 .type = CX88_VMUX_DVB,
926 .vmux = 0,
927 }},
928 .dvb = 1,
929 },
930 [CX88_BOARD_KWORLD_DVBS_100] = {
931 .name = "KWorld DVB-S 100",
932 .tuner_type = TUNER_ABSENT,
933 .radio_type = UNSET,
934 .tuner_addr = ADDR_UNSET,
935 .radio_addr = ADDR_UNSET,
936 .input = {{
937 .type = CX88_VMUX_DVB,
938 .vmux = 0,
939 },{
940 .type = CX88_VMUX_COMPOSITE1,
941 .vmux = 1,
942 },{
943 .type = CX88_VMUX_SVIDEO,
944 .vmux = 2,
945 }},
946 .dvb = 1,
947 },
948 [CX88_BOARD_HAUPPAUGE_HVR1100] = {
949 .name = "Hauppauge WinTV-HVR1100 DVB-T/Hybrid",
950 .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
951 .radio_type = UNSET,
952 .tuner_addr = ADDR_UNSET,
953 .radio_addr = ADDR_UNSET,
954 .tda9887_conf = TDA9887_PRESENT,
955 .input = {{
956 .type = CX88_VMUX_TELEVISION,
957 .vmux = 0,
958 },{
959 .type = CX88_VMUX_COMPOSITE1,
960 .vmux = 1,
961 },{
962 .type = CX88_VMUX_SVIDEO,
963 .vmux = 2,
964 }},
965 /* fixme: Add radio support */
966 .dvb = 1,
967 },
968 [CX88_BOARD_HAUPPAUGE_HVR1100LP] = {
969 .name = "Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)",
970 .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
971 .radio_type = UNSET,
972 .tuner_addr = ADDR_UNSET,
973 .radio_addr = ADDR_UNSET,
974 .tda9887_conf = TDA9887_PRESENT,
975 .input = {{
976 .type = CX88_VMUX_TELEVISION,
977 .vmux = 0,
978 },{
979 .type = CX88_VMUX_COMPOSITE1,
980 .vmux = 1,
981 }},
982 /* fixme: Add radio support */
983 .dvb = 1,
984 },
985 [CX88_BOARD_DNTV_LIVE_DVB_T_PRO] = {
986 .name = "digitalnow DNTV Live! DVB-T Pro",
987 .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
988 .radio_type = UNSET,
989 .tuner_addr = ADDR_UNSET,
990 .radio_addr = ADDR_UNSET,
991 .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE |
992 TDA9887_PORT2_ACTIVE,
993 .input = {{
994 .type = CX88_VMUX_TELEVISION,
995 .vmux = 0,
996 .gpio0 = 0xf80808,
997 },{
998 .type = CX88_VMUX_COMPOSITE1,
999 .vmux = 1,
1000 .gpio0 = 0xf80808,
1001 },{
1002 .type = CX88_VMUX_SVIDEO,
1003 .vmux = 2,
1004 .gpio0 = 0xf80808,
1005 }},
1006 .radio = {
1007 .type = CX88_RADIO,
1008 .gpio0 = 0xf80808,
1009 },
1010 .dvb = 1,
1011 },
1012 [CX88_BOARD_KWORLD_DVB_T_CX22702] = {
1013 /* Kworld V-stream Xpert DVB-T with Thomson tuner */
1014 /* DTT 7579 Conexant CX22702-19 Conexant CX2388x */
1015 /* Manenti Marco <marco_manenti@colman.it> */
1016 .name = "KWorld/VStream XPert DVB-T with cx22702",
1017 .tuner_type = TUNER_ABSENT,
1018 .radio_type = UNSET,
1019 .tuner_addr = ADDR_UNSET,
1020 .radio_addr = ADDR_UNSET,
1021 .input = {{
1022 .type = CX88_VMUX_COMPOSITE1,
1023 .vmux = 1,
1024 .gpio0 = 0x0700,
1025 .gpio2 = 0x0101,
1026 },{
1027 .type = CX88_VMUX_SVIDEO,
1028 .vmux = 2,
1029 .gpio0 = 0x0700,
1030 .gpio2 = 0x0101,
1031 }},
1032 .dvb = 1,
1033 },
1034 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL] = {
1035 .name = "DViCO FusionHDTV DVB-T Dual Digital",
1036 .tuner_type = TUNER_ABSENT, /* No analog tuner */
1037 .radio_type = UNSET,
1038 .tuner_addr = ADDR_UNSET,
1039 .radio_addr = ADDR_UNSET,
1040 .input = {{
1041 .type = CX88_VMUX_COMPOSITE1,
1042 .vmux = 1,
1043 .gpio0 = 0x000027df,
1044 },{
1045 .type = CX88_VMUX_SVIDEO,
1046 .vmux = 2,
1047 .gpio0 = 0x000027df,
1048 }},
1049 .dvb = 1,
1050 },
1051
900}; 1052};
901const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); 1053const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
902 1054
@@ -1044,6 +1196,54 @@ struct cx88_subid cx88_subids[] = {
1044 .subvendor = 0x1461, 1196 .subvendor = 0x1461,
1045 .subdevice = 0x000a, 1197 .subdevice = 0x000a,
1046 .card = CX88_BOARD_AVERTV_303, 1198 .card = CX88_BOARD_AVERTV_303,
1199 },{
1200 .subvendor = 0x0070,
1201 .subdevice = 0x9200,
1202 .card = CX88_BOARD_HAUPPAUGE_NOVASE2_S1,
1203 },{
1204 .subvendor = 0x0070,
1205 .subdevice = 0x9201,
1206 .card = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1,
1207 },{
1208 .subvendor = 0x0070,
1209 .subdevice = 0x9202,
1210 .card = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1,
1211 },{
1212 .subvendor = 0x17de,
1213 .subdevice = 0x08b2,
1214 .card = CX88_BOARD_KWORLD_DVBS_100,
1215 },{
1216 .subvendor = 0x0070,
1217 .subdevice = 0x9400,
1218 .card = CX88_BOARD_HAUPPAUGE_HVR1100,
1219 },{
1220 .subvendor = 0x0070,
1221 .subdevice = 0x9402,
1222 .card = CX88_BOARD_HAUPPAUGE_HVR1100,
1223 },{
1224 .subvendor = 0x0070,
1225 .subdevice = 0x9800,
1226 .card = CX88_BOARD_HAUPPAUGE_HVR1100LP,
1227 },{
1228 .subvendor = 0x0070,
1229 .subdevice = 0x9802,
1230 .card = CX88_BOARD_HAUPPAUGE_HVR1100LP,
1231 },{
1232 .subvendor = 0x0070,
1233 .subdevice = 0x9001,
1234 .card = CX88_BOARD_HAUPPAUGE_DVB_T1,
1235 },{
1236 .subvendor = 0x1822,
1237 .subdevice = 0x0025,
1238 .card = CX88_BOARD_DNTV_LIVE_DVB_T_PRO,
1239 },{
1240 .subvendor = 0x17de,
1241 .subdevice = 0x08a1,
1242 .card = CX88_BOARD_KWORLD_DVB_T_CX22702,
1243 },{
1244 .subvendor = 0x18ac,
1245 .subdevice = 0xdb50,
1246 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
1047 }, 1247 },
1048}; 1248};
1049const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); 1249const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1075,20 +1275,19 @@ static void __devinit leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
1075 core->name, core->tuner_type, eeprom_data[0]); 1275 core->name, core->tuner_type, eeprom_data[0]);
1076} 1276}
1077 1277
1078
1079/* ----------------------------------------------------------------------- */
1080
1081static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) 1278static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
1082{ 1279{
1083 struct tveeprom tv; 1280 struct tveeprom tv;
1084 1281
1085 tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data); 1282 tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data);
1086 core->tuner_type = tv.tuner_type; 1283 core->tuner_type = tv.tuner_type;
1284 core->tuner_formats = tv.tuner_formats;
1087 core->has_radio = tv.has_radio; 1285 core->has_radio = tv.has_radio;
1088 1286
1089 /* Make sure we support the board model */ 1287 /* Make sure we support the board model */
1090 switch (tv.model) 1288 switch (tv.model)
1091 { 1289 {
1290 case 28552: /* WinTV-PVR 'Roslyn' (No IR) */
1092 case 90002: /* Nova-T-PCI (9002) */ 1291 case 90002: /* Nova-T-PCI (9002) */
1093 case 92001: /* Nova-S-Plus (Video and IR) */ 1292 case 92001: /* Nova-S-Plus (Video and IR) */
1094 case 92002: /* Nova-S-Plus (Video and IR) */ 1293 case 92002: /* Nova-S-Plus (Video and IR) */
@@ -1096,7 +1295,9 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
1096 case 90500: /* Nova-T-PCI (oem) */ 1295 case 90500: /* Nova-T-PCI (oem) */
1097 case 90501: /* Nova-T-PCI (oem/IR) */ 1296 case 90501: /* Nova-T-PCI (oem/IR) */
1098 case 92000: /* Nova-SE2 (OEM, No Video or IR) */ 1297 case 92000: /* Nova-SE2 (OEM, No Video or IR) */
1099 1298 case 94009: /* WinTV-HVR1100 (Video and IR Retail) */
1299 case 94501: /* WinTV-HVR1100 (Video and IR OEM) */
1300 case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
1100 /* known */ 1301 /* known */
1101 break; 1302 break;
1102 default: 1303 default:
@@ -1211,12 +1412,21 @@ void cx88_card_setup(struct cx88_core *core)
1211 if (0 == core->i2c_rc) 1412 if (0 == core->i2c_rc)
1212 leadtek_eeprom(core,eeprom); 1413 leadtek_eeprom(core,eeprom);
1213 break; 1414 break;
1415 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
1416 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
1214 case CX88_BOARD_HAUPPAUGE_DVB_T1: 1417 case CX88_BOARD_HAUPPAUGE_DVB_T1:
1418 case CX88_BOARD_HAUPPAUGE_HVR1100:
1419 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
1215 if (0 == core->i2c_rc) 1420 if (0 == core->i2c_rc)
1216 hauppauge_eeprom(core,eeprom); 1421 hauppauge_eeprom(core,eeprom);
1217 break; 1422 break;
1423 case CX88_BOARD_KWORLD_DVBS_100:
1424 cx_write(MO_GP0_IO, 0x000007f8);
1425 cx_write(MO_GP1_IO, 0x00000001);
1426 break;
1218 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: 1427 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
1219 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: 1428 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
1429 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
1220 /* GPIO0:0 is hooked to mt352 reset pin */ 1430 /* GPIO0:0 is hooked to mt352 reset pin */
1221 cx_set(MO_GP0_IO, 0x00000101); 1431 cx_set(MO_GP0_IO, 0x00000101);
1222 cx_clear(MO_GP0_IO, 0x00000001); 1432 cx_clear(MO_GP0_IO, 0x00000001);
@@ -1232,6 +1442,9 @@ void cx88_card_setup(struct cx88_core *core)
1232 cx_clear(MO_GP0_IO, 0x00000007); 1442 cx_clear(MO_GP0_IO, 0x00000007);
1233 cx_set(MO_GP2_IO, 0x00000101); 1443 cx_set(MO_GP2_IO, 0x00000101);
1234 break; 1444 break;
1445 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
1446 cx_write(MO_GP0_IO, 0x00080808);
1447 break;
1235 case CX88_BOARD_ATI_HDTVWONDER: 1448 case CX88_BOARD_ATI_HDTVWONDER:
1236 if (0 == core->i2c_rc) { 1449 if (0 == core->i2c_rc) {
1237 /* enable tuner */ 1450 /* enable tuner */
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index bb6eb54e19ce..9975be1aca38 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -34,6 +34,7 @@
34#include <linux/videodev2.h> 34#include <linux/videodev2.h>
35 35
36#include "cx88.h" 36#include "cx88.h"
37#include <media/v4l2-common.h>
37 38
38MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); 39MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
39MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 40MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -76,60 +77,6 @@ static unsigned int cx88_devcount;
76static LIST_HEAD(cx88_devlist); 77static LIST_HEAD(cx88_devlist);
77static DECLARE_MUTEX(devlist); 78static DECLARE_MUTEX(devlist);
78 79
79/* ------------------------------------------------------------------ */
80/* debug help functions */
81
82static const char *v4l1_ioctls[] = {
83 "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
84 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
85 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
86 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
87 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
88#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
89
90static const char *v4l2_ioctls[] = {
91 "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
92 "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
93 "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
94 "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
95 "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
96 "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
97 "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
98 "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
99 "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
100 "S_MODULATOR"
101};
102#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
103
104void cx88_print_ioctl(char *name, unsigned int cmd)
105{
106 char *dir;
107
108 switch (_IOC_DIR(cmd)) {
109 case _IOC_NONE: dir = "--"; break;
110 case _IOC_READ: dir = "r-"; break;
111 case _IOC_WRITE: dir = "-w"; break;
112 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
113 default: dir = "??"; break;
114 }
115 switch (_IOC_TYPE(cmd)) {
116 case 'v':
117 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
118 name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
119 v4l1_ioctls[_IOC_NR(cmd)] : "???");
120 break;
121 case 'V':
122 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
123 name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
124 v4l2_ioctls[_IOC_NR(cmd)] : "???");
125 break;
126 default:
127 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
128 name, cmd, dir, _IOC_NR(cmd));
129 }
130}
131
132/* ------------------------------------------------------------------ */
133#define NO_SYNC_LINE (-1U) 80#define NO_SYNC_LINE (-1U)
134 81
135static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist, 82static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
@@ -291,9 +238,9 @@ cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf)
291 * channel 22 (u video) - 2.0k 238 * channel 22 (u video) - 2.0k
292 * channel 23 (v video) - 2.0k 239 * channel 23 (v video) - 2.0k
293 * channel 24 (vbi) - 4.0k 240 * channel 24 (vbi) - 4.0k
294 * channels 25+26 (audio) - 0.5k 241 * channels 25+26 (audio) - 4.0k
295 * channel 28 (mpeg) - 4.0k 242 * channel 28 (mpeg) - 4.0k
296 * TOTAL = 25.5k 243 * TOTAL = 29.0k
297 * 244 *
298 * Every channel has 160 bytes control data (64 bytes instruction 245 * Every channel has 160 bytes control data (64 bytes instruction
299 * queue and 6 CDT entries), which is close to 2k total. 246 * queue and 6 CDT entries), which is close to 2k total.
@@ -359,7 +306,7 @@ struct sram_channel cx88_sram_channels[] = {
359 .ctrl_start = 0x180680, 306 .ctrl_start = 0x180680,
360 .cdt = 0x180680 + 64, 307 .cdt = 0x180680 + 64,
361 .fifo_start = 0x185400, 308 .fifo_start = 0x185400,
362 .fifo_size = 0x000200, 309 .fifo_size = 0x001000,
363 .ptr1_reg = MO_DMA25_PTR1, 310 .ptr1_reg = MO_DMA25_PTR1,
364 .ptr2_reg = MO_DMA25_PTR2, 311 .ptr2_reg = MO_DMA25_PTR2,
365 .cnt1_reg = MO_DMA25_CNT1, 312 .cnt1_reg = MO_DMA25_CNT1,
@@ -371,7 +318,7 @@ struct sram_channel cx88_sram_channels[] = {
371 .ctrl_start = 0x180720, 318 .ctrl_start = 0x180720,
372 .cdt = 0x180680 + 64, /* same as audio IN */ 319 .cdt = 0x180680 + 64, /* same as audio IN */
373 .fifo_start = 0x185400, /* same as audio IN */ 320 .fifo_start = 0x185400, /* same as audio IN */
374 .fifo_size = 0x000200, /* same as audio IN */ 321 .fifo_size = 0x001000, /* same as audio IN */
375 .ptr1_reg = MO_DMA26_PTR1, 322 .ptr1_reg = MO_DMA26_PTR1,
376 .ptr2_reg = MO_DMA26_PTR2, 323 .ptr2_reg = MO_DMA26_PTR2,
377 .cnt1_reg = MO_DMA26_CNT1, 324 .cnt1_reg = MO_DMA26_CNT1,
@@ -382,7 +329,7 @@ struct sram_channel cx88_sram_channels[] = {
382 .cmds_start = 0x180200, 329 .cmds_start = 0x180200,
383 .ctrl_start = 0x1807C0, 330 .ctrl_start = 0x1807C0,
384 .cdt = 0x1807C0 + 64, 331 .cdt = 0x1807C0 + 64,
385 .fifo_start = 0x185600, 332 .fifo_start = 0x186400,
386 .fifo_size = 0x001000, 333 .fifo_size = 0x001000,
387 .ptr1_reg = MO_DMA28_PTR1, 334 .ptr1_reg = MO_DMA28_PTR1,
388 .ptr2_reg = MO_DMA28_PTR2, 335 .ptr2_reg = MO_DMA28_PTR2,
@@ -848,7 +795,6 @@ int cx88_start_audio_dma(struct cx88_core *core)
848 795
849 /* start dma */ 796 /* start dma */
850 cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */ 797 cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
851
852 return 0; 798 return 0;
853} 799}
854 800
@@ -1208,7 +1154,6 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1208 1154
1209/* ------------------------------------------------------------------ */ 1155/* ------------------------------------------------------------------ */
1210 1156
1211EXPORT_SYMBOL(cx88_print_ioctl);
1212EXPORT_SYMBOL(cx88_print_irqbits); 1157EXPORT_SYMBOL(cx88_print_irqbits);
1213 1158
1214EXPORT_SYMBOL(cx88_core_irq); 1159EXPORT_SYMBOL(cx88_core_irq);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 99ea955f5987..42c012aaa849 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -3,7 +3,7 @@
3 * device driver for Conexant 2388x based TV cards 3 * device driver for Conexant 2388x based TV cards
4 * MPEG Transport Stream (DVB) routines 4 * MPEG Transport Stream (DVB) routines
5 * 5 *
6 * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au> 6 * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
@@ -31,10 +31,14 @@
31 31
32#include "cx88.h" 32#include "cx88.h"
33#include "dvb-pll.h" 33#include "dvb-pll.h"
34#include <media/v4l2-common.h>
34 35
35#ifdef HAVE_MT352 36#ifdef HAVE_MT352
36# include "mt352.h" 37# include "mt352.h"
37# include "mt352_priv.h" 38# include "mt352_priv.h"
39# ifdef HAVE_VP3054_I2C
40# include "cx88-vp3054-i2c.h"
41# endif
38#endif 42#endif
39#ifdef HAVE_CX22702 43#ifdef HAVE_CX22702
40# include "cx22702.h" 44# include "cx22702.h"
@@ -48,6 +52,9 @@
48#ifdef HAVE_NXT200X 52#ifdef HAVE_NXT200X
49# include "nxt200x.h" 53# include "nxt200x.h"
50#endif 54#endif
55#ifdef HAVE_CX24123
56# include "cx24123.h"
57#endif
51 58
52MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 59MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
53MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 60MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -125,6 +132,27 @@ static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
125 return 0; 132 return 0;
126} 133}
127 134
135static int dvico_dual_demod_init(struct dvb_frontend *fe)
136{
137 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
138 static u8 reset [] = { RESET, 0x80 };
139 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
140 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
141 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
142 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
143
144 mt352_write(fe, clock_config, sizeof(clock_config));
145 udelay(200);
146 mt352_write(fe, reset, sizeof(reset));
147 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
148
149 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
150 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
151 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
152
153 return 0;
154}
155
128static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) 156static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
129{ 157{
130 static u8 clock_config [] = { 0x89, 0x38, 0x39 }; 158 static u8 clock_config [] = { 0x89, 0x38, 0x39 };
@@ -172,6 +200,98 @@ static struct mt352_config dntv_live_dvbt_config = {
172 .demod_init = dntv_live_dvbt_demod_init, 200 .demod_init = dntv_live_dvbt_demod_init,
173 .pll_set = mt352_pll_set, 201 .pll_set = mt352_pll_set,
174}; 202};
203
204static struct mt352_config dvico_fusionhdtv_dual = {
205 .demod_address = 0x0F,
206 .demod_init = dvico_dual_demod_init,
207 .pll_set = mt352_pll_set,
208};
209
210#ifdef HAVE_VP3054_I2C
211static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
212{
213 static u8 clock_config [] = { 0x89, 0x38, 0x38 };
214 static u8 reset [] = { 0x50, 0x80 };
215 static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
216 static u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
217 0x00, 0xFF, 0x00, 0x40, 0x40 };
218 static u8 dntv_extra[] = { 0xB5, 0x7A };
219 static u8 capt_range_cfg[] = { 0x75, 0x32 };
220
221 mt352_write(fe, clock_config, sizeof(clock_config));
222 udelay(2000);
223 mt352_write(fe, reset, sizeof(reset));
224 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
225
226 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
227 udelay(2000);
228 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
229 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
230
231 return 0;
232}
233
234static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
235{
236 struct cx8802_dev *dev= fe->dvb->priv;
237
238 /* this message is to set up ATC and ALC */
239 static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 };
240 struct i2c_msg msg =
241 { .addr = dev->core->pll_addr, .flags = 0,
242 .buf = fmd1216_init, .len = sizeof(fmd1216_init) };
243 int err;
244
245 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
246 if (err < 0)
247 return err;
248 else
249 return -EREMOTEIO;
250 }
251
252 return 0;
253}
254
255static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe,
256 struct dvb_frontend_parameters* params,
257 u8* pllbuf)
258{
259 struct cx8802_dev *dev= fe->dvb->priv;
260 struct i2c_msg msg =
261 { .addr = dev->core->pll_addr, .flags = 0,
262 .buf = pllbuf+1, .len = 4 };
263 int err;
264
265 /* Switch PLL to DVB mode */
266 err = philips_fmd1216_pll_init(fe);
267 if (err)
268 return err;
269
270 /* Tune PLL */
271 pllbuf[0] = dev->core->pll_addr << 1;
272 dvb_pll_configure(dev->core->pll_desc, pllbuf+1,
273 params->frequency,
274 params->u.ofdm.bandwidth);
275 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
276 printk(KERN_WARNING "cx88-dvb: %s error "
277 "(addr %02x <- %02x, err = %i)\n",
278 __FUNCTION__, pllbuf[0], pllbuf[1], err);
279 if (err < 0)
280 return err;
281 else
282 return -EREMOTEIO;
283 }
284
285 return 0;
286}
287
288static struct mt352_config dntv_live_dvbt_pro_config = {
289 .demod_address = 0x0f,
290 .no_tuner = 1,
291 .demod_init = dntv_live_dvbt_pro_demod_init,
292 .pll_set = dntv_live_dvbt_pro_pll_set,
293};
294#endif
175#endif 295#endif
176 296
177#ifdef HAVE_CX22702 297#ifdef HAVE_CX22702
@@ -188,6 +308,12 @@ static struct cx22702_config hauppauge_novat_config = {
188 .pll_address = 0x61, 308 .pll_address = 0x61,
189 .pll_desc = &dvb_pll_thomson_dtt759x, 309 .pll_desc = &dvb_pll_thomson_dtt759x,
190}; 310};
311static struct cx22702_config hauppauge_hvr1100_config = {
312 .demod_address = 0x63,
313 .output_mode = CX22702_SERIAL_OUTPUT,
314 .pll_address = 0x61,
315 .pll_desc = &dvb_pll_fmd1216me,
316};
191#endif 317#endif
192 318
193#ifdef HAVE_OR51132 319#ifdef HAVE_OR51132
@@ -314,6 +440,40 @@ static struct nxt200x_config ati_hdtvwonder = {
314}; 440};
315#endif 441#endif
316 442
443#ifdef HAVE_CX24123
444static int cx24123_set_ts_param(struct dvb_frontend* fe,
445 int is_punctured)
446{
447 struct cx8802_dev *dev= fe->dvb->priv;
448 dev->ts_gen_cntrl = 0x2;
449 return 0;
450}
451
452static void cx24123_enable_lnb_voltage(struct dvb_frontend* fe, int on)
453{
454 struct cx8802_dev *dev= fe->dvb->priv;
455 struct cx88_core *core = dev->core;
456
457 if (on)
458 cx_write(MO_GP0_IO, 0x000006f9);
459 else
460 cx_write(MO_GP0_IO, 0x000006fB);
461}
462
463static struct cx24123_config hauppauge_novas_config = {
464 .demod_address = 0x55,
465 .use_isl6421 = 1,
466 .set_ts_params = cx24123_set_ts_param,
467};
468
469static struct cx24123_config kworld_dvbs_100_config = {
470 .demod_address = 0x15,
471 .use_isl6421 = 0,
472 .set_ts_params = cx24123_set_ts_param,
473 .enable_lnb_voltage = cx24123_enable_lnb_voltage,
474};
475#endif
476
317static int dvb_register(struct cx8802_dev *dev) 477static int dvb_register(struct cx8802_dev *dev)
318{ 478{
319 /* init struct videobuf_dvb */ 479 /* init struct videobuf_dvb */
@@ -329,10 +489,16 @@ static int dvb_register(struct cx8802_dev *dev)
329 break; 489 break;
330 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 490 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
331 case CX88_BOARD_CONEXANT_DVB_T1: 491 case CX88_BOARD_CONEXANT_DVB_T1:
492 case CX88_BOARD_KWORLD_DVB_T_CX22702:
332 case CX88_BOARD_WINFAST_DTV1000: 493 case CX88_BOARD_WINFAST_DTV1000:
333 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, 494 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
334 &dev->core->i2c_adap); 495 &dev->core->i2c_adap);
335 break; 496 break;
497 case CX88_BOARD_HAUPPAUGE_HVR1100:
498 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
499 dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config,
500 &dev->core->i2c_adap);
501 break;
336#endif 502#endif
337#ifdef HAVE_MT352 503#ifdef HAVE_MT352
338 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: 504 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
@@ -355,6 +521,24 @@ static int dvb_register(struct cx8802_dev *dev)
355 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, 521 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
356 &dev->core->i2c_adap); 522 &dev->core->i2c_adap);
357 break; 523 break;
524 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
525#ifdef HAVE_VP3054_I2C
526 dev->core->pll_addr = 0x61;
527 dev->core->pll_desc = &dvb_pll_fmd1216me;
528 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config,
529 &((struct vp3054_i2c_state *)dev->card_priv)->adap);
530#else
531 printk("%s: built without vp3054 support\n", dev->core->name);
532#endif
533 break;
534 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
535 /* The tin box says DEE1601, but it seems to be DTT7579
536 * compatible, with a slightly different MT352 AGC gain. */
537 dev->core->pll_addr = 0x61;
538 dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
539 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual,
540 &dev->core->i2c_adap);
541 break;
358#endif 542#endif
359#ifdef HAVE_OR51132 543#ifdef HAVE_OR51132
360 case CX88_BOARD_PCHDTV_HD3000: 544 case CX88_BOARD_PCHDTV_HD3000:
@@ -393,7 +577,7 @@ static int dvb_register(struct cx8802_dev *dev)
393 cx_set(MO_GP0_IO, 9); 577 cx_set(MO_GP0_IO, 9);
394 mdelay(200); 578 mdelay(200);
395 dev->core->pll_addr = 0x61; 579 dev->core->pll_addr = 0x61;
396 dev->core->pll_desc = &dvb_pll_thomson_dtt7611; 580 dev->core->pll_desc = &dvb_pll_thomson_dtt761x;
397 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, 581 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold,
398 &dev->core->i2c_adap); 582 &dev->core->i2c_adap);
399 } 583 }
@@ -421,6 +605,17 @@ static int dvb_register(struct cx8802_dev *dev)
421 &dev->core->i2c_adap); 605 &dev->core->i2c_adap);
422 break; 606 break;
423#endif 607#endif
608#ifdef HAVE_CX24123
609 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
610 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
611 dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config,
612 &dev->core->i2c_adap);
613 break;
614 case CX88_BOARD_KWORLD_DVBS_100:
615 dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config,
616 &dev->core->i2c_adap);
617 break;
618#endif
424 default: 619 default:
425 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", 620 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
426 dev->core->name); 621 dev->core->name);
@@ -473,6 +668,12 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
473 if (0 != err) 668 if (0 != err)
474 goto fail_free; 669 goto fail_free;
475 670
671#ifdef HAVE_VP3054_I2C
672 err = vp3054_i2c_probe(dev);
673 if (0 != err)
674 goto fail_free;
675#endif
676
476 /* dvb stuff */ 677 /* dvb stuff */
477 printk("%s/2: cx2388x based dvb card\n", core->name); 678 printk("%s/2: cx2388x based dvb card\n", core->name);
478 videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops, 679 videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops,
@@ -484,6 +685,9 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
484 err = dvb_register(dev); 685 err = dvb_register(dev);
485 if (0 != err) 686 if (0 != err)
486 goto fail_fini; 687 goto fail_fini;
688
689 /* Maintain a reference to cx88-video can query the 8802 device. */
690 core->dvbdev = dev;
487 return 0; 691 return 0;
488 692
489 fail_fini: 693 fail_fini:
@@ -499,9 +703,16 @@ static void __devexit dvb_remove(struct pci_dev *pci_dev)
499{ 703{
500 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 704 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
501 705
706 /* Destroy any 8802 reference. */
707 dev->core->dvbdev = NULL;
708
502 /* dvb */ 709 /* dvb */
503 videobuf_dvb_unregister(&dev->dvb); 710 videobuf_dvb_unregister(&dev->dvb);
504 711
712#ifdef HAVE_VP3054_I2C
713 vp3054_i2c_remove(dev);
714#endif
715
505 /* common */ 716 /* common */
506 cx8802_fini_common(dev); 717 cx8802_fini_common(dev);
507 cx88_core_put(dev->core,dev->pci); 718 cx88_core_put(dev->core,dev->pci);
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 4a8fb161b16a..f720901e9638 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -30,6 +30,7 @@
30#include <asm/io.h> 30#include <asm/io.h>
31 31
32#include "cx88.h" 32#include "cx88.h"
33#include <media/v4l2-common.h>
33 34
34static unsigned int i2c_debug = 0; 35static unsigned int i2c_debug = 0;
35module_param(i2c_debug, int, 0644); 36module_param(i2c_debug, int, 0644);
@@ -135,7 +136,17 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
135{ 136{
136 if (0 != core->i2c_rc) 137 if (0 != core->i2c_rc)
137 return; 138 return;
138 i2c_clients_command(&core->i2c_adap, cmd, arg); 139
140 if (core->dvbdev) {
141 if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl)
142 core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
143
144 i2c_clients_command(&core->i2c_adap, cmd, arg);
145
146 if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl)
147 core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0);
148 } else
149 i2c_clients_command(&core->i2c_adap, cmd, arg);
139} 150}
140 151
141static struct i2c_algo_bit_data cx8800_i2c_algo_template = { 152static struct i2c_algo_bit_data cx8800_i2c_algo_template = {
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 461019dca901..286c85b6bdf9 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * Copyright (c) 2003 Pavel Machek 6 * Copyright (c) 2003 Pavel Machek
7 * Copyright (c) 2004 Gerd Knorr 7 * Copyright (c) 2004 Gerd Knorr
8 * Copyright (c) 2004 Chris Pascoe 8 * Copyright (c) 2004, 2005 Chris Pascoe
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -29,9 +29,8 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/moduleparam.h> 30#include <linux/moduleparam.h>
31 31
32#include <media/ir-common.h>
33
34#include "cx88.h" 32#include "cx88.h"
33#include <media/ir-common.h>
35 34
36/* ---------------------------------------------------------------------- */ 35/* ---------------------------------------------------------------------- */
37 36
@@ -258,6 +257,114 @@ static IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = {
258 257
259/* ---------------------------------------------------------------------- */ 258/* ---------------------------------------------------------------------- */
260 259
260/* AVERTV STUDIO 303 Remote */
261static IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = {
262 [ 0x2a ] = KEY_KP1,
263 [ 0x32 ] = KEY_KP2,
264 [ 0x3a ] = KEY_KP3,
265 [ 0x4a ] = KEY_KP4,
266 [ 0x52 ] = KEY_KP5,
267 [ 0x5a ] = KEY_KP6,
268 [ 0x6a ] = KEY_KP7,
269 [ 0x72 ] = KEY_KP8,
270 [ 0x7a ] = KEY_KP9,
271 [ 0x0e ] = KEY_KP0,
272
273 [ 0x02 ] = KEY_POWER,
274 [ 0x22 ] = KEY_VIDEO,
275 [ 0x42 ] = KEY_AUDIO,
276 [ 0x62 ] = KEY_ZOOM,
277 [ 0x0a ] = KEY_TV,
278 [ 0x12 ] = KEY_CD,
279 [ 0x1a ] = KEY_TEXT,
280
281 [ 0x16 ] = KEY_SUBTITLE,
282 [ 0x1e ] = KEY_REWIND,
283 [ 0x06 ] = KEY_PRINT,
284
285 [ 0x2e ] = KEY_SEARCH,
286 [ 0x36 ] = KEY_SLEEP,
287 [ 0x3e ] = KEY_SHUFFLE,
288 [ 0x26 ] = KEY_MUTE,
289
290 [ 0x4e ] = KEY_RECORD,
291 [ 0x56 ] = KEY_PAUSE,
292 [ 0x5e ] = KEY_STOP,
293 [ 0x46 ] = KEY_PLAY,
294
295 [ 0x6e ] = KEY_RED,
296 [ 0x0b ] = KEY_GREEN,
297 [ 0x66 ] = KEY_YELLOW,
298 [ 0x03 ] = KEY_BLUE,
299
300 [ 0x76 ] = KEY_LEFT,
301 [ 0x7e ] = KEY_RIGHT,
302 [ 0x13 ] = KEY_DOWN,
303 [ 0x1b ] = KEY_UP,
304};
305
306/* ---------------------------------------------------------------------- */
307
308/* DigitalNow DNTV Live! DVB-T Pro Remote */
309static IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = {
310 [ 0x16 ] = KEY_POWER,
311 [ 0x5b ] = KEY_HOME,
312
313 [ 0x55 ] = KEY_TV, /* live tv */
314 [ 0x58 ] = KEY_TUNER, /* digital Radio */
315 [ 0x5a ] = KEY_RADIO, /* FM radio */
316 [ 0x59 ] = KEY_DVD, /* dvd menu */
317 [ 0x03 ] = KEY_1,
318 [ 0x01 ] = KEY_2,
319 [ 0x06 ] = KEY_3,
320 [ 0x09 ] = KEY_4,
321 [ 0x1d ] = KEY_5,
322 [ 0x1f ] = KEY_6,
323 [ 0x0d ] = KEY_7,
324 [ 0x19 ] = KEY_8,
325 [ 0x1b ] = KEY_9,
326 [ 0x0c ] = KEY_CANCEL,
327 [ 0x15 ] = KEY_0,
328 [ 0x4a ] = KEY_CLEAR,
329 [ 0x13 ] = KEY_BACK,
330 [ 0x00 ] = KEY_TAB,
331 [ 0x4b ] = KEY_UP,
332 [ 0x4e ] = KEY_LEFT,
333 [ 0x4f ] = KEY_OK,
334 [ 0x52 ] = KEY_RIGHT,
335 [ 0x51 ] = KEY_DOWN,
336 [ 0x1e ] = KEY_VOLUMEUP,
337 [ 0x0a ] = KEY_VOLUMEDOWN,
338 [ 0x02 ] = KEY_CHANNELDOWN,
339 [ 0x05 ] = KEY_CHANNELUP,
340 [ 0x11 ] = KEY_RECORD,
341 [ 0x14 ] = KEY_PLAY,
342 [ 0x4c ] = KEY_PAUSE,
343 [ 0x1a ] = KEY_STOP,
344 [ 0x40 ] = KEY_REWIND,
345 [ 0x12 ] = KEY_FASTFORWARD,
346 [ 0x41 ] = KEY_PREVIOUSSONG, /* replay |< */
347 [ 0x42 ] = KEY_NEXTSONG, /* skip >| */
348 [ 0x54 ] = KEY_CAMERA, /* capture */
349 [ 0x50 ] = KEY_LANGUAGE, /* sap */
350 [ 0x47 ] = KEY_TV2, /* pip */
351 [ 0x4d ] = KEY_SCREEN,
352 [ 0x43 ] = KEY_SUBTITLE,
353 [ 0x10 ] = KEY_MUTE,
354 [ 0x49 ] = KEY_AUDIO, /* l/r */
355 [ 0x07 ] = KEY_SLEEP,
356 [ 0x08 ] = KEY_VIDEO, /* a/v */
357 [ 0x0e ] = KEY_PREVIOUS, /* recall */
358 [ 0x45 ] = KEY_ZOOM, /* zoom + */
359 [ 0x46 ] = KEY_ANGLE, /* zoom - */
360 [ 0x56 ] = KEY_RED,
361 [ 0x57 ] = KEY_GREEN,
362 [ 0x5c ] = KEY_YELLOW,
363 [ 0x5d ] = KEY_BLUE,
364};
365
366/* ---------------------------------------------------------------------- */
367
261struct cx88_IR { 368struct cx88_IR {
262 struct cx88_core *core; 369 struct cx88_core *core;
263 struct input_dev *input; 370 struct input_dev *input;
@@ -266,7 +373,7 @@ struct cx88_IR {
266 char phys[32]; 373 char phys[32];
267 374
268 /* sample from gpio pin 16 */ 375 /* sample from gpio pin 16 */
269 int sampling; 376 u32 sampling;
270 u32 samples[16]; 377 u32 samples[16];
271 int scount; 378 int scount;
272 unsigned long release; 379 unsigned long release;
@@ -384,10 +491,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
384 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 491 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
385 ir_codes = ir_codes_cinergy_1400; 492 ir_codes = ir_codes_cinergy_1400;
386 ir_type = IR_TYPE_PD; 493 ir_type = IR_TYPE_PD;
387 ir->sampling = 1; 494 ir->sampling = 0xeb04; /* address */
388 break; 495 break;
389 case CX88_BOARD_HAUPPAUGE: 496 case CX88_BOARD_HAUPPAUGE:
390 case CX88_BOARD_HAUPPAUGE_DVB_T1: 497 case CX88_BOARD_HAUPPAUGE_DVB_T1:
498 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
499 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
500 case CX88_BOARD_HAUPPAUGE_HVR1100:
391 ir_codes = ir_codes_hauppauge_new; 501 ir_codes = ir_codes_hauppauge_new;
392 ir_type = IR_TYPE_RC5; 502 ir_type = IR_TYPE_RC5;
393 ir->sampling = 1; 503 ir->sampling = 1;
@@ -427,6 +537,19 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
427 ir->mask_keyup = 0x40; 537 ir->mask_keyup = 0x40;
428 ir->polling = 1; /* ms */ 538 ir->polling = 1; /* ms */
429 break; 539 break;
540 case CX88_BOARD_AVERTV_303:
541 case CX88_BOARD_AVERTV_STUDIO_303:
542 ir_codes = ir_codes_avertv_303;
543 ir->gpio_addr = MO_GP2_IO;
544 ir->mask_keycode = 0xfb;
545 ir->mask_keydown = 0x02;
546 ir->polling = 50; /* ms */
547 break;
548 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
549 ir_codes = ir_codes_dntv_live_dvbt_pro;
550 ir_type = IR_TYPE_PD;
551 ir->sampling = 0xff00; /* address */
552 break;
430 } 553 }
431 554
432 if (NULL == ir_codes) { 555 if (NULL == ir_codes) {
@@ -484,6 +607,10 @@ int cx88_ir_fini(struct cx88_core *core)
484 if (NULL == ir) 607 if (NULL == ir)
485 return 0; 608 return 0;
486 609
610 if (ir->sampling) {
611 cx_write(MO_DDSCFG_IO, 0x0);
612 core->pci_irqmask &= ~(1 << 18);
613 }
487 if (ir->polling) { 614 if (ir->polling) {
488 del_timer(&ir->timer); 615 del_timer(&ir->timer);
489 flush_scheduled_work(); 616 flush_scheduled_work();
@@ -535,6 +662,7 @@ void cx88_ir_irq(struct cx88_core *core)
535 /* decode it */ 662 /* decode it */
536 switch (core->board) { 663 switch (core->board) {
537 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 664 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
665 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
538 ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4); 666 ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
539 667
540 if (ircode == 0xffffffff) { /* decoding error */ 668 if (ircode == 0xffffffff) { /* decoding error */
@@ -550,7 +678,7 @@ void cx88_ir_irq(struct cx88_core *core)
550 break; 678 break;
551 } 679 }
552 680
553 if ((ircode & 0xffff) != 0xeb04) { /* wrong address */ 681 if ((ircode & 0xffff) != (ir->sampling & 0xffff)) { /* wrong address */
554 ir_dprintk("pulse distance decoded wrong address\n"); 682 ir_dprintk("pulse distance decoded wrong address\n");
555 break; 683 break;
556 } 684 }
@@ -567,6 +695,8 @@ void cx88_ir_irq(struct cx88_core *core)
567 break; 695 break;
568 case CX88_BOARD_HAUPPAUGE: 696 case CX88_BOARD_HAUPPAUGE:
569 case CX88_BOARD_HAUPPAUGE_DVB_T1: 697 case CX88_BOARD_HAUPPAUGE_DVB_T1:
698 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
699 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
570 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); 700 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
571 ir_dprintk("biphase decoded: %x\n", ircode); 701 ir_dprintk("biphase decoded: %x\n", ircode);
572 if ((ircode & 0xfffff000) != 0x3000) 702 if ((ircode & 0xfffff000) != 0x3000)
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 35e6d0c2b872..c79cc1d2bf8b 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -78,6 +78,11 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
78 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: 78 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
79 cx_write(TS_SOP_STAT, 1<<13); 79 cx_write(TS_SOP_STAT, 1<<13);
80 break; 80 break;
81 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
82 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
83 cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */
84 udelay(100);
85 break;
81 default: 86 default:
82 cx_write(TS_SOP_STAT, 0x00); 87 cx_write(TS_SOP_STAT, 0x00);
83 break; 88 break;
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index a1b120c8a9b5..24118e43e73a 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -132,14 +132,22 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
132{ 132{
133 u32 volume; 133 u32 volume;
134 134
135#ifndef USING_CX88_ALSA
135 /* restart dma; This avoids buzz in NICAM and is good in others */ 136 /* restart dma; This avoids buzz in NICAM and is good in others */
136 cx88_stop_audio_dma(core); 137 cx88_stop_audio_dma(core);
138#endif
137 cx_write(AUD_RATE_THRES_DMD, 0x000000C0); 139 cx_write(AUD_RATE_THRES_DMD, 0x000000C0);
140#ifndef USING_CX88_ALSA
138 cx88_start_audio_dma(core); 141 cx88_start_audio_dma(core);
142#endif
139 143
140 if (cx88_boards[core->board].blackbird) { 144 if (cx88_boards[core->board].blackbird) {
141 /* sets sound input from external adc */ 145 /* sets sound input from external adc */
142 cx_set(AUD_CTL, EN_I2SIN_ENABLE); 146 if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN)
147 cx_clear(AUD_CTL, EN_I2SIN_ENABLE);
148 else
149 cx_set(AUD_CTL, EN_I2SIN_ENABLE);
150
143 cx_write(AUD_I2SINPUTCNTL, 4); 151 cx_write(AUD_I2SINPUTCNTL, 4);
144 cx_write(AUD_BAUDRATE, 1); 152 cx_write(AUD_BAUDRATE, 1);
145 /* 'pass-thru mode': this enables the i2s output to the mpeg encoder */ 153 /* 'pass-thru mode': this enables the i2s output to the mpeg encoder */
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 24a48f8a48c1..9a02515fe18b 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -33,6 +33,7 @@
33#include <asm/div64.h> 33#include <asm/div64.h>
34 34
35#include "cx88.h" 35#include "cx88.h"
36#include <media/v4l2-common.h>
36 37
37/* Include V4L1 specific functions. Should be removed soon */ 38/* Include V4L1 specific functions. Should be removed soon */
38#include <linux/videodev.h> 39#include <linux/videodev.h>
@@ -240,7 +241,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
240 .minimum = 0, 241 .minimum = 0,
241 .maximum = 0xff, 242 .maximum = 0xff,
242 .step = 1, 243 .step = 1,
243 .default_value = 0, 244 .default_value = 0x3f,
244 .type = V4L2_CTRL_TYPE_INTEGER, 245 .type = V4L2_CTRL_TYPE_INTEGER,
245 }, 246 },
246 .off = 0, 247 .off = 0,
@@ -271,7 +272,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
271 .minimum = 0, 272 .minimum = 0,
272 .maximum = 0xff, 273 .maximum = 0xff,
273 .step = 1, 274 .step = 1,
274 .default_value = 0, 275 .default_value = 0x7f,
275 .type = V4L2_CTRL_TYPE_INTEGER, 276 .type = V4L2_CTRL_TYPE_INTEGER,
276 }, 277 },
277 .off = 0, 278 .off = 0,
@@ -285,6 +286,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
285 .name = "Mute", 286 .name = "Mute",
286 .minimum = 0, 287 .minimum = 0,
287 .maximum = 1, 288 .maximum = 1,
289 .default_value = 1,
288 .type = V4L2_CTRL_TYPE_BOOLEAN, 290 .type = V4L2_CTRL_TYPE_BOOLEAN,
289 }, 291 },
290 .reg = AUD_VOL_CTL, 292 .reg = AUD_VOL_CTL,
@@ -298,7 +300,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
298 .minimum = 0, 300 .minimum = 0,
299 .maximum = 0x3f, 301 .maximum = 0x3f,
300 .step = 1, 302 .step = 1,
301 .default_value = 0, 303 .default_value = 0x1f,
302 .type = V4L2_CTRL_TYPE_INTEGER, 304 .type = V4L2_CTRL_TYPE_INTEGER,
303 }, 305 },
304 .reg = AUD_VOL_CTL, 306 .reg = AUD_VOL_CTL,
@@ -917,6 +919,9 @@ static int get_control(struct cx88_core *core, struct v4l2_control *ctl)
917 ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift; 919 ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift;
918 break; 920 break;
919 } 921 }
922 printk("get_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
923 ctl->id, c->reg, ctl->value,
924 c->mask, c->sreg ? " [shadowed]" : "");
920 return 0; 925 return 0;
921} 926}
922 927
@@ -925,13 +930,13 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
925{ 930{
926 /* struct cx88_core *core = dev->core; */ 931 /* struct cx88_core *core = dev->core; */
927 struct cx88_ctrl *c = NULL; 932 struct cx88_ctrl *c = NULL;
928 u32 v_sat_value; 933 u32 value,mask;
929 u32 value;
930 int i; 934 int i;
931 935 for (i = 0; i < CX8800_CTLS; i++) {
932 for (i = 0; i < CX8800_CTLS; i++) 936 if (cx8800_ctls[i].v.id == ctl->id) {
933 if (cx8800_ctls[i].v.id == ctl->id)
934 c = &cx8800_ctls[i]; 937 c = &cx8800_ctls[i];
938 }
939 }
935 if (NULL == c) 940 if (NULL == c)
936 return -EINVAL; 941 return -EINVAL;
937 942
@@ -939,6 +944,7 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
939 ctl->value = c->v.minimum; 944 ctl->value = c->v.minimum;
940 if (ctl->value > c->v.maximum) 945 if (ctl->value > c->v.maximum)
941 ctl->value = c->v.maximum; 946 ctl->value = c->v.maximum;
947 mask=c->mask;
942 switch (ctl->id) { 948 switch (ctl->id) {
943 case V4L2_CID_AUDIO_BALANCE: 949 case V4L2_CID_AUDIO_BALANCE:
944 value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; 950 value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value;
@@ -948,56 +954,44 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
948 break; 954 break;
949 case V4L2_CID_SATURATION: 955 case V4L2_CID_SATURATION:
950 /* special v_sat handling */ 956 /* special v_sat handling */
951 v_sat_value = ctl->value - (0x7f - 0x5a); 957
952 if (v_sat_value > 0xff) 958 value = ((ctl->value - c->off) << c->shift) & c->mask;
953 v_sat_value = 0xff; 959
954 if (v_sat_value < 0x00) 960 if (core->tvnorm->id & V4L2_STD_SECAM) {
955 v_sat_value = 0x00; 961 /* For SECAM, both U and V sat should be equal */
956 cx_andor(MO_UV_SATURATION, 0xff00, v_sat_value << 8); 962 value=value<<8|value;
957 /* fall through to default route for u_sat */ 963 } else {
964 /* Keeps U Saturation proportional to V Sat */
965 value=(value*0x5a)/0x7f<<8|value;
966 }
967 mask=0xffff;
968 break;
958 default: 969 default:
959 value = ((ctl->value - c->off) << c->shift) & c->mask; 970 value = ((ctl->value - c->off) << c->shift) & c->mask;
960 break; 971 break;
961 } 972 }
962 dprintk(1,"set_control id=0x%X reg=0x%x val=0x%x%s\n", 973 printk("set_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
963 ctl->id, c->reg, value, c->sreg ? " [shadowed]" : ""); 974 ctl->id, c->reg, value,
975 mask, c->sreg ? " [shadowed]" : "");
964 if (c->sreg) { 976 if (c->sreg) {
965 cx_sandor(c->sreg, c->reg, c->mask, value); 977 cx_sandor(c->sreg, c->reg, mask, value);
966 } else { 978 } else {
967 cx_andor(c->reg, c->mask, value); 979 cx_andor(c->reg, mask, value);
968 } 980 }
969 return 0; 981 return 0;
970} 982}
971 983
972/* static void init_controls(struct cx8800_dev *dev) */
973static void init_controls(struct cx88_core *core) 984static void init_controls(struct cx88_core *core)
974{ 985{
975 static struct v4l2_control mute = { 986 struct v4l2_control ctrl;
976 .id = V4L2_CID_AUDIO_MUTE, 987 int i;
977 .value = 1,
978 };
979 static struct v4l2_control volume = {
980 .id = V4L2_CID_AUDIO_VOLUME,
981 .value = 0x3f,
982 };
983 static struct v4l2_control hue = {
984 .id = V4L2_CID_HUE,
985 .value = 0x80,
986 };
987 static struct v4l2_control contrast = {
988 .id = V4L2_CID_CONTRAST,
989 .value = 0x80,
990 };
991 static struct v4l2_control brightness = {
992 .id = V4L2_CID_BRIGHTNESS,
993 .value = 0x80,
994 };
995 988
996 set_control(core,&mute); 989 for (i = 0; i < CX8800_CTLS; i++) {
997 set_control(core,&volume); 990 ctrl.id=cx8800_ctls[i].v.id;
998 set_control(core,&hue); 991 ctrl.value=cx8800_ctls[i].v.default_value
999 set_control(core,&contrast); 992 +cx8800_ctls[i].off;
1000 set_control(core,&brightness); 993 set_control(core, &ctrl);
994 }
1001} 995}
1002 996
1003/* ------------------------------------------------------------------ */ 997/* ------------------------------------------------------------------ */
@@ -1125,7 +1119,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1125 int err; 1119 int err;
1126 1120
1127 if (video_debug > 1) 1121 if (video_debug > 1)
1128 cx88_print_ioctl(core->name,cmd); 1122 v4l_print_ioctl(core->name,cmd);
1129 switch (cmd) { 1123 switch (cmd) {
1130 1124
1131 /* --- capabilities ------------------------------------------ */ 1125 /* --- capabilities ------------------------------------------ */
@@ -1261,7 +1255,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1261 1255
1262 dprintk( 1, "CORE IOCTL: 0x%x\n", cmd ); 1256 dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
1263 if (video_debug > 1) 1257 if (video_debug > 1)
1264 cx88_print_ioctl(core->name,cmd); 1258 v4l_print_ioctl(core->name,cmd);
1265 1259
1266 switch (cmd) { 1260 switch (cmd) {
1267 /* ---------- tv norms ---------- */ 1261 /* ---------- tv norms ---------- */
@@ -1481,7 +1475,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1481 struct cx88_core *core = dev->core; 1475 struct cx88_core *core = dev->core;
1482 1476
1483 if (video_debug > 1) 1477 if (video_debug > 1)
1484 cx88_print_ioctl(core->name,cmd); 1478 v4l_print_ioctl(core->name,cmd);
1485 1479
1486 switch (cmd) { 1480 switch (cmd) {
1487 case VIDIOC_QUERYCAP: 1481 case VIDIOC_QUERYCAP:
@@ -1740,6 +1734,7 @@ static struct file_operations video_fops =
1740 .poll = video_poll, 1734 .poll = video_poll,
1741 .mmap = video_mmap, 1735 .mmap = video_mmap,
1742 .ioctl = video_ioctl, 1736 .ioctl = video_ioctl,
1737 .compat_ioctl = v4l_compat_ioctl32,
1743 .llseek = no_llseek, 1738 .llseek = no_llseek,
1744}; 1739};
1745 1740
@@ -1767,6 +1762,7 @@ static struct file_operations radio_fops =
1767 .open = video_open, 1762 .open = video_open,
1768 .release = video_release, 1763 .release = video_release,
1769 .ioctl = radio_ioctl, 1764 .ioctl = radio_ioctl,
1765 .compat_ioctl = v4l_compat_ioctl32,
1770 .llseek = no_llseek, 1766 .llseek = no_llseek,
1771}; 1767};
1772 1768
@@ -1928,8 +1924,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1928 1924
1929 /* initial device configuration */ 1925 /* initial device configuration */
1930 down(&core->lock); 1926 down(&core->lock);
1931 init_controls(core);
1932 cx88_set_tvnorm(core,tvnorms); 1927 cx88_set_tvnorm(core,tvnorms);
1928 init_controls(core);
1933 video_mux(core,0); 1929 video_mux(core,0);
1934 up(&core->lock); 1930 up(&core->lock);
1935 1931
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c
new file mode 100644
index 000000000000..372cd29cedbd
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c
@@ -0,0 +1,173 @@
1/*
2
3 cx88-vp3054-i2c.c -- support for the secondary I2C bus of the
4 DNTV Live! DVB-T Pro (VP-3054), wired as:
5 GPIO[0] -> SCL, GPIO[1] -> SDA
6
7 (c) 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
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 as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23*/
24
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28
29#include <asm/io.h>
30
31#include "cx88.h"
32#include "cx88-vp3054-i2c.h"
33
34
35/* ----------------------------------------------------------------------- */
36
37static void vp3054_bit_setscl(void *data, int state)
38{
39 struct cx8802_dev *dev = data;
40 struct cx88_core *core = dev->core;
41 struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
42
43 if (state) {
44 vp3054_i2c->state |= 0x0001; /* SCL high */
45 vp3054_i2c->state &= ~0x0100; /* external pullup */
46 } else {
47 vp3054_i2c->state &= ~0x0001; /* SCL low */
48 vp3054_i2c->state |= 0x0100; /* drive pin */
49 }
50 cx_write(MO_GP0_IO, 0x010000 | vp3054_i2c->state);
51 cx_read(MO_GP0_IO);
52}
53
54static void vp3054_bit_setsda(void *data, int state)
55{
56 struct cx8802_dev *dev = data;
57 struct cx88_core *core = dev->core;
58 struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
59
60 if (state) {
61 vp3054_i2c->state |= 0x0002; /* SDA high */
62 vp3054_i2c->state &= ~0x0200; /* tristate pin */
63 } else {
64 vp3054_i2c->state &= ~0x0002; /* SDA low */
65 vp3054_i2c->state |= 0x0200; /* drive pin */
66 }
67 cx_write(MO_GP0_IO, 0x020000 | vp3054_i2c->state);
68 cx_read(MO_GP0_IO);
69}
70
71static int vp3054_bit_getscl(void *data)
72{
73 struct cx8802_dev *dev = data;
74 struct cx88_core *core = dev->core;
75 u32 state;
76
77 state = cx_read(MO_GP0_IO);
78 return (state & 0x01) ? 1 : 0;
79}
80
81static int vp3054_bit_getsda(void *data)
82{
83 struct cx8802_dev *dev = data;
84 struct cx88_core *core = dev->core;
85 u32 state;
86
87 state = cx_read(MO_GP0_IO);
88 return (state & 0x02) ? 1 : 0;
89}
90
91/* ----------------------------------------------------------------------- */
92
93static struct i2c_algo_bit_data vp3054_i2c_algo_template = {
94 .setsda = vp3054_bit_setsda,
95 .setscl = vp3054_bit_setscl,
96 .getsda = vp3054_bit_getsda,
97 .getscl = vp3054_bit_getscl,
98 .udelay = 16,
99 .mdelay = 10,
100 .timeout = 200,
101};
102
103/* ----------------------------------------------------------------------- */
104
105static struct i2c_adapter vp3054_i2c_adap_template = {
106 .name = "cx2388x",
107 .owner = THIS_MODULE,
108 .id = I2C_HW_B_CX2388x,
109};
110
111static struct i2c_client vp3054_i2c_client_template = {
112 .name = "VP-3054",
113};
114
115int vp3054_i2c_probe(struct cx8802_dev *dev)
116{
117 struct cx88_core *core = dev->core;
118 struct vp3054_i2c_state *vp3054_i2c;
119 int rc;
120
121 if (core->board != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
122 return 0;
123
124 dev->card_priv = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL);
125 if (dev->card_priv == NULL)
126 return -ENOMEM;
127 vp3054_i2c = dev->card_priv;
128
129 memcpy(&vp3054_i2c->adap, &vp3054_i2c_adap_template,
130 sizeof(vp3054_i2c->adap));
131 memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template,
132 sizeof(vp3054_i2c->algo));
133 memcpy(&vp3054_i2c->client, &vp3054_i2c_client_template,
134 sizeof(vp3054_i2c->client));
135
136 vp3054_i2c->adap.class |= I2C_CLASS_TV_DIGITAL;
137
138 vp3054_i2c->adap.dev.parent = &dev->pci->dev;
139 strlcpy(vp3054_i2c->adap.name, core->name,
140 sizeof(vp3054_i2c->adap.name));
141 vp3054_i2c->algo.data = dev;
142 i2c_set_adapdata(&vp3054_i2c->adap, dev);
143 vp3054_i2c->adap.algo_data = &vp3054_i2c->algo;
144 vp3054_i2c->client.adapter = &vp3054_i2c->adap;
145
146 vp3054_bit_setscl(dev,1);
147 vp3054_bit_setsda(dev,1);
148
149 rc = i2c_bit_add_bus(&vp3054_i2c->adap);
150 if (0 != rc) {
151 printk("%s: vp3054_i2c register FAILED\n", core->name);
152
153 kfree(dev->card_priv);
154 dev->card_priv = NULL;
155 }
156
157 return rc;
158}
159
160void vp3054_i2c_remove(struct cx8802_dev *dev)
161{
162 struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
163
164 if (vp3054_i2c == NULL ||
165 dev->core->board != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
166 return;
167
168 i2c_bit_del_bus(&vp3054_i2c->adap);
169 kfree(vp3054_i2c);
170}
171
172EXPORT_SYMBOL(vp3054_i2c_probe);
173EXPORT_SYMBOL(vp3054_i2c_remove);
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.h b/drivers/media/video/cx88/cx88-vp3054-i2c.h
new file mode 100644
index 000000000000..b7a0a04d2423
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-vp3054-i2c.h
@@ -0,0 +1,35 @@
1/*
2
3 cx88-vp3054-i2c.h -- support for the secondary I2C bus of the
4 DNTV Live! DVB-T Pro (VP-3054), wired as:
5 GPIO[0] -> SCL, GPIO[1] -> SDA
6
7 (c) 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
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 as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23*/
24
25/* ----------------------------------------------------------------------- */
26struct vp3054_i2c_state {
27 struct i2c_adapter adap;
28 struct i2c_algo_bit_data algo;
29 struct i2c_client client;
30 u32 state;
31};
32
33/* ----------------------------------------------------------------------- */
34int vp3054_i2c_probe(struct cx8802_dev *dev);
35void vp3054_i2c_remove(struct cx8802_dev *dev);
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 77beafc5c327..e9fd55b57fa6 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -179,6 +179,14 @@ extern struct sram_channel cx88_sram_channels[];
179#define CX88_BOARD_ATI_HDTVWONDER 34 179#define CX88_BOARD_ATI_HDTVWONDER 34
180#define CX88_BOARD_WINFAST_DTV1000 35 180#define CX88_BOARD_WINFAST_DTV1000 35
181#define CX88_BOARD_AVERTV_303 36 181#define CX88_BOARD_AVERTV_303 36
182#define CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1 37
183#define CX88_BOARD_HAUPPAUGE_NOVASE2_S1 38
184#define CX88_BOARD_KWORLD_DVBS_100 39
185#define CX88_BOARD_HAUPPAUGE_HVR1100 40
186#define CX88_BOARD_HAUPPAUGE_HVR1100LP 41
187#define CX88_BOARD_DNTV_LIVE_DVB_T_PRO 42
188#define CX88_BOARD_KWORLD_DVB_T_CX22702 43
189#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44
182 190
183enum cx88_itype { 191enum cx88_itype {
184 CX88_VMUX_COMPOSITE1 = 1, 192 CX88_VMUX_COMPOSITE1 = 1,
@@ -280,6 +288,9 @@ struct cx88_core {
280 unsigned int tda9887_conf; 288 unsigned int tda9887_conf;
281 unsigned int has_radio; 289 unsigned int has_radio;
282 290
291 /* Supported V4L _STD_ tuner formats */
292 unsigned int tuner_formats;
293
283 /* config info -- dvb */ 294 /* config info -- dvb */
284 struct dvb_pll_desc *pll_desc; 295 struct dvb_pll_desc *pll_desc;
285 unsigned int pll_addr; 296 unsigned int pll_addr;
@@ -301,6 +312,9 @@ struct cx88_core {
301 312
302 /* various v4l controls */ 313 /* various v4l controls */
303 u32 freq; 314 u32 freq;
315
316 /* cx88-video needs to access cx8802 for hybrid tuner pll access. */
317 struct cx8802_dev *dvbdev;
304}; 318};
305 319
306struct cx8800_dev; 320struct cx8800_dev;
@@ -411,6 +425,8 @@ struct cx8802_dev {
411 struct videobuf_dvb dvb; 425 struct videobuf_dvb dvb;
412 void* fe_handle; 426 void* fe_handle;
413 int (*fe_release)(void *handle); 427 int (*fe_release)(void *handle);
428
429 void *card_priv;
414 /* for switching modulation types */ 430 /* for switching modulation types */
415 unsigned char ts_gen_cntrl; 431 unsigned char ts_gen_cntrl;
416 432
@@ -447,7 +463,6 @@ struct cx8802_dev {
447 463
448extern void cx88_print_irqbits(char *name, char *tag, char **strings, 464extern void cx88_print_irqbits(char *name, char *tag, char **strings,
449 u32 bits, u32 mask); 465 u32 bits, u32 mask);
450extern void cx88_print_ioctl(char *name, unsigned int cmd);
451 466
452extern int cx88_core_irq(struct cx88_core *core, u32 status); 467extern int cx88_core_irq(struct cx88_core *core, u32 status);
453extern void cx88_wakeup(struct cx88_core *core, 468extern void cx88_wakeup(struct cx88_core *core,
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 57779e63f35d..58f7b4194a0d 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -30,6 +30,7 @@
30#include <media/tuner.h> 30#include <media/tuner.h>
31#include <media/audiochip.h> 31#include <media/audiochip.h>
32#include <media/tveeprom.h> 32#include <media/tveeprom.h>
33#include <media/v4l2-common.h>
33#include "msp3400.h" 34#include "msp3400.h"
34 35
35#include "em28xx.h" 36#include "em28xx.h"
@@ -261,7 +262,6 @@ void em28xx_card_setup(struct em28xx *dev)
261 /* request some modules */ 262 /* request some modules */
262 if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) { 263 if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) {
263 struct tveeprom tv; 264 struct tveeprom tv;
264 struct v4l2_audioout ao;
265#ifdef CONFIG_MODULES 265#ifdef CONFIG_MODULES
266 request_module("tveeprom"); 266 request_module("tveeprom");
267 request_module("ir-kbd-i2c"); 267 request_module("ir-kbd-i2c");
@@ -274,12 +274,8 @@ void em28xx_card_setup(struct em28xx *dev)
274 274
275 dev->tuner_type= tv.tuner_type; 275 dev->tuner_type= tv.tuner_type;
276 if (tv.audio_processor == AUDIO_CHIP_MSP34XX) { 276 if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
277 dev->i2s_speed=2048000;
277 dev->has_msp34xx=1; 278 dev->has_msp34xx=1;
278 memset (&ao,0,sizeof(ao));
279
280 ao.index=2;
281 ao.mode=V4L2_AUDMODE_32BITS;
282 em28xx_i2c_call_clients(dev, VIDIOC_S_AUDOUT, &ao);
283 } else 279 } else
284 dev->has_msp34xx=0; 280 dev->has_msp34xx=0;
285 } 281 }
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 0cfe75416ec6..dff3893f32fd 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -32,7 +32,7 @@
32 32
33/* #define ENABLE_DEBUG_ISOC_FRAMES */ 33/* #define ENABLE_DEBUG_ISOC_FRAMES */
34 34
35static unsigned int core_debug; 35static unsigned int core_debug = 0;
36module_param(core_debug,int,0644); 36module_param(core_debug,int,0644);
37MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); 37MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
38 38
@@ -41,7 +41,7 @@ MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
41 printk(KERN_INFO "%s %s :"fmt, \ 41 printk(KERN_INFO "%s %s :"fmt, \
42 dev->name, __FUNCTION__ , ##arg); } while (0) 42 dev->name, __FUNCTION__ , ##arg); } while (0)
43 43
44static unsigned int reg_debug; 44static unsigned int reg_debug = 0;
45module_param(reg_debug,int,0644); 45module_param(reg_debug,int,0644);
46MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); 46MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]");
47 47
@@ -50,7 +50,7 @@ MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]");
50 printk(KERN_INFO "%s %s :"fmt, \ 50 printk(KERN_INFO "%s %s :"fmt, \
51 dev->name, __FUNCTION__ , ##arg); } while (0) 51 dev->name, __FUNCTION__ , ##arg); } while (0)
52 52
53static unsigned int isoc_debug; 53static unsigned int isoc_debug = 0;
54module_param(isoc_debug,int,0644); 54module_param(isoc_debug,int,0644);
55MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]"); 55MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]");
56 56
@@ -63,59 +63,6 @@ static int alt = EM28XX_PINOUT;
63module_param(alt, int, 0644); 63module_param(alt, int, 0644);
64MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); 64MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
65 65
66/* ------------------------------------------------------------------ */
67/* debug help functions */
68
69static const char *v4l1_ioctls[] = {
70 "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
71 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
72 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
73 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
74 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
75#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
76
77static const char *v4l2_ioctls[] = {
78 "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
79 "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
80 "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
81 "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
82 "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
83 "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
84 "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
85 "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
86 "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
87 "S_MODULATOR"
88};
89#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
90
91void em28xx_print_ioctl(char *name, unsigned int cmd)
92{
93 char *dir;
94
95 switch (_IOC_DIR(cmd)) {
96 case _IOC_NONE: dir = "--"; break;
97 case _IOC_READ: dir = "r-"; break;
98 case _IOC_WRITE: dir = "-w"; break;
99 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
100 default: dir = "??"; break;
101 }
102 switch (_IOC_TYPE(cmd)) {
103 case 'v':
104 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
105 name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
106 v4l1_ioctls[_IOC_NR(cmd)] : "???");
107 break;
108 case 'V':
109 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
110 name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
111 v4l2_ioctls[_IOC_NR(cmd)] : "???");
112 break;
113 default:
114 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
115 name, cmd, dir, _IOC_NR(cmd));
116 }
117}
118
119 66
120/* 67/*
121 * em28xx_request_buffers() 68 * em28xx_request_buffers()
@@ -126,7 +73,7 @@ u32 em28xx_request_buffers(struct em28xx *dev, u32 count)
126 const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */ 73 const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */
127 void *buff = NULL; 74 void *buff = NULL;
128 u32 i; 75 u32 i;
129 em28xx_coredbg("requested %i buffers with size %zd", count, imagesize); 76 em28xx_coredbg("requested %i buffers with size %zi", count, imagesize);
130 if (count > EM28XX_NUM_FRAMES) 77 if (count > EM28XX_NUM_FRAMES)
131 count = EM28XX_NUM_FRAMES; 78 count = EM28XX_NUM_FRAMES;
132 79
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index d14bcf4ceaea..0591a705b7a1 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -28,6 +28,7 @@
28#include <linux/video_decoder.h> 28#include <linux/video_decoder.h>
29 29
30#include "em28xx.h" 30#include "em28xx.h"
31#include <media/v4l2-common.h>
31#include <media/tuner.h> 32#include <media/tuner.h>
32 33
33/* ----------------------------------------------------------- */ 34/* ----------------------------------------------------------- */
@@ -486,9 +487,7 @@ static struct i2c_adapter em28xx_adap_template = {
486 .inc_use = inc_use, 487 .inc_use = inc_use,
487 .dec_use = dec_use, 488 .dec_use = dec_use,
488#endif 489#endif
489#ifdef I2C_CLASS_TV_ANALOG
490 .class = I2C_CLASS_TV_ANALOG, 490 .class = I2C_CLASS_TV_ANALOG,
491#endif
492 .name = "em28xx", 491 .name = "em28xx",
493 .id = I2C_HW_B_EM28XX, 492 .id = I2C_HW_B_EM28XX,
494 .algo = &em28xx_algo, 493 .algo = &em28xx_algo,
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 3a56120397ae..fdc255918dde 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -32,6 +32,7 @@
32 32
33#include "em28xx.h" 33#include "em28xx.h"
34#include <media/tuner.h> 34#include <media/tuner.h>
35#include <media/v4l2-common.h>
35 36
36#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ 37#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
37 "Markus Rechberger <mrechberger@gmail.com>, " \ 38 "Markus Rechberger <mrechberger@gmail.com>, " \
@@ -106,8 +107,32 @@ static const unsigned char saa7114_i2c_init[] = {
106#define TVNORMS ARRAY_SIZE(tvnorms) 107#define TVNORMS ARRAY_SIZE(tvnorms)
107 108
108/* supported controls */ 109/* supported controls */
110/* Common to all boards */
109static struct v4l2_queryctrl em28xx_qctrl[] = { 111static struct v4l2_queryctrl em28xx_qctrl[] = {
110 { 112 {
113 .id = V4L2_CID_AUDIO_VOLUME,
114 .type = V4L2_CTRL_TYPE_INTEGER,
115 .name = "Volume",
116 .minimum = 0x0,
117 .maximum = 0x1f,
118 .step = 0x1,
119 .default_value = 0x1f,
120 .flags = 0,
121 },{
122 .id = V4L2_CID_AUDIO_MUTE,
123 .type = V4L2_CTRL_TYPE_BOOLEAN,
124 .name = "Mute",
125 .minimum = 0,
126 .maximum = 1,
127 .step = 1,
128 .default_value = 1,
129 .flags = 0,
130 }
131};
132
133/* FIXME: These are specific to saa711x - should be moved to its code */
134static struct v4l2_queryctrl saa711x_qctrl[] = {
135 {
111 .id = V4L2_CID_BRIGHTNESS, 136 .id = V4L2_CID_BRIGHTNESS,
112 .type = V4L2_CTRL_TYPE_INTEGER, 137 .type = V4L2_CTRL_TYPE_INTEGER,
113 .name = "Brightness", 138 .name = "Brightness",
@@ -135,24 +160,6 @@ static struct v4l2_queryctrl em28xx_qctrl[] = {
135 .default_value = 0x10, 160 .default_value = 0x10,
136 .flags = 0, 161 .flags = 0,
137 },{ 162 },{
138 .id = V4L2_CID_AUDIO_VOLUME,
139 .type = V4L2_CTRL_TYPE_INTEGER,
140 .name = "Volume",
141 .minimum = 0x0,
142 .maximum = 0x1f,
143 .step = 0x1,
144 .default_value = 0x1f,
145 .flags = 0,
146 },{
147 .id = V4L2_CID_AUDIO_MUTE,
148 .type = V4L2_CTRL_TYPE_BOOLEAN,
149 .name = "Mute",
150 .minimum = 0,
151 .maximum = 1,
152 .step = 1,
153 .default_value = 1,
154 .flags = 0,
155 },{
156 .id = V4L2_CID_RED_BALANCE, 163 .id = V4L2_CID_RED_BALANCE,
157 .type = V4L2_CTRL_TYPE_INTEGER, 164 .type = V4L2_CTRL_TYPE_INTEGER,
158 .name = "Red chroma balance", 165 .name = "Red chroma balance",
@@ -179,7 +186,7 @@ static struct v4l2_queryctrl em28xx_qctrl[] = {
179 .step = 0x1, 186 .step = 0x1,
180 .default_value = 0x20, 187 .default_value = 0x20,
181 .flags = 0, 188 .flags = 0,
182 } 189 }
183}; 190};
184 191
185static struct usb_driver em28xx_usb_driver; 192static struct usb_driver em28xx_usb_driver;
@@ -280,6 +287,8 @@ static void video_mux(struct em28xx *dev, int index)
280 em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput); 287 em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);
281 288
282 if (dev->has_msp34xx) { 289 if (dev->has_msp34xx) {
290 if (dev->i2s_speed)
291 em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed);
283 em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput); 292 em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput);
284 ainput = EM28XX_AUDIO_SRC_TUNER; 293 ainput = EM28XX_AUDIO_SRC_TUNER;
285 em28xx_audio_source(dev, ainput); 294 em28xx_audio_source(dev, ainput);
@@ -674,7 +683,6 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
674 */ 683 */
675static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) 684static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
676{ 685{
677 s32 tmp;
678 switch (ctrl->id) { 686 switch (ctrl->id) {
679 case V4L2_CID_AUDIO_MUTE: 687 case V4L2_CID_AUDIO_MUTE:
680 ctrl->value = dev->mute; 688 ctrl->value = dev->mute;
@@ -682,6 +690,16 @@ static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
682 case V4L2_CID_AUDIO_VOLUME: 690 case V4L2_CID_AUDIO_VOLUME:
683 ctrl->value = dev->volume; 691 ctrl->value = dev->volume;
684 return 0; 692 return 0;
693 default:
694 return -EINVAL;
695 }
696}
697
698/*FIXME: should be moved to saa711x */
699static int saa711x_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
700{
701 s32 tmp;
702 switch (ctrl->id) {
685 case V4L2_CID_BRIGHTNESS: 703 case V4L2_CID_BRIGHTNESS:
686 if ((tmp = em28xx_brightness_get(dev)) < 0) 704 if ((tmp = em28xx_brightness_get(dev)) < 0)
687 return -EIO; 705 return -EIO;
@@ -731,6 +749,15 @@ static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
731 case V4L2_CID_AUDIO_VOLUME: 749 case V4L2_CID_AUDIO_VOLUME:
732 dev->volume = ctrl->value; 750 dev->volume = ctrl->value;
733 return em28xx_audio_analog_set(dev); 751 return em28xx_audio_analog_set(dev);
752 default:
753 return -EINVAL;
754 }
755}
756
757/*FIXME: should be moved to saa711x */
758static int saa711x_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
759{
760 switch (ctrl->id) {
734 case V4L2_CID_BRIGHTNESS: 761 case V4L2_CID_BRIGHTNESS:
735 return em28xx_brightness_set(dev, ctrl->value); 762 return em28xx_brightness_set(dev, ctrl->value);
736 case V4L2_CID_CONTRAST: 763 case V4L2_CID_CONTRAST:
@@ -994,14 +1021,34 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
994 case VIDIOC_QUERYCTRL: 1021 case VIDIOC_QUERYCTRL:
995 { 1022 {
996 struct v4l2_queryctrl *qc = arg; 1023 struct v4l2_queryctrl *qc = arg;
997 u8 i, n; 1024 int i, id=qc->id;
998 n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]); 1025
999 for (i = 0; i < n; i++) 1026 memset(qc,0,sizeof(*qc));
1000 if (qc->id && qc->id == em28xx_qctrl[i].id) { 1027 qc->id=id;
1001 memcpy(qc, &(em28xx_qctrl[i]), 1028
1029 if (!dev->has_msp34xx) {
1030 for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
1031 if (qc->id && qc->id == em28xx_qctrl[i].id) {
1032 memcpy(qc, &(em28xx_qctrl[i]),
1033 sizeof(*qc));
1034 return 0;
1035 }
1036 }
1037 }
1038 if (dev->decoder == EM28XX_TVP5150) {
1039 em28xx_i2c_call_clients(dev,cmd,qc);
1040 if (qc->type)
1041 return 0;
1042 else
1043 return -EINVAL;
1044 }
1045 for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) {
1046 if (qc->id && qc->id == saa711x_qctrl[i].id) {
1047 memcpy(qc, &(saa711x_qctrl[i]),
1002 sizeof(*qc)); 1048 sizeof(*qc));
1003 return 0; 1049 return 0;
1004 } 1050 }
1051 }
1005 1052
1006 return -EINVAL; 1053 return -EINVAL;
1007 } 1054 }
@@ -1009,29 +1056,64 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
1009 case VIDIOC_G_CTRL: 1056 case VIDIOC_G_CTRL:
1010 { 1057 {
1011 struct v4l2_control *ctrl = arg; 1058 struct v4l2_control *ctrl = arg;
1059 int retval=-EINVAL;
1012 1060
1061 if (!dev->has_msp34xx)
1062 retval=em28xx_get_ctrl(dev, ctrl);
1063 if (retval==-EINVAL) {
1064 if (dev->decoder == EM28XX_TVP5150) {
1065 em28xx_i2c_call_clients(dev,cmd,arg);
1066 return 0;
1067 }
1013 1068
1014 return em28xx_get_ctrl(dev, ctrl); 1069 return saa711x_get_ctrl(dev, ctrl);
1070 } else return retval;
1015 } 1071 }
1016 1072
1017 case VIDIOC_S_CTRL_OLD: /* ??? */
1018 case VIDIOC_S_CTRL: 1073 case VIDIOC_S_CTRL:
1019 { 1074 {
1020 struct v4l2_control *ctrl = arg; 1075 struct v4l2_control *ctrl = arg;
1021 u8 i, n; 1076 u8 i;
1022 1077
1023 1078 if (!dev->has_msp34xx){
1024 n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]); 1079 for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
1025 for (i = 0; i < n; i++) 1080 if (ctrl->id == em28xx_qctrl[i].id) {
1026 if (ctrl->id == em28xx_qctrl[i].id) { 1081 if (ctrl->value <
1027 if (ctrl->value < 1082 em28xx_qctrl[i].minimum
1028 em28xx_qctrl[i].minimum 1083 || ctrl->value >
1029 || ctrl->value > 1084 em28xx_qctrl[i].maximum)
1030 em28xx_qctrl[i].maximum) 1085 return -ERANGE;
1031 return -ERANGE; 1086 return em28xx_set_ctrl(dev, ctrl);
1087 }
1088 }
1089 }
1032 1090
1033 return em28xx_set_ctrl(dev, ctrl); 1091 if (dev->decoder == EM28XX_TVP5150) {
1092 em28xx_i2c_call_clients(dev,cmd,arg);
1093 return 0;
1094 } else if (!dev->has_msp34xx) {
1095 for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
1096 if (ctrl->id == em28xx_qctrl[i].id) {
1097 if (ctrl->value <
1098 em28xx_qctrl[i].minimum
1099 || ctrl->value >
1100 em28xx_qctrl[i].maximum)
1101 return -ERANGE;
1102 return em28xx_set_ctrl(dev, ctrl);
1103 }
1034 } 1104 }
1105 for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) {
1106 if (ctrl->id == saa711x_qctrl[i].id) {
1107 if (ctrl->value <
1108 saa711x_qctrl[i].minimum
1109 || ctrl->value >
1110 saa711x_qctrl[i].maximum)
1111 return -ERANGE;
1112 return saa711x_set_ctrl(dev, ctrl);
1113 }
1114 }
1115 }
1116
1035 return -EINVAL; 1117 return -EINVAL;
1036 } 1118 }
1037 1119
@@ -1187,7 +1269,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1187 return -ENODEV; 1269 return -ENODEV;
1188 1270
1189 if (video_debug > 1) 1271 if (video_debug > 1)
1190 em28xx_print_ioctl(dev->name,cmd); 1272 v4l_print_ioctl(dev->name,cmd);
1191 1273
1192 switch (cmd) { 1274 switch (cmd) {
1193 1275
@@ -1564,6 +1646,8 @@ static struct file_operations em28xx_v4l_fops = {
1564 .poll = em28xx_v4l2_poll, 1646 .poll = em28xx_v4l2_poll,
1565 .mmap = em28xx_v4l2_mmap, 1647 .mmap = em28xx_v4l2_mmap,
1566 .llseek = no_llseek, 1648 .llseek = no_llseek,
1649 .compat_ioctl = v4l_compat_ioctl32,
1650
1567}; 1651};
1568 1652
1569/******************************** usb interface *****************************************/ 1653/******************************** usb interface *****************************************/
@@ -1848,9 +1932,12 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
1848 struct em28xx *dev = usb_get_intfdata(interface); 1932 struct em28xx *dev = usb_get_intfdata(interface);
1849 usb_set_intfdata(interface, NULL); 1933 usb_set_intfdata(interface, NULL);
1850 1934
1935/*FIXME: IR should be disconnected */
1936
1851 if (!dev) 1937 if (!dev)
1852 return; 1938 return;
1853 1939
1940
1854 down_write(&em28xx_disconnect); 1941 down_write(&em28xx_disconnect);
1855 1942
1856 down(&dev->lock); 1943 down(&dev->lock);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 5c7a41ce69f3..33de9d846af5 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -1,5 +1,5 @@
1/* 1/*
2 em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices 2 em28xx.h - driver for Empia EM2800/EM2820/2840 USB video capture devices
3 3
4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> 4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
5 Ludovico Cavedon <cavedon@sssup.it> 5 Ludovico Cavedon <cavedon@sssup.it>
@@ -216,6 +216,8 @@ struct em28xx {
216 unsigned int has_msp34xx:1; 216 unsigned int has_msp34xx:1;
217 unsigned int has_tda9887:1; 217 unsigned int has_tda9887:1;
218 218
219 u32 i2s_speed; /* I2S speed for audio digital stream */
220
219 enum em28xx_decoder decoder; 221 enum em28xx_decoder decoder;
220 222
221 int tuner_type; /* type of the tuner */ 223 int tuner_type; /* type of the tuner */
@@ -293,8 +295,6 @@ void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir);
293 295
294/* Provided by em28xx-core.c */ 296/* Provided by em28xx-core.c */
295 297
296void em28xx_print_ioctl(char *name, unsigned int cmd);
297
298u32 em28xx_request_buffers(struct em28xx *dev, u32 count); 298u32 em28xx_request_buffers(struct em28xx *dev, u32 count);
299void em28xx_queue_unusedframes(struct em28xx *dev); 299void em28xx_queue_unusedframes(struct em28xx *dev);
300void em28xx_release_buffers(struct em28xx *dev); 300void em28xx_release_buffers(struct em28xx *dev);
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 3cc1d6a6019b..58b0e6982822 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -279,7 +279,7 @@ static int ir_probe(struct i2c_adapter *adap);
279 279
280static struct i2c_driver driver = { 280static struct i2c_driver driver = {
281 .driver = { 281 .driver = {
282 .name = "ir remote kbd driver", 282 .name = "ir-kbd-i2c",
283 }, 283 },
284 .id = I2C_DRIVERID_INFRARED, 284 .id = I2C_DRIVERID_INFRARED,
285 .attach_adapter = ir_probe, 285 .attach_adapter = ir_probe,
@@ -304,18 +304,20 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
304 ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); 304 ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL);
305 input_dev = input_allocate_device(); 305 input_dev = input_allocate_device();
306 if (!ir || !input_dev) { 306 if (!ir || !input_dev) {
307 kfree(ir);
308 input_free_device(input_dev); 307 input_free_device(input_dev);
308 kfree(ir);
309 return -ENOMEM; 309 return -ENOMEM;
310 } 310 }
311 memset(ir,0,sizeof(*ir));
311 312
312 ir->c = client_template; 313 ir->c = client_template;
313 ir->input = input_dev; 314 ir->input = input_dev;
314 315
315 i2c_set_clientdata(&ir->c, ir);
316 ir->c.adapter = adap; 316 ir->c.adapter = adap;
317 ir->c.addr = addr; 317 ir->c.addr = addr;
318 318
319 i2c_set_clientdata(&ir->c, ir);
320
319 switch(addr) { 321 switch(addr) {
320 case 0x64: 322 case 0x64:
321 name = "Pixelview"; 323 name = "Pixelview";
@@ -378,13 +380,15 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
378 ir->c.dev.bus_id); 380 ir->c.dev.bus_id);
379 381
380 /* init + register input device */ 382 /* init + register input device */
381 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); 383 ir_input_init(input_dev,&ir->ir,ir_type,ir->ir_codes);
382 input_dev->id.bustype = BUS_I2C; 384 input_dev->id.bustype = BUS_I2C;
383 input_dev->name = ir->c.name; 385 input_dev->name = ir->c.name;
384 input_dev->phys = ir->phys; 386 input_dev->phys = ir->phys;
385 387
386 /* register event device */ 388 /* register event device */
387 input_register_device(ir->input); 389 input_register_device(ir->input);
390 printk(DEVNAME ": %s detected at %s [%s]\n",
391 ir->input->name,ir->input->phys,adap->name);
388 392
389 /* start polling via eventd */ 393 /* start polling via eventd */
390 INIT_WORK(&ir->work, ir_work, ir); 394 INIT_WORK(&ir->work, ir_work, ir);
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 3f2a882bc20a..2869464aee0d 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1754,6 +1754,7 @@ static struct file_operations meye_fops = {
1754 .release = meye_release, 1754 .release = meye_release,
1755 .mmap = meye_mmap, 1755 .mmap = meye_mmap,
1756 .ioctl = meye_ioctl, 1756 .ioctl = meye_ioctl,
1757 .compat_ioctl = v4l_compat_ioctl32,
1757 .poll = meye_poll, 1758 .poll = meye_poll,
1758 .llseek = no_llseek, 1759 .llseek = no_llseek,
1759}; 1760};
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
new file mode 100644
index 000000000000..aa8c556b6ba1
--- /dev/null
+++ b/drivers/media/video/msp3400-driver.c
@@ -0,0 +1,1274 @@
1/*
2 * Programming the mspx4xx sound processor family
3 *
4 * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
5 *
6 * what works and what doesn't:
7 *
8 * AM-Mono
9 * Support for Hauppauge cards added (decoding handled by tuner) added by
10 * Frederic Crozat <fcrozat@mail.dotcom.fr>
11 *
12 * FM-Mono
13 * should work. The stereo modes are backward compatible to FM-mono,
14 * therefore FM-Mono should be allways available.
15 *
16 * FM-Stereo (B/G, used in germany)
17 * should work, with autodetect
18 *
19 * FM-Stereo (satellite)
20 * should work, no autodetect (i.e. default is mono, but you can
21 * switch to stereo -- untested)
22 *
23 * NICAM (B/G, L , used in UK, Scandinavia, Spain and France)
24 * should work, with autodetect. Support for NICAM was added by
25 * Pekka Pietikainen <pp@netppl.fi>
26 *
27 * TODO:
28 * - better SAT support
29 *
30 * 980623 Thomas Sailer (sailer@ife.ee.ethz.ch)
31 * using soundcore instead of OSS
32 *
33 * This program is free software; you can redistribute it and/or
34 * modify it under the terms of the GNU General Public License
35 * as published by the Free Software Foundation; either version 2
36 * of the License, or (at your option) any later version.
37 *
38 * This program is distributed in the hope that it will be useful,
39 * but WITHOUT ANY WARRANTY; without even the implied warranty of
40 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41 * GNU General Public License for more details.
42 *
43 * You should have received a copy of the GNU General Public License
44 * along with this program; if not, write to the Free Software
45 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
46 */
47
48
49#include <linux/kernel.h>
50#include <linux/module.h>
51#include <linux/slab.h>
52#include <linux/i2c.h>
53#include <linux/videodev.h>
54#include <linux/videodev2.h>
55#include <media/v4l2-common.h>
56#include <media/audiochip.h>
57#include <linux/kthread.h>
58#include <linux/suspend.h>
59#include "msp3400.h"
60
61/* ---------------------------------------------------------------------- */
62
63MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
64MODULE_AUTHOR("Gerd Knorr");
65MODULE_LICENSE("GPL");
66
67/* module parameters */
68static int opmode = OPMODE_AUTO;
69int debug = 0; /* debug output */
70int once = 0; /* no continous stereo monitoring */
71int amsound = 0; /* hard-wire AM sound at 6.5 Hz (france),
72 the autoscan seems work well only with FM... */
73int standard = 1; /* Override auto detect of audio standard, if needed. */
74int dolby = 0;
75
76int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual
77 (msp34xxg only) 0x00a0-0x03c0 */
78
79/* read-only */
80module_param(opmode, int, 0444);
81
82/* read-write */
83module_param(once, bool, 0644);
84module_param(debug, int, 0644);
85module_param(stereo_threshold, int, 0644);
86module_param(standard, int, 0644);
87module_param(amsound, bool, 0644);
88module_param(dolby, bool, 0644);
89
90MODULE_PARM_DESC(opmode, "Forces a MSP3400 opmode. 0=Manual, 1=Autodetect, 2=Autodetect and autoselect");
91MODULE_PARM_DESC(once, "No continuous stereo monitoring");
92MODULE_PARM_DESC(debug, "Enable debug messages [0-3]");
93MODULE_PARM_DESC(stereo_threshold, "Sets signal threshold to activate stereo");
94MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect");
95MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
96MODULE_PARM_DESC(dolby, "Activates Dolby processsing");
97
98/* ---------------------------------------------------------------------- */
99
100/* control subaddress */
101#define I2C_MSP_CONTROL 0x00
102/* demodulator unit subaddress */
103#define I2C_MSP_DEM 0x10
104/* DSP unit subaddress */
105#define I2C_MSP_DSP 0x12
106
107/* Addresses to scan */
108static unsigned short normal_i2c[] = { 0x80 >> 1, 0x88 >> 1, I2C_CLIENT_END };
109I2C_CLIENT_INSMOD;
110
111/* ----------------------------------------------------------------------- */
112/* functions for talking to the MSP3400C Sound processor */
113
114int msp_reset(struct i2c_client *client)
115{
116 /* reset and read revision code */
117 static u8 reset_off[3] = { I2C_MSP_CONTROL, 0x80, 0x00 };
118 static u8 reset_on[3] = { I2C_MSP_CONTROL, 0x00, 0x00 };
119 static u8 write[3] = { I2C_MSP_DSP + 1, 0x00, 0x1e };
120 u8 read[2];
121 struct i2c_msg reset[2] = {
122 { client->addr, I2C_M_IGNORE_NAK, 3, reset_off },
123 { client->addr, I2C_M_IGNORE_NAK, 3, reset_on },
124 };
125 struct i2c_msg test[2] = {
126 { client->addr, 0, 3, write },
127 { client->addr, I2C_M_RD, 2, read },
128 };
129
130 v4l_dbg(3, client, "msp_reset\n");
131 if (i2c_transfer(client->adapter, &reset[0], 1) != 1 ||
132 i2c_transfer(client->adapter, &reset[1], 1) != 1 ||
133 i2c_transfer(client->adapter, test, 2) != 2) {
134 v4l_err(client, "chip reset failed\n");
135 return -1;
136 }
137 return 0;
138}
139
140static int msp_read(struct i2c_client *client, int dev, int addr)
141{
142 int err, retval;
143 u8 write[3];
144 u8 read[2];
145 struct i2c_msg msgs[2] = {
146 { client->addr, 0, 3, write },
147 { client->addr, I2C_M_RD, 2, read }
148 };
149
150 write[0] = dev + 1;
151 write[1] = addr >> 8;
152 write[2] = addr & 0xff;
153
154 for (err = 0; err < 3; err++) {
155 if (i2c_transfer(client->adapter, msgs, 2) == 2)
156 break;
157 v4l_warn(client, "I/O error #%d (read 0x%02x/0x%02x)\n", err,
158 dev, addr);
159 current->state = TASK_INTERRUPTIBLE;
160 schedule_timeout(msecs_to_jiffies(10));
161 }
162 if (err == 3) {
163 v4l_warn(client, "giving up, resetting chip. Sound will go off, sorry folks :-|\n");
164 msp_reset(client);
165 return -1;
166 }
167 retval = read[0] << 8 | read[1];
168 v4l_dbg(3, client, "msp_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval);
169 return retval;
170}
171
172int msp_read_dem(struct i2c_client *client, int addr)
173{
174 return msp_read(client, I2C_MSP_DEM, addr);
175}
176
177int msp_read_dsp(struct i2c_client *client, int addr)
178{
179 return msp_read(client, I2C_MSP_DSP, addr);
180}
181
182static int msp_write(struct i2c_client *client, int dev, int addr, int val)
183{
184 int err;
185 u8 buffer[5];
186
187 buffer[0] = dev;
188 buffer[1] = addr >> 8;
189 buffer[2] = addr & 0xff;
190 buffer[3] = val >> 8;
191 buffer[4] = val & 0xff;
192
193 v4l_dbg(3, client, "msp_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val);
194 for (err = 0; err < 3; err++) {
195 if (i2c_master_send(client, buffer, 5) == 5)
196 break;
197 v4l_warn(client, "I/O error #%d (write 0x%02x/0x%02x)\n", err,
198 dev, addr);
199 current->state = TASK_INTERRUPTIBLE;
200 schedule_timeout(msecs_to_jiffies(10));
201 }
202 if (err == 3) {
203 v4l_warn(client, "giving up, resetting chip. Sound will go off, sorry folks :-|\n");
204 msp_reset(client);
205 return -1;
206 }
207 return 0;
208}
209
210int msp_write_dem(struct i2c_client *client, int addr, int val)
211{
212 return msp_write(client, I2C_MSP_DEM, addr, val);
213}
214
215int msp_write_dsp(struct i2c_client *client, int addr, int val)
216{
217 return msp_write(client, I2C_MSP_DSP, addr, val);
218}
219
220/* ----------------------------------------------------------------------- *
221 * bits 9 8 5 - SCART DSP input Select:
222 * 0 0 0 - SCART 1 to DSP input (reset position)
223 * 0 1 0 - MONO to DSP input
224 * 1 0 0 - SCART 2 to DSP input
225 * 1 1 1 - Mute DSP input
226 *
227 * bits 11 10 6 - SCART 1 Output Select:
228 * 0 0 0 - undefined (reset position)
229 * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS)
230 * 1 0 0 - MONO input to SCART 1 Output
231 * 1 1 0 - SCART 1 DA to SCART 1 Output
232 * 0 0 1 - SCART 2 DA to SCART 1 Output
233 * 0 1 1 - SCART 1 Input to SCART 1 Output
234 * 1 1 1 - Mute SCART 1 Output
235 *
236 * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART):
237 * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position)
238 * 0 1 0 - SCART 1 Input to SCART 2 Output
239 * 1 0 0 - MONO input to SCART 2 Output
240 * 0 0 1 - SCART 2 DA to SCART 2 Output
241 * 0 1 1 - SCART 2 Input to SCART 2 Output
242 * 1 1 0 - Mute SCART 2 Output
243 *
244 * Bits 4 to 0 should be zero.
245 * ----------------------------------------------------------------------- */
246
247static int scarts[3][9] = {
248 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */
249 /* SCART DSP Input select */
250 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 },
251 /* SCART1 Output select */
252 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
253 /* SCART2 Output select */
254 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
255};
256
257static char *scart_names[] = {
258 "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
259};
260
261void msp_set_scart(struct i2c_client *client, int in, int out)
262{
263 struct msp_state *state = i2c_get_clientdata(client);
264
265 state->in_scart=in;
266
267 if (in >= 1 && in <= 8 && out >= 0 && out <= 2) {
268 if (-1 == scarts[out][in])
269 return;
270
271 state->acb &= ~scarts[out][SCART_MASK];
272 state->acb |= scarts[out][in];
273 } else
274 state->acb = 0xf60; /* Mute Input and SCART 1 Output */
275
276 v4l_dbg(1, client, "scart switch: %s => %d (ACB=0x%04x)\n",
277 scart_names[in], out, state->acb);
278 msp_write_dsp(client, 0x13, state->acb);
279
280 /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
281 msp_write_dem(client, 0x40, state->i2s_mode);
282}
283
284void msp_set_mute(struct i2c_client *client)
285{
286 struct msp_state *state = i2c_get_clientdata(client);
287
288 v4l_dbg(1, client, "mute audio\n");
289 msp_write_dsp(client, 0x0000, 0);
290 msp_write_dsp(client, 0x0007, 1);
291 if (state->has_scart2_out_volume)
292 msp_write_dsp(client, 0x0040, 1);
293 if (state->has_headphones)
294 msp_write_dsp(client, 0x0006, 0);
295}
296
297void msp_set_audio(struct i2c_client *client)
298{
299 struct msp_state *state = i2c_get_clientdata(client);
300 int bal = 0, bass, treble, loudness;
301 int val = 0;
302
303 if (!state->muted)
304 val = (state->volume * 0x7f / 65535) << 8;
305
306 v4l_dbg(1, client, "mute=%s volume=%d\n",
307 state->muted ? "on" : "off", state->volume);
308
309 msp_write_dsp(client, 0x0000, val);
310 msp_write_dsp(client, 0x0007, state->muted ? 0x1 : (val | 0x1));
311 if (state->has_scart2_out_volume)
312 msp_write_dsp(client, 0x0040, state->muted ? 0x1 : (val | 0x1));
313 if (state->has_headphones)
314 msp_write_dsp(client, 0x0006, val);
315 if (!state->has_sound_processing)
316 return;
317
318 if (val)
319 bal = (u8)((state->balance / 256) - 128);
320 bass = ((state->bass - 32768) * 0x60 / 65535) << 8;
321 treble = ((state->treble - 32768) * 0x60 / 65535) << 8;
322 loudness = state->loudness ? ((5 * 4) << 8) : 0;
323
324 v4l_dbg(1, client, "balance=%d bass=%d treble=%d loudness=%d\n",
325 state->balance, state->bass, state->treble, state->loudness);
326
327 msp_write_dsp(client, 0x0001, bal << 8);
328 msp_write_dsp(client, 0x0002, bass);
329 msp_write_dsp(client, 0x0003, treble);
330 msp_write_dsp(client, 0x0004, loudness);
331 if (!state->has_headphones)
332 return;
333 msp_write_dsp(client, 0x0030, bal << 8);
334 msp_write_dsp(client, 0x0031, bass);
335 msp_write_dsp(client, 0x0032, treble);
336 msp_write_dsp(client, 0x0033, loudness);
337}
338
339int msp_modus(struct i2c_client *client)
340{
341 struct msp_state *state = i2c_get_clientdata(client);
342
343 if (state->radio) {
344 v4l_dbg(1, client, "video mode selected to Radio\n");
345 return 0x0003;
346 }
347
348 if (state->v4l2_std & V4L2_STD_PAL) {
349 v4l_dbg(1, client, "video mode selected to PAL\n");
350
351#if 1
352 /* experimental: not sure this works with all chip versions */
353 return 0x7003;
354#else
355 /* previous value, try this if it breaks ... */
356 return 0x1003;
357#endif
358 }
359 if (state->v4l2_std & V4L2_STD_NTSC) {
360 v4l_dbg(1, client, "video mode selected to NTSC\n");
361 return 0x2003;
362 }
363 if (state->v4l2_std & V4L2_STD_SECAM) {
364 v4l_dbg(1, client, "video mode selected to SECAM\n");
365 return 0x0003;
366 }
367 return 0x0003;
368}
369
370/* ------------------------------------------------------------------------ */
371
372
373static void msp_wake_thread(struct i2c_client *client)
374{
375 struct msp_state *state = i2c_get_clientdata(client);
376
377 if (NULL == state->kthread)
378 return;
379 msp_set_mute(client);
380 state->watch_stereo = 0;
381 state->restart = 1;
382 wake_up_interruptible(&state->wq);
383}
384
385int msp_sleep(struct msp_state *state, int timeout)
386{
387 DECLARE_WAITQUEUE(wait, current);
388
389 add_wait_queue(&state->wq, &wait);
390 if (!kthread_should_stop()) {
391 if (timeout < 0) {
392 set_current_state(TASK_INTERRUPTIBLE);
393 schedule();
394 } else {
395 schedule_timeout_interruptible
396 (msecs_to_jiffies(timeout));
397 }
398 }
399
400 remove_wait_queue(&state->wq, &wait);
401 try_to_freeze();
402 return state->restart;
403}
404
405/* ------------------------------------------------------------------------ */
406
407static int msp_mode_v4l2_to_v4l1(int rxsubchans)
408{
409 int mode = 0;
410
411 if (rxsubchans & V4L2_TUNER_SUB_STEREO)
412 mode |= VIDEO_SOUND_STEREO;
413 if (rxsubchans & V4L2_TUNER_SUB_LANG2)
414 mode |= VIDEO_SOUND_LANG2;
415 if (rxsubchans & V4L2_TUNER_SUB_LANG1)
416 mode |= VIDEO_SOUND_LANG1;
417 if (mode == 0)
418 mode |= VIDEO_SOUND_MONO;
419 return mode;
420}
421
422static int msp_mode_v4l1_to_v4l2(int mode)
423{
424 if (mode & VIDEO_SOUND_STEREO)
425 return V4L2_TUNER_MODE_STEREO;
426 if (mode & VIDEO_SOUND_LANG2)
427 return V4L2_TUNER_MODE_LANG2;
428 if (mode & VIDEO_SOUND_LANG1)
429 return V4L2_TUNER_MODE_LANG1;
430 return V4L2_TUNER_MODE_MONO;
431}
432
433static void msp_any_detect_stereo(struct i2c_client *client)
434{
435 struct msp_state *state = i2c_get_clientdata(client);
436
437 switch (state->opmode) {
438 case OPMODE_MANUAL:
439 case OPMODE_AUTODETECT:
440 autodetect_stereo(client);
441 break;
442 case OPMODE_AUTOSELECT:
443 msp34xxg_detect_stereo(client);
444 break;
445 }
446}
447
448static struct v4l2_queryctrl msp_qctrl_std[] = {
449 {
450 .id = V4L2_CID_AUDIO_VOLUME,
451 .name = "Volume",
452 .minimum = 0,
453 .maximum = 65535,
454 .step = 65535/100,
455 .default_value = 58880,
456 .flags = 0,
457 .type = V4L2_CTRL_TYPE_INTEGER,
458 },{
459 .id = V4L2_CID_AUDIO_MUTE,
460 .name = "Mute",
461 .minimum = 0,
462 .maximum = 1,
463 .step = 1,
464 .default_value = 1,
465 .flags = 0,
466 .type = V4L2_CTRL_TYPE_BOOLEAN,
467 },
468};
469
470static struct v4l2_queryctrl msp_qctrl_sound_processing[] = {
471 {
472 .id = V4L2_CID_AUDIO_BALANCE,
473 .name = "Balance",
474 .minimum = 0,
475 .maximum = 65535,
476 .step = 65535/100,
477 .default_value = 32768,
478 .flags = 0,
479 .type = V4L2_CTRL_TYPE_INTEGER,
480 },{
481 .id = V4L2_CID_AUDIO_BASS,
482 .name = "Bass",
483 .minimum = 0,
484 .maximum = 65535,
485 .step = 65535/100,
486 .default_value = 32768,
487 .type = V4L2_CTRL_TYPE_INTEGER,
488 },{
489 .id = V4L2_CID_AUDIO_TREBLE,
490 .name = "Treble",
491 .minimum = 0,
492 .maximum = 65535,
493 .step = 65535/100,
494 .default_value = 32768,
495 .type = V4L2_CTRL_TYPE_INTEGER,
496 },{
497 .id = V4L2_CID_AUDIO_LOUDNESS,
498 .name = "Loudness",
499 .minimum = 0,
500 .maximum = 1,
501 .step = 1,
502 .default_value = 1,
503 .flags = 0,
504 .type = V4L2_CTRL_TYPE_BOOLEAN,
505 },
506};
507
508
509static void msp_any_set_audmode(struct i2c_client *client, int audmode)
510{
511 struct msp_state *state = i2c_get_clientdata(client);
512
513 switch (state->opmode) {
514 case OPMODE_MANUAL:
515 case OPMODE_AUTODETECT:
516 state->watch_stereo = 0;
517 msp3400c_setstereo(client, audmode);
518 break;
519 case OPMODE_AUTOSELECT:
520 msp34xxg_set_audmode(client, audmode);
521 break;
522 }
523}
524
525static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
526{
527 struct msp_state *state = i2c_get_clientdata(client);
528
529 switch (ctrl->id) {
530 case V4L2_CID_AUDIO_VOLUME:
531 ctrl->value = state->volume;
532 break;
533
534 case V4L2_CID_AUDIO_MUTE:
535 ctrl->value = state->muted;
536 break;
537
538 case V4L2_CID_AUDIO_BALANCE:
539 if (!state->has_sound_processing)
540 return -EINVAL;
541 ctrl->value = state->balance;
542 break;
543
544 case V4L2_CID_AUDIO_BASS:
545 if (!state->has_sound_processing)
546 return -EINVAL;
547 ctrl->value = state->bass;
548 break;
549
550 case V4L2_CID_AUDIO_TREBLE:
551 if (!state->has_sound_processing)
552 return -EINVAL;
553 ctrl->value = state->treble;
554 break;
555
556 case V4L2_CID_AUDIO_LOUDNESS:
557 if (!state->has_sound_processing)
558 return -EINVAL;
559 ctrl->value = state->loudness;
560 break;
561
562 default:
563 return -EINVAL;
564 }
565 return 0;
566}
567
568static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
569{
570 struct msp_state *state = i2c_get_clientdata(client);
571
572 switch (ctrl->id) {
573 case V4L2_CID_AUDIO_VOLUME:
574 state->volume = ctrl->value;
575 if (state->volume == 0)
576 state->balance = 32768;
577 break;
578
579 case V4L2_CID_AUDIO_MUTE:
580 if (ctrl->value < 0 || ctrl->value >= 2)
581 return -ERANGE;
582 state->muted = ctrl->value;
583 break;
584
585 case V4L2_CID_AUDIO_BASS:
586 if (!state->has_sound_processing)
587 return -EINVAL;
588 state->bass = ctrl->value;
589 break;
590
591 case V4L2_CID_AUDIO_TREBLE:
592 if (!state->has_sound_processing)
593 return -EINVAL;
594 state->treble = ctrl->value;
595 break;
596
597 case V4L2_CID_AUDIO_LOUDNESS:
598 if (!state->has_sound_processing)
599 return -EINVAL;
600 state->loudness = ctrl->value;
601 break;
602
603 case V4L2_CID_AUDIO_BALANCE:
604 if (!state->has_sound_processing)
605 return -EINVAL;
606 state->balance = ctrl->value;
607 break;
608
609 default:
610 return -EINVAL;
611 }
612 msp_set_audio(client);
613 return 0;
614}
615
616static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
617{
618 struct msp_state *state = i2c_get_clientdata(client);
619 u16 *sarg = arg;
620 int scart = 0;
621
622 if (debug >= 2)
623 v4l_i2c_print_ioctl(client, cmd);
624
625 switch (cmd) {
626 case AUDC_SET_INPUT:
627 if (*sarg == state->input)
628 break;
629 state->input = *sarg;
630 switch (*sarg) {
631 case AUDIO_RADIO:
632 /* Hauppauge uses IN2 for the radio */
633 state->mode = MSP_MODE_FM_RADIO;
634 scart = SCART_IN2;
635 break;
636 case AUDIO_EXTERN_1:
637 /* IN1 is often used for external input ... */
638 state->mode = MSP_MODE_EXTERN;
639 scart = SCART_IN1;
640 break;
641 case AUDIO_EXTERN_2:
642 /* ... sometimes it is IN2 through ;) */
643 state->mode = MSP_MODE_EXTERN;
644 scart = SCART_IN2;
645 break;
646 case AUDIO_TUNER:
647 state->mode = -1;
648 break;
649 default:
650 if (*sarg & AUDIO_MUTE)
651 msp_set_scart(client, SCART_MUTE, 0);
652 break;
653 }
654 if (scart) {
655 state->rxsubchans = V4L2_TUNER_SUB_STEREO;
656 state->audmode = V4L2_TUNER_MODE_STEREO;
657 msp_set_scart(client, scart, 0);
658 msp_write_dsp(client, 0x000d, 0x1900);
659 if (state->opmode != OPMODE_AUTOSELECT)
660 msp3400c_setstereo(client, state->audmode);
661 }
662 msp_wake_thread(client);
663 break;
664
665 case AUDC_SET_RADIO:
666 if (state->radio)
667 return 0;
668 state->radio = 1;
669 v4l_dbg(1, client, "switching to radio mode\n");
670 state->watch_stereo = 0;
671 switch (state->opmode) {
672 case OPMODE_MANUAL:
673 /* set msp3400 to FM radio mode */
674 msp3400c_setmode(client, MSP_MODE_FM_RADIO);
675 msp3400c_setcarrier(client, MSP_CARRIER(10.7),
676 MSP_CARRIER(10.7));
677 msp_set_audio(client);
678 break;
679 case OPMODE_AUTODETECT:
680 case OPMODE_AUTOSELECT:
681 /* the thread will do for us */
682 msp_wake_thread(client);
683 break;
684 }
685 break;
686
687 /* --- v4l ioctls --- */
688 /* take care: bttv does userspace copying, we'll get a
689 kernel pointer here... */
690 case VIDIOCGAUDIO:
691 {
692 struct video_audio *va = arg;
693
694 va->flags |= VIDEO_AUDIO_VOLUME | VIDEO_AUDIO_MUTABLE;
695 if (state->has_sound_processing)
696 va->flags |= VIDEO_AUDIO_BALANCE |
697 VIDEO_AUDIO_BASS |
698 VIDEO_AUDIO_TREBLE;
699 if (state->muted)
700 va->flags |= VIDEO_AUDIO_MUTE;
701 va->volume = state->volume;
702 va->balance = state->volume ? state->balance : 32768;
703 va->bass = state->bass;
704 va->treble = state->treble;
705
706 if (state->radio)
707 break;
708 if (state->opmode == OPMODE_AUTOSELECT)
709 msp_any_detect_stereo(client);
710 va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans);
711 break;
712 }
713
714 case VIDIOCSAUDIO:
715 {
716 struct video_audio *va = arg;
717
718 state->muted = (va->flags & VIDEO_AUDIO_MUTE);
719 state->volume = va->volume;
720 state->balance = va->balance;
721 state->bass = va->bass;
722 state->treble = va->treble;
723 msp_set_audio(client);
724
725 if (va->mode != 0 && state->radio == 0)
726 msp_any_set_audmode(client, msp_mode_v4l1_to_v4l2(va->mode));
727 break;
728 }
729
730 case VIDIOCSCHAN:
731 {
732 struct video_channel *vc = arg;
733 int update = 0;
734 v4l2_std_id std;
735
736 if (state->radio)
737 update = 1;
738 state->radio = 0;
739 if (vc->norm == VIDEO_MODE_PAL)
740 std = V4L2_STD_PAL;
741 else if (vc->norm == VIDEO_MODE_SECAM)
742 std = V4L2_STD_SECAM;
743 else
744 std = V4L2_STD_NTSC;
745 if (std != state->v4l2_std) {
746 state->v4l2_std = std;
747 update = 1;
748 }
749 if (update)
750 msp_wake_thread(client);
751 break;
752 }
753
754 case VIDIOCSFREQ:
755 case VIDIOC_S_FREQUENCY:
756 {
757 /* new channel -- kick audio carrier scan */
758 msp_wake_thread(client);
759 break;
760 }
761
762 /* msp34xx specific */
763 case MSP_SET_MATRIX:
764 {
765 struct msp_matrix *mspm = arg;
766
767 msp_set_scart(client, mspm->input, mspm->output);
768 break;
769 }
770
771 /* --- v4l2 ioctls --- */
772 case VIDIOC_S_STD:
773 {
774 v4l2_std_id *id = arg;
775 int update = state->radio || state->v4l2_std != *id;
776
777 state->v4l2_std = *id;
778 state->radio = 0;
779 if (update)
780 msp_wake_thread(client);
781 return 0;
782 }
783
784 case VIDIOC_ENUMINPUT:
785 {
786 struct v4l2_input *i = arg;
787
788 if (i->index != 0)
789 return -EINVAL;
790
791 i->type = V4L2_INPUT_TYPE_TUNER;
792 switch (i->index) {
793 case AUDIO_RADIO:
794 strcpy(i->name, "Radio");
795 break;
796 case AUDIO_EXTERN_1:
797 strcpy(i->name, "Extern 1");
798 break;
799 case AUDIO_EXTERN_2:
800 strcpy(i->name, "Extern 2");
801 break;
802 case AUDIO_TUNER:
803 strcpy(i->name, "Television");
804 break;
805 default:
806 return -EINVAL;
807 }
808 return 0;
809 }
810
811 case VIDIOC_G_AUDIO:
812 {
813 struct v4l2_audio *a = arg;
814
815 memset(a, 0, sizeof(*a));
816
817 switch (a->index) {
818 case AUDIO_RADIO:
819 strcpy(a->name, "Radio");
820 break;
821 case AUDIO_EXTERN_1:
822 strcpy(a->name, "Extern 1");
823 break;
824 case AUDIO_EXTERN_2:
825 strcpy(a->name, "Extern 2");
826 break;
827 case AUDIO_TUNER:
828 strcpy(a->name, "Television");
829 break;
830 default:
831 return -EINVAL;
832 }
833
834 msp_any_detect_stereo(client);
835 if (state->audmode == V4L2_TUNER_MODE_STEREO) {
836 a->capability = V4L2_AUDCAP_STEREO;
837 }
838
839 break;
840 }
841
842 case VIDIOC_S_AUDIO:
843 {
844 struct v4l2_audio *sarg = arg;
845
846 switch (sarg->index) {
847 case AUDIO_RADIO:
848 /* Hauppauge uses IN2 for the radio */
849 state->mode = MSP_MODE_FM_RADIO;
850 scart = SCART_IN2;
851 break;
852 case AUDIO_EXTERN_1:
853 /* IN1 is often used for external input ... */
854 state->mode = MSP_MODE_EXTERN;
855 scart = SCART_IN1;
856 break;
857 case AUDIO_EXTERN_2:
858 /* ... sometimes it is IN2 through ;) */
859 state->mode = MSP_MODE_EXTERN;
860 scart = SCART_IN2;
861 break;
862 case AUDIO_TUNER:
863 state->mode = -1;
864 break;
865 }
866 if (scart) {
867 state->rxsubchans = V4L2_TUNER_SUB_STEREO;
868 state->audmode = V4L2_TUNER_MODE_STEREO;
869 msp_set_scart(client, scart, 0);
870 msp_write_dsp(client, 0x000d, 0x1900);
871 }
872 if (sarg->capability == V4L2_AUDCAP_STEREO) {
873 state->audmode = V4L2_TUNER_MODE_STEREO;
874 } else {
875 state->audmode &= ~V4L2_TUNER_MODE_STEREO;
876 }
877 msp_any_set_audmode(client, state->audmode);
878 msp_wake_thread(client);
879 break;
880 }
881
882 case VIDIOC_G_TUNER:
883 {
884 struct v4l2_tuner *vt = arg;
885
886 if (state->radio)
887 break;
888 if (state->opmode == OPMODE_AUTOSELECT)
889 msp_any_detect_stereo(client);
890 vt->audmode = state->audmode;
891 vt->rxsubchans = state->rxsubchans;
892 vt->capability = V4L2_TUNER_CAP_STEREO |
893 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
894 break;
895 }
896
897 case VIDIOC_S_TUNER:
898 {
899 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
900
901 if (state->radio)
902 break;
903 /* only set audmode */
904 if (vt->audmode != -1 && vt->audmode != 0)
905 msp_any_set_audmode(client, vt->audmode);
906 break;
907 }
908
909 case VIDIOC_G_AUDOUT:
910 {
911 struct v4l2_audioout *a = (struct v4l2_audioout *)arg;
912 int idx = a->index;
913
914 memset(a, 0, sizeof(*a));
915
916 switch (idx) {
917 case 0:
918 strcpy(a->name, "Scart1 Out");
919 break;
920 case 1:
921 strcpy(a->name, "Scart2 Out");
922 break;
923 case 2:
924 strcpy(a->name, "I2S Out");
925 break;
926 default:
927 return -EINVAL;
928 }
929 break;
930
931 }
932
933 case VIDIOC_S_AUDOUT:
934 {
935 struct v4l2_audioout *a = (struct v4l2_audioout *)arg;
936
937 if (a->index < 0 || a->index > 2)
938 return -EINVAL;
939
940 v4l_dbg(1, client, "Setting audio out on msp34xx to input %i\n", a->index);
941 msp_set_scart(client, state->in_scart, a->index + 1);
942
943 break;
944 }
945
946 case VIDIOC_INT_I2S_CLOCK_FREQ:
947 {
948 u32 *a = (u32 *)arg;
949
950 v4l_dbg(1, client, "Setting I2S speed to %d\n", *a);
951
952 switch (*a) {
953 case 1024000:
954 state->i2s_mode = 0;
955 break;
956 case 2048000:
957 state->i2s_mode = 1;
958 break;
959 default:
960 return -EINVAL;
961 }
962 break;
963 }
964
965 case VIDIOC_QUERYCTRL:
966 {
967 struct v4l2_queryctrl *qc = arg;
968 int i;
969
970 for (i = 0; i < ARRAY_SIZE(msp_qctrl_std); i++)
971 if (qc->id && qc->id == msp_qctrl_std[i].id) {
972 memcpy(qc, &msp_qctrl_std[i], sizeof(*qc));
973 return 0;
974 }
975 if (!state->has_sound_processing)
976 return -EINVAL;
977 for (i = 0; i < ARRAY_SIZE(msp_qctrl_sound_processing); i++)
978 if (qc->id && qc->id == msp_qctrl_sound_processing[i].id) {
979 memcpy(qc, &msp_qctrl_sound_processing[i], sizeof(*qc));
980 return 0;
981 }
982 return -EINVAL;
983 }
984
985 case VIDIOC_G_CTRL:
986 return msp_get_ctrl(client, arg);
987
988 case VIDIOC_S_CTRL:
989 return msp_set_ctrl(client, arg);
990
991 case VIDIOC_LOG_STATUS:
992 {
993 const char *p;
994
995 if (state->opmode == OPMODE_AUTOSELECT)
996 msp_any_detect_stereo(client);
997 v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n",
998 client->name, state->rev1, state->rev2);
999 v4l_info(client, "Audio: volume %d%s\n",
1000 state->volume, state->muted ? " (muted)" : "");
1001 if (state->has_sound_processing) {
1002 v4l_info(client, "Audio: balance %d bass %d treble %d loudness %s\n",
1003 state->balance, state->bass, state->treble,
1004 state->loudness ? "on" : "off");
1005 }
1006 switch (state->mode) {
1007 case MSP_MODE_AM_DETECT: p = "AM (for carrier detect)"; break;
1008 case MSP_MODE_FM_RADIO: p = "FM Radio"; break;
1009 case MSP_MODE_FM_TERRA: p = "Terrestial FM-mono + FM-stereo"; break;
1010 case MSP_MODE_FM_SAT: p = "Satellite FM-mono"; break;
1011 case MSP_MODE_FM_NICAM1: p = "NICAM/FM (B/G, D/K)"; break;
1012 case MSP_MODE_FM_NICAM2: p = "NICAM/FM (I)"; break;
1013 case MSP_MODE_AM_NICAM: p = "NICAM/AM (L)"; break;
1014 case MSP_MODE_BTSC: p = "BTSC"; break;
1015 case MSP_MODE_EXTERN: p = "External input"; break;
1016 default: p = "unknown"; break;
1017 }
1018 if (state->opmode == OPMODE_MANUAL) {
1019 v4l_info(client, "Mode: %s (%s%s)\n", p,
1020 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
1021 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
1022 } else {
1023 v4l_info(client, "Mode: %s\n", p);
1024 v4l_info(client, "Standard: %s (%s%s)\n",
1025 msp_standard_std_name(state->std),
1026 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
1027 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
1028 }
1029 v4l_info(client, "ACB: 0x%04x\n", state->acb);
1030 break;
1031 }
1032
1033 default:
1034 /* nothing */
1035 break;
1036 }
1037 return 0;
1038}
1039
1040static int msp_suspend(struct device * dev, pm_message_t state)
1041{
1042 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1043
1044 v4l_dbg(1, client, "suspend\n");
1045 msp_reset(client);
1046 return 0;
1047}
1048
1049static int msp_resume(struct device * dev)
1050{
1051 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1052
1053 v4l_dbg(1, client, "resume\n");
1054 msp_wake_thread(client);
1055 return 0;
1056}
1057
1058/* ----------------------------------------------------------------------- */
1059
1060static struct i2c_driver i2c_driver;
1061
1062static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
1063{
1064 struct i2c_client *client;
1065 struct msp_state *state;
1066 int (*thread_func)(void *data) = NULL;
1067 int msp_hard;
1068 int msp_family;
1069 int msp_revision;
1070 int msp_product, msp_prod_hi, msp_prod_lo;
1071 int msp_rom;
1072
1073 client = kmalloc(sizeof(*client), GFP_KERNEL);
1074 if (client == NULL)
1075 return -ENOMEM;
1076 memset(client, 0, sizeof(*client));
1077 client->addr = address;
1078 client->adapter = adapter;
1079 client->driver = &i2c_driver;
1080 snprintf(client->name, sizeof(client->name) - 1, "msp3400");
1081
1082 if (msp_reset(client) == -1) {
1083 v4l_dbg(1, client, "msp3400 not found\n");
1084 kfree(client);
1085 return -1;
1086 }
1087
1088 state = kmalloc(sizeof(*state), GFP_KERNEL);
1089 if (state == NULL) {
1090 kfree(client);
1091 return -ENOMEM;
1092 }
1093 i2c_set_clientdata(client, state);
1094
1095 memset(state, 0, sizeof(*state));
1096 state->v4l2_std = V4L2_STD_NTSC;
1097 state->volume = 58880; /* 0db gain */
1098 state->balance = 32768; /* 0db gain */
1099 state->bass = 32768;
1100 state->treble = 32768;
1101 state->loudness = 0;
1102 state->input = -1;
1103 state->muted = 0;
1104 state->i2s_mode = 0;
1105 init_waitqueue_head(&state->wq);
1106
1107 state->rev1 = msp_read_dsp(client, 0x1e);
1108 if (state->rev1 != -1)
1109 state->rev2 = msp_read_dsp(client, 0x1f);
1110 v4l_dbg(1, client, "rev1=0x%04x, rev2=0x%04x\n", state->rev1, state->rev2);
1111 if (state->rev1 == -1 || (state->rev1 == 0 && state->rev2 == 0)) {
1112 v4l_dbg(1, client, "not an msp3400 (cannot read chip version)\n");
1113 kfree(state);
1114 kfree(client);
1115 return -1;
1116 }
1117
1118 msp_set_audio(client);
1119
1120 msp_family = ((state->rev1 >> 4) & 0x0f) + 3;
1121 msp_product = (state->rev2 >> 8) & 0xff;
1122 msp_prod_hi = msp_product / 10;
1123 msp_prod_lo = msp_product % 10;
1124 msp_revision = (state->rev1 & 0x0f) + '@';
1125 msp_hard = ((state->rev1 >> 8) & 0xff) + '@';
1126 msp_rom = state->rev2 & 0x1f;
1127 snprintf(client->name, sizeof(client->name), "MSP%d4%02d%c-%c%d",
1128 msp_family, msp_product,
1129 msp_revision, msp_hard, msp_rom);
1130
1131 /* Has NICAM support: all mspx41x and mspx45x products have NICAM */
1132 state->has_nicam = msp_prod_hi == 1 || msp_prod_hi == 5;
1133 /* Has radio support: was added with revision G */
1134 state->has_radio = msp_revision >= 'G';
1135 /* Has headphones output: not for stripped down products */
1136 state->has_headphones = msp_prod_lo < 5;
1137 /* Has scart4 input: not in pre D revisions, not in stripped D revs */
1138 state->has_scart4 = msp_family >= 4 || (msp_revision >= 'D' && msp_prod_lo < 5);
1139 /* Has scart2 and scart3 inputs and scart2 output: not in stripped
1140 down products of the '3' family */
1141 state->has_scart23_in_scart2_out = msp_family >= 4 || msp_prod_lo < 5;
1142 /* Has scart2 a volume control? Not in pre-D revisions. */
1143 state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart23_in_scart2_out;
1144 /* Has a configurable i2s out? */
1145 state->has_i2s_conf = msp_revision >= 'G' && msp_prod_lo < 7;
1146 /* Has subwoofer output: not in pre-D revs and not in stripped down products */
1147 state->has_subwoofer = msp_revision >= 'D' && msp_prod_lo < 5;
1148 /* Has soundprocessing (bass/treble/balance/loudness/equalizer): not in
1149 stripped down products */
1150 state->has_sound_processing = msp_prod_lo < 7;
1151 /* Has Virtual Dolby Surround: only in msp34x1 */
1152 state->has_virtual_dolby_surround = msp_revision == 'G' && msp_prod_lo == 1;
1153 /* Has Virtual Dolby Surround & Dolby Pro Logic: only in msp34x2 */
1154 state->has_dolby_pro_logic = msp_revision == 'G' && msp_prod_lo == 2;
1155
1156 state->opmode = opmode;
1157 if (state->opmode == OPMODE_AUTO) {
1158 /* MSP revision G and up have both autodetect and autoselect */
1159 if (msp_revision >= 'G')
1160 state->opmode = OPMODE_AUTOSELECT;
1161 /* MSP revision D and up have autodetect */
1162 else if (msp_revision >= 'D')
1163 state->opmode = OPMODE_AUTODETECT;
1164 else
1165 state->opmode = OPMODE_MANUAL;
1166 }
1167
1168 /* hello world :-) */
1169 v4l_info(client, "%s found @ 0x%x (%s)\n", client->name, address << 1, adapter->name);
1170 v4l_info(client, "%s ", client->name);
1171 if (state->has_nicam && state->has_radio)
1172 printk("supports nicam and radio, ");
1173 else if (state->has_nicam)
1174 printk("supports nicam, ");
1175 else if (state->has_radio)
1176 printk("supports radio, ");
1177 printk("mode is ");
1178
1179 /* version-specific initialization */
1180 switch (state->opmode) {
1181 case OPMODE_MANUAL:
1182 printk("manual");
1183 thread_func = msp3400c_thread;
1184 break;
1185 case OPMODE_AUTODETECT:
1186 printk("autodetect");
1187 thread_func = msp3410d_thread;
1188 break;
1189 case OPMODE_AUTOSELECT:
1190 printk("autodetect and autoselect");
1191 thread_func = msp34xxg_thread;
1192 break;
1193 }
1194 printk("\n");
1195
1196 /* startup control thread if needed */
1197 if (thread_func) {
1198 state->kthread = kthread_run(thread_func, client, "msp34xx");
1199
1200 if (state->kthread == NULL)
1201 v4l_warn(client, "kernel_thread() failed\n");
1202 msp_wake_thread(client);
1203 }
1204
1205 /* done */
1206 i2c_attach_client(client);
1207
1208 return 0;
1209}
1210
1211static int msp_probe(struct i2c_adapter *adapter)
1212{
1213 if (adapter->class & I2C_CLASS_TV_ANALOG)
1214 return i2c_probe(adapter, &addr_data, msp_attach);
1215 return 0;
1216}
1217
1218static int msp_detach(struct i2c_client *client)
1219{
1220 struct msp_state *state = i2c_get_clientdata(client);
1221 int err;
1222
1223 /* shutdown control thread */
1224 if (state->kthread) {
1225 state->restart = 1;
1226 kthread_stop(state->kthread);
1227 }
1228 msp_reset(client);
1229
1230 err = i2c_detach_client(client);
1231 if (err) {
1232 return err;
1233 }
1234
1235 kfree(state);
1236 kfree(client);
1237 return 0;
1238}
1239
1240/* ----------------------------------------------------------------------- */
1241
1242/* i2c implementation */
1243static struct i2c_driver i2c_driver = {
1244 .id = I2C_DRIVERID_MSP3400,
1245 .attach_adapter = msp_probe,
1246 .detach_client = msp_detach,
1247 .command = msp_command,
1248 .driver = {
1249 .name = "msp3400",
1250 .suspend = msp_suspend,
1251 .resume = msp_resume,
1252 },
1253};
1254
1255static int __init msp3400_init_module(void)
1256{
1257 return i2c_add_driver(&i2c_driver);
1258}
1259
1260static void __exit msp3400_cleanup_module(void)
1261{
1262 i2c_del_driver(&i2c_driver);
1263}
1264
1265module_init(msp3400_init_module);
1266module_exit(msp3400_cleanup_module);
1267
1268/*
1269 * Overrides for Emacs so that we follow Linus's tabbing style.
1270 * ---------------------------------------------------------------------------
1271 * Local variables:
1272 * c-basic-offset: 8
1273 * End:
1274 */
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
new file mode 100644
index 000000000000..2b59b6847535
--- /dev/null
+++ b/drivers/media/video/msp3400-kthreads.c
@@ -0,0 +1,1010 @@
1/*
2 * Programming the mspx4xx sound processor family
3 *
4 * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/slab.h>
25#include <linux/i2c.h>
26#include <linux/videodev.h>
27#include <linux/videodev2.h>
28#include <media/v4l2-common.h>
29#include <media/audiochip.h>
30#include <linux/kthread.h>
31#include <linux/suspend.h>
32#include "msp3400.h"
33
34/* this one uses the automatic sound standard detection of newer msp34xx
35 chip versions */
36static struct {
37 int retval;
38 int main, second;
39 char *name;
40} msp_stdlist[] = {
41 { 0x0000, 0, 0, "could not detect sound standard" },
42 { 0x0001, 0, 0, "autodetect start" },
43 { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72 M Dual FM-Stereo" },
44 { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74 B/G Dual FM-Stereo" },
45 { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" },
46 { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" },
47 { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" },
48 { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" },
49 { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" },
50 { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" },
51 { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" },
52 { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" },
53 { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" },
54 { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" },
55 { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" },
56 { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7 FM-Stereo Radio" },
57 { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 SAT-Mono" },
58 { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20 SAT-Stereo" },
59 { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2 SAT ADR" },
60 { -1, 0, 0, NULL }, /* EOF */
61};
62
63static struct msp3400c_init_data_dem {
64 int fir1[6];
65 int fir2[6];
66 int cdo1;
67 int cdo2;
68 int ad_cv;
69 int mode_reg;
70 int dsp_src;
71 int dsp_matrix;
72} msp3400c_init_data[] = {
73 { /* AM (for carrier detect / msp3400) */
74 {75, 19, 36, 35, 39, 40},
75 {75, 19, 36, 35, 39, 40},
76 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
77 0x00d0, 0x0500, 0x0020, 0x3000
78 },{ /* AM (for carrier detect / msp3410) */
79 {-1, -1, -8, 2, 59, 126},
80 {-1, -1, -8, 2, 59, 126},
81 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
82 0x00d0, 0x0100, 0x0020, 0x3000
83 },{ /* FM Radio */
84 {-8, -8, 4, 6, 78, 107},
85 {-8, -8, 4, 6, 78, 107},
86 MSP_CARRIER(10.7), MSP_CARRIER(10.7),
87 0x00d0, 0x0480, 0x0020, 0x3000
88 },{ /* Terrestial FM-mono + FM-stereo */
89 {3, 18, 27, 48, 66, 72},
90 {3, 18, 27, 48, 66, 72},
91 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
92 0x00d0, 0x0480, 0x0030, 0x3000
93 },{ /* Sat FM-mono */
94 { 1, 9, 14, 24, 33, 37},
95 { 3, 18, 27, 48, 66, 72},
96 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
97 0x00c6, 0x0480, 0x0000, 0x3000
98 },{ /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */
99 {-2, -8, -10, 10, 50, 86},
100 {3, 18, 27, 48, 66, 72},
101 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
102 0x00d0, 0x0040, 0x0120, 0x3000
103 },{ /* NICAM/FM -- I (6.0/6.552) */
104 {2, 4, -6, -4, 40, 94},
105 {3, 18, 27, 48, 66, 72},
106 MSP_CARRIER(6.0), MSP_CARRIER(6.0),
107 0x00d0, 0x0040, 0x0120, 0x3000
108 },{ /* NICAM/AM -- L (6.5/5.85) */
109 {-2, -8, -10, 10, 50, 86},
110 {-4, -12, -9, 23, 79, 126},
111 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
112 0x00c6, 0x0140, 0x0120, 0x7c03
113 },
114};
115
116struct msp3400c_carrier_detect {
117 int cdo;
118 char *name;
119};
120
121static struct msp3400c_carrier_detect msp3400c_carrier_detect_main[] = {
122 /* main carrier */
123 { MSP_CARRIER(4.5), "4.5 NTSC" },
124 { MSP_CARRIER(5.5), "5.5 PAL B/G" },
125 { MSP_CARRIER(6.0), "6.0 PAL I" },
126 { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" }
127};
128
129static struct msp3400c_carrier_detect msp3400c_carrier_detect_55[] = {
130 /* PAL B/G */
131 { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" },
132 { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" }
133};
134
135static struct msp3400c_carrier_detect msp3400c_carrier_detect_65[] = {
136 /* PAL SAT / SECAM */
137 { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" },
138 { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" },
139 { MSP_CARRIER(6.7421875), "6.74 PAL D/K2 FM-stereo" },
140 { MSP_CARRIER(7.02), "7.02 PAL SAT FM-stereo s/b" },
141 { MSP_CARRIER(7.20), "7.20 PAL SAT FM-stereo s" },
142 { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" },
143};
144
145/* ------------------------------------------------------------------------ */
146
147const char *msp_standard_std_name(int std)
148{
149 int i;
150
151 for (i = 0; msp_stdlist[i].name != NULL; i++)
152 if (msp_stdlist[i].retval == std)
153 return msp_stdlist[i].name;
154 return "unknown";
155}
156
157void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
158{
159 msp_write_dem(client, 0x0093, cdo1 & 0xfff);
160 msp_write_dem(client, 0x009b, cdo1 >> 12);
161 msp_write_dem(client, 0x00a3, cdo2 & 0xfff);
162 msp_write_dem(client, 0x00ab, cdo2 >> 12);
163 msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/
164}
165
166void msp3400c_setmode(struct i2c_client *client, int type)
167{
168 struct msp_state *state = i2c_get_clientdata(client);
169 int i;
170
171 v4l_dbg(1, client, "setmode: %d\n", type);
172 state->mode = type;
173 state->audmode = V4L2_TUNER_MODE_MONO;
174 state->rxsubchans = V4L2_TUNER_SUB_MONO;
175
176 msp_write_dem(client, 0x00bb, msp3400c_init_data[type].ad_cv);
177
178 for (i = 5; i >= 0; i--) /* fir 1 */
179 msp_write_dem(client, 0x0001, msp3400c_init_data[type].fir1[i]);
180
181 msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */
182 msp_write_dem(client, 0x0005, 0x0040);
183 msp_write_dem(client, 0x0005, 0x0000);
184 for (i = 5; i >= 0; i--)
185 msp_write_dem(client, 0x0005, msp3400c_init_data[type].fir2[i]);
186
187 msp_write_dem(client, 0x0083, msp3400c_init_data[type].mode_reg);
188
189 msp3400c_setcarrier(client, msp3400c_init_data[type].cdo1,
190 msp3400c_init_data[type].cdo2);
191
192 msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/
193
194 if (dolby) {
195 msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */
196 msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */
197 msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src);
198 } else {
199 msp_write_dsp(client, 0x0008, msp3400c_init_data[type].dsp_src);
200 msp_write_dsp(client, 0x0009, msp3400c_init_data[type].dsp_src);
201 msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src);
202 }
203 msp_write_dsp(client, 0x000a, msp3400c_init_data[type].dsp_src);
204 msp_write_dsp(client, 0x000e, msp3400c_init_data[type].dsp_matrix);
205
206 if (state->has_nicam) {
207 /* nicam prescale */
208 msp_write_dsp(client, 0x0010, 0x5a00); /* was: 0x3000 */
209 }
210}
211
212/* turn on/off nicam + stereo */
213void msp3400c_setstereo(struct i2c_client *client, int mode)
214{
215 static char *strmode[] = { "mono", "stereo", "lang2", "lang1" };
216 struct msp_state *state = i2c_get_clientdata(client);
217 int nicam = 0; /* channel source: FM/AM or nicam */
218 int src = 0;
219
220 if (state->opmode == OPMODE_AUTOSELECT) {
221 /* this method would break everything, let's make sure
222 * it's never called
223 */
224 v4l_dbg(1, client, "setstereo called with mode=%d instead of set_source (ignored)\n",
225 mode);
226 return;
227 }
228
229 /* switch demodulator */
230 switch (state->mode) {
231 case MSP_MODE_FM_TERRA:
232 v4l_dbg(1, client, "FM setstereo: %s\n", strmode[mode]);
233 msp3400c_setcarrier(client, state->second, state->main);
234 switch (mode) {
235 case V4L2_TUNER_MODE_STEREO:
236 msp_write_dsp(client, 0x000e, 0x3001);
237 break;
238 case V4L2_TUNER_MODE_MONO:
239 case V4L2_TUNER_MODE_LANG1:
240 case V4L2_TUNER_MODE_LANG2:
241 msp_write_dsp(client, 0x000e, 0x3000);
242 break;
243 }
244 break;
245 case MSP_MODE_FM_SAT:
246 v4l_dbg(1, client, "SAT setstereo: %s\n", strmode[mode]);
247 switch (mode) {
248 case V4L2_TUNER_MODE_MONO:
249 msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
250 break;
251 case V4L2_TUNER_MODE_STEREO:
252 msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
253 break;
254 case V4L2_TUNER_MODE_LANG1:
255 msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
256 break;
257 case V4L2_TUNER_MODE_LANG2:
258 msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
259 break;
260 }
261 break;
262 case MSP_MODE_FM_NICAM1:
263 case MSP_MODE_FM_NICAM2:
264 case MSP_MODE_AM_NICAM:
265 v4l_dbg(1, client, "NICAM setstereo: %s\n",strmode[mode]);
266 msp3400c_setcarrier(client,state->second,state->main);
267 if (state->nicam_on)
268 nicam=0x0100;
269 break;
270 case MSP_MODE_BTSC:
271 v4l_dbg(1, client, "BTSC setstereo: %s\n",strmode[mode]);
272 nicam=0x0300;
273 break;
274 case MSP_MODE_EXTERN:
275 v4l_dbg(1, client, "extern setstereo: %s\n",strmode[mode]);
276 nicam = 0x0200;
277 break;
278 case MSP_MODE_FM_RADIO:
279 v4l_dbg(1, client, "FM-Radio setstereo: %s\n",strmode[mode]);
280 break;
281 default:
282 v4l_dbg(1, client, "mono setstereo\n");
283 return;
284 }
285
286 /* switch audio */
287 switch (mode) {
288 case V4L2_TUNER_MODE_STEREO:
289 src = 0x0020 | nicam;
290 break;
291 case V4L2_TUNER_MODE_MONO:
292 if (state->mode == MSP_MODE_AM_NICAM) {
293 v4l_dbg(1, client, "switching to AM mono\n");
294 /* AM mono decoding is handled by tuner, not MSP chip */
295 /* SCART switching control register */
296 msp_set_scart(client, SCART_MONO, 0);
297 src = 0x0200;
298 break;
299 }
300 case V4L2_TUNER_MODE_LANG1:
301 src = 0x0000 | nicam;
302 break;
303 case V4L2_TUNER_MODE_LANG2:
304 src = 0x0010 | nicam;
305 break;
306 }
307 v4l_dbg(1, client, "setstereo final source/matrix = 0x%x\n", src);
308
309 if (dolby) {
310 msp_write_dsp(client, 0x0008, 0x0520);
311 msp_write_dsp(client, 0x0009, 0x0620);
312 msp_write_dsp(client, 0x000a, src);
313 msp_write_dsp(client, 0x000b, src);
314 } else {
315 msp_write_dsp(client, 0x0008, src);
316 msp_write_dsp(client, 0x0009, src);
317 msp_write_dsp(client, 0x000a, src);
318 msp_write_dsp(client, 0x000b, src);
319 msp_write_dsp(client, 0x000c, src);
320 if (state->has_scart23_in_scart2_out)
321 msp_write_dsp(client, 0x0041, src);
322 }
323}
324
325static void msp3400c_print_mode(struct i2c_client *client)
326{
327 struct msp_state *state = i2c_get_clientdata(client);
328
329 if (state->main == state->second) {
330 v4l_dbg(1, client, "mono sound carrier: %d.%03d MHz\n",
331 state->main / 910000, (state->main / 910) % 1000);
332 } else {
333 v4l_dbg(1, client, "main sound carrier: %d.%03d MHz\n",
334 state->main / 910000, (state->main / 910) % 1000);
335 }
336 if (state->mode == MSP_MODE_FM_NICAM1 || state->mode == MSP_MODE_FM_NICAM2)
337 v4l_dbg(1, client, "NICAM/FM carrier : %d.%03d MHz\n",
338 state->second / 910000, (state->second/910) % 1000);
339 if (state->mode == MSP_MODE_AM_NICAM)
340 v4l_dbg(1, client, "NICAM/AM carrier : %d.%03d MHz\n",
341 state->second / 910000, (state->second / 910) % 1000);
342 if (state->mode == MSP_MODE_FM_TERRA && state->main != state->second) {
343 v4l_dbg(1, client, "FM-stereo carrier : %d.%03d MHz\n",
344 state->second / 910000, (state->second / 910) % 1000);
345 }
346}
347
348/* ----------------------------------------------------------------------- */
349
350int autodetect_stereo(struct i2c_client *client)
351{
352 struct msp_state *state = i2c_get_clientdata(client);
353 int val;
354 int rxsubchans = state->rxsubchans;
355 int newnicam = state->nicam_on;
356 int update = 0;
357
358 switch (state->mode) {
359 case MSP_MODE_FM_TERRA:
360 val = msp_read_dsp(client, 0x18);
361 if (val > 32767)
362 val -= 65536;
363 v4l_dbg(2, client, "stereo detect register: %d\n", val);
364 if (val > 4096) {
365 rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
366 } else if (val < -4096) {
367 rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
368 } else {
369 rxsubchans = V4L2_TUNER_SUB_MONO;
370 }
371 newnicam = 0;
372 break;
373 case MSP_MODE_FM_NICAM1:
374 case MSP_MODE_FM_NICAM2:
375 case MSP_MODE_AM_NICAM:
376 val = msp_read_dem(client, 0x23);
377 v4l_dbg(2, client, "nicam sync=%d, mode=%d\n",
378 val & 1, (val & 0x1e) >> 1);
379
380 if (val & 1) {
381 /* nicam synced */
382 switch ((val & 0x1e) >> 1) {
383 case 0:
384 case 8:
385 rxsubchans = V4L2_TUNER_SUB_STEREO;
386 break;
387 case 1:
388 case 9:
389 rxsubchans = V4L2_TUNER_SUB_MONO
390 | V4L2_TUNER_SUB_LANG1;
391 break;
392 case 2:
393 case 10:
394 rxsubchans = V4L2_TUNER_SUB_MONO
395 | V4L2_TUNER_SUB_LANG1
396 | V4L2_TUNER_SUB_LANG2;
397 break;
398 default:
399 rxsubchans = V4L2_TUNER_SUB_MONO;
400 break;
401 }
402 newnicam = 1;
403 } else {
404 newnicam = 0;
405 rxsubchans = V4L2_TUNER_SUB_MONO;
406 }
407 break;
408 case MSP_MODE_BTSC:
409 val = msp_read_dem(client, 0x200);
410 v4l_dbg(2, client, "status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
411 val,
412 (val & 0x0002) ? "no" : "yes",
413 (val & 0x0004) ? "no" : "yes",
414 (val & 0x0040) ? "stereo" : "mono",
415 (val & 0x0080) ? ", nicam 2nd mono" : "",
416 (val & 0x0100) ? ", bilingual/SAP" : "");
417 rxsubchans = V4L2_TUNER_SUB_MONO;
418 if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO;
419 if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1;
420 break;
421 }
422 if (rxsubchans != state->rxsubchans) {
423 update = 1;
424 v4l_dbg(1, client, "watch: rxsubchans %d => %d\n",
425 state->rxsubchans,rxsubchans);
426 state->rxsubchans = rxsubchans;
427 }
428 if (newnicam != state->nicam_on) {
429 update = 1;
430 v4l_dbg(1, client, "watch: nicam %d => %d\n",
431 state->nicam_on,newnicam);
432 state->nicam_on = newnicam;
433 }
434 return update;
435}
436
437/*
438 * A kernel thread for msp3400 control -- we don't want to block the
439 * in the ioctl while doing the sound carrier & stereo detect
440 */
441/* stereo/multilang monitoring */
442static void watch_stereo(struct i2c_client *client)
443{
444 struct msp_state *state = i2c_get_clientdata(client);
445
446 if (autodetect_stereo(client)) {
447 if (state->rxsubchans & V4L2_TUNER_SUB_STEREO)
448 msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO);
449 else if (state->rxsubchans & V4L2_TUNER_SUB_LANG1)
450 msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1);
451 else
452 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
453 }
454
455 if (once)
456 state->watch_stereo = 0;
457}
458
459int msp3400c_thread(void *data)
460{
461 struct i2c_client *client = data;
462 struct msp_state *state = i2c_get_clientdata(client);
463 struct msp3400c_carrier_detect *cd;
464 int count, max1,max2,val1,val2, val,this;
465
466
467 v4l_dbg(1, client, "msp3400 daemon started\n");
468 for (;;) {
469 v4l_dbg(2, client, "msp3400 thread: sleep\n");
470 msp_sleep(state, -1);
471 v4l_dbg(2, client, "msp3400 thread: wakeup\n");
472
473 restart:
474 v4l_dbg(1, client, "thread: restart scan\n");
475 state->restart = 0;
476 if (kthread_should_stop())
477 break;
478
479 if (state->radio || MSP_MODE_EXTERN == state->mode) {
480 /* no carrier scan, just unmute */
481 v4l_dbg(1, client, "thread: no carrier scan\n");
482 msp_set_audio(client);
483 continue;
484 }
485
486 /* mute */
487 msp_set_mute(client);
488 msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
489 val1 = val2 = 0;
490 max1 = max2 = -1;
491 state->watch_stereo = 0;
492
493 /* some time for the tuner to sync */
494 if (msp_sleep(state,200))
495 goto restart;
496
497 /* carrier detect pass #1 -- main carrier */
498 cd = msp3400c_carrier_detect_main;
499 count = ARRAY_SIZE(msp3400c_carrier_detect_main);
500
501 if (amsound && (state->v4l2_std & V4L2_STD_SECAM)) {
502 /* autodetect doesn't work well with AM ... */
503 max1 = 3;
504 count = 0;
505 v4l_dbg(1, client, "AM sound override\n");
506 }
507
508 for (this = 0; this < count; this++) {
509 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
510 if (msp_sleep(state,100))
511 goto restart;
512 val = msp_read_dsp(client, 0x1b);
513 if (val > 32767)
514 val -= 65536;
515 if (val1 < val)
516 val1 = val, max1 = this;
517 v4l_dbg(1, client, "carrier1 val: %5d / %s\n", val,cd[this].name);
518 }
519
520 /* carrier detect pass #2 -- second (stereo) carrier */
521 switch (max1) {
522 case 1: /* 5.5 */
523 cd = msp3400c_carrier_detect_55;
524 count = ARRAY_SIZE(msp3400c_carrier_detect_55);
525 break;
526 case 3: /* 6.5 */
527 cd = msp3400c_carrier_detect_65;
528 count = ARRAY_SIZE(msp3400c_carrier_detect_65);
529 break;
530 case 0: /* 4.5 */
531 case 2: /* 6.0 */
532 default:
533 cd = NULL;
534 count = 0;
535 break;
536 }
537
538 if (amsound && (state->v4l2_std & V4L2_STD_SECAM)) {
539 /* autodetect doesn't work well with AM ... */
540 cd = NULL;
541 count = 0;
542 max2 = 0;
543 }
544 for (this = 0; this < count; this++) {
545 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
546 if (msp_sleep(state,100))
547 goto restart;
548 val = msp_read_dsp(client, 0x1b);
549 if (val > 32767)
550 val -= 65536;
551 if (val2 < val)
552 val2 = val, max2 = this;
553 v4l_dbg(1, client, "carrier2 val: %5d / %s\n", val,cd[this].name);
554 }
555
556 /* program the msp3400 according to the results */
557 state->main = msp3400c_carrier_detect_main[max1].cdo;
558 switch (max1) {
559 case 1: /* 5.5 */
560 if (max2 == 0) {
561 /* B/G FM-stereo */
562 state->second = msp3400c_carrier_detect_55[max2].cdo;
563 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
564 state->nicam_on = 0;
565 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
566 state->watch_stereo = 1;
567 } else if (max2 == 1 && state->has_nicam) {
568 /* B/G NICAM */
569 state->second = msp3400c_carrier_detect_55[max2].cdo;
570 msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
571 state->nicam_on = 1;
572 msp3400c_setcarrier(client, state->second, state->main);
573 state->watch_stereo = 1;
574 } else {
575 goto no_second;
576 }
577 break;
578 case 2: /* 6.0 */
579 /* PAL I NICAM */
580 state->second = MSP_CARRIER(6.552);
581 msp3400c_setmode(client, MSP_MODE_FM_NICAM2);
582 state->nicam_on = 1;
583 msp3400c_setcarrier(client, state->second, state->main);
584 state->watch_stereo = 1;
585 break;
586 case 3: /* 6.5 */
587 if (max2 == 1 || max2 == 2) {
588 /* D/K FM-stereo */
589 state->second = msp3400c_carrier_detect_65[max2].cdo;
590 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
591 state->nicam_on = 0;
592 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
593 state->watch_stereo = 1;
594 } else if (max2 == 0 && (state->v4l2_std & V4L2_STD_SECAM)) {
595 /* L NICAM or AM-mono */
596 state->second = msp3400c_carrier_detect_65[max2].cdo;
597 msp3400c_setmode(client, MSP_MODE_AM_NICAM);
598 state->nicam_on = 0;
599 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
600 msp3400c_setcarrier(client, state->second, state->main);
601 /* volume prescale for SCART (AM mono input) */
602 msp_write_dsp(client, 0x000d, 0x1900);
603 state->watch_stereo = 1;
604 } else if (max2 == 0 && state->has_nicam) {
605 /* D/K NICAM */
606 state->second = msp3400c_carrier_detect_65[max2].cdo;
607 msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
608 state->nicam_on = 1;
609 msp3400c_setcarrier(client, state->second, state->main);
610 state->watch_stereo = 1;
611 } else {
612 goto no_second;
613 }
614 break;
615 case 0: /* 4.5 */
616 default:
617 no_second:
618 state->second = msp3400c_carrier_detect_main[max1].cdo;
619 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
620 state->nicam_on = 0;
621 msp3400c_setcarrier(client, state->second, state->main);
622 state->rxsubchans = V4L2_TUNER_SUB_MONO;
623 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
624 break;
625 }
626
627 /* unmute */
628 msp_set_audio(client);
629
630 if (debug)
631 msp3400c_print_mode(client);
632
633 /* monitor tv audio mode */
634 while (state->watch_stereo) {
635 if (msp_sleep(state,5000))
636 goto restart;
637 watch_stereo(client);
638 }
639 }
640 v4l_dbg(1, client, "thread: exit\n");
641 return 0;
642}
643
644
645int msp3410d_thread(void *data)
646{
647 struct i2c_client *client = data;
648 struct msp_state *state = i2c_get_clientdata(client);
649 int val, i, std;
650
651 v4l_dbg(1, client, "msp3410 daemon started\n");
652
653 for (;;) {
654 v4l_dbg(2, client, "msp3410 thread: sleep\n");
655 msp_sleep(state,-1);
656 v4l_dbg(2, client, "msp3410 thread: wakeup\n");
657
658 restart:
659 v4l_dbg(1, client, "thread: restart scan\n");
660 state->restart = 0;
661 if (kthread_should_stop())
662 break;
663
664 if (state->mode == MSP_MODE_EXTERN) {
665 /* no carrier scan needed, just unmute */
666 v4l_dbg(1, client, "thread: no carrier scan\n");
667 msp_set_audio(client);
668 continue;
669 }
670
671 /* put into sane state (and mute) */
672 msp_reset(client);
673
674 /* some time for the tuner to sync */
675 if (msp_sleep(state,200))
676 goto restart;
677
678 /* start autodetect */
679 if (state->radio)
680 std = 0x40;
681 else
682 std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1;
683 state->watch_stereo = 0;
684
685 if (debug)
686 v4l_dbg(1, client, "setting standard: %s (0x%04x)\n",
687 msp_standard_std_name(std), std);
688
689 if (std != 1) {
690 /* programmed some specific mode */
691 val = std;
692 } else {
693 /* triggered autodetect */
694 msp_write_dem(client, 0x20, std);
695 for (;;) {
696 if (msp_sleep(state, 100))
697 goto restart;
698
699 /* check results */
700 val = msp_read_dem(client, 0x7e);
701 if (val < 0x07ff)
702 break;
703 v4l_dbg(1, client, "detection still in progress\n");
704 }
705 }
706 for (i = 0; msp_stdlist[i].name != NULL; i++)
707 if (msp_stdlist[i].retval == val)
708 break;
709 v4l_dbg(1, client, "current standard: %s (0x%04x)\n",
710 msp_standard_std_name(val), val);
711 state->main = msp_stdlist[i].main;
712 state->second = msp_stdlist[i].second;
713 state->std = val;
714
715 if (amsound && !state->radio && (state->v4l2_std & V4L2_STD_SECAM) &&
716 (val != 0x0009)) {
717 /* autodetection has failed, let backup */
718 v4l_dbg(1, client, "autodetection failed,"
719 " switching to backup standard: %s (0x%04x)\n",
720 msp_stdlist[8].name ? msp_stdlist[8].name : "unknown",val);
721 val = 0x0009;
722 msp_write_dem(client, 0x20, val);
723 }
724
725 /* set various prescales */
726 msp_write_dsp(client, 0x0d, 0x1900); /* scart */
727 msp_write_dsp(client, 0x0e, 0x2403); /* FM */
728 msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
729
730 /* set stereo */
731 switch (val) {
732 case 0x0008: /* B/G NICAM */
733 case 0x000a: /* I NICAM */
734 if (val == 0x0008)
735 state->mode = MSP_MODE_FM_NICAM1;
736 else
737 state->mode = MSP_MODE_FM_NICAM2;
738 /* just turn on stereo */
739 state->rxsubchans = V4L2_TUNER_SUB_STEREO;
740 state->nicam_on = 1;
741 state->watch_stereo = 1;
742 msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
743 break;
744 case 0x0009:
745 state->mode = MSP_MODE_AM_NICAM;
746 state->rxsubchans = V4L2_TUNER_SUB_MONO;
747 state->nicam_on = 1;
748 msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO);
749 state->watch_stereo = 1;
750 break;
751 case 0x0020: /* BTSC */
752 /* just turn on stereo */
753 state->mode = MSP_MODE_BTSC;
754 state->rxsubchans = V4L2_TUNER_SUB_STEREO;
755 state->nicam_on = 0;
756 state->watch_stereo = 1;
757 msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
758 break;
759 case 0x0040: /* FM radio */
760 state->mode = MSP_MODE_FM_RADIO;
761 state->rxsubchans = V4L2_TUNER_SUB_STEREO;
762 state->audmode = V4L2_TUNER_MODE_STEREO;
763 state->nicam_on = 0;
764 state->watch_stereo = 0;
765 /* not needed in theory if we have radio, but
766 short programming enables carrier mute */
767 msp3400c_setmode(client, MSP_MODE_FM_RADIO);
768 msp3400c_setcarrier(client, MSP_CARRIER(10.7),
769 MSP_CARRIER(10.7));
770 /* scart routing */
771 msp_set_scart(client,SCART_IN2,0);
772 /* msp34xx does radio decoding */
773 msp_write_dsp(client, 0x08, 0x0020);
774 msp_write_dsp(client, 0x09, 0x0020);
775 msp_write_dsp(client, 0x0b, 0x0020);
776 break;
777 case 0x0003:
778 case 0x0004:
779 case 0x0005:
780 state->mode = MSP_MODE_FM_TERRA;
781 state->rxsubchans = V4L2_TUNER_SUB_MONO;
782 state->audmode = V4L2_TUNER_MODE_MONO;
783 state->nicam_on = 0;
784 state->watch_stereo = 1;
785 break;
786 }
787
788 /* unmute, restore misc registers */
789 msp_set_audio(client);
790 msp_write_dsp(client, 0x13, state->acb);
791 if (state->has_i2s_conf)
792 msp_write_dem(client, 0x40, state->i2s_mode);
793
794 /* monitor tv audio mode */
795 while (state->watch_stereo) {
796 if (msp_sleep(state,5000))
797 goto restart;
798 watch_stereo(client);
799 }
800 }
801 v4l_dbg(1, client, "thread: exit\n");
802 return 0;
803}
804
805/* ----------------------------------------------------------------------- */
806
807/* msp34xxG + (autoselect no-thread) */
808/* this one uses both automatic standard detection and automatic sound */
809/* select which are available in the newer G versions */
810/* struct msp: only norm, acb and source are really used in this mode */
811
812/* set the same 'source' for the loudspeaker, scart and quasi-peak detector
813 * the value for source is the same as bit 15:8 of DSP registers 0x08,
814 * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B
815 *
816 * this function replaces msp3400c_setstereo
817 */
818static void msp34xxg_set_source(struct i2c_client *client, int source)
819{
820 struct msp_state *state = i2c_get_clientdata(client);
821
822 /* fix matrix mode to stereo and let the msp choose what
823 * to output according to 'source', as recommended
824 * for MONO (source==0) downmixing set bit[7:0] to 0x30
825 */
826 int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20);
827
828 v4l_dbg(1, client, "set source to %d (0x%x)\n", source, value);
829 /* Loudspeaker Output */
830 msp_write_dsp(client, 0x08, value);
831 /* SCART1 DA Output */
832 msp_write_dsp(client, 0x0a, value);
833 /* Quasi-peak detector */
834 msp_write_dsp(client, 0x0c, value);
835 /*
836 * set identification threshold. Personally, I
837 * I set it to a higher value that the default
838 * of 0x190 to ignore noisy stereo signals.
839 * this needs tuning. (recommended range 0x00a0-0x03c0)
840 * 0x7f0 = forced mono mode
841 */
842 /* a2 threshold for stereo/bilingual */
843 msp_write_dem(client, 0x22, stereo_threshold);
844 state->source = source;
845}
846
847/* (re-)initialize the msp34xxg, according to the current norm in state->norm
848 * return 0 if it worked, -1 if it failed
849 */
850static int msp34xxg_reset(struct i2c_client *client)
851{
852 struct msp_state *state = i2c_get_clientdata(client);
853 int modus, std;
854
855 if (msp_reset(client))
856 return -1;
857
858 /* make sure that input/output is muted (paranoid mode) */
859 /* ACB, mute DSP input, mute SCART 1 */
860 if (msp_write_dsp(client, 0x13, 0x0f20))
861 return -1;
862
863 if (state->has_i2s_conf)
864 msp_write_dem(client, 0x40, state->i2s_mode);
865
866 /* step-by-step initialisation, as described in the manual */
867 modus = msp_modus(client);
868 if (state->radio)
869 std = 0x40;
870 else
871 std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1;
872 modus &= ~0x03; /* STATUS_CHANGE = 0 */
873 modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION = 1 */
874 if (msp_write_dem(client, 0x30, modus))
875 return -1;
876 if (msp_write_dem(client, 0x20, std))
877 return -1;
878
879 /* write the dsps that may have an influence on
880 standard/audio autodetection right now */
881 msp34xxg_set_source(client, state->source);
882
883 /* AM/FM Prescale [15:8] 75khz deviation */
884 if (msp_write_dsp(client, 0x0e, 0x3000))
885 return -1;
886
887 /* NICAM Prescale 9db gain (as recommended) */
888 if (msp_write_dsp(client, 0x10, 0x5a00))
889 return -1;
890
891 return 0;
892}
893
894int msp34xxg_thread(void *data)
895{
896 struct i2c_client *client = data;
897 struct msp_state *state = i2c_get_clientdata(client);
898 int val, std, i;
899
900 v4l_dbg(1, client, "msp34xxg daemon started\n");
901
902 state->source = 1; /* default */
903 for (;;) {
904 v4l_dbg(2, client, "msp34xxg thread: sleep\n");
905 msp_sleep(state, -1);
906 v4l_dbg(2, client, "msp34xxg thread: wakeup\n");
907
908 restart:
909 v4l_dbg(1, client, "thread: restart scan\n");
910 state->restart = 0;
911 if (kthread_should_stop())
912 break;
913
914 /* setup the chip*/
915 msp34xxg_reset(client);
916 std = standard;
917 if (std != 0x01)
918 goto unmute;
919
920 /* watch autodetect */
921 v4l_dbg(1, client, "triggered autodetect, waiting for result\n");
922 for (i = 0; i < 10; i++) {
923 if (msp_sleep(state, 100))
924 goto restart;
925
926 /* check results */
927 val = msp_read_dem(client, 0x7e);
928 if (val < 0x07ff) {
929 std = val;
930 break;
931 }
932 v4l_dbg(2, client, "detection still in progress\n");
933 }
934 if (std == 1) {
935 v4l_dbg(1, client, "detection still in progress after 10 tries. giving up.\n");
936 continue;
937 }
938
939 unmute:
940 state->std = std;
941 v4l_dbg(1, client, "current standard: %s (0x%04x)\n",
942 msp_standard_std_name(std), std);
943
944 /* unmute: dispatch sound to scart output, set scart volume */
945 msp_set_audio(client);
946
947 /* restore ACB */
948 if (msp_write_dsp(client, 0x13, state->acb))
949 return -1;
950
951 msp_write_dem(client, 0x40, state->i2s_mode);
952 }
953 v4l_dbg(1, client, "thread: exit\n");
954 return 0;
955}
956
957void msp34xxg_detect_stereo(struct i2c_client *client)
958{
959 struct msp_state *state = i2c_get_clientdata(client);
960
961 int status = msp_read_dem(client, 0x0200);
962 int is_bilingual = status & 0x100;
963 int is_stereo = status & 0x40;
964
965 state->rxsubchans = 0;
966 if (is_stereo)
967 state->rxsubchans |= V4L2_TUNER_SUB_STEREO;
968 else
969 state->rxsubchans |= V4L2_TUNER_SUB_MONO;
970 if (is_bilingual) {
971 state->rxsubchans |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
972 /* I'm supposed to check whether it's SAP or not
973 * and set only LANG2/SAP in this case. Yet, the MSP
974 * does a lot of work to hide this and handle everything
975 * the same way. I don't want to work around it so unless
976 * this is a problem, I'll handle SAP just like lang1/lang2.
977 */
978 }
979 v4l_dbg(1, client, "status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
980 status, is_stereo, is_bilingual, state->rxsubchans);
981}
982
983void msp34xxg_set_audmode(struct i2c_client *client, int audmode)
984{
985 struct msp_state *state = i2c_get_clientdata(client);
986 int source;
987
988 switch (audmode) {
989 case V4L2_TUNER_MODE_MONO:
990 source = 0; /* mono only */
991 break;
992 case V4L2_TUNER_MODE_STEREO:
993 source = 1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */
994 /* problem: that could also mean 2 (scart input) */
995 break;
996 case V4L2_TUNER_MODE_LANG1:
997 source = 3; /* stereo or A */
998 break;
999 case V4L2_TUNER_MODE_LANG2:
1000 source = 4; /* stereo or B */
1001 break;
1002 default:
1003 audmode = 0;
1004 source = 1;
1005 break;
1006 }
1007 state->audmode = audmode;
1008 msp34xxg_set_source(client, source);
1009}
1010
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
deleted file mode 100644
index 183253e2dd91..000000000000
--- a/drivers/media/video/msp3400.c
+++ /dev/null
@@ -1,2229 +0,0 @@
1/*
2 * programming the msp34* sound processor family
3 *
4 * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
5 *
6 * what works and what doesn't:
7 *
8 * AM-Mono
9 * Support for Hauppauge cards added (decoding handled by tuner) added by
10 * Frederic Crozat <fcrozat@mail.dotcom.fr>
11 *
12 * FM-Mono
13 * should work. The stereo modes are backward compatible to FM-mono,
14 * therefore FM-Mono should be allways available.
15 *
16 * FM-Stereo (B/G, used in germany)
17 * should work, with autodetect
18 *
19 * FM-Stereo (satellite)
20 * should work, no autodetect (i.e. default is mono, but you can
21 * switch to stereo -- untested)
22 *
23 * NICAM (B/G, L , used in UK, Scandinavia, Spain and France)
24 * should work, with autodetect. Support for NICAM was added by
25 * Pekka Pietikainen <pp@netppl.fi>
26 *
27 *
28 * TODO:
29 * - better SAT support
30 *
31 *
32 * 980623 Thomas Sailer (sailer@ife.ee.ethz.ch)
33 * using soundcore instead of OSS
34 *
35 */
36
37#include <linux/config.h>
38#include <linux/module.h>
39#include <linux/moduleparam.h>
40#include <linux/kernel.h>
41#include <linux/sched.h>
42#include <linux/string.h>
43#include <linux/timer.h>
44#include <linux/delay.h>
45#include <linux/errno.h>
46#include <linux/slab.h>
47#include <linux/i2c.h>
48#include <linux/videodev.h>
49#include <linux/init.h>
50#include <linux/smp_lock.h>
51#include <linux/kthread.h>
52#include <linux/suspend.h>
53#include <asm/semaphore.h>
54#include <asm/pgtable.h>
55
56#include <media/audiochip.h>
57#include "msp3400.h"
58
59#define msp3400_dbg(fmt, arg...) \
60 do { \
61 if (debug) \
62 printk(KERN_INFO "%s debug %d-%04x: " fmt, \
63 client->driver->driver.name, \
64 i2c_adapter_id(client->adapter), client->addr , ## arg); \
65 } while (0)
66
67/* Medium volume debug. */
68#define msp3400_dbg_mediumvol(fmt, arg...) \
69 do { \
70 if (debug >= 2) \
71 printk(KERN_INFO "%s debug %d-%04x: " fmt, \
72 client->driver->driver.name, \
73 i2c_adapter_id(client->adapter), client->addr , ## arg); \
74 } while (0)
75
76/* High volume debug. Use with care. */
77#define msp3400_dbg_highvol(fmt, arg...) \
78 do { \
79 if (debug >= 16) \
80 printk(KERN_INFO "%s debug %d-%04x: " fmt, \
81 client->driver->driver.name, \
82 i2c_adapter_id(client->adapter), client->addr , ## arg); \
83 } while (0)
84
85#define msp3400_err(fmt, arg...) do { \
86 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
87 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
88#define msp3400_warn(fmt, arg...) do { \
89 printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->driver.name, \
90 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
91#define msp3400_info(fmt, arg...) do { \
92 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
93 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
94
95#define OPMODE_AUTO -1
96#define OPMODE_MANUAL 0
97#define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */
98#define OPMODE_SIMPLER 2 /* use shorter programming (>= msp34xxG) */
99
100/* insmod parameters */
101static int opmode = OPMODE_AUTO;
102static int debug = 0; /* debug output */
103static int once = 0; /* no continous stereo monitoring */
104static int amsound = 0; /* hard-wire AM sound at 6.5 Hz (france),
105 the autoscan seems work well only with FM... */
106static int standard = 1; /* Override auto detect of audio standard, if needed. */
107static int dolby = 0;
108
109static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual
110 (msp34xxg only) 0x00a0-0x03c0 */
111#define DFP_COUNT 0x41
112static const int bl_dfp[] = {
113 0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x09, 0x0a,
114 0x0b, 0x0d, 0x0e, 0x10
115};
116
117#define IS_MSP34XX_G(msp) ((msp)->opmode==2)
118
119struct msp3400c {
120 int rev1,rev2;
121
122 int opmode;
123 int nicam;
124 int mode;
125 int norm;
126 int stereo;
127 int nicam_on;
128 int acb;
129 int in_scart;
130 int i2s_mode;
131 int main, second; /* sound carrier */
132 int input;
133 int source; /* see msp34xxg_set_source */
134
135 /* v4l2 */
136 int audmode;
137 int rxsubchans;
138
139 int muted;
140 int left, right; /* volume */
141 int bass, treble;
142
143 /* shadow register set */
144 int dfp_regs[DFP_COUNT];
145
146 /* thread */
147 struct task_struct *kthread;
148 wait_queue_head_t wq;
149 int restart:1;
150 int watch_stereo:1;
151};
152
153#define MIN(a,b) (((a)>(b))?(b):(a))
154#define MAX(a,b) (((a)>(b))?(a):(b))
155#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00)
156#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@')
157#define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@')
158#define HAVE_RADIO(msp) ((msp->rev1 & 0xff) >= 'G'-'@')
159
160#define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */
161
162/* ---------------------------------------------------------------------- */
163
164/* read-only */
165module_param(opmode, int, 0444);
166
167/* read-write */
168module_param(once, int, 0644);
169module_param(debug, int, 0644);
170module_param(stereo_threshold, int, 0644);
171module_param(standard, int, 0644);
172module_param(amsound, int, 0644);
173module_param(dolby, int, 0644);
174
175MODULE_PARM_DESC(opmode, "Forces a MSP3400 opmode. 0=Manual, 1=Simple, 2=Simpler");
176MODULE_PARM_DESC(once, "No continuous stereo monitoring");
177MODULE_PARM_DESC(debug, "Enable debug messages");
178MODULE_PARM_DESC(stereo_threshold, "Sets signal threshold to activate stereo");
179MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect");
180MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
181MODULE_PARM_DESC(dolby, "Activates Dolby processsing");
182
183/* ---------------------------------------------------------------------- */
184
185#define I2C_MSP3400C 0x80
186#define I2C_MSP3400C_ALT 0x88
187
188#define I2C_MSP3400C_DEM 0x10
189#define I2C_MSP3400C_DFP 0x12
190
191/* Addresses to scan */
192static unsigned short normal_i2c[] = {
193 I2C_MSP3400C >> 1,
194 I2C_MSP3400C_ALT >> 1,
195 I2C_CLIENT_END
196};
197I2C_CLIENT_INSMOD;
198
199MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
200MODULE_AUTHOR("Gerd Knorr");
201MODULE_LICENSE("GPL");
202
203/* ----------------------------------------------------------------------- */
204/* functions for talking to the MSP3400C Sound processor */
205
206static int msp3400c_reset(struct i2c_client *client)
207{
208 /* reset and read revision code */
209 static char reset_off[3] = { 0x00, 0x80, 0x00 };
210 static char reset_on[3] = { 0x00, 0x00, 0x00 };
211 static char write[3] = { I2C_MSP3400C_DFP + 1, 0x00, 0x1e };
212 char read[2];
213 struct i2c_msg reset[2] = {
214 { client->addr, I2C_M_IGNORE_NAK, 3, reset_off },
215 { client->addr, I2C_M_IGNORE_NAK, 3, reset_on },
216 };
217 struct i2c_msg test[2] = {
218 { client->addr, 0, 3, write },
219 { client->addr, I2C_M_RD, 2, read },
220 };
221
222 msp3400_dbg_highvol("msp3400c_reset\n");
223 if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) ||
224 (1 != i2c_transfer(client->adapter,&reset[1],1)) ||
225 (2 != i2c_transfer(client->adapter,test,2)) ) {
226 msp3400_err("chip reset failed\n");
227 return -1;
228 }
229 return 0;
230}
231
232static int msp3400c_read(struct i2c_client *client, int dev, int addr)
233{
234 int err,retval;
235
236 unsigned char write[3];
237 unsigned char read[2];
238 struct i2c_msg msgs[2] = {
239 { client->addr, 0, 3, write },
240 { client->addr, I2C_M_RD, 2, read }
241 };
242
243 write[0] = dev+1;
244 write[1] = addr >> 8;
245 write[2] = addr & 0xff;
246
247 for (err = 0; err < 3;) {
248 if (2 == i2c_transfer(client->adapter,msgs,2))
249 break;
250 err++;
251 msp3400_warn("I/O error #%d (read 0x%02x/0x%02x)\n", err,
252 dev, addr);
253 current->state = TASK_INTERRUPTIBLE;
254 schedule_timeout(msecs_to_jiffies(10));
255 }
256 if (3 == err) {
257 msp3400_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n");
258 msp3400c_reset(client);
259 return -1;
260 }
261 retval = read[0] << 8 | read[1];
262 msp3400_dbg_highvol("msp3400c_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval);
263 return retval;
264}
265
266static int msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
267{
268 int err;
269 unsigned char buffer[5];
270
271 buffer[0] = dev;
272 buffer[1] = addr >> 8;
273 buffer[2] = addr & 0xff;
274 buffer[3] = val >> 8;
275 buffer[4] = val & 0xff;
276
277 msp3400_dbg_highvol("msp3400c_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val);
278 for (err = 0; err < 3;) {
279 if (5 == i2c_master_send(client, buffer, 5))
280 break;
281 err++;
282 msp3400_warn("I/O error #%d (write 0x%02x/0x%02x)\n", err,
283 dev, addr);
284 current->state = TASK_INTERRUPTIBLE;
285 schedule_timeout(msecs_to_jiffies(10));
286 }
287 if (3 == err) {
288 msp3400_warn("giving up, reseting chip. Sound will go off, sorry folks :-|\n");
289 msp3400c_reset(client);
290 return -1;
291 }
292 return 0;
293}
294
295/* ------------------------------------------------------------------------ */
296
297/* This macro is allowed for *constants* only, gcc must calculate it
298 at compile time. Remember -- no floats in kernel mode */
299#define MSP_CARRIER(freq) ((int)((float)(freq/18.432)*(1<<24)))
300
301#define MSP_MODE_AM_DETECT 0
302#define MSP_MODE_FM_RADIO 2
303#define MSP_MODE_FM_TERRA 3
304#define MSP_MODE_FM_SAT 4
305#define MSP_MODE_FM_NICAM1 5
306#define MSP_MODE_FM_NICAM2 6
307#define MSP_MODE_AM_NICAM 7
308#define MSP_MODE_BTSC 8
309#define MSP_MODE_EXTERN 9
310
311static struct MSP_INIT_DATA_DEM {
312 int fir1[6];
313 int fir2[6];
314 int cdo1;
315 int cdo2;
316 int ad_cv;
317 int mode_reg;
318 int dfp_src;
319 int dfp_matrix;
320} msp_init_data[] = {
321 { /* AM (for carrier detect / msp3400) */
322 {75, 19, 36, 35, 39, 40},
323 {75, 19, 36, 35, 39, 40},
324 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
325 0x00d0, 0x0500, 0x0020, 0x3000
326 },{ /* AM (for carrier detect / msp3410) */
327 {-1, -1, -8, 2, 59, 126},
328 {-1, -1, -8, 2, 59, 126},
329 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
330 0x00d0, 0x0100, 0x0020, 0x3000
331 },{ /* FM Radio */
332 {-8, -8, 4, 6, 78, 107},
333 {-8, -8, 4, 6, 78, 107},
334 MSP_CARRIER(10.7), MSP_CARRIER(10.7),
335 0x00d0, 0x0480, 0x0020, 0x3000
336 },{ /* Terrestial FM-mono + FM-stereo */
337 {3, 18, 27, 48, 66, 72},
338 {3, 18, 27, 48, 66, 72},
339 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
340 0x00d0, 0x0480, 0x0030, 0x3000
341 },{ /* Sat FM-mono */
342 { 1, 9, 14, 24, 33, 37},
343 { 3, 18, 27, 48, 66, 72},
344 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
345 0x00c6, 0x0480, 0x0000, 0x3000
346 },{ /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */
347 {-2, -8, -10, 10, 50, 86},
348 {3, 18, 27, 48, 66, 72},
349 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
350 0x00d0, 0x0040, 0x0120, 0x3000
351 },{ /* NICAM/FM -- I (6.0/6.552) */
352 {2, 4, -6, -4, 40, 94},
353 {3, 18, 27, 48, 66, 72},
354 MSP_CARRIER(6.0), MSP_CARRIER(6.0),
355 0x00d0, 0x0040, 0x0120, 0x3000
356 },{ /* NICAM/AM -- L (6.5/5.85) */
357 {-2, -8, -10, 10, 50, 86},
358 {-4, -12, -9, 23, 79, 126},
359 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
360 0x00c6, 0x0140, 0x0120, 0x7c03
361 },
362};
363
364struct CARRIER_DETECT {
365 int cdo;
366 char *name;
367};
368
369static struct CARRIER_DETECT carrier_detect_main[] = {
370 /* main carrier */
371 { MSP_CARRIER(4.5), "4.5 NTSC" },
372 { MSP_CARRIER(5.5), "5.5 PAL B/G" },
373 { MSP_CARRIER(6.0), "6.0 PAL I" },
374 { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" }
375};
376
377static struct CARRIER_DETECT carrier_detect_55[] = {
378 /* PAL B/G */
379 { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" },
380 { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" }
381};
382
383static struct CARRIER_DETECT carrier_detect_65[] = {
384 /* PAL SAT / SECAM */
385 { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" },
386 { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" },
387 { MSP_CARRIER(6.7421875), "6.74 PAL D/K2 FM-stereo" },
388 { MSP_CARRIER(7.02), "7.02 PAL SAT FM-stereo s/b" },
389 { MSP_CARRIER(7.20), "7.20 PAL SAT FM-stereo s" },
390 { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" },
391};
392
393#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
394
395/* ----------------------------------------------------------------------- *
396 * bits 9 8 5 - SCART DSP input Select:
397 * 0 0 0 - SCART 1 to DSP input (reset position)
398 * 0 1 0 - MONO to DSP input
399 * 1 0 0 - SCART 2 to DSP input
400 * 1 1 1 - Mute DSP input
401 *
402 * bits 11 10 6 - SCART 1 Output Select:
403 * 0 0 0 - undefined (reset position)
404 * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS)
405 * 1 0 0 - MONO input to SCART 1 Output
406 * 1 1 0 - SCART 1 DA to SCART 1 Output
407 * 0 0 1 - SCART 2 DA to SCART 1 Output
408 * 0 1 1 - SCART 1 Input to SCART 1 Output
409 * 1 1 1 - Mute SCART 1 Output
410 *
411 * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART):
412 * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position)
413 * 0 1 0 - SCART 1 Input to SCART 2 Output
414 * 1 0 0 - MONO input to SCART 2 Output
415 * 0 0 1 - SCART 2 DA to SCART 2 Output
416 * 0 1 1 - SCART 2 Input to SCART 2 Output
417 * 1 1 0 - Mute SCART 2 Output
418 *
419 * Bits 4 to 0 should be zero.
420 * ----------------------------------------------------------------------- */
421
422static int scarts[3][9] = {
423 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */
424 /* SCART DSP Input select */
425 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 },
426 /* SCART1 Output select */
427 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
428 /* SCART2 Output select */
429 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
430};
431
432static char *scart_names[] = {
433 "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
434};
435
436static void msp3400c_set_scart(struct i2c_client *client, int in, int out)
437{
438 struct msp3400c *msp = i2c_get_clientdata(client);
439
440 msp->in_scart=in;
441
442 if (in >= 1 && in <= 8 && out >= 0 && out <= 2) {
443 if (-1 == scarts[out][in])
444 return;
445
446 msp->acb &= ~scarts[out][SCART_MASK];
447 msp->acb |= scarts[out][in];
448 } else
449 msp->acb = 0xf60; /* Mute Input and SCART 1 Output */
450
451 msp3400_dbg("scart switch: %s => %d (ACB=0x%04x)\n",
452 scart_names[in], out, msp->acb);
453 msp3400c_write(client,I2C_MSP3400C_DFP, 0x13, msp->acb);
454
455 /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
456 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
457}
458
459/* ------------------------------------------------------------------------ */
460
461static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
462{
463 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0093, cdo1 & 0xfff);
464 msp3400c_write(client,I2C_MSP3400C_DEM, 0x009b, cdo1 >> 12);
465 msp3400c_write(client,I2C_MSP3400C_DEM, 0x00a3, cdo2 & 0xfff);
466 msp3400c_write(client,I2C_MSP3400C_DEM, 0x00ab, cdo2 >> 12);
467 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
468}
469
470static void msp3400c_setvolume(struct i2c_client *client,
471 int muted, int left, int right)
472 {
473 int vol = 0, val = 0, balance = 0;
474
475 if (!muted) {
476 /* 0x7f instead if 0x73 here has sound quality issues,
477 * probably due to overmodulation + clipping ... */
478 vol = (left > right) ? left : right;
479 val = (vol * 0x73 / 65535) << 8;
480 }
481 if (vol > 0) {
482 balance = ((right - left) * 127) / vol;
483 }
484
485 msp3400_dbg("setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n",
486 muted ? "on" : "off", left, right, val >> 8, balance);
487 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */
488 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */
489 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007,
490 muted ? 0x1 : (val | 0x1));
491 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0001, balance << 8);
492}
493
494static void msp3400c_setbass(struct i2c_client *client, int bass)
495{
496 int val = ((bass-32768) * 0x60 / 65535) << 8;
497
498 msp3400_dbg("setbass: %d 0x%02x\n", bass, val >> 8);
499 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
500}
501
502static void msp3400c_settreble(struct i2c_client *client, int treble)
503{
504 int val = ((treble-32768) * 0x60 / 65535) << 8;
505
506 msp3400_dbg("settreble: %d 0x%02x\n",treble, val>>8);
507 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
508}
509
510static void msp3400c_setmode(struct i2c_client *client, int type)
511{
512 struct msp3400c *msp = i2c_get_clientdata(client);
513 int i;
514
515 msp3400_dbg("setmode: %d\n",type);
516 msp->mode = type;
517 msp->audmode = V4L2_TUNER_MODE_MONO;
518 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
519
520 msp3400c_write(client,I2C_MSP3400C_DEM, 0x00bb, /* ad_cv */
521 msp_init_data[type].ad_cv);
522
523 for (i = 5; i >= 0; i--) /* fir 1 */
524 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0001,
525 msp_init_data[type].fir1[i]);
526
527 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0004); /* fir 2 */
528 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0040);
529 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0000);
530 for (i = 5; i >= 0; i--)
531 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005,
532 msp_init_data[type].fir2[i]);
533
534 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0083, /* MODE_REG */
535 msp_init_data[type].mode_reg);
536
537 msp3400c_setcarrier(client, msp_init_data[type].cdo1,
538 msp_init_data[type].cdo2);
539
540 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
541
542 if (dolby) {
543 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,
544 0x0520); /* I2S1 */
545 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
546 0x0620); /* I2S2 */
547 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,
548 msp_init_data[type].dfp_src);
549 } else {
550 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,
551 msp_init_data[type].dfp_src);
552 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
553 msp_init_data[type].dfp_src);
554 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,
555 msp_init_data[type].dfp_src);
556 }
557 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,
558 msp_init_data[type].dfp_src);
559 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e,
560 msp_init_data[type].dfp_matrix);
561
562 if (HAVE_NICAM(msp)) {
563 /* nicam prescale */
564 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0010, 0x5a00); /* was: 0x3000 */
565 }
566}
567
568/* given a bitmask of VIDEO_SOUND_XXX returns the "best" in the bitmask */
569static int best_video_sound(int rxsubchans)
570{
571 if (rxsubchans & V4L2_TUNER_SUB_STEREO)
572 return V4L2_TUNER_MODE_STEREO;
573 if (rxsubchans & V4L2_TUNER_SUB_LANG1)
574 return V4L2_TUNER_MODE_LANG1;
575 if (rxsubchans & V4L2_TUNER_SUB_LANG2)
576 return V4L2_TUNER_MODE_LANG2;
577 return V4L2_TUNER_MODE_MONO;
578}
579
580/* turn on/off nicam + stereo */
581static void msp3400c_setstereo(struct i2c_client *client, int mode)
582{
583 static char *strmode[] = { "0", "mono", "stereo", "3",
584 "lang1", "5", "6", "7", "lang2"
585 };
586 struct msp3400c *msp = i2c_get_clientdata(client);
587 int nicam = 0; /* channel source: FM/AM or nicam */
588 int src = 0;
589
590 if (IS_MSP34XX_G(msp)) {
591 /* this method would break everything, let's make sure
592 * it's never called
593 */
594 msp3400_dbg
595 ("DEBUG WARNING setstereo called with mode=%d instead of set_source (ignored)\n",
596 mode);
597 return;
598 }
599
600 /* switch demodulator */
601 switch (msp->mode) {
602 case MSP_MODE_FM_TERRA:
603 msp3400_dbg("FM setstereo: %s\n", strmode[mode]);
604 msp3400c_setcarrier(client,msp->second,msp->main);
605 switch (mode) {
606 case V4L2_TUNER_MODE_STEREO:
607 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001);
608 break;
609 case V4L2_TUNER_MODE_MONO:
610 case V4L2_TUNER_MODE_LANG1:
611 case V4L2_TUNER_MODE_LANG2:
612 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3000);
613 break;
614 }
615 break;
616 case MSP_MODE_FM_SAT:
617 msp3400_dbg("SAT setstereo: %s\n", strmode[mode]);
618 switch (mode) {
619 case V4L2_TUNER_MODE_MONO:
620 msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
621 break;
622 case V4L2_TUNER_MODE_STEREO:
623 msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
624 break;
625 case V4L2_TUNER_MODE_LANG1:
626 msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
627 break;
628 case V4L2_TUNER_MODE_LANG2:
629 msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
630 break;
631 }
632 break;
633 case MSP_MODE_FM_NICAM1:
634 case MSP_MODE_FM_NICAM2:
635 case MSP_MODE_AM_NICAM:
636 msp3400_dbg("NICAM setstereo: %s\n",strmode[mode]);
637 msp3400c_setcarrier(client,msp->second,msp->main);
638 if (msp->nicam_on)
639 nicam=0x0100;
640 break;
641 case MSP_MODE_BTSC:
642 msp3400_dbg("BTSC setstereo: %s\n",strmode[mode]);
643 nicam=0x0300;
644 break;
645 case MSP_MODE_EXTERN:
646 msp3400_dbg("extern setstereo: %s\n",strmode[mode]);
647 nicam = 0x0200;
648 break;
649 case MSP_MODE_FM_RADIO:
650 msp3400_dbg("FM-Radio setstereo: %s\n",strmode[mode]);
651 break;
652 default:
653 msp3400_dbg("mono setstereo\n");
654 return;
655 }
656
657 /* switch audio */
658 switch (best_video_sound(mode)) {
659 case V4L2_TUNER_MODE_STEREO:
660 src = 0x0020 | nicam;
661 break;
662 case V4L2_TUNER_MODE_MONO:
663 if (msp->mode == MSP_MODE_AM_NICAM) {
664 msp3400_dbg("switching to AM mono\n");
665 /* AM mono decoding is handled by tuner, not MSP chip */
666 /* SCART switching control register */
667 msp3400c_set_scart(client,SCART_MONO,0);
668 src = 0x0200;
669 break;
670 }
671 case V4L2_TUNER_MODE_LANG1:
672 src = 0x0000 | nicam;
673 break;
674 case V4L2_TUNER_MODE_LANG2:
675 src = 0x0010 | nicam;
676 break;
677 }
678 msp3400_dbg("setstereo final source/matrix = 0x%x\n", src);
679
680 if (dolby) {
681 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
682 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620);
683 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src);
684 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src);
685 } else {
686 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,src);
687 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,src);
688 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src);
689 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src);
690 }
691}
692
693static void
694msp3400c_print_mode(struct i2c_client *client)
695{
696 struct msp3400c *msp = i2c_get_clientdata(client);
697
698 if (msp->main == msp->second) {
699 msp3400_dbg("mono sound carrier: %d.%03d MHz\n",
700 msp->main/910000,(msp->main/910)%1000);
701 } else {
702 msp3400_dbg("main sound carrier: %d.%03d MHz\n",
703 msp->main/910000,(msp->main/910)%1000);
704 }
705 if (msp->mode == MSP_MODE_FM_NICAM1 || msp->mode == MSP_MODE_FM_NICAM2)
706 msp3400_dbg("NICAM/FM carrier : %d.%03d MHz\n",
707 msp->second/910000,(msp->second/910)%1000);
708 if (msp->mode == MSP_MODE_AM_NICAM)
709 msp3400_dbg("NICAM/AM carrier : %d.%03d MHz\n",
710 msp->second/910000,(msp->second/910)%1000);
711 if (msp->mode == MSP_MODE_FM_TERRA &&
712 msp->main != msp->second) {
713 msp3400_dbg("FM-stereo carrier : %d.%03d MHz\n",
714 msp->second/910000,(msp->second/910)%1000);
715 }
716}
717
718#define MSP3400_MAX 4
719static struct i2c_client *msps[MSP3400_MAX];
720static void msp3400c_restore_dfp(struct i2c_client *client)
721{
722 struct msp3400c *msp = i2c_get_clientdata(client);
723 int i;
724
725 for (i = 0; i < DFP_COUNT; i++) {
726 if (-1 == msp->dfp_regs[i])
727 continue;
728 msp3400c_write(client, I2C_MSP3400C_DFP, i, msp->dfp_regs[i]);
729 }
730}
731
732/* if the dfp_regs is set, set what's in there. Otherwise, set the default value */
733static int msp3400c_write_dfp_with_default(struct i2c_client *client,
734 int addr, int default_value)
735{
736 struct msp3400c *msp = i2c_get_clientdata(client);
737 int value = default_value;
738 if (addr < DFP_COUNT && -1 != msp->dfp_regs[addr])
739 value = msp->dfp_regs[addr];
740 return msp3400c_write(client, I2C_MSP3400C_DFP, addr, value);
741}
742
743/* ----------------------------------------------------------------------- */
744
745struct REGISTER_DUMP {
746 int addr;
747 char *name;
748};
749
750struct REGISTER_DUMP d1[] = {
751 {0x007e, "autodetect"},
752 {0x0023, "C_AD_BITS "},
753 {0x0038, "ADD_BITS "},
754 {0x003e, "CIB_BITS "},
755 {0x0057, "ERROR_RATE"},
756};
757
758static int autodetect_stereo(struct i2c_client *client)
759{
760 struct msp3400c *msp = i2c_get_clientdata(client);
761 int val;
762 int rxsubchans = msp->rxsubchans;
763 int newnicam = msp->nicam_on;
764 int update = 0;
765
766 switch (msp->mode) {
767 case MSP_MODE_FM_TERRA:
768 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18);
769 if (val > 32767)
770 val -= 65536;
771 msp3400_dbg("stereo detect register: %d\n",val);
772 if (val > 4096) {
773 rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
774 } else if (val < -4096) {
775 rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
776 } else {
777 rxsubchans = V4L2_TUNER_SUB_MONO;
778 }
779 newnicam = 0;
780 break;
781 case MSP_MODE_FM_NICAM1:
782 case MSP_MODE_FM_NICAM2:
783 case MSP_MODE_AM_NICAM:
784 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23);
785 msp3400_dbg("nicam sync=%d, mode=%d\n",
786 val & 1, (val & 0x1e) >> 1);
787
788 if (val & 1) {
789 /* nicam synced */
790 switch ((val & 0x1e) >> 1) {
791 case 0:
792 case 8:
793 rxsubchans = V4L2_TUNER_SUB_STEREO;
794 break;
795 case 1:
796 case 9:
797 rxsubchans = V4L2_TUNER_SUB_MONO
798 | V4L2_TUNER_SUB_LANG1;
799 break;
800 case 2:
801 case 10:
802 rxsubchans = V4L2_TUNER_SUB_MONO
803 | V4L2_TUNER_SUB_LANG1
804 | V4L2_TUNER_SUB_LANG2;
805 break;
806 default:
807 rxsubchans = V4L2_TUNER_SUB_MONO;
808 break;
809 }
810 newnicam=1;
811 } else {
812 newnicam = 0;
813 rxsubchans = V4L2_TUNER_SUB_MONO;
814 }
815 break;
816 case MSP_MODE_BTSC:
817 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200);
818 msp3400_dbg("status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
819 val,
820 (val & 0x0002) ? "no" : "yes",
821 (val & 0x0004) ? "no" : "yes",
822 (val & 0x0040) ? "stereo" : "mono",
823 (val & 0x0080) ? ", nicam 2nd mono" : "",
824 (val & 0x0100) ? ", bilingual/SAP" : "");
825 rxsubchans = V4L2_TUNER_SUB_MONO;
826 if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO;
827 if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1;
828 break;
829 }
830 if (rxsubchans != msp->rxsubchans) {
831 update = 1;
832 msp3400_dbg("watch: rxsubchans %d => %d\n",
833 msp->rxsubchans,rxsubchans);
834 msp->rxsubchans = rxsubchans;
835 }
836 if (newnicam != msp->nicam_on) {
837 update = 1;
838 msp3400_dbg("watch: nicam %d => %d\n",
839 msp->nicam_on,newnicam);
840 msp->nicam_on = newnicam;
841 }
842 return update;
843}
844
845/*
846 * A kernel thread for msp3400 control -- we don't want to block the
847 * in the ioctl while doing the sound carrier & stereo detect
848 */
849
850static int msp34xx_sleep(struct msp3400c *msp, int timeout)
851{
852 DECLARE_WAITQUEUE(wait, current);
853
854 add_wait_queue(&msp->wq, &wait);
855 if (!kthread_should_stop()) {
856 if (timeout < 0) {
857 set_current_state(TASK_INTERRUPTIBLE);
858 schedule();
859 } else {
860 schedule_timeout_interruptible
861 (msecs_to_jiffies(timeout));
862 }
863 }
864
865 remove_wait_queue(&msp->wq, &wait);
866 try_to_freeze();
867 return msp->restart;
868}
869
870/* stereo/multilang monitoring */
871static void watch_stereo(struct i2c_client *client)
872{
873 struct msp3400c *msp = i2c_get_clientdata(client);
874
875 if (autodetect_stereo(client)) {
876 if (msp->stereo & V4L2_TUNER_MODE_STEREO)
877 msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO);
878 else if (msp->stereo & VIDEO_SOUND_LANG1)
879 msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1);
880 else
881 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
882 }
883
884 if (once)
885 msp->watch_stereo = 0;
886}
887
888
889static int msp3400c_thread(void *data)
890{
891 struct i2c_client *client = data;
892 struct msp3400c *msp = i2c_get_clientdata(client);
893 struct CARRIER_DETECT *cd;
894 int count, max1,max2,val1,val2, val,this;
895
896
897 msp3400_info("msp3400 daemon started\n");
898 for (;;) {
899 msp3400_dbg_mediumvol("msp3400 thread: sleep\n");
900 msp34xx_sleep(msp,-1);
901 msp3400_dbg_mediumvol("msp3400 thread: wakeup\n");
902
903 restart:
904 msp3400_dbg("thread: restart scan\n");
905 msp->restart = 0;
906 if (kthread_should_stop())
907 break;
908
909 if (VIDEO_MODE_RADIO == msp->norm ||
910 MSP_MODE_EXTERN == msp->mode) {
911 /* no carrier scan, just unmute */
912 msp3400_info("thread: no carrier scan\n");
913 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
914 continue;
915 }
916
917 /* mute */
918 msp3400c_setvolume(client, msp->muted, 0, 0);
919 msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
920 val1 = val2 = 0;
921 max1 = max2 = -1;
922 msp->watch_stereo = 0;
923
924 /* some time for the tuner to sync */
925 if (msp34xx_sleep(msp,200))
926 goto restart;
927
928 /* carrier detect pass #1 -- main carrier */
929 cd = carrier_detect_main;
930 count = CARRIER_COUNT(carrier_detect_main);
931
932 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
933 /* autodetect doesn't work well with AM ... */
934 max1 = 3;
935 count = 0;
936 msp3400_dbg("AM sound override\n");
937 }
938
939 for (this = 0; this < count; this++) {
940 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
941 if (msp34xx_sleep(msp,100))
942 goto restart;
943 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
944 if (val > 32767)
945 val -= 65536;
946 if (val1 < val)
947 val1 = val, max1 = this;
948 msp3400_dbg("carrier1 val: %5d / %s\n", val,cd[this].name);
949 }
950
951 /* carrier detect pass #2 -- second (stereo) carrier */
952 switch (max1) {
953 case 1: /* 5.5 */
954 cd = carrier_detect_55;
955 count = CARRIER_COUNT(carrier_detect_55);
956 break;
957 case 3: /* 6.5 */
958 cd = carrier_detect_65;
959 count = CARRIER_COUNT(carrier_detect_65);
960 break;
961 case 0: /* 4.5 */
962 case 2: /* 6.0 */
963 default:
964 cd = NULL;
965 count = 0;
966 break;
967 }
968
969 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
970 /* autodetect doesn't work well with AM ... */
971 cd = NULL;
972 count = 0;
973 max2 = 0;
974 }
975 for (this = 0; this < count; this++) {
976 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
977 if (msp34xx_sleep(msp,100))
978 goto restart;
979 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
980 if (val > 32767)
981 val -= 65536;
982 if (val2 < val)
983 val2 = val, max2 = this;
984 msp3400_dbg("carrier2 val: %5d / %s\n", val,cd[this].name);
985 }
986
987 /* programm the msp3400 according to the results */
988 msp->main = carrier_detect_main[max1].cdo;
989 switch (max1) {
990 case 1: /* 5.5 */
991 if (max2 == 0) {
992 /* B/G FM-stereo */
993 msp->second = carrier_detect_55[max2].cdo;
994 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
995 msp->nicam_on = 0;
996 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
997 msp->watch_stereo = 1;
998 } else if (max2 == 1 && HAVE_NICAM(msp)) {
999 /* B/G NICAM */
1000 msp->second = carrier_detect_55[max2].cdo;
1001 msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
1002 msp->nicam_on = 1;
1003 msp3400c_setcarrier(client, msp->second, msp->main);
1004 msp->watch_stereo = 1;
1005 } else {
1006 goto no_second;
1007 }
1008 break;
1009 case 2: /* 6.0 */
1010 /* PAL I NICAM */
1011 msp->second = MSP_CARRIER(6.552);
1012 msp3400c_setmode(client, MSP_MODE_FM_NICAM2);
1013 msp->nicam_on = 1;
1014 msp3400c_setcarrier(client, msp->second, msp->main);
1015 msp->watch_stereo = 1;
1016 break;
1017 case 3: /* 6.5 */
1018 if (max2 == 1 || max2 == 2) {
1019 /* D/K FM-stereo */
1020 msp->second = carrier_detect_65[max2].cdo;
1021 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
1022 msp->nicam_on = 0;
1023 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
1024 msp->watch_stereo = 1;
1025 } else if (max2 == 0 &&
1026 msp->norm == VIDEO_MODE_SECAM) {
1027 /* L NICAM or AM-mono */
1028 msp->second = carrier_detect_65[max2].cdo;
1029 msp3400c_setmode(client, MSP_MODE_AM_NICAM);
1030 msp->nicam_on = 0;
1031 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
1032 msp3400c_setcarrier(client, msp->second, msp->main);
1033 /* volume prescale for SCART (AM mono input) */
1034 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900);
1035 msp->watch_stereo = 1;
1036 } else if (max2 == 0 && HAVE_NICAM(msp)) {
1037 /* D/K NICAM */
1038 msp->second = carrier_detect_65[max2].cdo;
1039 msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
1040 msp->nicam_on = 1;
1041 msp3400c_setcarrier(client, msp->second, msp->main);
1042 msp->watch_stereo = 1;
1043 } else {
1044 goto no_second;
1045 }
1046 break;
1047 case 0: /* 4.5 */
1048 default:
1049 no_second:
1050 msp->second = carrier_detect_main[max1].cdo;
1051 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
1052 msp->nicam_on = 0;
1053 msp3400c_setcarrier(client, msp->second, msp->main);
1054 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
1055 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
1056 break;
1057 }
1058
1059 /* unmute */
1060 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1061 msp3400c_restore_dfp(client);
1062
1063 if (debug)
1064 msp3400c_print_mode(client);
1065
1066 /* monitor tv audio mode */
1067 while (msp->watch_stereo) {
1068 if (msp34xx_sleep(msp,5000))
1069 goto restart;
1070 watch_stereo(client);
1071 }
1072 }
1073 msp3400_dbg("thread: exit\n");
1074 return 0;
1075}
1076
1077/* ----------------------------------------------------------------------- */
1078/* this one uses the automatic sound standard detection of newer */
1079/* msp34xx chip versions */
1080
1081static struct MODES {
1082 int retval;
1083 int main, second;
1084 char *name;
1085} modelist[] = {
1086 { 0x0000, 0, 0, "ERROR" },
1087 { 0x0001, 0, 0, "autodetect start" },
1088 { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72 M Dual FM-Stereo" },
1089 { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74 B/G Dual FM-Stereo" },
1090 { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" },
1091 { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" },
1092 { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" },
1093 { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" },
1094 { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" },
1095 { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" },
1096 { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" },
1097 { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" },
1098 { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" },
1099 { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" },
1100 { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" },
1101 { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7 FM-Stereo Radio" },
1102 { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 SAT-Mono" },
1103 { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20 SAT-Stereo" },
1104 { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2 SAT ADR" },
1105 { -1, 0, 0, NULL }, /* EOF */
1106};
1107
1108static inline const char *msp34xx_standard_mode_name(int mode)
1109{
1110 int i;
1111 for (i = 0; modelist[i].name != NULL; i++)
1112 if (modelist[i].retval == mode)
1113 return modelist[i].name;
1114 return "unknown";
1115}
1116
1117static int msp34xx_modus(struct i2c_client *client, int norm)
1118{
1119 switch (norm) {
1120 case VIDEO_MODE_PAL:
1121 msp3400_dbg("video mode selected to PAL\n");
1122
1123#if 1
1124 /* experimental: not sure this works with all chip versions */
1125 return 0x7003;
1126#else
1127 /* previous value, try this if it breaks ... */
1128 return 0x1003;
1129#endif
1130 case VIDEO_MODE_NTSC: /* BTSC */
1131 msp3400_dbg("video mode selected to NTSC\n");
1132 return 0x2003;
1133 case VIDEO_MODE_SECAM:
1134 msp3400_dbg("video mode selected to SECAM\n");
1135 return 0x0003;
1136 case VIDEO_MODE_RADIO:
1137 msp3400_dbg("video mode selected to Radio\n");
1138 return 0x0003;
1139 case VIDEO_MODE_AUTO:
1140 msp3400_dbg("video mode selected to Auto\n");
1141 return 0x2003;
1142 default:
1143 return 0x0003;
1144 }
1145}
1146
1147static int msp34xx_standard(int norm)
1148{
1149 switch (norm) {
1150 case VIDEO_MODE_PAL:
1151 return 1;
1152 case VIDEO_MODE_NTSC: /* BTSC */
1153 return 0x0020;
1154 case VIDEO_MODE_SECAM:
1155 return 1;
1156 case VIDEO_MODE_RADIO:
1157 return 0x0040;
1158 default:
1159 return 1;
1160 }
1161}
1162
1163static int msp3410d_thread(void *data)
1164{
1165 struct i2c_client *client = data;
1166 struct msp3400c *msp = i2c_get_clientdata(client);
1167 int mode,val,i,std;
1168
1169 msp3400_info("msp3410 daemon started\n");
1170
1171 for (;;) {
1172 msp3400_dbg_mediumvol("msp3410 thread: sleep\n");
1173 msp34xx_sleep(msp,-1);
1174 msp3400_dbg_mediumvol("msp3410 thread: wakeup\n");
1175
1176 restart:
1177 msp3400_dbg("thread: restart scan\n");
1178 msp->restart = 0;
1179 if (kthread_should_stop())
1180 break;
1181
1182 if (msp->mode == MSP_MODE_EXTERN) {
1183 /* no carrier scan needed, just unmute */
1184 msp3400_dbg("thread: no carrier scan\n");
1185 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1186 continue;
1187 }
1188
1189 /* put into sane state (and mute) */
1190 msp3400c_reset(client);
1191
1192 /* some time for the tuner to sync */
1193 if (msp34xx_sleep(msp,200))
1194 goto restart;
1195
1196 /* start autodetect */
1197 mode = msp34xx_modus(client, msp->norm);
1198 std = msp34xx_standard(msp->norm);
1199 msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode);
1200 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std);
1201 msp->watch_stereo = 0;
1202
1203 if (debug)
1204 msp3400_dbg("setting mode: %s (0x%04x)\n",
1205 msp34xx_standard_mode_name(std) ,std);
1206
1207 if (std != 1) {
1208 /* programmed some specific mode */
1209 val = std;
1210 } else {
1211 /* triggered autodetect */
1212 for (;;) {
1213 if (msp34xx_sleep(msp,100))
1214 goto restart;
1215
1216 /* check results */
1217 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
1218 if (val < 0x07ff)
1219 break;
1220 msp3400_dbg("detection still in progress\n");
1221 }
1222 }
1223 for (i = 0; modelist[i].name != NULL; i++)
1224 if (modelist[i].retval == val)
1225 break;
1226 msp3400_dbg("current mode: %s (0x%04x)\n",
1227 modelist[i].name ? modelist[i].name : "unknown",
1228 val);
1229 msp->main = modelist[i].main;
1230 msp->second = modelist[i].second;
1231
1232 if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) {
1233 /* autodetection has failed, let backup */
1234 msp3400_dbg("autodetection failed,"
1235 " switching to backup mode: %s (0x%04x)\n",
1236 modelist[8].name ? modelist[8].name : "unknown",val);
1237 val = 0x0009;
1238 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, val);
1239 }
1240
1241 /* set various prescales */
1242 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0d, 0x1900); /* scart */
1243 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0e, 0x2403); /* FM */
1244 msp3400c_write(client, I2C_MSP3400C_DFP, 0x10, 0x5a00); /* nicam */
1245
1246 /* set stereo */
1247 switch (val) {
1248 case 0x0008: /* B/G NICAM */
1249 case 0x000a: /* I NICAM */
1250 if (val == 0x0008)
1251 msp->mode = MSP_MODE_FM_NICAM1;
1252 else
1253 msp->mode = MSP_MODE_FM_NICAM2;
1254 /* just turn on stereo */
1255 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1256 msp->nicam_on = 1;
1257 msp->watch_stereo = 1;
1258 msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
1259 break;
1260 case 0x0009:
1261 msp->mode = MSP_MODE_AM_NICAM;
1262 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
1263 msp->nicam_on = 1;
1264 msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO);
1265 msp->watch_stereo = 1;
1266 break;
1267 case 0x0020: /* BTSC */
1268 /* just turn on stereo */
1269 msp->mode = MSP_MODE_BTSC;
1270 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1271 msp->nicam_on = 0;
1272 msp->watch_stereo = 1;
1273 msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
1274 break;
1275 case 0x0040: /* FM radio */
1276 msp->mode = MSP_MODE_FM_RADIO;
1277 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1278 msp->audmode = V4L2_TUNER_MODE_STEREO;
1279 msp->nicam_on = 0;
1280 msp->watch_stereo = 0;
1281 /* not needed in theory if HAVE_RADIO(), but
1282 short programming enables carrier mute */
1283 msp3400c_setmode(client,MSP_MODE_FM_RADIO);
1284 msp3400c_setcarrier(client, MSP_CARRIER(10.7),
1285 MSP_CARRIER(10.7));
1286 /* scart routing */
1287 msp3400c_set_scart(client,SCART_IN2,0);
1288 /* msp34xx does radio decoding */
1289 msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0020);
1290 msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0020);
1291 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0020);
1292 break;
1293 case 0x0003:
1294 case 0x0004:
1295 case 0x0005:
1296 msp->mode = MSP_MODE_FM_TERRA;
1297 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
1298 msp->audmode = V4L2_TUNER_MODE_MONO;
1299 msp->nicam_on = 0;
1300 msp->watch_stereo = 1;
1301 break;
1302 }
1303
1304 /* unmute, restore misc registers */
1305 msp3400c_setbass(client, msp->bass);
1306 msp3400c_settreble(client, msp->treble);
1307 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1308 msp3400c_write(client, I2C_MSP3400C_DFP, 0x13, msp->acb);
1309 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1310 msp3400c_restore_dfp(client);
1311
1312 /* monitor tv audio mode */
1313 while (msp->watch_stereo) {
1314 if (msp34xx_sleep(msp,5000))
1315 goto restart;
1316 watch_stereo(client);
1317 }
1318 }
1319 msp3400_dbg("thread: exit\n");
1320 return 0;
1321}
1322
1323/* ----------------------------------------------------------------------- */
1324/* msp34xxG + (simpler no-thread) */
1325/* this one uses both automatic standard detection and automatic sound */
1326/* select which are available in the newer G versions */
1327/* struct msp: only norm, acb and source are really used in this mode */
1328
1329static void msp34xxg_set_source(struct i2c_client *client, int source);
1330
1331/* (re-)initialize the msp34xxg, according to the current norm in msp->norm
1332 * return 0 if it worked, -1 if it failed
1333 */
1334static int msp34xxg_reset(struct i2c_client *client)
1335{
1336 struct msp3400c *msp = i2c_get_clientdata(client);
1337 int modus,std;
1338
1339 if (msp3400c_reset(client))
1340 return -1;
1341
1342 /* make sure that input/output is muted (paranoid mode) */
1343 if (msp3400c_write(client,
1344 I2C_MSP3400C_DFP,
1345 0x13, /* ACB */
1346 0x0f20 /* mute DSP input, mute SCART 1 */))
1347 return -1;
1348
1349 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1350
1351 /* step-by-step initialisation, as described in the manual */
1352 modus = msp34xx_modus(client, msp->norm);
1353 std = msp34xx_standard(msp->norm);
1354 modus &= ~0x03; /* STATUS_CHANGE=0 */
1355 modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */
1356 if (msp3400c_write(client,
1357 I2C_MSP3400C_DEM,
1358 0x30/*MODUS*/,
1359 modus))
1360 return -1;
1361 if (msp3400c_write(client,
1362 I2C_MSP3400C_DEM,
1363 0x20/*standard*/,
1364 std))
1365 return -1;
1366
1367 /* write the dfps that may have an influence on
1368 standard/audio autodetection right now */
1369 msp34xxg_set_source(client, msp->source);
1370
1371 if (msp3400c_write_dfp_with_default(client, 0x0e, /* AM/FM Prescale */
1372 0x3000
1373 /* default: [15:8] 75khz deviation */
1374 ))
1375 return -1;
1376
1377 if (msp3400c_write_dfp_with_default(client, 0x10, /* NICAM Prescale */
1378 0x5a00
1379 /* default: 9db gain (as recommended) */
1380 ))
1381 return -1;
1382
1383 return 0;
1384}
1385
1386static int msp34xxg_thread(void *data)
1387{
1388 struct i2c_client *client = data;
1389 struct msp3400c *msp = i2c_get_clientdata(client);
1390 int val, std, i;
1391
1392 msp3400_info("msp34xxg daemon started\n");
1393
1394 msp->source = 1; /* default */
1395 for (;;) {
1396 msp3400_dbg_mediumvol("msp34xxg thread: sleep\n");
1397 msp34xx_sleep(msp,-1);
1398 msp3400_dbg_mediumvol("msp34xxg thread: wakeup\n");
1399
1400 restart:
1401 msp3400_dbg("thread: restart scan\n");
1402 msp->restart = 0;
1403 if (kthread_should_stop())
1404 break;
1405
1406 /* setup the chip*/
1407 msp34xxg_reset(client);
1408 std = standard;
1409 if (std != 0x01)
1410 goto unmute;
1411
1412 /* watch autodetect */
1413 msp3400_dbg("triggered autodetect, waiting for result\n");
1414 for (i = 0; i < 10; i++) {
1415 if (msp34xx_sleep(msp,100))
1416 goto restart;
1417
1418 /* check results */
1419 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
1420 if (val < 0x07ff) {
1421 std = val;
1422 break;
1423 }
1424 msp3400_dbg("detection still in progress\n");
1425 }
1426 if (0x01 == std) {
1427 msp3400_dbg("detection still in progress after 10 tries. giving up.\n");
1428 continue;
1429 }
1430
1431 unmute:
1432 msp3400_dbg("current mode: %s (0x%04x)\n",
1433 msp34xx_standard_mode_name(std), std);
1434
1435 /* unmute: dispatch sound to scart output, set scart volume */
1436 msp3400_dbg("unmute\n");
1437
1438 msp3400c_setbass(client, msp->bass);
1439 msp3400c_settreble(client, msp->treble);
1440 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1441
1442 /* restore ACB */
1443 if (msp3400c_write(client,
1444 I2C_MSP3400C_DFP,
1445 0x13, /* ACB */
1446 msp->acb))
1447 return -1;
1448
1449 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1450 }
1451 msp3400_dbg("thread: exit\n");
1452 return 0;
1453}
1454
1455/* set the same 'source' for the loudspeaker, scart and quasi-peak detector
1456 * the value for source is the same as bit 15:8 of DFP registers 0x08,
1457 * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B
1458 *
1459 * this function replaces msp3400c_setstereo
1460 */
1461static void msp34xxg_set_source(struct i2c_client *client, int source)
1462{
1463 struct msp3400c *msp = i2c_get_clientdata(client);
1464
1465 /* fix matrix mode to stereo and let the msp choose what
1466 * to output according to 'source', as recommended
1467 * for MONO (source==0) downmixing set bit[7:0] to 0x30
1468 */
1469 int value = (source&0x07)<<8|(source==0 ? 0x30:0x20);
1470 msp3400_dbg("set source to %d (0x%x)\n", source, value);
1471 msp3400c_write(client,
1472 I2C_MSP3400C_DFP,
1473 0x08, /* Loudspeaker Output */
1474 value);
1475 msp3400c_write(client,
1476 I2C_MSP3400C_DFP,
1477 0x0a, /* SCART1 DA Output */
1478 value);
1479 msp3400c_write(client,
1480 I2C_MSP3400C_DFP,
1481 0x0c, /* Quasi-peak detector */
1482 value);
1483 /*
1484 * set identification threshold. Personally, I
1485 * I set it to a higher value that the default
1486 * of 0x190 to ignore noisy stereo signals.
1487 * this needs tuning. (recommended range 0x00a0-0x03c0)
1488 * 0x7f0 = forced mono mode
1489 */
1490 msp3400c_write(client,
1491 I2C_MSP3400C_DEM,
1492 0x22, /* a2 threshold for stereo/bilingual */
1493 stereo_threshold);
1494 msp->source=source;
1495}
1496
1497static void msp34xxg_detect_stereo(struct i2c_client *client)
1498{
1499 struct msp3400c *msp = i2c_get_clientdata(client);
1500
1501 int status = msp3400c_read(client,
1502 I2C_MSP3400C_DEM,
1503 0x0200 /* STATUS */);
1504 int is_bilingual = status&0x100;
1505 int is_stereo = status&0x40;
1506
1507 msp->rxsubchans = 0;
1508 if (is_stereo)
1509 msp->rxsubchans |= V4L2_TUNER_SUB_STEREO;
1510 else
1511 msp->rxsubchans |= V4L2_TUNER_SUB_MONO;
1512 if (is_bilingual) {
1513 msp->rxsubchans |= V4L2_TUNER_SUB_LANG1|V4L2_TUNER_SUB_LANG2;
1514 /* I'm supposed to check whether it's SAP or not
1515 * and set only LANG2/SAP in this case. Yet, the MSP
1516 * does a lot of work to hide this and handle everything
1517 * the same way. I don't want to work around it so unless
1518 * this is a problem, I'll handle SAP just like lang1/lang2.
1519 */
1520 }
1521 msp3400_dbg("status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
1522 status, is_stereo, is_bilingual, msp->rxsubchans);
1523}
1524
1525static void msp34xxg_set_audmode(struct i2c_client *client, int audmode)
1526{
1527 struct msp3400c *msp = i2c_get_clientdata(client);
1528 int source;
1529
1530 switch (audmode) {
1531 case V4L2_TUNER_MODE_MONO:
1532 source=0; /* mono only */
1533 break;
1534 case V4L2_TUNER_MODE_STEREO:
1535 source=1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */
1536 /* problem: that could also mean 2 (scart input) */
1537 break;
1538 case V4L2_TUNER_MODE_LANG1:
1539 source=3; /* stereo or A */
1540 break;
1541 case V4L2_TUNER_MODE_LANG2:
1542 source=4; /* stereo or B */
1543 break;
1544 default:
1545 audmode = 0;
1546 source = 1;
1547 break;
1548 }
1549 msp->audmode = audmode;
1550 msp34xxg_set_source(client, source);
1551}
1552
1553
1554/* ----------------------------------------------------------------------- */
1555
1556static int msp_attach(struct i2c_adapter *adap, int addr, int kind);
1557static int msp_detach(struct i2c_client *client);
1558static int msp_probe(struct i2c_adapter *adap);
1559static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
1560
1561static int msp_suspend(struct device * dev, pm_message_t state);
1562static int msp_resume(struct device * dev);
1563
1564static void msp_wake_thread(struct i2c_client *client);
1565
1566static struct i2c_driver driver = {
1567 .id = I2C_DRIVERID_MSP3400,
1568 .attach_adapter = msp_probe,
1569 .detach_client = msp_detach,
1570 .command = msp_command,
1571 .driver = {
1572 .name = "i2c msp3400 driver",
1573 .suspend = msp_suspend,
1574 .resume = msp_resume,
1575 },
1576};
1577
1578static struct i2c_client client_template =
1579{
1580 .name = "(unset)",
1581 .driver = &driver,
1582};
1583
1584static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1585{
1586 struct msp3400c *msp;
1587 struct i2c_client *client = &client_template;
1588 int (*thread_func)(void *data) = NULL;
1589 int i;
1590
1591 client_template.adapter = adap;
1592 client_template.addr = addr;
1593
1594 if (-1 == msp3400c_reset(&client_template)) {
1595 msp3400_dbg("no chip found\n");
1596 return -1;
1597 }
1598
1599 if (NULL == (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
1600 return -ENOMEM;
1601 memcpy(client,&client_template,sizeof(struct i2c_client));
1602 if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) {
1603 kfree(client);
1604 return -ENOMEM;
1605 }
1606
1607 memset(msp,0,sizeof(struct msp3400c));
1608 msp->norm = VIDEO_MODE_NTSC;
1609 msp->left = 58880; /* 0db gain */
1610 msp->right = 58880; /* 0db gain */
1611 msp->bass = 32768;
1612 msp->treble = 32768;
1613 msp->input = -1;
1614 msp->muted = 0;
1615 msp->i2s_mode = 0;
1616 for (i = 0; i < DFP_COUNT; i++)
1617 msp->dfp_regs[i] = -1;
1618
1619 i2c_set_clientdata(client, msp);
1620 init_waitqueue_head(&msp->wq);
1621
1622 if (-1 == msp3400c_reset(client)) {
1623 kfree(msp);
1624 kfree(client);
1625 msp3400_dbg("no chip found\n");
1626 return -1;
1627 }
1628
1629 msp->rev1 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1e);
1630 if (-1 != msp->rev1)
1631 msp->rev2 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1f);
1632 if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) {
1633 kfree(msp);
1634 kfree(client);
1635 msp3400_dbg("error while reading chip version\n");
1636 return -1;
1637 }
1638 msp3400_dbg("rev1=0x%04x, rev2=0x%04x\n", msp->rev1, msp->rev2);
1639
1640 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1641
1642 snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d",
1643 ((msp->rev1>>4)&0x0f) + '3',
1644 (msp->rev2>>8)&0xff, (msp->rev1&0x0f)+'@',
1645 ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f);
1646
1647 msp->opmode = opmode;
1648 if (OPMODE_AUTO == msp->opmode) {
1649 if (HAVE_SIMPLER(msp))
1650 msp->opmode = OPMODE_SIMPLER;
1651 else if (HAVE_SIMPLE(msp))
1652 msp->opmode = OPMODE_SIMPLE;
1653 else
1654 msp->opmode = OPMODE_MANUAL;
1655 }
1656
1657 /* hello world :-) */
1658 msp3400_info("chip=%s", client->name);
1659 if (HAVE_NICAM(msp))
1660 printk(" +nicam");
1661 if (HAVE_SIMPLE(msp))
1662 printk(" +simple");
1663 if (HAVE_SIMPLER(msp))
1664 printk(" +simpler");
1665 if (HAVE_RADIO(msp))
1666 printk(" +radio");
1667
1668 /* version-specific initialization */
1669 switch (msp->opmode) {
1670 case OPMODE_MANUAL:
1671 printk(" mode=manual");
1672 thread_func = msp3400c_thread;
1673 break;
1674 case OPMODE_SIMPLE:
1675 printk(" mode=simple");
1676 thread_func = msp3410d_thread;
1677 break;
1678 case OPMODE_SIMPLER:
1679 printk(" mode=simpler");
1680 thread_func = msp34xxg_thread;
1681 break;
1682 }
1683 printk("\n");
1684
1685 /* startup control thread if needed */
1686 if (thread_func) {
1687 msp->kthread = kthread_run(thread_func, client, "msp34xx");
1688
1689 if (NULL == msp->kthread)
1690 msp3400_warn("kernel_thread() failed\n");
1691 msp_wake_thread(client);
1692 }
1693
1694 /* done */
1695 i2c_attach_client(client);
1696
1697 /* update our own array */
1698 for (i = 0; i < MSP3400_MAX; i++) {
1699 if (NULL == msps[i]) {
1700 msps[i] = client;
1701 break;
1702 }
1703 }
1704
1705 return 0;
1706}
1707
1708static int msp_detach(struct i2c_client *client)
1709{
1710 struct msp3400c *msp = i2c_get_clientdata(client);
1711 int i;
1712
1713 /* shutdown control thread */
1714 if (msp->kthread) {
1715 msp->restart = 1;
1716 kthread_stop(msp->kthread);
1717 }
1718 msp3400c_reset(client);
1719
1720 /* update our own array */
1721 for (i = 0; i < MSP3400_MAX; i++) {
1722 if (client == msps[i]) {
1723 msps[i] = NULL;
1724 break;
1725 }
1726 }
1727
1728 i2c_detach_client(client);
1729
1730 kfree(msp);
1731 kfree(client);
1732 return 0;
1733}
1734
1735static int msp_probe(struct i2c_adapter *adap)
1736{
1737 if (adap->class & I2C_CLASS_TV_ANALOG)
1738 return i2c_probe(adap, &addr_data, msp_attach);
1739 return 0;
1740}
1741
1742static void msp_wake_thread(struct i2c_client *client)
1743{
1744 struct msp3400c *msp = i2c_get_clientdata(client);
1745
1746 if (NULL == msp->kthread)
1747 return;
1748 msp3400c_setvolume(client,msp->muted,0,0);
1749 msp->watch_stereo = 0;
1750 msp->restart = 1;
1751 wake_up_interruptible(&msp->wq);
1752}
1753
1754/* ----------------------------------------------------------------------- */
1755
1756static int mode_v4l2_to_v4l1(int rxsubchans)
1757{
1758 int mode = 0;
1759
1760 if (rxsubchans & V4L2_TUNER_SUB_STEREO)
1761 mode |= VIDEO_SOUND_STEREO;
1762 if (rxsubchans & V4L2_TUNER_SUB_LANG2)
1763 mode |= VIDEO_SOUND_LANG2;
1764 if (rxsubchans & V4L2_TUNER_SUB_LANG1)
1765 mode |= VIDEO_SOUND_LANG1;
1766 if (0 == mode)
1767 mode |= VIDEO_SOUND_MONO;
1768 return mode;
1769}
1770
1771static int mode_v4l1_to_v4l2(int mode)
1772{
1773 if (mode & VIDEO_SOUND_STEREO)
1774 return V4L2_TUNER_MODE_STEREO;
1775 if (mode & VIDEO_SOUND_LANG2)
1776 return V4L2_TUNER_MODE_LANG2;
1777 if (mode & VIDEO_SOUND_LANG1)
1778 return V4L2_TUNER_MODE_LANG1;
1779 return V4L2_TUNER_MODE_MONO;
1780}
1781
1782static void msp_any_detect_stereo(struct i2c_client *client)
1783{
1784 struct msp3400c *msp = i2c_get_clientdata(client);
1785
1786 switch (msp->opmode) {
1787 case OPMODE_MANUAL:
1788 case OPMODE_SIMPLE:
1789 autodetect_stereo(client);
1790 break;
1791 case OPMODE_SIMPLER:
1792 msp34xxg_detect_stereo(client);
1793 break;
1794 }
1795}
1796
1797static void msp_any_set_audmode(struct i2c_client *client, int audmode)
1798{
1799 struct msp3400c *msp = i2c_get_clientdata(client);
1800
1801 switch (msp->opmode) {
1802 case OPMODE_MANUAL:
1803 case OPMODE_SIMPLE:
1804 msp->watch_stereo = 0;
1805 msp3400c_setstereo(client, audmode);
1806 break;
1807 case OPMODE_SIMPLER:
1808 msp34xxg_set_audmode(client, audmode);
1809 break;
1810 }
1811}
1812
1813
1814static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1815{
1816 struct msp3400c *msp = i2c_get_clientdata(client);
1817 __u16 *sarg = arg;
1818 int scart = 0;
1819
1820 switch (cmd) {
1821
1822 case AUDC_SET_INPUT:
1823 msp3400_dbg("AUDC_SET_INPUT(%d)\n",*sarg);
1824
1825 if (*sarg == msp->input)
1826 break;
1827 msp->input = *sarg;
1828 switch (*sarg) {
1829 case AUDIO_RADIO:
1830 /* Hauppauge uses IN2 for the radio */
1831 msp->mode = MSP_MODE_FM_RADIO;
1832 scart = SCART_IN2;
1833 break;
1834 case AUDIO_EXTERN_1:
1835 /* IN1 is often used for external input ... */
1836 msp->mode = MSP_MODE_EXTERN;
1837 scart = SCART_IN1;
1838 break;
1839 case AUDIO_EXTERN_2:
1840 /* ... sometimes it is IN2 through ;) */
1841 msp->mode = MSP_MODE_EXTERN;
1842 scart = SCART_IN2;
1843 break;
1844 case AUDIO_TUNER:
1845 msp->mode = -1;
1846 break;
1847 default:
1848 if (*sarg & AUDIO_MUTE)
1849 msp3400c_set_scart(client,SCART_MUTE,0);
1850 break;
1851 }
1852 if (scart) {
1853 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1854 msp->audmode = V4L2_TUNER_MODE_STEREO;
1855 msp3400c_set_scart(client,scart,0);
1856 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
1857 if (msp->opmode != OPMODE_SIMPLER)
1858 msp3400c_setstereo(client, msp->audmode);
1859 }
1860 msp_wake_thread(client);
1861 break;
1862
1863 case AUDC_SET_RADIO:
1864 msp3400_dbg("AUDC_SET_RADIO\n");
1865 msp->norm = VIDEO_MODE_RADIO;
1866 msp3400_dbg("switching to radio mode\n");
1867 msp->watch_stereo = 0;
1868 switch (msp->opmode) {
1869 case OPMODE_MANUAL:
1870 /* set msp3400 to FM radio mode */
1871 msp3400c_setmode(client,MSP_MODE_FM_RADIO);
1872 msp3400c_setcarrier(client, MSP_CARRIER(10.7),
1873 MSP_CARRIER(10.7));
1874 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1875 break;
1876 case OPMODE_SIMPLE:
1877 case OPMODE_SIMPLER:
1878 /* the thread will do for us */
1879 msp_wake_thread(client);
1880 break;
1881 }
1882 break;
1883 /* work-in-progress: hook to control the DFP registers */
1884 case MSP_SET_DFPREG:
1885 {
1886 struct msp_dfpreg *r = arg;
1887 int i;
1888
1889 if (r->reg < 0 || r->reg >= DFP_COUNT)
1890 return -EINVAL;
1891 for (i = 0; i < sizeof(bl_dfp) / sizeof(int); i++)
1892 if (r->reg == bl_dfp[i])
1893 return -EINVAL;
1894 msp->dfp_regs[r->reg] = r->value;
1895 msp3400c_write(client, I2C_MSP3400C_DFP, r->reg, r->value);
1896 return 0;
1897 }
1898 case MSP_GET_DFPREG:
1899 {
1900 struct msp_dfpreg *r = arg;
1901
1902 if (r->reg < 0 || r->reg >= DFP_COUNT)
1903 return -EINVAL;
1904 r->value = msp3400c_read(client, I2C_MSP3400C_DFP, r->reg);
1905 return 0;
1906 }
1907
1908 /* --- v4l ioctls --- */
1909 /* take care: bttv does userspace copying, we'll get a
1910 kernel pointer here... */
1911 case VIDIOCGAUDIO:
1912 {
1913 struct video_audio *va = arg;
1914
1915 msp3400_dbg("VIDIOCGAUDIO\n");
1916 va->flags |= VIDEO_AUDIO_VOLUME |
1917 VIDEO_AUDIO_BASS |
1918 VIDEO_AUDIO_TREBLE |
1919 VIDEO_AUDIO_MUTABLE;
1920 if (msp->muted)
1921 va->flags |= VIDEO_AUDIO_MUTE;
1922
1923 if (msp->muted)
1924 va->flags |= VIDEO_AUDIO_MUTE;
1925 va->volume = MAX(msp->left, msp->right);
1926 va->balance = (32768 * MIN(msp->left, msp->right)) /
1927 (va->volume ? va->volume : 1);
1928 va->balance = (msp->left < msp->right) ?
1929 (65535 - va->balance) : va->balance;
1930 if (0 == va->volume)
1931 va->balance = 32768;
1932 va->bass = msp->bass;
1933 va->treble = msp->treble;
1934
1935 msp_any_detect_stereo(client);
1936 va->mode = mode_v4l2_to_v4l1(msp->rxsubchans);
1937 break;
1938 }
1939 case VIDIOCSAUDIO:
1940 {
1941 struct video_audio *va = arg;
1942
1943 msp3400_dbg("VIDIOCSAUDIO\n");
1944 msp->muted = (va->flags & VIDEO_AUDIO_MUTE);
1945 msp->left = (MIN(65536 - va->balance, 32768) *
1946 va->volume) / 32768;
1947 msp->right = (MIN(va->balance, 32768) * va->volume) / 32768;
1948 msp->bass = va->bass;
1949 msp->treble = va->treble;
1950 msp3400_dbg("VIDIOCSAUDIO setting va->volume to %d\n",
1951 va->volume);
1952 msp3400_dbg("VIDIOCSAUDIO setting va->balance to %d\n",
1953 va->balance);
1954 msp3400_dbg("VIDIOCSAUDIO setting va->flags to %d\n",
1955 va->flags);
1956 msp3400_dbg("VIDIOCSAUDIO setting msp->left to %d\n",
1957 msp->left);
1958 msp3400_dbg("VIDIOCSAUDIO setting msp->right to %d\n",
1959 msp->right);
1960 msp3400_dbg("VIDIOCSAUDIO setting msp->bass to %d\n",
1961 msp->bass);
1962 msp3400_dbg("VIDIOCSAUDIO setting msp->treble to %d\n",
1963 msp->treble);
1964 msp3400_dbg("VIDIOCSAUDIO setting msp->mode to %d\n",
1965 msp->mode);
1966 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1967 msp3400c_setbass(client, msp->bass);
1968 msp3400c_settreble(client, msp->treble);
1969
1970 if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO)
1971 msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode));
1972 break;
1973 }
1974
1975 case VIDIOCSCHAN:
1976 {
1977 struct video_channel *vc = arg;
1978
1979 msp3400_dbg("VIDIOCSCHAN (norm=%d)\n",vc->norm);
1980 msp->norm = vc->norm;
1981 msp_wake_thread(client);
1982 break;
1983 }
1984
1985 case VIDIOCSFREQ:
1986 case VIDIOC_S_FREQUENCY:
1987 {
1988 /* new channel -- kick audio carrier scan */
1989 msp3400_dbg("VIDIOCSFREQ\n");
1990 msp_wake_thread(client);
1991 break;
1992 }
1993
1994 /* msp34xx specific */
1995 case MSP_SET_MATRIX:
1996 {
1997 struct msp_matrix *mspm = arg;
1998
1999 msp3400_dbg("MSP_SET_MATRIX\n");
2000 msp3400c_set_scart(client, mspm->input, mspm->output);
2001 break;
2002 }
2003
2004 /* --- v4l2 ioctls --- */
2005 case VIDIOC_S_STD:
2006 {
2007 v4l2_std_id *id = arg;
2008
2009 /*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/
2010 if (*id & V4L2_STD_PAL) {
2011 msp->norm=VIDEO_MODE_PAL;
2012 } else if (*id & V4L2_STD_SECAM) {
2013 msp->norm=VIDEO_MODE_SECAM;
2014 } else {
2015 msp->norm=VIDEO_MODE_NTSC;
2016 }
2017
2018 msp_wake_thread(client);
2019 return 0;
2020 }
2021
2022 case VIDIOC_ENUMINPUT:
2023 {
2024 struct v4l2_input *i = arg;
2025
2026 if (i->index != 0)
2027 return -EINVAL;
2028
2029 i->type = V4L2_INPUT_TYPE_TUNER;
2030 switch (i->index) {
2031 case AUDIO_RADIO:
2032 strcpy(i->name,"Radio");
2033 break;
2034 case AUDIO_EXTERN_1:
2035 strcpy(i->name,"Extern 1");
2036 break;
2037 case AUDIO_EXTERN_2:
2038 strcpy(i->name,"Extern 2");
2039 break;
2040 case AUDIO_TUNER:
2041 strcpy(i->name,"Television");
2042 break;
2043 default:
2044 return -EINVAL;
2045 }
2046 return 0;
2047 }
2048
2049 case VIDIOC_G_AUDIO:
2050 {
2051 struct v4l2_audio *a = arg;
2052
2053 memset(a,0,sizeof(*a));
2054
2055 switch (a->index) {
2056 case AUDIO_RADIO:
2057 strcpy(a->name,"Radio");
2058 break;
2059 case AUDIO_EXTERN_1:
2060 strcpy(a->name,"Extern 1");
2061 break;
2062 case AUDIO_EXTERN_2:
2063 strcpy(a->name,"Extern 2");
2064 break;
2065 case AUDIO_TUNER:
2066 strcpy(a->name,"Television");
2067 break;
2068 default:
2069 return -EINVAL;
2070 }
2071
2072 msp_any_detect_stereo(client);
2073 if (msp->audmode == V4L2_TUNER_MODE_STEREO) {
2074 a->capability=V4L2_AUDCAP_STEREO;
2075 }
2076
2077 break;
2078 }
2079 case VIDIOC_S_AUDIO:
2080 {
2081 struct v4l2_audio *sarg = arg;
2082
2083 switch (sarg->index) {
2084 case AUDIO_RADIO:
2085 /* Hauppauge uses IN2 for the radio */
2086 msp->mode = MSP_MODE_FM_RADIO;
2087 scart = SCART_IN2;
2088 break;
2089 case AUDIO_EXTERN_1:
2090 /* IN1 is often used for external input ... */
2091 msp->mode = MSP_MODE_EXTERN;
2092 scart = SCART_IN1;
2093 break;
2094 case AUDIO_EXTERN_2:
2095 /* ... sometimes it is IN2 through ;) */
2096 msp->mode = MSP_MODE_EXTERN;
2097 scart = SCART_IN2;
2098 break;
2099 case AUDIO_TUNER:
2100 msp->mode = -1;
2101 break;
2102 }
2103 if (scart) {
2104 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
2105 msp->audmode = V4L2_TUNER_MODE_STEREO;
2106 msp3400c_set_scart(client,scart,0);
2107 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
2108 }
2109 if (sarg->capability==V4L2_AUDCAP_STEREO) {
2110 msp->audmode = V4L2_TUNER_MODE_STEREO;
2111 } else {
2112 msp->audmode &= ~V4L2_TUNER_MODE_STEREO;
2113 }
2114 msp_any_set_audmode(client, msp->audmode);
2115 msp_wake_thread(client);
2116 break;
2117 }
2118 case VIDIOC_G_TUNER:
2119 {
2120 struct v4l2_tuner *vt = arg;
2121
2122 msp_any_detect_stereo(client);
2123 vt->audmode = msp->audmode;
2124 vt->rxsubchans = msp->rxsubchans;
2125 vt->capability = V4L2_TUNER_CAP_STEREO |
2126 V4L2_TUNER_CAP_LANG1|
2127 V4L2_TUNER_CAP_LANG2;
2128 break;
2129 }
2130 case VIDIOC_S_TUNER:
2131 {
2132 struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;
2133
2134 /* only set audmode */
2135 if (vt->audmode != -1 && vt->audmode != 0)
2136 msp_any_set_audmode(client, vt->audmode);
2137 break;
2138 }
2139
2140 case VIDIOC_G_AUDOUT:
2141 {
2142 struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
2143 int idx=a->index;
2144
2145 memset(a,0,sizeof(*a));
2146
2147 switch (idx) {
2148 case 0:
2149 strcpy(a->name,"Scart1 Out");
2150 break;
2151 case 1:
2152 strcpy(a->name,"Scart2 Out");
2153 break;
2154 case 2:
2155 strcpy(a->name,"I2S Out");
2156 break;
2157 default:
2158 return -EINVAL;
2159 }
2160 break;
2161
2162 }
2163 case VIDIOC_S_AUDOUT:
2164 {
2165 struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
2166
2167 if (a->index<0||a->index>2)
2168 return -EINVAL;
2169
2170 if (a->index==2) {
2171 if (a->mode == V4L2_AUDMODE_32BITS)
2172 msp->i2s_mode=1;
2173 else
2174 msp->i2s_mode=0;
2175 }
2176 msp3400_dbg("Setting audio out on msp34xx to input %i, mode %i\n",
2177 a->index,msp->i2s_mode);
2178 msp3400c_set_scart(client,msp->in_scart,a->index+1);
2179
2180 break;
2181 }
2182
2183 default:
2184 /* nothing */
2185 break;
2186 }
2187 return 0;
2188}
2189
2190static int msp_suspend(struct device * dev, pm_message_t state)
2191{
2192 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
2193
2194 msp3400_dbg("msp34xx: suspend\n");
2195 msp3400c_reset(client);
2196 return 0;
2197}
2198
2199static int msp_resume(struct device * dev)
2200{
2201 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
2202
2203 msp3400_dbg("msp34xx: resume\n");
2204 msp_wake_thread(client);
2205 return 0;
2206}
2207
2208/* ----------------------------------------------------------------------- */
2209
2210static int __init msp3400_init_module(void)
2211{
2212 return i2c_add_driver(&driver);
2213}
2214
2215static void __exit msp3400_cleanup_module(void)
2216{
2217 i2c_del_driver(&driver);
2218}
2219
2220module_init(msp3400_init_module);
2221module_exit(msp3400_cleanup_module);
2222
2223/*
2224 * Overrides for Emacs so that we follow Linus's tabbing style.
2225 * ---------------------------------------------------------------------------
2226 * Local variables:
2227 * c-basic-offset: 8
2228 * End:
2229 */
diff --git a/drivers/media/video/msp3400.h b/drivers/media/video/msp3400.h
index 2d9ff40f0b09..8a05cf500a8c 100644
--- a/drivers/media/video/msp3400.h
+++ b/drivers/media/video/msp3400.h
@@ -6,22 +6,28 @@
6 6
7/* ---------------------------------------------------------------------- */ 7/* ---------------------------------------------------------------------- */
8 8
9struct msp_dfpreg {
10 int reg;
11 int value;
12};
13
14struct msp_matrix { 9struct msp_matrix {
15 int input; 10 int input;
16 int output; 11 int output;
17}; 12};
18 13
19#define MSP_SET_DFPREG _IOW('m',15,struct msp_dfpreg)
20#define MSP_GET_DFPREG _IOW('m',16,struct msp_dfpreg)
21
22/* ioctl for MSP_SET_MATRIX will have to be registered */ 14/* ioctl for MSP_SET_MATRIX will have to be registered */
23#define MSP_SET_MATRIX _IOW('m',17,struct msp_matrix) 15#define MSP_SET_MATRIX _IOW('m',17,struct msp_matrix)
24 16
17/* This macro is allowed for *constants* only, gcc must calculate it
18 at compile time. Remember -- no floats in kernel mode */
19#define MSP_CARRIER(freq) ((int)((float)(freq / 18.432) * (1 << 24)))
20
21#define MSP_MODE_AM_DETECT 0
22#define MSP_MODE_FM_RADIO 2
23#define MSP_MODE_FM_TERRA 3
24#define MSP_MODE_FM_SAT 4
25#define MSP_MODE_FM_NICAM1 5
26#define MSP_MODE_FM_NICAM2 6
27#define MSP_MODE_AM_NICAM 7
28#define MSP_MODE_BTSC 8
29#define MSP_MODE_EXTERN 9
30
25#define SCART_MASK 0 31#define SCART_MASK 0
26#define SCART_IN1 1 32#define SCART_IN1 1
27#define SCART_IN2 2 33#define SCART_IN2 2
@@ -36,4 +42,84 @@ struct msp_matrix {
36#define SCART1_OUT 1 42#define SCART1_OUT 1
37#define SCART2_OUT 2 43#define SCART2_OUT 2
38 44
45#define OPMODE_AUTO -1
46#define OPMODE_MANUAL 0
47#define OPMODE_AUTODETECT 1 /* use autodetect (>= msp3410 only) */
48#define OPMODE_AUTOSELECT 2 /* use autodetect & autoselect (>= msp34xxG) */
49
50/* module parameters */
51extern int debug;
52extern int once;
53extern int amsound;
54extern int standard;
55extern int dolby;
56extern int stereo_threshold;
57
58struct msp_state {
59 int rev1, rev2;
60 u8 has_nicam;
61 u8 has_radio;
62 u8 has_headphones;
63 u8 has_ntsc_jp_d_k3;
64 u8 has_scart4;
65 u8 has_scart23_in_scart2_out;
66 u8 has_scart2_out_volume;
67 u8 has_i2s_conf;
68 u8 has_subwoofer;
69 u8 has_sound_processing;
70 u8 has_virtual_dolby_surround;
71 u8 has_dolby_pro_logic;
72
73 int radio;
74 int opmode;
75 int std;
76 int mode;
77 v4l2_std_id v4l2_std;
78 int nicam_on;
79 int acb;
80 int in_scart;
81 int i2s_mode;
82 int main, second; /* sound carrier */
83 int input;
84 int source; /* see msp34xxg_set_source */
85
86 /* v4l2 */
87 int audmode;
88 int rxsubchans;
89
90 int volume, muted;
91 int balance, loudness;
92 int bass, treble;
93
94 /* thread */
95 struct task_struct *kthread;
96 wait_queue_head_t wq;
97 int restart:1;
98 int watch_stereo:1;
99};
100
101/* msp3400-driver.c */
102int msp_write_dem(struct i2c_client *client, int addr, int val);
103int msp_write_dsp(struct i2c_client *client, int addr, int val);
104int msp_read_dem(struct i2c_client *client, int addr);
105int msp_read_dsp(struct i2c_client *client, int addr);
106int msp_reset(struct i2c_client *client);
107void msp_set_scart(struct i2c_client *client, int in, int out);
108void msp_set_mute(struct i2c_client *client);
109void msp_set_audio(struct i2c_client *client);
110int msp_modus(struct i2c_client *client);
111int msp_sleep(struct msp_state *state, int timeout);
112
113/* msp3400-kthreads.c */
114const char *msp_standard_std_name(int std);
115void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2);
116void msp3400c_setmode(struct i2c_client *client, int type);
117void msp3400c_setstereo(struct i2c_client *client, int mode);
118int autodetect_stereo(struct i2c_client *client);
119int msp3400c_thread(void *data);
120int msp3410d_thread(void *data);
121int msp34xxg_thread(void *data);
122void msp34xxg_detect_stereo(struct i2c_client *client);
123void msp34xxg_set_audmode(struct i2c_client *client, int audmode);
124
39#endif /* MSP3400_H */ 125#endif /* MSP3400_H */
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
index 2180018f06de..2c19c9588c02 100644
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/video/mt20xx.c
@@ -20,6 +20,9 @@ module_param(tv_antenna, int, 0644);
20static unsigned int radio_antenna = 0; 20static unsigned int radio_antenna = 0;
21module_param(radio_antenna, int, 0644); 21module_param(radio_antenna, int, 0644);
22 22
23/* from tuner-core.c */
24extern int debug;
25
23/* ---------------------------------------------------------------------- */ 26/* ---------------------------------------------------------------------- */
24 27
25#define MT2032 0x04 28#define MT2032 0x04
@@ -401,7 +404,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned
401 div2a=(lo2/8)-1; 404 div2a=(lo2/8)-1;
402 div2b=lo2-(div2a+1)*8; 405 div2b=lo2-(div2a+1)*8;
403 406
404 if (tuner_debug > 1) { 407 if (debug > 1) {
405 tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2); 408 tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2);
406 tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n", 409 tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n",
407 num1,num2,div1a,div1b,div2a,div2b); 410 num1,num2,div1a,div1b,div2a,div2b);
@@ -417,7 +420,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned
417 buf[5]=div2a; 420 buf[5]=div2a;
418 if(num2!=0) buf[5]=buf[5]|0x40; 421 if(num2!=0) buf[5]=buf[5]|0x40;
419 422
420 if (tuner_debug > 1) { 423 if (debug > 1) {
421 int i; 424 int i;
422 tuner_dbg("bufs is: "); 425 tuner_dbg("bufs is: ");
423 for(i=0;i<6;i++) 426 for(i=0;i<6;i++)
@@ -494,11 +497,18 @@ int microtune_init(struct i2c_client *c)
494 t->tv_freq = NULL; 497 t->tv_freq = NULL;
495 t->radio_freq = NULL; 498 t->radio_freq = NULL;
496 t->standby = NULL; 499 t->standby = NULL;
500 if (t->std & V4L2_STD_525_60) {
501 tuner_dbg("pinnacle ntsc\n");
502 t->radio_if2 = 41300 * 1000;
503 } else {
504 tuner_dbg("pinnacle pal\n");
505 t->radio_if2 = 33300 * 1000;
506 }
497 name = "unknown"; 507 name = "unknown";
498 508
499 i2c_master_send(c,buf,1); 509 i2c_master_send(c,buf,1);
500 i2c_master_recv(c,buf,21); 510 i2c_master_recv(c,buf,21);
501 if (tuner_debug) { 511 if (debug) {
502 int i; 512 int i;
503 tuner_dbg("MT20xx hexdump:"); 513 tuner_dbg("MT20xx hexdump:");
504 for(i=0;i<21;i++) { 514 for(i=0;i<21;i++) {
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index d04793fb80fc..91681aa6c657 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -26,6 +26,7 @@
26#include <media/saa7146_vv.h> 26#include <media/saa7146_vv.h>
27#include <media/tuner.h> 27#include <media/tuner.h>
28#include <linux/video_decoder.h> 28#include <linux/video_decoder.h>
29#include <media/v4l2-common.h>
29 30
30#include "mxb.h" 31#include "mxb.h"
31#include "tea6415c.h" 32#include "tea6415c.h"
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 2504207b2e3d..9e6448639480 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -883,6 +883,7 @@ static struct file_operations pms_fops = {
883 .open = video_exclusive_open, 883 .open = video_exclusive_open,
884 .release = video_exclusive_release, 884 .release = video_exclusive_release,
885 .ioctl = pms_ioctl, 885 .ioctl = pms_ioctl,
886 .compat_ioctl = v4l_compat_ioctl32,
886 .read = pms_read, 887 .read = pms_read,
887 .llseek = no_llseek, 888 .llseek = no_llseek,
888}; 889};
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index a51c7bd96618..73b4f0e2abf0 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -702,6 +702,7 @@ static struct file_operations saa_fops = {
702 .open = saa5249_open, 702 .open = saa5249_open,
703 .release = saa5249_release, 703 .release = saa5249_release,
704 .ioctl = saa5249_ioctl, 704 .ioctl = saa5249_ioctl,
705 .compat_ioctl = v4l_compat_ioctl32,
705 .llseek = no_llseek, 706 .llseek = no_llseek,
706}; 707};
707 708
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index d60a783e0473..e70b17ef36e9 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -427,18 +427,8 @@ static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind)
427 427
428static int saa6588_probe(struct i2c_adapter *adap) 428static int saa6588_probe(struct i2c_adapter *adap)
429{ 429{
430#ifdef I2C_CLASS_TV_ANALOG
431 if (adap->class & I2C_CLASS_TV_ANALOG) 430 if (adap->class & I2C_CLASS_TV_ANALOG)
432 return i2c_probe(adap, &addr_data, saa6588_attach); 431 return i2c_probe(adap, &addr_data, saa6588_attach);
433#else
434 switch (adap->id) {
435 case I2C_HW_B_BT848:
436 case I2C_HW_B_RIVA:
437 case I2C_HW_SAA7134:
438 return i2c_probe(adap, &addr_data, saa6588_attach);
439 break;
440 }
441#endif
442 return 0; 432 return 0;
443} 433}
444 434
@@ -496,7 +486,7 @@ static int saa6588_command(struct i2c_client *client, unsigned int cmd,
496 486
497static struct i2c_driver driver = { 487static struct i2c_driver driver = {
498 .driver = { 488 .driver = {
499 .name = "i2c saa6588 driver", 489 .name = "saa6588",
500 }, 490 },
501 .id = -1, /* FIXME */ 491 .id = -1, /* FIXME */
502 .attach_adapter = saa6588_probe, 492 .attach_adapter = saa6588_probe,
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 29e28c742cd4..4a4bc69fb0e9 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -39,31 +39,18 @@
39#include <linux/i2c.h> 39#include <linux/i2c.h>
40#include <linux/videodev2.h> 40#include <linux/videodev2.h>
41#include <media/v4l2-common.h> 41#include <media/v4l2-common.h>
42#include <media/audiochip.h>
43#include <asm/div64.h>
42 44
43MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver"); 45MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver");
44MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil"); 46MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil");
45MODULE_LICENSE("GPL"); 47MODULE_LICENSE("GPL");
46 48
47static int debug = 0; 49static int debug = 0;
48module_param(debug, int, 0644); 50module_param(debug, bool, 0644);
49 51
50MODULE_PARM_DESC(debug, "Debug level (0-1)"); 52MODULE_PARM_DESC(debug, "Debug level (0-1)");
51 53
52#define saa7115_dbg(fmt,arg...) \
53 do { \
54 if (debug) \
55 printk(KERN_INFO "%s debug %d-%04x: " fmt, \
56 client->driver->driver.name, \
57 i2c_adapter_id(client->adapter), client->addr , ## arg); \
58 } while (0)
59
60#define saa7115_err(fmt, arg...) do { \
61 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
62 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
63#define saa7115_info(fmt, arg...) do { \
64 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
65 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
66
67static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; 54static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
68 55
69 56
@@ -73,12 +60,13 @@ struct saa7115_state {
73 v4l2_std_id std; 60 v4l2_std_id std;
74 int input; 61 int input;
75 int enable; 62 int enable;
63 int radio;
76 int bright; 64 int bright;
77 int contrast; 65 int contrast;
78 int hue; 66 int hue;
79 int sat; 67 int sat;
80 enum v4l2_chip_ident ident; 68 enum v4l2_chip_ident ident;
81 enum v4l2_audio_clock_freq audclk_freq; 69 u32 audclk_freq;
82}; 70};
83 71
84/* ----------------------------------------------------------------------- */ 72/* ----------------------------------------------------------------------- */
@@ -469,80 +457,6 @@ static const unsigned char saa7115_init_misc[] = {
469 0x00, 0x00 457 0x00, 0x00
470}; 458};
471 459
472/* ============== SAA7715 AUDIO settings ============= */
473
474/* 48.0 kHz */
475static const unsigned char saa7115_cfg_48_audio[] = {
476 0x34, 0xce,
477 0x35, 0xfb,
478 0x36, 0x30,
479 0x00, 0x00
480};
481
482/* 44.1 kHz */
483static const unsigned char saa7115_cfg_441_audio[] = {
484 0x34, 0xf2,
485 0x35, 0x00,
486 0x36, 0x2d,
487 0x00, 0x00
488};
489
490/* 32.0 kHz */
491static const unsigned char saa7115_cfg_32_audio[] = {
492 0x34, 0xdf,
493 0x35, 0xa7,
494 0x36, 0x20,
495 0x00, 0x00
496};
497
498/* 48.0 kHz 60hz */
499static const unsigned char saa7115_cfg_60hz_48_audio[] = {
500 0x30, 0xcd,
501 0x31, 0x20,
502 0x32, 0x03,
503 0x00, 0x00
504};
505
506/* 48.0 kHz 50hz */
507static const unsigned char saa7115_cfg_50hz_48_audio[] = {
508 0x30, 0x00,
509 0x31, 0xc0,
510 0x32, 0x03,
511 0x00, 0x00
512};
513
514/* 44.1 kHz 60hz */
515static const unsigned char saa7115_cfg_60hz_441_audio[] = {
516 0x30, 0xbc,
517 0x31, 0xdf,
518 0x32, 0x02,
519 0x00, 0x00
520};
521
522/* 44.1 kHz 50hz */
523static const unsigned char saa7115_cfg_50hz_441_audio[] = {
524 0x30, 0x00,
525 0x31, 0x72,
526 0x32, 0x03,
527 0x00, 0x00
528};
529
530/* 32.0 kHz 60hz */
531static const unsigned char saa7115_cfg_60hz_32_audio[] = {
532 0x30, 0xde,
533 0x31, 0x15,
534 0x32, 0x02,
535 0x00, 0x00
536};
537
538/* 32.0 kHz 50hz */
539static const unsigned char saa7115_cfg_50hz_32_audio[] = {
540 0x30, 0x00,
541 0x31, 0x80,
542 0x32, 0x02,
543 0x00, 0x00
544};
545
546static int saa7115_odd_parity(u8 c) 460static int saa7115_odd_parity(u8 c)
547{ 461{
548 c ^= (c >> 4); 462 c ^= (c >> 4);
@@ -627,40 +541,38 @@ static int saa7115_decode_wss(u8 * p)
627} 541}
628 542
629 543
630static int saa7115_set_audio_clock_freq(struct i2c_client *client, enum v4l2_audio_clock_freq freq) 544static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
631{ 545{
632 struct saa7115_state *state = i2c_get_clientdata(client); 546 struct saa7115_state *state = i2c_get_clientdata(client);
547 u32 acpf;
548 u32 acni;
549 u32 hz;
550 u64 f;
633 551
634 saa7115_dbg("set audio clock freq: %d\n", freq); 552 v4l_dbg(1, client, "set audio clock freq: %d\n", freq);
635 switch (freq) { 553
636 case V4L2_AUDCLK_32_KHZ: 554 /* sanity check */
637 saa7115_writeregs(client, saa7115_cfg_32_audio); 555 if (freq < 32000 || freq > 48000)
638 if (state->std & V4L2_STD_525_60) { 556 return -EINVAL;
639 saa7115_writeregs(client, saa7115_cfg_60hz_32_audio); 557
640 } else { 558 /* hz is the refresh rate times 100 */
641 saa7115_writeregs(client, saa7115_cfg_50hz_32_audio); 559 hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
642 } 560 /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
643 break; 561 acpf = (25600 * freq) / hz;
644 case V4L2_AUDCLK_441_KHZ: 562 /* acni = (256 * freq * 2^23) / crystal_frequency =
645 saa7115_writeregs(client, saa7115_cfg_441_audio); 563 (freq * 2^(8+23)) / crystal_frequency =
646 if (state->std & V4L2_STD_525_60) { 564 (freq << 31) / 32.11 MHz */
647 saa7115_writeregs(client, saa7115_cfg_60hz_441_audio); 565 f = freq;
648 } else { 566 f = f << 31;
649 saa7115_writeregs(client, saa7115_cfg_50hz_441_audio); 567 do_div(f, 32110000);
650 } 568 acni = f;
651 break; 569
652 case V4L2_AUDCLK_48_KHZ: 570 saa7115_write(client, 0x30, acpf & 0xff);
653 saa7115_writeregs(client, saa7115_cfg_48_audio); 571 saa7115_write(client, 0x31, (acpf >> 8) & 0xff);
654 if (state->std & V4L2_STD_525_60) { 572 saa7115_write(client, 0x32, (acpf >> 16) & 0x03);
655 saa7115_writeregs(client, saa7115_cfg_60hz_48_audio); 573 saa7115_write(client, 0x34, acni & 0xff);
656 } else { 574 saa7115_write(client, 0x35, (acni >> 8) & 0xff);
657 saa7115_writeregs(client, saa7115_cfg_50hz_48_audio); 575 saa7115_write(client, 0x36, (acni >> 16) & 0x3f);
658 }
659 break;
660 default:
661 saa7115_dbg("invalid audio setting %d\n", freq);
662 return -EINVAL;
663 }
664 state->audclk_freq = freq; 576 state->audclk_freq = freq;
665 return 0; 577 return 0;
666} 578}
@@ -672,7 +584,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
672 switch (ctrl->id) { 584 switch (ctrl->id) {
673 case V4L2_CID_BRIGHTNESS: 585 case V4L2_CID_BRIGHTNESS:
674 if (ctrl->value < 0 || ctrl->value > 255) { 586 if (ctrl->value < 0 || ctrl->value > 255) {
675 saa7115_err("invalid brightness setting %d\n", ctrl->value); 587 v4l_err(client, "invalid brightness setting %d\n", ctrl->value);
676 return -ERANGE; 588 return -ERANGE;
677 } 589 }
678 590
@@ -682,7 +594,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
682 594
683 case V4L2_CID_CONTRAST: 595 case V4L2_CID_CONTRAST:
684 if (ctrl->value < 0 || ctrl->value > 127) { 596 if (ctrl->value < 0 || ctrl->value > 127) {
685 saa7115_err("invalid contrast setting %d\n", ctrl->value); 597 v4l_err(client, "invalid contrast setting %d\n", ctrl->value);
686 return -ERANGE; 598 return -ERANGE;
687 } 599 }
688 600
@@ -692,7 +604,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
692 604
693 case V4L2_CID_SATURATION: 605 case V4L2_CID_SATURATION:
694 if (ctrl->value < 0 || ctrl->value > 127) { 606 if (ctrl->value < 0 || ctrl->value > 127) {
695 saa7115_err("invalid saturation setting %d\n", ctrl->value); 607 v4l_err(client, "invalid saturation setting %d\n", ctrl->value);
696 return -ERANGE; 608 return -ERANGE;
697 } 609 }
698 610
@@ -702,13 +614,16 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
702 614
703 case V4L2_CID_HUE: 615 case V4L2_CID_HUE:
704 if (ctrl->value < -127 || ctrl->value > 127) { 616 if (ctrl->value < -127 || ctrl->value > 127) {
705 saa7115_err("invalid hue setting %d\n", ctrl->value); 617 v4l_err(client, "invalid hue setting %d\n", ctrl->value);
706 return -ERANGE; 618 return -ERANGE;
707 } 619 }
708 620
709 state->hue = ctrl->value; 621 state->hue = ctrl->value;
710 saa7115_write(client, 0x0d, state->hue); 622 saa7115_write(client, 0x0d, state->hue);
711 break; 623 break;
624
625 default:
626 return -EINVAL;
712 } 627 }
713 628
714 return 0; 629 return 0;
@@ -743,12 +658,22 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
743 struct saa7115_state *state = i2c_get_clientdata(client); 658 struct saa7115_state *state = i2c_get_clientdata(client);
744 int taskb = saa7115_read(client, 0x80) & 0x10; 659 int taskb = saa7115_read(client, 0x80) & 0x10;
745 660
661 /* Prevent unnecessary standard changes. During a standard
662 change the I-Port is temporarily disabled. Any devices
663 reading from that port can get confused.
664 Note that VIDIOC_S_STD is also used to switch from
665 radio to TV mode, so if a VIDIOC_S_STD is broadcast to
666 all I2C devices then you do not want to have an unwanted
667 side-effect here. */
668 if (std == state->std)
669 return;
670
746 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants. 671 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
747 if (std & V4L2_STD_525_60) { 672 if (std & V4L2_STD_525_60) {
748 saa7115_dbg("decoder set standard 60 Hz\n"); 673 v4l_dbg(1, client, "decoder set standard 60 Hz\n");
749 saa7115_writeregs(client, saa7115_cfg_60hz_video); 674 saa7115_writeregs(client, saa7115_cfg_60hz_video);
750 } else { 675 } else {
751 saa7115_dbg("decoder set standard 50 Hz\n"); 676 v4l_dbg(1, client, "decoder set standard 50 Hz\n");
752 saa7115_writeregs(client, saa7115_cfg_50hz_video); 677 saa7115_writeregs(client, saa7115_cfg_50hz_video);
753 } 678 }
754 679
@@ -773,24 +698,17 @@ static v4l2_std_id saa7115_get_v4lstd(struct i2c_client *client)
773static void saa7115_log_status(struct i2c_client *client) 698static void saa7115_log_status(struct i2c_client *client)
774{ 699{
775 struct saa7115_state *state = i2c_get_clientdata(client); 700 struct saa7115_state *state = i2c_get_clientdata(client);
776 char *audfreq = "undefined";
777 int reg1e, reg1f; 701 int reg1e, reg1f;
778 int signalOk; 702 int signalOk;
779 int vcr; 703 int vcr;
780 704
781 switch (state->audclk_freq) { 705 v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq);
782 case V4L2_AUDCLK_32_KHZ: audfreq = "32 kHz"; break;
783 case V4L2_AUDCLK_441_KHZ: audfreq = "44.1 kHz"; break;
784 case V4L2_AUDCLK_48_KHZ: audfreq = "48 kHz"; break;
785 }
786
787 saa7115_info("Audio frequency: %s\n", audfreq);
788 if (client->name[6] == '4') { 706 if (client->name[6] == '4') {
789 /* status for the saa7114 */ 707 /* status for the saa7114 */
790 reg1f = saa7115_read(client, 0x1f); 708 reg1f = saa7115_read(client, 0x1f);
791 signalOk = (reg1f & 0xc1) == 0x81; 709 signalOk = (reg1f & 0xc1) == 0x81;
792 saa7115_info("Video signal: %s\n", signalOk ? "ok" : "bad"); 710 v4l_info(client, "Video signal: %s\n", signalOk ? "ok" : "bad");
793 saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz"); 711 v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
794 return; 712 return;
795 } 713 }
796 714
@@ -801,21 +719,26 @@ static void saa7115_log_status(struct i2c_client *client)
801 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80; 719 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
802 vcr = !(reg1f & 0x10); 720 vcr = !(reg1f & 0x10);
803 721
804 saa7115_info("Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad"); 722 if (state->input >= 6) {
805 saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz"); 723 v4l_info(client, "Input: S-Video %d\n", state->input - 6);
724 } else {
725 v4l_info(client, "Input: Composite %d\n", state->input);
726 }
727 v4l_info(client, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
728 v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
806 729
807 switch (reg1e & 0x03) { 730 switch (reg1e & 0x03) {
808 case 1: 731 case 1:
809 saa7115_info("Detected format: NTSC\n"); 732 v4l_info(client, "Detected format: NTSC\n");
810 break; 733 break;
811 case 2: 734 case 2:
812 saa7115_info("Detected format: PAL\n"); 735 v4l_info(client, "Detected format: PAL\n");
813 break; 736 break;
814 case 3: 737 case 3:
815 saa7115_info("Detected format: SECAM\n"); 738 v4l_info(client, "Detected format: SECAM\n");
816 break; 739 break;
817 default: 740 default:
818 saa7115_info("Detected format: BW/No color\n"); 741 v4l_info(client, "Detected format: BW/No color\n");
819 break; 742 break;
820 } 743 }
821} 744}
@@ -940,7 +863,7 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
940 863
941 pix = &(fmt->fmt.pix); 864 pix = &(fmt->fmt.pix);
942 865
943 saa7115_dbg("decoder set size\n"); 866 v4l_dbg(1, client, "decoder set size\n");
944 867
945 /* FIXME need better bounds checking here */ 868 /* FIXME need better bounds checking here */
946 if ((pix->width < 1) || (pix->width > 1440)) 869 if ((pix->width < 1) || (pix->width > 1440))
@@ -966,7 +889,7 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
966 HPSC = HPSC ? HPSC : 1; 889 HPSC = HPSC ? HPSC : 1;
967 HFSC = (int)((1024 * 720) / (HPSC * pix->width)); 890 HFSC = (int)((1024 * 720) / (HPSC * pix->width));
968 891
969 saa7115_dbg("Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC); 892 v4l_dbg(1, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
970 /* FIXME hardcodes to "Task B" 893 /* FIXME hardcodes to "Task B"
971 * write H prescaler integer */ 894 * write H prescaler integer */
972 saa7115_write(client, 0xd0, (u8) (HPSC & 0x3f)); 895 saa7115_write(client, 0xd0, (u8) (HPSC & 0x3f));
@@ -980,10 +903,10 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
980 saa7115_write(client, 0xDD, (u8) ((HFSC >> 9) & 0xff)); 903 saa7115_write(client, 0xDD, (u8) ((HFSC >> 9) & 0xff));
981 } else { 904 } else {
982 if (is_50hz) { 905 if (is_50hz) {
983 saa7115_dbg("Setting full 50hz width\n"); 906 v4l_dbg(1, client, "Setting full 50hz width\n");
984 saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x); 907 saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x);
985 } else { 908 } else {
986 saa7115_dbg("Setting full 60hz width\n"); 909 v4l_dbg(1, client, "Setting full 60hz width\n");
987 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); 910 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
988 } 911 }
989 } 912 }
@@ -992,7 +915,7 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
992 915
993 if (pix->height != Vsrc) { 916 if (pix->height != Vsrc) {
994 VSCY = (int)((1024 * Vsrc) / pix->height); 917 VSCY = (int)((1024 * Vsrc) / pix->height);
995 saa7115_dbg("Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY); 918 v4l_dbg(1, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
996 919
997 /* Correct Contrast and Luminance */ 920 /* Correct Contrast and Luminance */
998 saa7115_write(client, 0xd5, (u8) (64 * 1024 / VSCY)); 921 saa7115_write(client, 0xd5, (u8) (64 * 1024 / VSCY));
@@ -1006,10 +929,10 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
1006 saa7115_write(client, 0xe3, (u8) ((VSCY >> 8) & 0xff)); 929 saa7115_write(client, 0xe3, (u8) ((VSCY >> 8) & 0xff));
1007 } else { 930 } else {
1008 if (is_50hz) { 931 if (is_50hz) {
1009 saa7115_dbg("Setting full 50Hz height\n"); 932 v4l_dbg(1, client, "Setting full 50Hz height\n");
1010 saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y); 933 saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y);
1011 } else { 934 } else {
1012 saa7115_dbg("Setting full 60hz height\n"); 935 v4l_dbg(1, client, "Setting full 60hz height\n");
1013 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); 936 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
1014 } 937 }
1015 } 938 }
@@ -1089,6 +1012,48 @@ static void saa7115_decode_vbi_line(struct i2c_client *client,
1089 1012
1090/* ============ SAA7115 AUDIO settings (end) ============= */ 1013/* ============ SAA7115 AUDIO settings (end) ============= */
1091 1014
1015static struct v4l2_queryctrl saa7115_qctrl[] = {
1016 {
1017 .id = V4L2_CID_BRIGHTNESS,
1018 .type = V4L2_CTRL_TYPE_INTEGER,
1019 .name = "Brightness",
1020 .minimum = 0,
1021 .maximum = 255,
1022 .step = 1,
1023 .default_value = 128,
1024 .flags = 0,
1025 }, {
1026 .id = V4L2_CID_CONTRAST,
1027 .type = V4L2_CTRL_TYPE_INTEGER,
1028 .name = "Contrast",
1029 .minimum = 0,
1030 .maximum = 255,
1031 .step = 1,
1032 .default_value = 64,
1033 .flags = 0,
1034 }, {
1035 .id = V4L2_CID_SATURATION,
1036 .type = V4L2_CTRL_TYPE_INTEGER,
1037 .name = "Saturation",
1038 .minimum = 0,
1039 .maximum = 255,
1040 .step = 1,
1041 .default_value = 64,
1042 .flags = 0,
1043 }, {
1044 .id = V4L2_CID_HUE,
1045 .type = V4L2_CTRL_TYPE_INTEGER,
1046 .name = "Hue",
1047 .minimum = -128,
1048 .maximum = 127,
1049 .step = 1,
1050 .default_value = 0,
1051 .flags = 0,
1052 },
1053};
1054
1055/* ----------------------------------------------------------------------- */
1056
1092static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg) 1057static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg)
1093{ 1058{
1094 struct saa7115_state *state = i2c_get_clientdata(client); 1059 struct saa7115_state *state = i2c_get_clientdata(client);
@@ -1103,16 +1068,18 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1103 return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg); 1068 return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg);
1104 1069
1105 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 1070 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
1106 return saa7115_set_audio_clock_freq(client, *(enum v4l2_audio_clock_freq *)arg); 1071 return saa7115_set_audio_clock_freq(client, *(u32 *)arg);
1107 1072
1108 case VIDIOC_G_TUNER: 1073 case VIDIOC_G_TUNER:
1109 { 1074 {
1110 struct v4l2_tuner *vt = arg; 1075 struct v4l2_tuner *vt = arg;
1111 int status; 1076 int status;
1112 1077
1078 if (state->radio)
1079 break;
1113 status = saa7115_read(client, 0x1f); 1080 status = saa7115_read(client, 0x1f);
1114 1081
1115 saa7115_dbg("status: 0x%02x\n", status); 1082 v4l_dbg(1, client, "status: 0x%02x\n", status);
1116 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0; 1083 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
1117 break; 1084 break;
1118 } 1085 }
@@ -1127,20 +1094,38 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1127 case VIDIOC_S_CTRL: 1094 case VIDIOC_S_CTRL:
1128 return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg); 1095 return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg);
1129 1096
1097 case VIDIOC_QUERYCTRL:
1098 {
1099 struct v4l2_queryctrl *qc = arg;
1100 int i;
1101
1102 for (i = 0; i < ARRAY_SIZE(saa7115_qctrl); i++)
1103 if (qc->id && qc->id == saa7115_qctrl[i].id) {
1104 memcpy(qc, &saa7115_qctrl[i], sizeof(*qc));
1105 return 0;
1106 }
1107 return -EINVAL;
1108 }
1109
1130 case VIDIOC_G_STD: 1110 case VIDIOC_G_STD:
1131 *(v4l2_std_id *)arg = saa7115_get_v4lstd(client); 1111 *(v4l2_std_id *)arg = saa7115_get_v4lstd(client);
1132 break; 1112 break;
1133 1113
1134 case VIDIOC_S_STD: 1114 case VIDIOC_S_STD:
1115 state->radio = 0;
1135 saa7115_set_v4lstd(client, *(v4l2_std_id *)arg); 1116 saa7115_set_v4lstd(client, *(v4l2_std_id *)arg);
1136 break; 1117 break;
1137 1118
1119 case AUDC_SET_RADIO:
1120 state->radio = 1;
1121 break;
1122
1138 case VIDIOC_G_INPUT: 1123 case VIDIOC_G_INPUT:
1139 *(int *)arg = state->input; 1124 *(int *)arg = state->input;
1140 break; 1125 break;
1141 1126
1142 case VIDIOC_S_INPUT: 1127 case VIDIOC_S_INPUT:
1143 saa7115_dbg("decoder set input %d\n", *iarg); 1128 v4l_dbg(1, client, "decoder set input %d\n", *iarg);
1144 /* inputs from 0-9 are available */ 1129 /* inputs from 0-9 are available */
1145 if (*iarg < 0 || *iarg > 9) { 1130 if (*iarg < 0 || *iarg > 9) {
1146 return -EINVAL; 1131 return -EINVAL;
@@ -1148,7 +1133,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1148 1133
1149 if (state->input == *iarg) 1134 if (state->input == *iarg)
1150 break; 1135 break;
1151 saa7115_dbg("now setting %s input\n", 1136 v4l_dbg(1, client, "now setting %s input\n",
1152 *iarg >= 6 ? "S-Video" : "Composite"); 1137 *iarg >= 6 ? "S-Video" : "Composite");
1153 state->input = *iarg; 1138 state->input = *iarg;
1154 1139
@@ -1165,7 +1150,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1165 1150
1166 case VIDIOC_STREAMON: 1151 case VIDIOC_STREAMON:
1167 case VIDIOC_STREAMOFF: 1152 case VIDIOC_STREAMOFF:
1168 saa7115_dbg("%s output\n", 1153 v4l_dbg(1, client, "%s output\n",
1169 (cmd == VIDIOC_STREAMON) ? "enable" : "disable"); 1154 (cmd == VIDIOC_STREAMON) ? "enable" : "disable");
1170 1155
1171 if (state->enable != (cmd == VIDIOC_STREAMON)) { 1156 if (state->enable != (cmd == VIDIOC_STREAMON)) {
@@ -1179,7 +1164,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1179 break; 1164 break;
1180 1165
1181 case VIDIOC_INT_RESET: 1166 case VIDIOC_INT_RESET:
1182 saa7115_dbg("decoder RESET\n"); 1167 v4l_dbg(1, client, "decoder RESET\n");
1183 saa7115_writeregs(client, saa7115_cfg_reset_scaler); 1168 saa7115_writeregs(client, saa7115_cfg_reset_scaler);
1184 break; 1169 break;
1185 1170
@@ -1273,19 +1258,19 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
1273 client->driver = &i2c_driver_saa7115; 1258 client->driver = &i2c_driver_saa7115;
1274 snprintf(client->name, sizeof(client->name) - 1, "saa7115"); 1259 snprintf(client->name, sizeof(client->name) - 1, "saa7115");
1275 1260
1276 saa7115_dbg("detecting saa7115 client on address 0x%x\n", address << 1); 1261 v4l_dbg(1, client, "detecting saa7115 client on address 0x%x\n", address << 1);
1277 1262
1278 saa7115_write(client, 0, 5); 1263 saa7115_write(client, 0, 5);
1279 chip_id = saa7115_read(client, 0) & 0x0f; 1264 chip_id = saa7115_read(client, 0) & 0x0f;
1280 if (chip_id != 4 && chip_id != 5) { 1265 if (chip_id != 4 && chip_id != 5) {
1281 saa7115_dbg("saa7115 not found\n"); 1266 v4l_dbg(1, client, "saa7115 not found\n");
1282 kfree(client); 1267 kfree(client);
1283 return 0; 1268 return 0;
1284 } 1269 }
1285 if (chip_id == 4) { 1270 if (chip_id == 4) {
1286 snprintf(client->name, sizeof(client->name) - 1, "saa7114"); 1271 snprintf(client->name, sizeof(client->name) - 1, "saa7114");
1287 } 1272 }
1288 saa7115_info("saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name); 1273 v4l_info(client, "saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name);
1289 1274
1290 state = kmalloc(sizeof(struct saa7115_state), GFP_KERNEL); 1275 state = kmalloc(sizeof(struct saa7115_state), GFP_KERNEL);
1291 i2c_set_clientdata(client, state); 1276 i2c_set_clientdata(client, state);
@@ -1297,14 +1282,15 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
1297 state->std = V4L2_STD_NTSC; 1282 state->std = V4L2_STD_NTSC;
1298 state->input = -1; 1283 state->input = -1;
1299 state->enable = 1; 1284 state->enable = 1;
1285 state->radio = 0;
1300 state->bright = 128; 1286 state->bright = 128;
1301 state->contrast = 64; 1287 state->contrast = 64;
1302 state->hue = 0; 1288 state->hue = 0;
1303 state->sat = 64; 1289 state->sat = 64;
1304 state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115; 1290 state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115;
1305 state->audclk_freq = V4L2_AUDCLK_48_KHZ; 1291 state->audclk_freq = 48000;
1306 1292
1307 saa7115_dbg("writing init values\n"); 1293 v4l_dbg(1, client, "writing init values\n");
1308 1294
1309 /* init to 60hz/48khz */ 1295 /* init to 60hz/48khz */
1310 saa7115_writeregs(client, saa7115_init_auto_input); 1296 saa7115_writeregs(client, saa7115_init_auto_input);
@@ -1312,13 +1298,12 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
1312 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); 1298 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
1313 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); 1299 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
1314 saa7115_writeregs(client, saa7115_cfg_60hz_video); 1300 saa7115_writeregs(client, saa7115_cfg_60hz_video);
1315 saa7115_writeregs(client, saa7115_cfg_48_audio); 1301 saa7115_set_audio_clock_freq(client, state->audclk_freq);
1316 saa7115_writeregs(client, saa7115_cfg_60hz_48_audio);
1317 saa7115_writeregs(client, saa7115_cfg_reset_scaler); 1302 saa7115_writeregs(client, saa7115_cfg_reset_scaler);
1318 1303
1319 i2c_attach_client(client); 1304 i2c_attach_client(client);
1320 1305
1321 saa7115_dbg("status: (1E) 0x%02x, (1F) 0x%02x\n", 1306 v4l_dbg(1, client, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1322 saa7115_read(client, 0x1e), saa7115_read(client, 0x1f)); 1307 saa7115_read(client, 0x1e), saa7115_read(client, 0x1f));
1323 1308
1324 return 0; 1309 return 0;
@@ -1326,11 +1311,7 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
1326 1311
1327static int saa7115_probe(struct i2c_adapter *adapter) 1312static int saa7115_probe(struct i2c_adapter *adapter)
1328{ 1313{
1329#ifdef I2C_CLASS_TV_ANALOG
1330 if (adapter->class & I2C_CLASS_TV_ANALOG) 1314 if (adapter->class & I2C_CLASS_TV_ANALOG)
1331#else
1332 if (adapter->id == I2C_HW_B_BT848)
1333#endif
1334 return i2c_probe(adapter, &addr_data, &saa7115_attach); 1315 return i2c_probe(adapter, &addr_data, &saa7115_attach);
1335 return 0; 1316 return 0;
1336} 1317}
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c
index 8008537391b5..f39a7be08588 100644
--- a/drivers/media/video/saa711x.c
+++ b/drivers/media/video/saa711x.c
@@ -567,9 +567,7 @@ static struct i2c_driver i2c_driver_saa711x = {
567 .driver = { 567 .driver = {
568 .name = "saa711x", 568 .name = "saa711x",
569 }, 569 },
570
571 .id = I2C_DRIVERID_SAA711X, 570 .id = I2C_DRIVERID_SAA711X,
572
573 .attach_adapter = saa711x_attach_adapter, 571 .attach_adapter = saa711x_attach_adapter,
574 .detach_client = saa711x_detach_client, 572 .detach_client = saa711x_detach_client,
575 .command = saa711x_command, 573 .command = saa711x_command,
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index bca6ed0e2752..2009c1bc4720 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -66,30 +66,6 @@ module_param(test_image, int, 0644);
66MODULE_PARM_DESC(debug, "debug level (0-2)"); 66MODULE_PARM_DESC(debug, "debug level (0-2)");
67MODULE_PARM_DESC(test_image, "test_image (0-1)"); 67MODULE_PARM_DESC(test_image, "test_image (0-1)");
68 68
69#define saa7127_dbg(fmt, arg...) \
70 do { \
71 if (debug >= 1) \
72 printk(KERN_INFO "%s debug %d-%04x: " fmt, \
73 client->driver->driver.name, \
74 i2c_adapter_id(client->adapter), client->addr , ## arg); \
75 } while (0)
76
77/* High volume debug. Use with care. */
78#define saa7127_dbg_highvol(fmt, arg...) \
79 do { \
80 if (debug == 2) \
81 printk(KERN_INFO "%s debug %d-%04x: " fmt, \
82 client->driver->driver.name, \
83 i2c_adapter_id(client->adapter), client->addr , ## arg); \
84 } while (0)
85
86#define saa7127_err(fmt, arg...) do { \
87 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
88 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
89#define saa7127_info(fmt, arg...) do { \
90 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
91 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
92
93static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; 69static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
94 70
95 71
@@ -336,7 +312,7 @@ static int saa7127_write(struct i2c_client *client, u8 reg, u8 val)
336 if (i2c_smbus_write_byte_data(client, reg, val) == 0) 312 if (i2c_smbus_write_byte_data(client, reg, val) == 0)
337 return 0; 313 return 0;
338 } 314 }
339 saa7127_err("I2C Write Problem\n"); 315 v4l_err(client, "I2C Write Problem\n");
340 return -1; 316 return -1;
341} 317}
342 318
@@ -362,7 +338,7 @@ static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_dat
362 if (enable && (data->field != 0 || data->line != 16)) 338 if (enable && (data->field != 0 || data->line != 16))
363 return -EINVAL; 339 return -EINVAL;
364 if (state->vps_enable != enable) { 340 if (state->vps_enable != enable) {
365 saa7127_dbg("Turn VPS Signal %s\n", enable ? "on" : "off"); 341 v4l_dbg(1, client, "Turn VPS Signal %s\n", enable ? "on" : "off");
366 saa7127_write(client, 0x54, enable << 7); 342 saa7127_write(client, 0x54, enable << 7);
367 state->vps_enable = enable; 343 state->vps_enable = enable;
368 } 344 }
@@ -374,7 +350,7 @@ static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_dat
374 state->vps_data[2] = data->data[11]; 350 state->vps_data[2] = data->data[11];
375 state->vps_data[3] = data->data[12]; 351 state->vps_data[3] = data->data[12];
376 state->vps_data[4] = data->data[13]; 352 state->vps_data[4] = data->data[13];
377 saa7127_dbg("Set VPS data %02x %02x %02x %02x %02x\n", 353 v4l_dbg(1, client, "Set VPS data %02x %02x %02x %02x %02x\n",
378 state->vps_data[0], state->vps_data[1], 354 state->vps_data[0], state->vps_data[1],
379 state->vps_data[2], state->vps_data[3], 355 state->vps_data[2], state->vps_data[3],
380 state->vps_data[4]); 356 state->vps_data[4]);
@@ -397,7 +373,7 @@ static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data
397 if (enable && (data->field != 0 || data->line != 21)) 373 if (enable && (data->field != 0 || data->line != 21))
398 return -EINVAL; 374 return -EINVAL;
399 if (state->cc_enable != enable) { 375 if (state->cc_enable != enable) {
400 saa7127_dbg("Turn CC %s\n", enable ? "on" : "off"); 376 v4l_dbg(1, client, "Turn CC %s\n", enable ? "on" : "off");
401 saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, 377 saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
402 (state->xds_enable << 7) | (enable << 6) | 0x11); 378 (state->xds_enable << 7) | (enable << 6) | 0x11);
403 state->cc_enable = enable; 379 state->cc_enable = enable;
@@ -405,7 +381,7 @@ static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data
405 if (!enable) 381 if (!enable)
406 return 0; 382 return 0;
407 383
408 saa7127_dbg_highvol("CC data: %04x\n", cc); 384 v4l_dbg(2, client, "CC data: %04x\n", cc);
409 saa7127_write(client, SAA7127_REG_LINE_21_ODD_0, cc & 0xff); 385 saa7127_write(client, SAA7127_REG_LINE_21_ODD_0, cc & 0xff);
410 saa7127_write(client, SAA7127_REG_LINE_21_ODD_1, cc >> 8); 386 saa7127_write(client, SAA7127_REG_LINE_21_ODD_1, cc >> 8);
411 state->cc_data = cc; 387 state->cc_data = cc;
@@ -423,7 +399,7 @@ static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_dat
423 if (enable && (data->field != 1 || data->line != 21)) 399 if (enable && (data->field != 1 || data->line != 21))
424 return -EINVAL; 400 return -EINVAL;
425 if (state->xds_enable != enable) { 401 if (state->xds_enable != enable) {
426 saa7127_dbg("Turn XDS %s\n", enable ? "on" : "off"); 402 v4l_dbg(1, client, "Turn XDS %s\n", enable ? "on" : "off");
427 saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, 403 saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
428 (enable << 7) | (state->cc_enable << 6) | 0x11); 404 (enable << 7) | (state->cc_enable << 6) | 0x11);
429 state->xds_enable = enable; 405 state->xds_enable = enable;
@@ -431,7 +407,7 @@ static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_dat
431 if (!enable) 407 if (!enable)
432 return 0; 408 return 0;
433 409
434 saa7127_dbg_highvol("XDS data: %04x\n", xds); 410 v4l_dbg(2, client, "XDS data: %04x\n", xds);
435 saa7127_write(client, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff); 411 saa7127_write(client, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff);
436 saa7127_write(client, SAA7127_REG_LINE_21_EVEN_1, xds >> 8); 412 saa7127_write(client, SAA7127_REG_LINE_21_EVEN_1, xds >> 8);
437 state->xds_data = xds; 413 state->xds_data = xds;
@@ -448,7 +424,7 @@ static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_dat
448 if (enable && (data->field != 0 || data->line != 23)) 424 if (enable && (data->field != 0 || data->line != 23))
449 return -EINVAL; 425 return -EINVAL;
450 if (state->wss_enable != enable) { 426 if (state->wss_enable != enable) {
451 saa7127_dbg("Turn WSS %s\n", enable ? "on" : "off"); 427 v4l_dbg(1, client, "Turn WSS %s\n", enable ? "on" : "off");
452 saa7127_write(client, 0x27, enable << 7); 428 saa7127_write(client, 0x27, enable << 7);
453 state->wss_enable = enable; 429 state->wss_enable = enable;
454 } 430 }
@@ -457,7 +433,7 @@ static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_dat
457 433
458 saa7127_write(client, 0x26, data->data[0]); 434 saa7127_write(client, 0x26, data->data[0]);
459 saa7127_write(client, 0x27, 0x80 | (data->data[1] & 0x3f)); 435 saa7127_write(client, 0x27, 0x80 | (data->data[1] & 0x3f));
460 saa7127_dbg("WSS mode: %s\n", wss_strs[data->data[0] & 0xf]); 436 v4l_dbg(1, client, "WSS mode: %s\n", wss_strs[data->data[0] & 0xf]);
461 state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0]; 437 state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0];
462 return 0; 438 return 0;
463} 439}
@@ -469,11 +445,11 @@ static int saa7127_set_video_enable(struct i2c_client *client, int enable)
469 struct saa7127_state *state = i2c_get_clientdata(client); 445 struct saa7127_state *state = i2c_get_clientdata(client);
470 446
471 if (enable) { 447 if (enable) {
472 saa7127_dbg("Enable Video Output\n"); 448 v4l_dbg(1, client, "Enable Video Output\n");
473 saa7127_write(client, 0x2d, state->reg_2d); 449 saa7127_write(client, 0x2d, state->reg_2d);
474 saa7127_write(client, 0x61, state->reg_61); 450 saa7127_write(client, 0x61, state->reg_61);
475 } else { 451 } else {
476 saa7127_dbg("Disable Video Output\n"); 452 v4l_dbg(1, client, "Disable Video Output\n");
477 saa7127_write(client, 0x2d, (state->reg_2d & 0xf0)); 453 saa7127_write(client, 0x2d, (state->reg_2d & 0xf0));
478 saa7127_write(client, 0x61, (state->reg_61 | 0xc0)); 454 saa7127_write(client, 0x61, (state->reg_61 | 0xc0));
479 } 455 }
@@ -489,11 +465,11 @@ static int saa7127_set_std(struct i2c_client *client, v4l2_std_id std)
489 const struct i2c_reg_value *inittab; 465 const struct i2c_reg_value *inittab;
490 466
491 if (std & V4L2_STD_525_60) { 467 if (std & V4L2_STD_525_60) {
492 saa7127_dbg("Selecting 60 Hz video Standard\n"); 468 v4l_dbg(1, client, "Selecting 60 Hz video Standard\n");
493 inittab = saa7127_init_config_60hz; 469 inittab = saa7127_init_config_60hz;
494 state->reg_61 = SAA7127_60HZ_DAC_CONTROL; 470 state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
495 } else { 471 } else {
496 saa7127_dbg("Selecting 50 Hz video Standard\n"); 472 v4l_dbg(1, client, "Selecting 50 Hz video Standard\n");
497 inittab = saa7127_init_config_50hz; 473 inittab = saa7127_init_config_50hz;
498 state->reg_61 = SAA7127_50HZ_DAC_CONTROL; 474 state->reg_61 = SAA7127_50HZ_DAC_CONTROL;
499 } 475 }
@@ -544,7 +520,7 @@ static int saa7127_set_output_type(struct i2c_client *client, int output)
544 default: 520 default:
545 return -EINVAL; 521 return -EINVAL;
546 } 522 }
547 saa7127_dbg("Selecting %s output type\n", output_strs[output]); 523 v4l_dbg(1, client, "Selecting %s output type\n", output_strs[output]);
548 524
549 /* Configure Encoder */ 525 /* Configure Encoder */
550 saa7127_write(client, 0x2d, state->reg_2d); 526 saa7127_write(client, 0x2d, state->reg_2d);
@@ -561,12 +537,12 @@ static int saa7127_set_input_type(struct i2c_client *client, int input)
561 537
562 switch (input) { 538 switch (input) {
563 case SAA7127_INPUT_TYPE_NORMAL: /* avia */ 539 case SAA7127_INPUT_TYPE_NORMAL: /* avia */
564 saa7127_dbg("Selecting Normal Encoder Input\n"); 540 v4l_dbg(1, client, "Selecting Normal Encoder Input\n");
565 state->reg_3a_cb = 0; 541 state->reg_3a_cb = 0;
566 break; 542 break;
567 543
568 case SAA7127_INPUT_TYPE_TEST_IMAGE: /* color bar */ 544 case SAA7127_INPUT_TYPE_TEST_IMAGE: /* color bar */
569 saa7127_dbg("Selecting Color Bar generator\n"); 545 v4l_dbg(1, client, "Selecting Color Bar generator\n");
570 state->reg_3a_cb = 0x80; 546 state->reg_3a_cb = 0x80;
571 break; 547 break;
572 548
@@ -633,14 +609,14 @@ static int saa7127_command(struct i2c_client *client,
633 break; 609 break;
634 610
635 case VIDIOC_LOG_STATUS: 611 case VIDIOC_LOG_STATUS:
636 saa7127_info("Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz"); 612 v4l_info(client, "Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz");
637 saa7127_info("Input: %s\n", state->input_type ? "color bars" : "normal"); 613 v4l_info(client, "Input: %s\n", state->input_type ? "color bars" : "normal");
638 saa7127_info("Output: %s\n", state->video_enable ? 614 v4l_info(client, "Output: %s\n", state->video_enable ?
639 output_strs[state->output_type] : "disabled"); 615 output_strs[state->output_type] : "disabled");
640 saa7127_info("WSS: %s\n", state->wss_enable ? 616 v4l_info(client, "WSS: %s\n", state->wss_enable ?
641 wss_strs[state->wss_mode] : "disabled"); 617 wss_strs[state->wss_mode] : "disabled");
642 saa7127_info("VPS: %s\n", state->vps_enable ? "enabled" : "disabled"); 618 v4l_info(client, "VPS: %s\n", state->vps_enable ? "enabled" : "disabled");
643 saa7127_info("CC: %s\n", state->cc_enable ? "enabled" : "disabled"); 619 v4l_info(client, "CC: %s\n", state->cc_enable ? "enabled" : "disabled");
644 break; 620 break;
645 621
646#ifdef CONFIG_VIDEO_ADV_DEBUG 622#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -723,7 +699,7 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind)
723 client->driver = &i2c_driver_saa7127; 699 client->driver = &i2c_driver_saa7127;
724 snprintf(client->name, sizeof(client->name) - 1, "saa7127"); 700 snprintf(client->name, sizeof(client->name) - 1, "saa7127");
725 701
726 saa7127_dbg("detecting saa7127 client on address 0x%x\n", address << 1); 702 v4l_dbg(1, client, "detecting saa7127 client on address 0x%x\n", address << 1);
727 703
728 /* First test register 0: Bits 5-7 are a version ID (should be 0), 704 /* First test register 0: Bits 5-7 are a version ID (should be 0),
729 and bit 2 should also be 0. 705 and bit 2 should also be 0.
@@ -732,7 +708,7 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind)
732 0x1d after a reset and not expected to ever change. */ 708 0x1d after a reset and not expected to ever change. */
733 if ((saa7127_read(client, 0) & 0xe4) != 0 || 709 if ((saa7127_read(client, 0) & 0xe4) != 0 ||
734 (saa7127_read(client, 0x29) & 0x3f) != 0x1d) { 710 (saa7127_read(client, 0x29) & 0x3f) != 0x1d) {
735 saa7127_dbg("saa7127 not found\n"); 711 v4l_dbg(1, client, "saa7127 not found\n");
736 kfree(client); 712 kfree(client);
737 return 0; 713 return 0;
738 } 714 }
@@ -748,7 +724,7 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind)
748 724
749 /* Configure Encoder */ 725 /* Configure Encoder */
750 726
751 saa7127_dbg("Configuring encoder\n"); 727 v4l_dbg(1, client, "Configuring encoder\n");
752 saa7127_write_inittab(client, saa7127_init_config_common); 728 saa7127_write_inittab(client, saa7127_init_config_common);
753 saa7127_set_std(client, V4L2_STD_NTSC); 729 saa7127_set_std(client, V4L2_STD_NTSC);
754 saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH); 730 saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH);
@@ -769,12 +745,12 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind)
769 read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2); 745 read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2);
770 saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa); 746 saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa);
771 if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) { 747 if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
772 saa7127_info("saa7129 found @ 0x%x (%s)\n", address << 1, adapter->name); 748 v4l_info(client, "saa7129 found @ 0x%x (%s)\n", address << 1, adapter->name);
773 saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result); 749 saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result);
774 saa7127_write_inittab(client, saa7129_init_config_extra); 750 saa7127_write_inittab(client, saa7129_init_config_extra);
775 state->ident = V4L2_IDENT_SAA7129; 751 state->ident = V4L2_IDENT_SAA7129;
776 } else { 752 } else {
777 saa7127_info("saa7127 found @ 0x%x (%s)\n", address << 1, adapter->name); 753 v4l_info(client, "saa7127 found @ 0x%x (%s)\n", address << 1, adapter->name);
778 state->ident = V4L2_IDENT_SAA7127; 754 state->ident = V4L2_IDENT_SAA7127;
779 } 755 }
780 756
@@ -787,11 +763,7 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind)
787 763
788static int saa7127_probe(struct i2c_adapter *adapter) 764static int saa7127_probe(struct i2c_adapter *adapter)
789{ 765{
790#ifdef I2C_CLASS_TV_ANALOG
791 if (adapter->class & I2C_CLASS_TV_ANALOG) 766 if (adapter->class & I2C_CLASS_TV_ANALOG)
792#else
793 if (adapter->id == I2C_HW_B_BT848)
794#endif
795 return i2c_probe(adapter, &addr_data, saa7127_attach); 767 return i2c_probe(adapter, &addr_data, saa7127_attach);
796 return 0; 768 return 0;
797} 769}
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 4615a982ac64..ad73c4a60f2b 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -9,7 +9,8 @@
9#include <linux/poll.h> 9#include <linux/poll.h>
10#include <linux/i2c.h> 10#include <linux/i2c.h>
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/videodev.h> 12#include <linux/videodev2.h>
13#include <media/v4l2-common.h>
13#include <linux/init.h> 14#include <linux/init.h>
14#include <linux/crc32.h> 15#include <linux/crc32.h>
15 16
@@ -509,7 +510,6 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
509{ 510{
510 struct saa6752hs_state *h; 511 struct saa6752hs_state *h;
511 512
512 printk("saa6752hs: chip found @ 0x%x\n", addr<<1);
513 513
514 if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL))) 514 if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL)))
515 return -ENOMEM; 515 return -ENOMEM;
@@ -525,6 +525,8 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
525 i2c_set_clientdata(&h->client, h); 525 i2c_set_clientdata(&h->client, h);
526 i2c_attach_client(&h->client); 526 i2c_attach_client(&h->client);
527 527
528 v4l_info(&h->client,"saa6752hs: chip found @ 0x%x\n", addr<<1);
529
528 return 0; 530 return 0;
529} 531}
530 532
@@ -598,7 +600,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
598 600
599static struct i2c_driver driver = { 601static struct i2c_driver driver = {
600 .driver = { 602 .driver = {
601 .name = "i2c saa6752hs MPEG encoder", 603 .name = "saa6752hs",
602 }, 604 },
603 .id = I2C_DRIVERID_SAA6752HS, 605 .id = I2C_DRIVERID_SAA6752HS,
604 .attach_adapter = saa6752hs_probe, 606 .attach_adapter = saa6752hs_probe,
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index ade05f75fdb0..a7a6ab9298a9 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -20,13 +20,13 @@
20 * 20 *
21 */ 21 */
22 22
23#include <sound/driver.h>
24#include <linux/init.h> 23#include <linux/init.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
26#include <linux/time.h> 25#include <linux/time.h>
27#include <linux/wait.h> 26#include <linux/wait.h>
28#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
29#include <linux/module.h> 28#include <linux/module.h>
29#include <sound/driver.h>
30#include <sound/core.h> 30#include <sound/core.h>
31#include <sound/control.h> 31#include <sound/control.h>
32#include <sound/pcm.h> 32#include <sound/pcm.h>
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 672fb205959f..77e5be98e4c6 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -25,6 +25,7 @@
25 25
26#include "saa7134-reg.h" 26#include "saa7134-reg.h"
27#include "saa7134.h" 27#include "saa7134.h"
28#include <media/v4l2-common.h>
28 29
29/* commly used strings */ 30/* commly used strings */
30static char name_mute[] = "mute"; 31static char name_mute[] = "mute";
@@ -2555,6 +2556,69 @@ struct saa7134_board saa7134_boards[] = {
2555 .amux = LINE1, 2556 .amux = LINE1,
2556 }, 2557 },
2557 }, 2558 },
2559 [SAA7134_BOARD_CINERGY250PCI] = {
2560 /* remote-control does not work. The signal about a
2561 key press comes in via gpio, but the key code
2562 doesn't. Neither does it have an i2c remote control
2563 interface. */
2564 .name = "Terratec Cinergy 250 PCI TV",
2565 .audio_clock = 0x00187de7,
2566 .tuner_type = TUNER_PHILIPS_TDA8290,
2567 .radio_type = UNSET,
2568 .tuner_addr = ADDR_UNSET,
2569 .radio_addr = ADDR_UNSET,
2570 .gpiomask = 0x80200000,
2571 .inputs = {{
2572 .name = name_tv,
2573 .vmux = 1,
2574 .amux = TV,
2575 .tv = 1,
2576 },{
2577 .name = name_svideo, /* NOT tested */
2578 .vmux = 8,
2579 .amux = LINE1,
2580 }},
2581 .radio = {
2582 .name = name_radio,
2583 .amux = LINE1,
2584 .gpio = 0x0200000,
2585 },
2586 },
2587 [SAA7134_BOARD_FLYDVB_TRIO] = {
2588 /* LifeView LR319 FlyDVB Trio */
2589 /* Peter Missel <peter.missel@onlinehome.de> */
2590 .name = "LifeView FlyDVB Trio",
2591 .audio_clock = 0x00200000,
2592 .tuner_type = TUNER_PHILIPS_TDA8290,
2593 .radio_type = UNSET,
2594 .tuner_addr = ADDR_UNSET,
2595 .radio_addr = ADDR_UNSET,
2596 .gpiomask = 0x00200000,
2597 .inputs = {{
2598 .name = name_tv, /* Analog broadcast/cable TV */
2599 .vmux = 1,
2600 .amux = TV,
2601 .gpio = 0x200000, /* GPIO21=High for TV input */
2602 .tv = 1,
2603 },{
2604 .name = name_svideo, /* S-Video signal on S-Video input */
2605 .vmux = 8,
2606 .amux = LINE2,
2607 },{
2608 .name = name_comp1, /* Composite signal on S-Video input */
2609 .vmux = 0,
2610 .amux = LINE2,
2611 },{
2612 .name = name_comp2, /* Composite input */
2613 .vmux = 3,
2614 .amux = LINE2,
2615 }},
2616 .radio = {
2617 .name = name_radio,
2618 .amux = TV,
2619 .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */
2620 },
2621 },
2558}; 2622};
2559 2623
2560const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); 2624const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -2895,6 +2959,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
2895 .vendor = PCI_VENDOR_ID_PHILIPS, 2959 .vendor = PCI_VENDOR_ID_PHILIPS,
2896 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 2960 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2897 .subvendor = 0x1421, 2961 .subvendor = 0x1421,
2962 .subdevice = 0x0351, /* PCI version, new revision */
2963 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
2964 },{
2965 .vendor = PCI_VENDOR_ID_PHILIPS,
2966 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2967 .subvendor = 0x1421,
2898 .subdevice = 0x0370, /* cardbus version */ 2968 .subdevice = 0x0370, /* cardbus version */
2899 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, 2969 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
2900 },{ 2970 },{
@@ -3002,6 +3072,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
3002 .subdevice = 0x6231, 3072 .subdevice = 0x6231,
3003 .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS, 3073 .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS,
3004 },{ 3074 },{
3075 .vendor = PCI_VENDOR_ID_PHILIPS,
3076 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
3077 .subvendor = 0x153b,
3078 .subdevice = 0x1160,
3079 .driver_data = SAA7134_BOARD_CINERGY250PCI,
3080 },{
3081 .vendor = PCI_VENDOR_ID_PHILIPS,
3082 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA 7131E */
3083 .subvendor = 0x5168,
3084 .subdevice = 0x0319,
3085 .driver_data = SAA7134_BOARD_FLYDVB_TRIO,
3086 },{
3005 /* --- boards without eeprom + subsystem ID --- */ 3087 /* --- boards without eeprom + subsystem ID --- */
3006 .vendor = PCI_VENDOR_ID_PHILIPS, 3088 .vendor = PCI_VENDOR_ID_PHILIPS,
3007 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 3089 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -3090,6 +3172,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
3090 case SAA7134_BOARD_AVERMEDIA_GO_007_FM: 3172 case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
3091/* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ 3173/* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */
3092 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 3174 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
3175 case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
3093 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: 3176 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
3094 case SAA7134_BOARD_VIDEOMATE_DVBT_300: 3177 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
3095 case SAA7134_BOARD_VIDEOMATE_DVBT_200: 3178 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 23d8747338ed..accbc32725cf 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -95,77 +95,6 @@ int (*dmasound_exit)(struct saa7134_dev *dev);
95#define dprintk(fmt, arg...) if (core_debug) \ 95#define dprintk(fmt, arg...) if (core_debug) \
96 printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg) 96 printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg)
97 97
98/* ------------------------------------------------------------------ */
99/* debug help functions */
100
101static const char *v4l1_ioctls[] = {
102 "0", "GCAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
103 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
104 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
105 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
106 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
107#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
108
109static const char *v4l2_ioctls[] = {
110 "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
111 "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
112 "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
113 "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
114 "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
115 "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
116 "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
117 "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
118 "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
119 "S_MODULATOR"
120};
121#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
122
123static const char *osspcm_ioctls[] = {
124 "RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT",
125 "CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS",
126 "GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER",
127 "GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO",
128 "SETDUPLEX", "GETODELAY"
129};
130#define OSSPCM_IOCTLS ARRAY_SIZE(v4l2_ioctls)
131
132void saa7134_print_ioctl(char *name, unsigned int cmd)
133{
134 char *dir;
135
136 switch (_IOC_DIR(cmd)) {
137 case _IOC_NONE: dir = "--"; break;
138 case _IOC_READ: dir = "r-"; break;
139 case _IOC_WRITE: dir = "-w"; break;
140 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
141 default: dir = "??"; break;
142 }
143 switch (_IOC_TYPE(cmd)) {
144 case 'v':
145 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
146 name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
147 v4l1_ioctls[_IOC_NR(cmd)] : "???");
148 break;
149 case 'V':
150 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
151 name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
152 v4l2_ioctls[_IOC_NR(cmd)] : "???");
153 break;
154 case 'P':
155 printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n",
156 name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ?
157 osspcm_ioctls[_IOC_NR(cmd)] : "???");
158 break;
159 case 'M':
160 printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n",
161 name, cmd, dir, _IOC_NR(cmd));
162 break;
163 default:
164 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
165 name, cmd, dir, _IOC_NR(cmd));
166 }
167}
168
169void saa7134_track_gpio(struct saa7134_dev *dev, char *msg) 98void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
170{ 99{
171 unsigned long mode,status; 100 unsigned long mode,status;
@@ -211,7 +140,7 @@ static int pending_call(struct notifier_block *self, unsigned long state,
211 return NOTIFY_DONE; 140 return NOTIFY_DONE;
212} 141}
213 142
214static int pending_registered; 143static int pending_registered=0;
215static struct notifier_block pending_notifier = { 144static struct notifier_block pending_notifier = {
216 .notifier_call = pending_call, 145 .notifier_call = pending_call,
217}; 146};
@@ -610,11 +539,38 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
610 card_has_mpeg(dev)) 539 card_has_mpeg(dev))
611 saa7134_irq_ts_done(dev,status); 540 saa7134_irq_ts_done(dev,status);
612 541
613 if ((report & (SAA7134_IRQ_REPORT_GPIO16 | 542 if (report & SAA7134_IRQ_REPORT_GPIO16) {
614 SAA7134_IRQ_REPORT_GPIO18)) && 543 switch (dev->has_remote) {
615 dev->remote) 544 case SAA7134_REMOTE_GPIO:
616 saa7134_input_irq(dev); 545 if (dev->remote->mask_keydown & 0x10000) {
546 saa7134_input_irq(dev);
547 }
548 break;
549
550 case SAA7134_REMOTE_I2C:
551 break; /* FIXME: invoke I2C get_key() */
617 552
553 default: /* GPIO16 not used by IR remote */
554 break;
555 }
556 }
557
558 if (report & SAA7134_IRQ_REPORT_GPIO18) {
559 switch (dev->has_remote) {
560 case SAA7134_REMOTE_GPIO:
561 if ((dev->remote->mask_keydown & 0x40000) ||
562 (dev->remote->mask_keyup & 0x40000)) {
563 saa7134_input_irq(dev);
564 }
565 break;
566
567 case SAA7134_REMOTE_I2C:
568 break; /* FIXME: invoke I2C get_key() */
569
570 default: /* GPIO18 not used by IR remote */
571 break;
572 }
573 }
618 } 574 }
619 575
620 if (10 == loop) { 576 if (10 == loop) {
@@ -624,13 +580,16 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
624 printk(KERN_WARNING "%s/irq: looping -- " 580 printk(KERN_WARNING "%s/irq: looping -- "
625 "clearing PE (parity error!) enable bit\n",dev->name); 581 "clearing PE (parity error!) enable bit\n",dev->name);
626 saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE); 582 saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE);
627 } else if (report & (SAA7134_IRQ_REPORT_GPIO16 | 583 } else if (report & SAA7134_IRQ_REPORT_GPIO16) {
628 SAA7134_IRQ_REPORT_GPIO18)) { 584 /* disable gpio16 IRQ */
629 /* disable gpio IRQs */
630 printk(KERN_WARNING "%s/irq: looping -- " 585 printk(KERN_WARNING "%s/irq: looping -- "
631 "clearing GPIO enable bits\n",dev->name); 586 "clearing GPIO16 enable bit\n",dev->name);
632 saa_clearl(SAA7134_IRQ2, (SAA7134_IRQ2_INTE_GPIO16 | 587 saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO16);
633 SAA7134_IRQ2_INTE_GPIO18)); 588 } else if (report & SAA7134_IRQ_REPORT_GPIO18) {
589 /* disable gpio18 IRQs */
590 printk(KERN_WARNING "%s/irq: looping -- "
591 "clearing GPIO18 enable bit\n",dev->name);
592 saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18);
634 } else { 593 } else {
635 /* disable all irqs */ 594 /* disable all irqs */
636 printk(KERN_WARNING "%s/irq: looping -- " 595 printk(KERN_WARNING "%s/irq: looping -- "
@@ -711,10 +670,14 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
711 SAA7134_IRQ2_INTE_PE | 670 SAA7134_IRQ2_INTE_PE |
712 SAA7134_IRQ2_INTE_AR; 671 SAA7134_IRQ2_INTE_AR;
713 672
714 if (dev->has_remote == SAA7134_REMOTE_GPIO) 673 if (dev->has_remote == SAA7134_REMOTE_GPIO) {
715 irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 | 674 if (dev->remote->mask_keydown & 0x10000)
716 SAA7134_IRQ2_INTE_GPIO18A | 675 irq2_mask |= SAA7134_IRQ2_INTE_GPIO16;
717 SAA7134_IRQ2_INTE_GPIO16 ); 676 else if (dev->remote->mask_keydown & 0x40000)
677 irq2_mask |= SAA7134_IRQ2_INTE_GPIO18;
678 else if (dev->remote->mask_keyup & 0x40000)
679 irq2_mask |= SAA7134_IRQ2_INTE_GPIO18A;
680 }
718 681
719 saa_writel(SAA7134_IRQ1, 0); 682 saa_writel(SAA7134_IRQ1, 0);
720 saa_writel(SAA7134_IRQ2, irq2_mask); 683 saa_writel(SAA7134_IRQ2, irq2_mask);
@@ -1156,7 +1119,7 @@ static int saa7134_init(void)
1156 printk(KERN_INFO "saa7130/34: snapshot date %04d-%02d-%02d\n", 1119 printk(KERN_INFO "saa7130/34: snapshot date %04d-%02d-%02d\n",
1157 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); 1120 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1158#endif 1121#endif
1159 return pci_module_init(&saa7134_pci_driver); 1122 return pci_register_driver(&saa7134_pci_driver);
1160} 1123}
1161 1124
1162static void saa7134_fini(void) 1125static void saa7134_fini(void)
@@ -1173,7 +1136,6 @@ module_exit(saa7134_fini);
1173 1136
1174/* ----------------------------------------------------------- */ 1137/* ----------------------------------------------------------- */
1175 1138
1176EXPORT_SYMBOL(saa7134_print_ioctl);
1177EXPORT_SYMBOL(saa7134_i2c_call_clients); 1139EXPORT_SYMBOL(saa7134_i2c_call_clients);
1178EXPORT_SYMBOL(saa7134_devlist); 1140EXPORT_SYMBOL(saa7134_devlist);
1179EXPORT_SYMBOL(saa7134_boards); 1141EXPORT_SYMBOL(saa7134_boards);
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index e016480c3468..399f9952596c 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -31,6 +31,7 @@
31 31
32#include "saa7134-reg.h" 32#include "saa7134-reg.h"
33#include "saa7134.h" 33#include "saa7134.h"
34#include <media/v4l2-common.h>
34 35
35#ifdef HAVE_MT352 36#ifdef HAVE_MT352
36# include "mt352.h" 37# include "mt352.h"
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 575f3e835f91..bd4c389d4c37 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -29,6 +29,7 @@
29#include "saa7134.h" 29#include "saa7134.h"
30 30
31#include <media/saa6752hs.h> 31#include <media/saa6752hs.h>
32#include <media/v4l2-common.h>
32 33
33/* ------------------------------------------------------------------ */ 34/* ------------------------------------------------------------------ */
34 35
@@ -163,7 +164,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
163 struct saa7134_dev *dev = file->private_data; 164 struct saa7134_dev *dev = file->private_data;
164 165
165 if (debug > 1) 166 if (debug > 1)
166 saa7134_print_ioctl(dev->name,cmd); 167 v4l_print_ioctl(dev->name,cmd);
167 switch (cmd) { 168 switch (cmd) {
168 case VIDIOC_QUERYCAP: 169 case VIDIOC_QUERYCAP:
169 { 170 {
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 1792d03d621d..6162550c4136 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -30,6 +30,7 @@
30 30
31#include "saa7134-reg.h" 31#include "saa7134-reg.h"
32#include "saa7134.h" 32#include "saa7134.h"
33#include <media/v4l2-common.h>
33 34
34/* ----------------------------------------------------------- */ 35/* ----------------------------------------------------------- */
35 36
@@ -390,9 +391,7 @@ static struct i2c_algorithm saa7134_algo = {
390 391
391static struct i2c_adapter saa7134_adap_template = { 392static struct i2c_adapter saa7134_adap_template = {
392 .owner = THIS_MODULE, 393 .owner = THIS_MODULE,
393#ifdef I2C_CLASS_TV_ANALOG
394 .class = I2C_CLASS_TV_ANALOG, 394 .class = I2C_CLASS_TV_ANALOG,
395#endif
396 .name = "saa7134", 395 .name = "saa7134",
397 .id = I2C_HW_SAA7134, 396 .id = I2C_HW_SAA7134,
398 .algo = &saa7134_algo, 397 .algo = &saa7134_algo,
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index ab75ca5ac356..82d28cbf289f 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -56,23 +56,23 @@ static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = {
56 [ 12 ] = KEY_KP8, 56 [ 12 ] = KEY_KP8,
57 [ 13 ] = KEY_KP9, 57 [ 13 ] = KEY_KP9,
58 58
59 [ 14 ] = KEY_TUNER, // Air/Cable 59 [ 14 ] = KEY_MODE, // Air/Cable
60 [ 17 ] = KEY_VIDEO, // Video 60 [ 17 ] = KEY_VIDEO, // Video
61 [ 21 ] = KEY_AUDIO, // Audio 61 [ 21 ] = KEY_AUDIO, // Audio
62 [ 0 ] = KEY_POWER, // Pover 62 [ 0 ] = KEY_POWER, // Power
63 [ 24 ] = KEY_TUNER, // AV Source
63 [ 2 ] = KEY_ZOOM, // Fullscreen 64 [ 2 ] = KEY_ZOOM, // Fullscreen
65 [ 26 ] = KEY_LANGUAGE, // Stereo
64 [ 27 ] = KEY_MUTE, // Mute 66 [ 27 ] = KEY_MUTE, // Mute
65 [ 20 ] = KEY_VOLUMEUP, 67 [ 20 ] = KEY_VOLUMEUP, // Volume +
66 [ 23 ] = KEY_VOLUMEDOWN, 68 [ 23 ] = KEY_VOLUMEDOWN, // Volume -
67 [ 18 ] = KEY_CHANNELUP, // Channel + 69 [ 18 ] = KEY_CHANNELUP, // Channel +
68 [ 19 ] = KEY_CHANNELDOWN, // Channel - 70 [ 19 ] = KEY_CHANNELDOWN, // Channel -
69 [ 6 ] = KEY_AGAIN, // Recal 71 [ 6 ] = KEY_AGAIN, // Recall
70 [ 16 ] = KEY_KPENTER, // Enter 72 [ 16 ] = KEY_ENTER, // Enter
71
72 [ 26 ] = KEY_F22, // Stereo
73 [ 24 ] = KEY_EDIT, // AV Source
74}; 73};
75 74
75
76static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = { 76static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
77 [ 0 ] = KEY_KP0, 77 [ 0 ] = KEY_KP0,
78 [ 1 ] = KEY_KP1, 78 [ 1 ] = KEY_KP1,
@@ -543,12 +543,22 @@ static int build_key(struct saa7134_dev *dev)
543 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n", 543 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
544 gpio, ir->mask_keycode, data); 544 gpio, ir->mask_keycode, data);
545 545
546 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || 546 if (ir->polling) {
547 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { 547 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
548 ir_input_keydown(ir->dev, &ir->ir, data, data); 548 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
549 } else { 549 ir_input_keydown(ir->dev, &ir->ir, data, data);
550 ir_input_nokey(ir->dev, &ir->ir); 550 } else {
551 ir_input_nokey(ir->dev, &ir->ir);
552 }
553 }
554 else { /* IRQ driven mode - handle key press and release in one go */
555 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
556 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
557 ir_input_keydown(ir->dev, &ir->ir, data, data);
558 ir_input_nokey(ir->dev, &ir->ir);
559 }
551 } 560 }
561
552 return 0; 562 return 0;
553} 563}
554 564
@@ -686,6 +696,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
686 polling = 50; // ms 696 polling = 50; // ms
687 break; 697 break;
688 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 698 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
699 case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
689 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: 700 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
690 ir_codes = videomate_tv_pvr_codes; 701 ir_codes = videomate_tv_pvr_codes;
691 mask_keycode = 0x00003F; 702 mask_keycode = 0x00003F;
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index 8badd2a9cb2f..7448e386a804 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -373,6 +373,42 @@ static ssize_t dsp_write(struct file *file, const char __user *buffer,
373 return -EINVAL; 373 return -EINVAL;
374} 374}
375 375
376static const char *osspcm_ioctls[] = {
377 "RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT",
378 "CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS",
379 "GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER",
380 "GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO",
381 "SETDUPLEX", "GETODELAY"
382};
383#define OSSPCM_IOCTLS ARRAY_SIZE(osspcm_ioctls)
384
385static void saa7134_oss_print_ioctl(char *name, unsigned int cmd)
386{
387 char *dir;
388
389 switch (_IOC_DIR(cmd)) {
390 case _IOC_NONE: dir = "--"; break;
391 case _IOC_READ: dir = "r-"; break;
392 case _IOC_WRITE: dir = "-w"; break;
393 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
394 default: dir = "??"; break;
395 }
396 switch (_IOC_TYPE(cmd)) {
397 case 'P':
398 printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n",
399 name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ?
400 osspcm_ioctls[_IOC_NR(cmd)] : "???");
401 break;
402 case 'M':
403 printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n",
404 name, cmd, dir, _IOC_NR(cmd));
405 break;
406 default:
407 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
408 name, cmd, dir, _IOC_NR(cmd));
409 }
410}
411
376static int dsp_ioctl(struct inode *inode, struct file *file, 412static int dsp_ioctl(struct inode *inode, struct file *file,
377 unsigned int cmd, unsigned long arg) 413 unsigned int cmd, unsigned long arg)
378{ 414{
@@ -382,7 +418,7 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
382 int val = 0; 418 int val = 0;
383 419
384 if (debug > 1) 420 if (debug > 1)
385 saa7134_print_ioctl(dev->name,cmd); 421 saa7134_oss_print_ioctl(dev->name,cmd);
386 switch (cmd) { 422 switch (cmd) {
387 case OSS_GETVERSION: 423 case OSS_GETVERSION:
388 return put_user(SOUND_VERSION, p); 424 return put_user(SOUND_VERSION, p);
@@ -678,7 +714,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
678 int __user *p = argp; 714 int __user *p = argp;
679 715
680 if (debug > 1) 716 if (debug > 1)
681 saa7134_print_ioctl(dev->name,cmd); 717 saa7134_oss_print_ioctl(dev->name,cmd);
682 switch (cmd) { 718 switch (cmd) {
683 case OSS_GETVERSION: 719 case OSS_GETVERSION:
684 return put_user(SOUND_VERSION, p); 720 return put_user(SOUND_VERSION, p);
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 45c852df13ed..adfa8fe49a11 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -29,6 +29,7 @@
29 29
30#include "saa7134-reg.h" 30#include "saa7134-reg.h"
31#include "saa7134.h" 31#include "saa7134.h"
32#include <media/v4l2-common.h>
32 33
33/* Include V4L1 specific functions. Should be removed soon */ 34/* Include V4L1 specific functions. Should be removed soon */
34#include <linux/videodev.h> 35#include <linux/videodev.h>
@@ -1689,7 +1690,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1689 int err; 1690 int err;
1690 1691
1691 if (video_debug > 1) 1692 if (video_debug > 1)
1692 saa7134_print_ioctl(dev->name,cmd); 1693 v4l_print_ioctl(dev->name,cmd);
1693 1694
1694 switch (cmd) { 1695 switch (cmd) {
1695 case VIDIOC_S_CTRL: 1696 case VIDIOC_S_CTRL:
@@ -2142,7 +2143,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
2142 struct saa7134_dev *dev = fh->dev; 2143 struct saa7134_dev *dev = fh->dev;
2143 2144
2144 if (video_debug > 1) 2145 if (video_debug > 1)
2145 saa7134_print_ioctl(dev->name,cmd); 2146 v4l_print_ioctl(dev->name,cmd);
2146 switch (cmd) { 2147 switch (cmd) {
2147 case VIDIOC_QUERYCAP: 2148 case VIDIOC_QUERYCAP:
2148 { 2149 {
@@ -2262,6 +2263,7 @@ static struct file_operations video_fops =
2262 .poll = video_poll, 2263 .poll = video_poll,
2263 .mmap = video_mmap, 2264 .mmap = video_mmap,
2264 .ioctl = video_ioctl, 2265 .ioctl = video_ioctl,
2266 .compat_ioctl = v4l_compat_ioctl32,
2265 .llseek = no_llseek, 2267 .llseek = no_llseek,
2266}; 2268};
2267 2269
@@ -2271,6 +2273,7 @@ static struct file_operations radio_fops =
2271 .open = video_open, 2273 .open = video_open,
2272 .release = video_release, 2274 .release = video_release,
2273 .ioctl = radio_ioctl, 2275 .ioctl = radio_ioctl,
2276 .compat_ioctl = v4l_compat_ioctl32,
2274 .llseek = no_llseek, 2277 .llseek = no_llseek,
2275}; 2278};
2276 2279
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index add49db1ad41..e70eae8d29bb 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -37,6 +37,9 @@
37#include <media/ir-common.h> 37#include <media/ir-common.h>
38#include <media/ir-kbd-i2c.h> 38#include <media/ir-kbd-i2c.h>
39#include <media/video-buf.h> 39#include <media/video-buf.h>
40#include <sound/driver.h>
41#include <sound/core.h>
42#include <sound/pcm.h>
40#include <media/video-buf-dvb.h> 43#include <media/video-buf-dvb.h>
41 44
42#ifndef TRUE 45#ifndef TRUE
@@ -47,10 +50,6 @@
47#endif 50#endif
48#define UNSET (-1U) 51#define UNSET (-1U)
49 52
50#include <sound/driver.h>
51#include <sound/core.h>
52#include <sound/pcm.h>
53
54/* ----------------------------------------------------------- */ 53/* ----------------------------------------------------------- */
55/* enums */ 54/* enums */
56 55
@@ -209,6 +208,8 @@ struct saa7134_format {
209#define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80 208#define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80
210#define SAA7134_BOARD_PHILIPS_TIGER 81 209#define SAA7134_BOARD_PHILIPS_TIGER 81
211#define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS 82 210#define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS 82
211#define SAA7134_BOARD_CINERGY250PCI 83
212#define SAA7134_BOARD_FLYDVB_TRIO 84
212 213
213#define SAA7134_MAXBOARDS 8 214#define SAA7134_MAXBOARDS 8
214#define SAA7134_INPUT_MAX 8 215#define SAA7134_INPUT_MAX 8
@@ -546,7 +547,6 @@ struct saa7134_dev {
546 547
547extern struct list_head saa7134_devlist; 548extern struct list_head saa7134_devlist;
548 549
549void saa7134_print_ioctl(char *name, unsigned int cmd);
550void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); 550void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
551 551
552#define SAA7134_PGTABLE_SIZE 4096 552#define SAA7134_PGTABLE_SIZE 4096
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
index d4497dbae05c..6ee54a45411f 100644
--- a/drivers/media/video/stradis.c
+++ b/drivers/media/video/stradis.c
@@ -1974,6 +1974,7 @@ static struct file_operations saa_fops =
1974 .open = saa_open, 1974 .open = saa_open,
1975 .release = saa_release, 1975 .release = saa_release,
1976 .ioctl = saa_ioctl, 1976 .ioctl = saa_ioctl,
1977 .compat_ioctl = v4l_compat_ioctl32,
1977 .read = saa_read, 1978 .read = saa_read,
1978 .llseek = no_llseek, 1979 .llseek = no_llseek,
1979 .write = saa_write, 1980 .write = saa_write,
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 549c9929f107..99261f15e66e 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -50,6 +50,7 @@
50 50
51#include "bttv.h" 51#include "bttv.h"
52#include <media/audiochip.h> 52#include <media/audiochip.h>
53#include <media/v4l2-common.h>
53 54
54#ifndef VIDEO_AUDIO_BALANCE 55#ifndef VIDEO_AUDIO_BALANCE
55# define VIDEO_AUDIO_BALANCE 32 56# define VIDEO_AUDIO_BALANCE 32
@@ -90,9 +91,6 @@ struct tda7432 {
90static struct i2c_driver driver; 91static struct i2c_driver driver;
91static struct i2c_client client_template; 92static struct i2c_client client_template;
92 93
93#define dprintk if (debug) printk
94#define d2printk if (debug > 1) printk
95
96/* The TDA7432 is made by STS-Thompson 94/* The TDA7432 is made by STS-Thompson
97 * http://www.st.com 95 * http://www.st.com
98 * http://us.st.com/stonline/books/pdf/docs/4056.pdf 96 * http://us.st.com/stonline/books/pdf/docs/4056.pdf
@@ -229,12 +227,12 @@ static struct i2c_client client_template;
229static int tda7432_write(struct i2c_client *client, int subaddr, int val) 227static int tda7432_write(struct i2c_client *client, int subaddr, int val)
230{ 228{
231 unsigned char buffer[2]; 229 unsigned char buffer[2];
232 d2printk("tda7432: In tda7432_write\n"); 230 v4l_dbg(2,client,"In tda7432_write\n");
233 dprintk("tda7432: Writing %d 0x%x\n", subaddr, val); 231 v4l_dbg(1,client,"Writing %d 0x%x\n", subaddr, val);
234 buffer[0] = subaddr; 232 buffer[0] = subaddr;
235 buffer[1] = val; 233 buffer[1] = val;
236 if (2 != i2c_master_send(client,buffer,2)) { 234 if (2 != i2c_master_send(client,buffer,2)) {
237 printk(KERN_WARNING "tda7432: I/O error, trying (write %d 0x%x)\n", 235 v4l_err(client,"I/O error, trying (write %d 0x%x)\n",
238 subaddr, val); 236 subaddr, val);
239 return -1; 237 return -1;
240 } 238 }
@@ -247,9 +245,9 @@ static int tda7432_set(struct i2c_client *client)
247{ 245{
248 struct tda7432 *t = i2c_get_clientdata(client); 246 struct tda7432 *t = i2c_get_clientdata(client);
249 unsigned char buf[16]; 247 unsigned char buf[16];
250 d2printk("tda7432: In tda7432_set\n"); 248 v4l_dbg(2,client,"In tda7432_set\n");
251 249
252 dprintk(KERN_INFO 250 v4l_dbg(1,client,
253 "tda7432: 7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n", 251 "tda7432: 7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n",
254 t->input,t->volume,t->bass,t->treble,t->lf,t->lr,t->rf,t->rr,t->loud); 252 t->input,t->volume,t->bass,t->treble,t->lf,t->lr,t->rf,t->rr,t->loud);
255 buf[0] = TDA7432_IN; 253 buf[0] = TDA7432_IN;
@@ -263,7 +261,7 @@ static int tda7432_set(struct i2c_client *client)
263 buf[8] = t->rr; 261 buf[8] = t->rr;
264 buf[9] = t->loud; 262 buf[9] = t->loud;
265 if (10 != i2c_master_send(client,buf,10)) { 263 if (10 != i2c_master_send(client,buf,10)) {
266 printk(KERN_WARNING "tda7432: I/O error, trying tda7432_set\n"); 264 v4l_err(client,"I/O error, trying tda7432_set\n");
267 return -1; 265 return -1;
268 } 266 }
269 267
@@ -273,7 +271,7 @@ static int tda7432_set(struct i2c_client *client)
273static void do_tda7432_init(struct i2c_client *client) 271static void do_tda7432_init(struct i2c_client *client)
274{ 272{
275 struct tda7432 *t = i2c_get_clientdata(client); 273 struct tda7432 *t = i2c_get_clientdata(client);
276 d2printk("tda7432: In tda7432_init\n"); 274 v4l_dbg(2,client,"In tda7432_init\n");
277 275
278 t->input = TDA7432_STEREO_IN | /* Main (stereo) input */ 276 t->input = TDA7432_STEREO_IN | /* Main (stereo) input */
279 TDA7432_BASS_SYM | /* Symmetric bass cut */ 277 TDA7432_BASS_SYM | /* Symmetric bass cut */
@@ -301,7 +299,6 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind)
301{ 299{
302 struct tda7432 *t; 300 struct tda7432 *t;
303 struct i2c_client *client; 301 struct i2c_client *client;
304 d2printk("tda7432: In tda7432_attach\n");
305 302
306 t = kmalloc(sizeof *t,GFP_KERNEL); 303 t = kmalloc(sizeof *t,GFP_KERNEL);
307 if (!t) 304 if (!t)
@@ -315,21 +312,16 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind)
315 i2c_set_clientdata(client, t); 312 i2c_set_clientdata(client, t);
316 313
317 do_tda7432_init(client); 314 do_tda7432_init(client);
318 printk(KERN_INFO "tda7432: init\n");
319
320 i2c_attach_client(client); 315 i2c_attach_client(client);
316
317 v4l_info(client, "chip found @ 0x%x (%s)\n", addr << 1, adap->name);
321 return 0; 318 return 0;
322} 319}
323 320
324static int tda7432_probe(struct i2c_adapter *adap) 321static int tda7432_probe(struct i2c_adapter *adap)
325{ 322{
326#ifdef I2C_CLASS_TV_ANALOG
327 if (adap->class & I2C_CLASS_TV_ANALOG) 323 if (adap->class & I2C_CLASS_TV_ANALOG)
328 return i2c_probe(adap, &addr_data, tda7432_attach); 324 return i2c_probe(adap, &addr_data, tda7432_attach);
329#else
330 if (adap->id == I2C_HW_B_BT848)
331 return i2c_probe(adap, &addr_data, tda7432_attach);
332#endif
333 return 0; 325 return 0;
334} 326}
335 327
@@ -348,7 +340,9 @@ static int tda7432_command(struct i2c_client *client,
348 unsigned int cmd, void *arg) 340 unsigned int cmd, void *arg)
349{ 341{
350 struct tda7432 *t = i2c_get_clientdata(client); 342 struct tda7432 *t = i2c_get_clientdata(client);
351 d2printk("tda7432: In tda7432_command\n"); 343 v4l_dbg(2,client,"In tda7432_command\n");
344 if (debug>1)
345 v4l_i2c_print_ioctl(client,cmd);
352 346
353 switch (cmd) { 347 switch (cmd) {
354 /* --- v4l ioctls --- */ 348 /* --- v4l ioctls --- */
@@ -359,7 +353,6 @@ static int tda7432_command(struct i2c_client *client,
359 case VIDIOCGAUDIO: 353 case VIDIOCGAUDIO:
360 { 354 {
361 struct video_audio *va = arg; 355 struct video_audio *va = arg;
362 dprintk("tda7432: VIDIOCGAUDIO\n");
363 356
364 va->flags |= VIDEO_AUDIO_VOLUME | 357 va->flags |= VIDEO_AUDIO_VOLUME |
365 VIDEO_AUDIO_BASS | 358 VIDEO_AUDIO_BASS |
@@ -414,7 +407,6 @@ static int tda7432_command(struct i2c_client *client,
414 case VIDIOCSAUDIO: 407 case VIDIOCSAUDIO:
415 { 408 {
416 struct video_audio *va = arg; 409 struct video_audio *va = arg;
417 dprintk("tda7432: VIDEOCSAUDIO\n");
418 410
419 if(va->flags & VIDEO_AUDIO_VOLUME){ 411 if(va->flags & VIDEO_AUDIO_VOLUME){
420 if(!maxvol){ /* max +20db */ 412 if(!maxvol){ /* max +20db */
@@ -490,11 +482,6 @@ static int tda7432_command(struct i2c_client *client,
490 482
491 } /* end of VIDEOCSAUDIO case */ 483 } /* end of VIDEOCSAUDIO case */
492 484
493 default: /* Not VIDEOCGAUDIO or VIDEOCSAUDIO */
494
495 /* nothing */
496 d2printk("tda7432: Default\n");
497
498 } /* end of (cmd) switch */ 485 } /* end of (cmd) switch */
499 486
500 return 0; 487 return 0;
@@ -502,7 +489,7 @@ static int tda7432_command(struct i2c_client *client,
502 489
503static struct i2c_driver driver = { 490static struct i2c_driver driver = {
504 .driver = { 491 .driver = {
505 .name = "i2c tda7432 driver", 492 .name = "tda7432",
506 }, 493 },
507 .id = I2C_DRIVERID_TDA7432, 494 .id = I2C_DRIVERID_TDA7432,
508 .attach_adapter = tda7432_probe, 495 .attach_adapter = tda7432_probe,
@@ -519,7 +506,7 @@ static struct i2c_client client_template =
519static int __init tda7432_init(void) 506static int __init tda7432_init(void)
520{ 507{
521 if ( (loudness < 0) || (loudness > 15) ) { 508 if ( (loudness < 0) || (loudness > 15) ) {
522 printk(KERN_ERR "tda7432: loudness parameter must be between 0 and 15\n"); 509 printk(KERN_ERR "loudness parameter must be between 0 and 15\n");
523 return -EINVAL; 510 return -EINVAL;
524 } 511 }
525 512
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index 61d94ddaff41..2498b76df429 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -398,14 +398,8 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
398 return 0; 398 return 0;
399} 399}
400 400
401
402/*---------------------------------------------------------------------*/ 401/*---------------------------------------------------------------------*/
403 402
404#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
405#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
406#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
407#define V4L2_STD_DK (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK)
408
409static void set_audio(struct tuner *t) 403static void set_audio(struct tuner *t)
410{ 404{
411 char* mode; 405 char* mode;
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 9c3ecf7a0fed..299393bf900a 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -257,13 +257,8 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind)
257 257
258static int tda9875_probe(struct i2c_adapter *adap) 258static int tda9875_probe(struct i2c_adapter *adap)
259{ 259{
260#ifdef I2C_CLASS_TV_ANALOG
261 if (adap->class & I2C_CLASS_TV_ANALOG) 260 if (adap->class & I2C_CLASS_TV_ANALOG)
262 return i2c_probe(adap, &addr_data, tda9875_attach); 261 return i2c_probe(adap, &addr_data, tda9875_attach);
263#else
264 if (adap->id == I2C_HW_B_BT848)
265 return i2c_probe(adap, &addr_data, tda9875_attach);
266#endif
267 return 0; 262 return 0;
268} 263}
269 264
@@ -373,7 +368,7 @@ static int tda9875_command(struct i2c_client *client,
373 368
374static struct i2c_driver driver = { 369static struct i2c_driver driver = {
375 .driver = { 370 .driver = {
376 .name = "i2c tda9875 driver", 371 .name = "tda9875",
377 }, 372 },
378 .id = I2C_DRIVERID_TDA9875, 373 .id = I2C_DRIVERID_TDA9875,
379 .attach_adapter = tda9875_probe, 374 .attach_adapter = tda9875_probe,
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 7165a1b9625a..9cf47dc65579 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -9,7 +9,7 @@
9#include <linux/slab.h> 9#include <linux/slab.h>
10#include <linux/delay.h> 10#include <linux/delay.h>
11 11
12#include <media/audiochip.h> 12#include <media/v4l2-common.h>
13#include <media/tuner.h> 13#include <media/tuner.h>
14 14
15 15
@@ -57,7 +57,6 @@ struct tda9887 {
57 v4l2_std_id std; 57 v4l2_std_id std;
58 enum tuner_mode mode; 58 enum tuner_mode mode;
59 unsigned int config; 59 unsigned int config;
60 unsigned int pinnacle_id;
61 unsigned int using_v4l2; 60 unsigned int using_v4l2;
62 unsigned int radio_mode; 61 unsigned int radio_mode;
63 unsigned char data[4]; 62 unsigned char data[4];
@@ -115,6 +114,9 @@ static struct i2c_client client_template;
115#define cAudioGain0 0x00 // bit c7 114#define cAudioGain0 0x00 // bit c7
116#define cAudioGain6 0x80 // bit c7 115#define cAudioGain6 0x80 // bit c7
117 116
117#define cTopMask 0x1f // bit c0:4
118#define cTopPalSecamDefault 0x14 // bit c0:4
119#define cTopNtscRadioDefault 0x10 // bit c0:4
118 120
119//// third reg (e) 121//// third reg (e)
120#define cAudioIF_4_5 0x00 // bit e0:1 122#define cAudioIF_4_5 0x00 // bit e0:1
@@ -146,13 +148,15 @@ static struct i2c_client client_template;
146 148
147static struct tvnorm tvnorms[] = { 149static struct tvnorm tvnorms[] = {
148 { 150 {
149 .std = V4L2_STD_PAL_BG, 151 .std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N,
150 .name = "PAL-BG", 152 .name = "PAL-BGHN",
151 .b = ( cNegativeFmTV | 153 .b = ( cNegativeFmTV |
152 cQSS ), 154 cQSS ),
153 .c = ( cDeemphasisON | 155 .c = ( cDeemphasisON |
154 cDeemphasis50 ), 156 cDeemphasis50 |
155 .e = ( cAudioIF_5_5 | 157 cTopPalSecamDefault),
158 .e = ( cGating_36 |
159 cAudioIF_5_5 |
156 cVideoIF_38_90 ), 160 cVideoIF_38_90 ),
157 },{ 161 },{
158 .std = V4L2_STD_PAL_I, 162 .std = V4L2_STD_PAL_I,
@@ -160,8 +164,10 @@ static struct tvnorm tvnorms[] = {
160 .b = ( cNegativeFmTV | 164 .b = ( cNegativeFmTV |
161 cQSS ), 165 cQSS ),
162 .c = ( cDeemphasisON | 166 .c = ( cDeemphasisON |
163 cDeemphasis50 ), 167 cDeemphasis50 |
164 .e = ( cAudioIF_6_0 | 168 cTopPalSecamDefault),
169 .e = ( cGating_36 |
170 cAudioIF_6_0 |
165 cVideoIF_38_90 ), 171 cVideoIF_38_90 ),
166 },{ 172 },{
167 .std = V4L2_STD_PAL_DK, 173 .std = V4L2_STD_PAL_DK,
@@ -169,52 +175,80 @@ static struct tvnorm tvnorms[] = {
169 .b = ( cNegativeFmTV | 175 .b = ( cNegativeFmTV |
170 cQSS ), 176 cQSS ),
171 .c = ( cDeemphasisON | 177 .c = ( cDeemphasisON |
172 cDeemphasis50 ), 178 cDeemphasis50 |
173 .e = ( cAudioIF_6_5 | 179 cTopPalSecamDefault),
174 cVideoIF_38_00 ), 180 .e = ( cGating_36 |
181 cAudioIF_6_5 |
182 cVideoIF_38_90 ),
175 },{ 183 },{
176 .std = V4L2_STD_PAL_M | V4L2_STD_PAL_N, 184 .std = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc,
177 .name = "PAL-M/N", 185 .name = "PAL-M/Nc",
178 .b = ( cNegativeFmTV | 186 .b = ( cNegativeFmTV |
179 cQSS ), 187 cQSS ),
180 .c = ( cDeemphasisON | 188 .c = ( cDeemphasisON |
181 cDeemphasis75 ), 189 cDeemphasis75 |
182 .e = ( cAudioIF_4_5 | 190 cTopNtscRadioDefault),
191 .e = ( cGating_36 |
192 cAudioIF_4_5 |
183 cVideoIF_45_75 ), 193 cVideoIF_45_75 ),
184 },{ 194 },{
195 .std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,
196 .name = "SECAM-BGH",
197 .b = ( cPositiveAmTV |
198 cQSS ),
199 .c = ( cTopPalSecamDefault),
200 .e = ( cGating_36 |
201 cAudioIF_5_5 |
202 cVideoIF_38_90 ),
203 },{
185 .std = V4L2_STD_SECAM_L, 204 .std = V4L2_STD_SECAM_L,
186 .name = "SECAM-L", 205 .name = "SECAM-L",
187 .b = ( cPositiveAmTV | 206 .b = ( cPositiveAmTV |
188 cQSS ), 207 cQSS ),
208 .c = ( cTopPalSecamDefault),
189 .e = ( cGating_36 | 209 .e = ( cGating_36 |
190 cAudioIF_6_5 | 210 cAudioIF_6_5 |
191 cVideoIF_38_90 ), 211 cVideoIF_38_90 ),
192 },{ 212 },{
213 .std = V4L2_STD_SECAM_LC,
214 .name = "SECAM-L'",
215 .b = ( cOutputPort2Inactive |
216 cPositiveAmTV |
217 cQSS ),
218 .c = ( cTopPalSecamDefault),
219 .e = ( cGating_36 |
220 cAudioIF_6_5 |
221 cVideoIF_33_90 ),
222 },{
193 .std = V4L2_STD_SECAM_DK, 223 .std = V4L2_STD_SECAM_DK,
194 .name = "SECAM-DK", 224 .name = "SECAM-DK",
195 .b = ( cNegativeFmTV | 225 .b = ( cNegativeFmTV |
196 cQSS ), 226 cQSS ),
197 .c = ( cDeemphasisON | 227 .c = ( cDeemphasisON |
198 cDeemphasis50 ), 228 cDeemphasis50 |
199 .e = ( cAudioIF_6_5 | 229 cTopPalSecamDefault),
200 cVideoIF_38_00 ), 230 .e = ( cGating_36 |
231 cAudioIF_6_5 |
232 cVideoIF_38_90 ),
201 },{ 233 },{
202 .std = V4L2_STD_NTSC_M, 234 .std = V4L2_STD_NTSC_M,
203 .name = "NTSC-M", 235 .name = "NTSC-M",
204 .b = ( cNegativeFmTV | 236 .b = ( cNegativeFmTV |
205 cQSS ), 237 cQSS ),
206 .c = ( cDeemphasisON | 238 .c = ( cDeemphasisON |
207 cDeemphasis75 ), 239 cDeemphasis75 |
240 cTopNtscRadioDefault),
208 .e = ( cGating_36 | 241 .e = ( cGating_36 |
209 cAudioIF_4_5 | 242 cAudioIF_4_5 |
210 cVideoIF_45_75 ), 243 cVideoIF_45_75 ),
211 },{ 244 },{
212 .std = V4L2_STD_NTSC_M_JP, 245 .std = V4L2_STD_NTSC_M_JP,
213 .name = "NTSC-JP", 246 .name = "NTSC-M-JP",
214 .b = ( cNegativeFmTV | 247 .b = ( cNegativeFmTV |
215 cQSS ), 248 cQSS ),
216 .c = ( cDeemphasisON | 249 .c = ( cDeemphasisON |
217 cDeemphasis50 ), 250 cDeemphasis50 |
251 cTopNtscRadioDefault),
218 .e = ( cGating_36 | 252 .e = ( cGating_36 |
219 cAudioIF_4_5 | 253 cAudioIF_4_5 |
220 cVideoIF_58_75 ), 254 cVideoIF_58_75 ),
@@ -226,8 +260,10 @@ static struct tvnorm radio_stereo = {
226 .b = ( cFmRadio | 260 .b = ( cFmRadio |
227 cQSS ), 261 cQSS ),
228 .c = ( cDeemphasisOFF | 262 .c = ( cDeemphasisOFF |
229 cAudioGain6 ), 263 cAudioGain6 |
230 .e = ( cAudioIF_5_5 | 264 cTopNtscRadioDefault),
265 .e = ( cTunerGainLow |
266 cAudioIF_5_5 |
231 cRadioIF_38_90 ), 267 cRadioIF_38_90 ),
232}; 268};
233 269
@@ -236,8 +272,10 @@ static struct tvnorm radio_mono = {
236 .b = ( cFmRadio | 272 .b = ( cFmRadio |
237 cQSS ), 273 cQSS ),
238 .c = ( cDeemphasisON | 274 .c = ( cDeemphasisON |
239 cDeemphasis50), 275 cDeemphasis75 |
240 .e = ( cAudioIF_5_5 | 276 cTopNtscRadioDefault),
277 .e = ( cTunerGainLow |
278 cAudioIF_5_5 |
241 cRadioIF_38_90 ), 279 cRadioIF_38_90 ),
242}; 280};
243 281
@@ -400,7 +438,8 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
400static unsigned int port1 = UNSET; 438static unsigned int port1 = UNSET;
401static unsigned int port2 = UNSET; 439static unsigned int port2 = UNSET;
402static unsigned int qss = UNSET; 440static unsigned int qss = UNSET;
403static unsigned int adjust = 0x10; 441static unsigned int adjust = UNSET;
442
404module_param(port1, int, 0644); 443module_param(port1, int, 0644);
405module_param(port2, int, 0644); 444module_param(port2, int, 0644);
406module_param(qss, int, 0644); 445module_param(qss, int, 0644);
@@ -428,8 +467,10 @@ static int tda9887_set_insmod(struct tda9887 *t, char *buf)
428 buf[1] &= ~cQSS; 467 buf[1] &= ~cQSS;
429 } 468 }
430 469
431 if (adjust >= 0x00 && adjust < 0x20) 470 if (adjust >= 0x00 && adjust < 0x20) {
471 buf[2] &= ~cTopMask;
432 buf[2] |= adjust; 472 buf[2] |= adjust;
473 }
433 return 0; 474 return 0;
434} 475}
435 476
@@ -465,6 +506,10 @@ static int tda9887_set_config(struct tda9887 *t, char *buf)
465 break; 506 break;
466 } 507 }
467 } 508 }
509 if (t->config & TDA9887_TOP_SET) {
510 buf[2] &= ~cTopMask;
511 buf[2] |= (t->config >> 8) & cTopMask;
512 }
468 if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC)) 513 if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
469 buf[1] &= ~cQSS; 514 buf[1] &= ~cQSS;
470 return 0; 515 return 0;
@@ -472,38 +517,13 @@ static int tda9887_set_config(struct tda9887 *t, char *buf)
472 517
473/* ---------------------------------------------------------------------- */ 518/* ---------------------------------------------------------------------- */
474 519
475static int tda9887_set_pinnacle(struct tda9887 *t, char *buf) 520static char pal[] = "--";
476{ 521static char secam[] = "--";
477 unsigned int bCarrierMode = UNSET; 522static char ntsc[] = "-";
478
479 if (t->std & V4L2_STD_625_50) {
480 if ((1 == t->pinnacle_id) || (7 == t->pinnacle_id)) {
481 bCarrierMode = cIntercarrier;
482 } else {
483 bCarrierMode = cQSS;
484 }
485 }
486 if (t->std & V4L2_STD_525_60) {
487 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {
488 bCarrierMode = cIntercarrier;
489 } else {
490 bCarrierMode = cQSS;
491 }
492 }
493
494 if (bCarrierMode != UNSET) {
495 buf[1] &= ~0x04;
496 buf[1] |= bCarrierMode;
497 }
498 return 0;
499}
500
501/* ---------------------------------------------------------------------- */
502 523
503static char pal[] = "-";
504module_param_string(pal, pal, sizeof(pal), 0644); 524module_param_string(pal, pal, sizeof(pal), 0644);
505static char secam[] = "-";
506module_param_string(secam, secam, sizeof(secam), 0644); 525module_param_string(secam, secam, sizeof(secam), 0644);
526module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
507 527
508static int tda9887_fixup_std(struct tda9887 *t) 528static int tda9887_fixup_std(struct tda9887 *t)
509{ 529{
@@ -514,8 +534,17 @@ static int tda9887_fixup_std(struct tda9887 *t)
514 case 'B': 534 case 'B':
515 case 'g': 535 case 'g':
516 case 'G': 536 case 'G':
517 tda9887_dbg("insmod fixup: PAL => PAL-BG\n"); 537 case 'h':
518 t->std = V4L2_STD_PAL_BG; 538 case 'H':
539 case 'n':
540 case 'N':
541 if (pal[1] == 'c' || pal[1] == 'C') {
542 tda9887_dbg("insmod fixup: PAL => PAL-Nc\n");
543 t->std = V4L2_STD_PAL_Nc;
544 } else {
545 tda9887_dbg("insmod fixup: PAL => PAL-BGHN\n");
546 t->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N;
547 }
519 break; 548 break;
520 case 'i': 549 case 'i':
521 case 'I': 550 case 'I':
@@ -529,6 +558,11 @@ static int tda9887_fixup_std(struct tda9887 *t)
529 tda9887_dbg("insmod fixup: PAL => PAL-DK\n"); 558 tda9887_dbg("insmod fixup: PAL => PAL-DK\n");
530 t->std = V4L2_STD_PAL_DK; 559 t->std = V4L2_STD_PAL_DK;
531 break; 560 break;
561 case 'm':
562 case 'M':
563 tda9887_dbg("insmod fixup: PAL => PAL-M\n");
564 t->std = V4L2_STD_PAL_M;
565 break;
532 case '-': 566 case '-':
533 /* default parameter, do nothing */ 567 /* default parameter, do nothing */
534 break; 568 break;
@@ -539,6 +573,15 @@ static int tda9887_fixup_std(struct tda9887 *t)
539 } 573 }
540 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { 574 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
541 switch (secam[0]) { 575 switch (secam[0]) {
576 case 'b':
577 case 'B':
578 case 'g':
579 case 'G':
580 case 'h':
581 case 'H':
582 tda9887_dbg("insmod fixup: SECAM => SECAM-BGH\n");
583 t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
584 break;
542 case 'd': 585 case 'd':
543 case 'D': 586 case 'D':
544 case 'k': 587 case 'k':
@@ -548,8 +591,13 @@ static int tda9887_fixup_std(struct tda9887 *t)
548 break; 591 break;
549 case 'l': 592 case 'l':
550 case 'L': 593 case 'L':
551 tda9887_dbg("insmod fixup: SECAM => SECAM-L\n"); 594 if (secam[1] == 'c' || secam[1] == 'C') {
552 t->std = V4L2_STD_SECAM_L; 595 tda9887_dbg("insmod fixup: SECAM => SECAM-L'\n");
596 t->std = V4L2_STD_SECAM_LC;
597 } else {
598 tda9887_dbg("insmod fixup: SECAM => SECAM-L\n");
599 t->std = V4L2_STD_SECAM_L;
600 }
553 break; 601 break;
554 case '-': 602 case '-':
555 /* default parameter, do nothing */ 603 /* default parameter, do nothing */
@@ -559,6 +607,26 @@ static int tda9887_fixup_std(struct tda9887 *t)
559 break; 607 break;
560 } 608 }
561 } 609 }
610 if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
611 switch (ntsc[0]) {
612 case 'm':
613 case 'M':
614 tda9887_dbg("insmod fixup: NTSC => NTSC-M\n");
615 t->std = V4L2_STD_NTSC_M;
616 break;
617 case 'j':
618 case 'J':
619 tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
620 t->std = V4L2_STD_NTSC_M_JP;
621 break;
622 case '-':
623 /* default parameter, do nothing */
624 break;
625 default:
626 tda9887_info("ntsc= argument not recognised\n");
627 break;
628 }
629 }
562 return 0; 630 return 0;
563} 631}
564 632
@@ -581,12 +649,22 @@ static int tda9887_configure(struct tda9887 *t)
581 memset(t->data,0,sizeof(t->data)); 649 memset(t->data,0,sizeof(t->data));
582 tda9887_set_tvnorm(t,t->data); 650 tda9887_set_tvnorm(t,t->data);
583 651
652 /* A note on the port settings:
653 These settings tend to depend on the specifics of the board.
654 By default they are set to inactive (bit value 1) by this driver,
655 overwriting any changes made by the tvnorm. This means that it
656 is the responsibility of the module using the tda9887 to set
657 these values in case of changes in the tvnorm.
658 In many cases port 2 should be made active (0) when selecting
659 SECAM-L, and port 2 should remain inactive (1) for SECAM-L'.
660
661 For the other standards the tda9887 application note says that
662 the ports should be set to active (0), but, again, that may
663 differ depending on the precise hardware configuration.
664 */
584 t->data[1] |= cOutputPort1Inactive; 665 t->data[1] |= cOutputPort1Inactive;
585 t->data[1] |= cOutputPort2Inactive; 666 t->data[1] |= cOutputPort2Inactive;
586 667
587 if (UNSET != t->pinnacle_id) {
588 tda9887_set_pinnacle(t,t->data);
589 }
590 tda9887_set_config(t,t->data); 668 tda9887_set_config(t,t->data);
591 tda9887_set_insmod(t,t->data); 669 tda9887_set_insmod(t,t->data);
592 670
@@ -594,7 +672,6 @@ static int tda9887_configure(struct tda9887 *t)
594 t->data[1] |= cForcedMuteAudioON; 672 t->data[1] |= cForcedMuteAudioON;
595 } 673 }
596 674
597
598 tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", 675 tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
599 t->data[1],t->data[2],t->data[3]); 676 t->data[1],t->data[2],t->data[3]);
600 if (debug > 1) 677 if (debug > 1)
@@ -625,7 +702,6 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
625 702
626 t->client = client_template; 703 t->client = client_template;
627 t->std = 0; 704 t->std = 0;
628 t->pinnacle_id = UNSET;
629 t->radio_mode = V4L2_TUNER_MODE_STEREO; 705 t->radio_mode = V4L2_TUNER_MODE_STEREO;
630 706
631 tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name); 707 tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name);
@@ -638,18 +714,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
638 714
639static int tda9887_probe(struct i2c_adapter *adap) 715static int tda9887_probe(struct i2c_adapter *adap)
640{ 716{
641#ifdef I2C_CLASS_TV_ANALOG
642 if (adap->class & I2C_CLASS_TV_ANALOG) 717 if (adap->class & I2C_CLASS_TV_ANALOG)
643 return i2c_probe(adap, &addr_data, tda9887_attach); 718 return i2c_probe(adap, &addr_data, tda9887_attach);
644#else
645 switch (adap->id) {
646 case I2C_HW_B_BT848:
647 case I2C_HW_B_RIVA:
648 case I2C_HW_SAA7134:
649 return i2c_probe(adap, &addr_data, tda9887_attach);
650 break;
651 }
652#endif
653 return 0; 719 return 0;
654} 720}
655 721
@@ -689,14 +755,6 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
689 tda9887_configure(t); 755 tda9887_configure(t);
690 break; 756 break;
691 } 757 }
692 case AUDC_CONFIG_PINNACLE:
693 {
694 int *i = arg;
695
696 t->pinnacle_id = *i;
697 tda9887_configure(t);
698 break;
699 }
700 case TDA9887_SET_CONFIG: 758 case TDA9887_SET_CONFIG:
701 { 759 {
702 int *i = arg; 760 int *i = arg;
@@ -787,7 +845,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
787 } 845 }
788 case VIDIOC_LOG_STATUS: 846 case VIDIOC_LOG_STATUS:
789 { 847 {
790 tda9887_info("Data bytes: b=%02x c=%02x e=%02x\n", t->data[1], t->data[2], t->data[3]); 848 tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->data[1], t->data[2], t->data[3]);
791 break; 849 break;
792 } 850 }
793 default: 851 default:
@@ -824,7 +882,7 @@ static struct i2c_driver driver = {
824 .detach_client = tda9887_detach, 882 .detach_client = tda9887_detach,
825 .command = tda9887_command, 883 .command = tda9887_command,
826 .driver = { 884 .driver = {
827 .name = "i2c tda9887 driver", 885 .name = "tda9887",
828 .suspend = tda9887_suspend, 886 .suspend = tda9887_suspend,
829 .resume = tda9887_resume, 887 .resume = tda9887_resume,
830 }, 888 },
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
index a9375ef05de1..261b7a3c0417 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/video/tea5767.c
@@ -17,6 +17,9 @@
17 17
18#define PREFIX "TEA5767 " 18#define PREFIX "TEA5767 "
19 19
20/* from tuner-core.c */
21extern int debug;
22
20/*****************************************************************************/ 23/*****************************************************************************/
21 24
22/****************************** 25/******************************
@@ -246,7 +249,7 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq)
246 if (5 != (rc = i2c_master_send(c, buffer, 5))) 249 if (5 != (rc = i2c_master_send(c, buffer, 5)))
247 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); 250 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
248 251
249 if (tuner_debug) { 252 if (debug) {
250 if (5 != (rc = i2c_master_recv(c, buffer, 5))) 253 if (5 != (rc = i2c_master_recv(c, buffer, 5)))
251 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); 254 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
252 else 255 else
@@ -264,7 +267,7 @@ static int tea5767_signal(struct i2c_client *c)
264 if (5 != (rc = i2c_master_recv(c, buffer, 5))) 267 if (5 != (rc = i2c_master_recv(c, buffer, 5)))
265 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); 268 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
266 269
267 return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << (13 - 4)); 270 return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8);
268} 271}
269 272
270static int tea5767_stereo(struct i2c_client *c) 273static int tea5767_stereo(struct i2c_client *c)
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index c13c7b95ef35..57bc585a6955 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -20,10 +20,9 @@
20#include <linux/init.h> 20#include <linux/init.h>
21 21
22#include <media/tuner.h> 22#include <media/tuner.h>
23#include <media/v4l2-common.h>
23#include <media/audiochip.h> 24#include <media/audiochip.h>
24 25
25#include "msp3400.h"
26
27#define UNSET (-1U) 26#define UNSET (-1U)
28 27
29/* standard i2c insmod options */ 28/* standard i2c insmod options */
@@ -38,21 +37,30 @@ I2C_CLIENT_INSMOD;
38 37
39/* insmod options used at init time => read/only */ 38/* insmod options used at init time => read/only */
40static unsigned int addr = 0; 39static unsigned int addr = 0;
41module_param(addr, int, 0444);
42
43static unsigned int no_autodetect = 0; 40static unsigned int no_autodetect = 0;
44module_param(no_autodetect, int, 0444);
45
46static unsigned int show_i2c = 0; 41static unsigned int show_i2c = 0;
47module_param(show_i2c, int, 0444);
48 42
49/* insmod options used at runtime => read/write */ 43/* insmod options used at runtime => read/write */
50unsigned int tuner_debug = 0; 44static unsigned int tuner_debug = 0;
51module_param(tuner_debug, int, 0644); 45int debug = 0;
52 46
53static unsigned int tv_range[2] = { 44, 958 }; 47static unsigned int tv_range[2] = { 44, 958 };
54static unsigned int radio_range[2] = { 65, 108 }; 48static unsigned int radio_range[2] = { 65, 108 };
55 49
50static char pal[] = "--";
51static char secam[] = "--";
52static char ntsc[] = "-";
53
54module_param(addr, int, 0444);
55module_param(no_autodetect, int, 0444);
56module_param(show_i2c, int, 0444);
57/* Note: tuner_debug is deprecated and will be removed in 2.6.17 */
58module_param(tuner_debug, int, 0444);
59module_param(debug, int, 0644);
60
61module_param_string(pal, pal, sizeof(pal), 0644);
62module_param_string(secam, secam, sizeof(secam), 0644);
63module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
56module_param_array(tv_range, int, NULL, 0644); 64module_param_array(tv_range, int, NULL, 0644);
57module_param_array(radio_range, int, NULL, 0644); 65module_param_array(radio_range, int, NULL, 0644);
58 66
@@ -249,11 +257,6 @@ static inline int check_mode(struct tuner *t, char *cmd)
249 return 0; 257 return 0;
250} 258}
251 259
252static char pal[] = "-";
253module_param_string(pal, pal, sizeof(pal), 0644);
254static char secam[] = "--";
255module_param_string(secam, secam, sizeof(secam), 0644);
256
257/* get more precise norm info from insmod option */ 260/* get more precise norm info from insmod option */
258static int tuner_fixup_std(struct tuner *t) 261static int tuner_fixup_std(struct tuner *t)
259{ 262{
@@ -285,8 +288,13 @@ static int tuner_fixup_std(struct tuner *t)
285 break; 288 break;
286 case 'N': 289 case 'N':
287 case 'n': 290 case 'n':
288 tuner_dbg ("insmod fixup: PAL => PAL-N\n"); 291 if (pal[1] == 'c' || pal[1] == 'C') {
289 t->std = V4L2_STD_PAL_N; 292 tuner_dbg("insmod fixup: PAL => PAL-Nc\n");
293 t->std = V4L2_STD_PAL_Nc;
294 } else {
295 tuner_dbg ("insmod fixup: PAL => PAL-N\n");
296 t->std = V4L2_STD_PAL_N;
297 }
290 break; 298 break;
291 case '-': 299 case '-':
292 /* default parameter, do nothing */ 300 /* default parameter, do nothing */
@@ -298,6 +306,15 @@ static int tuner_fixup_std(struct tuner *t)
298 } 306 }
299 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { 307 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
300 switch (secam[0]) { 308 switch (secam[0]) {
309 case 'b':
310 case 'B':
311 case 'g':
312 case 'G':
313 case 'h':
314 case 'H':
315 tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n");
316 t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
317 break;
301 case 'd': 318 case 'd':
302 case 'D': 319 case 'D':
303 case 'k': 320 case 'k':
@@ -324,9 +341,60 @@ static int tuner_fixup_std(struct tuner *t)
324 } 341 }
325 } 342 }
326 343
344 if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
345 switch (ntsc[0]) {
346 case 'm':
347 case 'M':
348 tuner_dbg("insmod fixup: NTSC => NTSC-M\n");
349 t->std = V4L2_STD_NTSC_M;
350 break;
351 case 'j':
352 case 'J':
353 tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
354 t->std = V4L2_STD_NTSC_M_JP;
355 break;
356 case '-':
357 /* default parameter, do nothing */
358 break;
359 default:
360 tuner_info("ntsc= argument not recognised\n");
361 break;
362 }
363 }
327 return 0; 364 return 0;
328} 365}
329 366
367static void tuner_status(struct i2c_client *client)
368{
369 struct tuner *t = i2c_get_clientdata(client);
370 unsigned long freq, freq_fraction;
371 const char *p;
372
373 switch (t->mode) {
374 case V4L2_TUNER_RADIO: p = "radio"; break;
375 case V4L2_TUNER_ANALOG_TV: p = "analog TV"; break;
376 case V4L2_TUNER_DIGITAL_TV: p = "digital TV"; break;
377 default: p = "undefined"; break;
378 }
379 if (t->mode == V4L2_TUNER_RADIO) {
380 freq = t->freq / 16000;
381 freq_fraction = (t->freq % 16000) * 100 / 16000;
382 } else {
383 freq = t->freq / 16;
384 freq_fraction = (t->freq % 16) * 100 / 16;
385 }
386 tuner_info("Tuner mode: %s\n", p);
387 tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction);
388 tuner_info("Standard: 0x%08llx\n", t->std);
389 if (t->mode == V4L2_TUNER_RADIO) {
390 if (t->has_signal) {
391 tuner_info("Signal strength: %d\n", t->has_signal(client));
392 }
393 if (t->is_stereo) {
394 tuner_info("Stereo: %s\n", t->is_stereo(client) ? "yes" : "no");
395 }
396 }
397}
330/* ---------------------------------------------------------------------- */ 398/* ---------------------------------------------------------------------- */
331 399
332/* static var Used only in tuner_attach and tuner_probe */ 400/* static var Used only in tuner_attach and tuner_probe */
@@ -352,6 +420,11 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
352 t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ 420 t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */
353 t->audmode = V4L2_TUNER_MODE_STEREO; 421 t->audmode = V4L2_TUNER_MODE_STEREO;
354 t->mode_mask = T_UNINITIALIZED; 422 t->mode_mask = T_UNINITIALIZED;
423 if (tuner_debug) {
424 debug = tuner_debug;
425 printk(KERN_ERR "tuner: tuner_debug is deprecated and will be removed in 2.6.17.\n");
426 printk(KERN_ERR "tuner: use the debug option instead.\n");
427 }
355 428
356 if (show_i2c) { 429 if (show_i2c) {
357 unsigned char buffer[16]; 430 unsigned char buffer[16];
@@ -478,7 +551,9 @@ static inline int check_v4l2(struct tuner *t)
478static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) 551static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
479{ 552{
480 struct tuner *t = i2c_get_clientdata(client); 553 struct tuner *t = i2c_get_clientdata(client);
481 unsigned int *iarg = (int *)arg; 554
555 if (debug>1)
556 v4l_i2c_print_ioctl(&(t->i2c),cmd);
482 557
483 switch (cmd) { 558 switch (cmd) {
484 /* --- configuration --- */ 559 /* --- configuration --- */
@@ -501,18 +576,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
501 t->standby (client); 576 t->standby (client);
502 break; 577 break;
503 } 578 }
504 case AUDC_CONFIG_PINNACLE:
505 switch (*iarg) {
506 case 2:
507 tuner_dbg("pinnacle pal\n");
508 t->radio_if2 = 33300 * 1000;
509 break;
510 case 3:
511 tuner_dbg("pinnacle ntsc\n");
512 t->radio_if2 = 41300 * 1000;
513 break;
514 }
515 break;
516 case VIDIOCSAUDIO: 579 case VIDIOCSAUDIO:
517 if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) 580 if (check_mode(t, "VIDIOCSAUDIO") == EINVAL)
518 return 0; 581 return 0;
@@ -523,9 +586,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
523 tuner_dbg("VIDIOCSAUDIO not implemented.\n"); 586 tuner_dbg("VIDIOCSAUDIO not implemented.\n");
524 587
525 break; 588 break;
526 case MSP_SET_MATRIX:
527 case TDA9887_SET_CONFIG:
528 break;
529 /* --- v4l ioctls --- */ 589 /* --- v4l ioctls --- */
530 /* take care: bttv does userspace copying, we'll get a 590 /* take care: bttv does userspace copying, we'll get a
531 kernel pointer here... */ 591 kernel pointer here... */
@@ -708,10 +768,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
708 } 768 }
709 break; 769 break;
710 } 770 }
711 default: 771 case VIDIOC_LOG_STATUS:
712 tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp='%c',nr=%d,sz=%d)\n", 772 tuner_status(client);
713 cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd),
714 _IOC_NR(cmd), _IOC_SIZE(cmd));
715 break; 773 break;
716 } 774 }
717 775
@@ -747,10 +805,10 @@ static struct i2c_driver driver = {
747 .detach_client = tuner_detach, 805 .detach_client = tuner_detach,
748 .command = tuner_command, 806 .command = tuner_command,
749 .driver = { 807 .driver = {
750 .name = "tuner", 808 .name = "tuner",
751 .suspend = tuner_suspend, 809 .suspend = tuner_suspend,
752 .resume = tuner_resume, 810 .resume = tuner_resume,
753 }, 811 },
754}; 812};
755static struct i2c_client client_template = { 813static struct i2c_client client_template = {
756 .name = "(tuner unset)", 814 .name = "(tuner unset)",
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index e0c9fdb9914a..e5fb74365836 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -8,6 +8,10 @@
8#include <linux/videodev.h> 8#include <linux/videodev.h>
9#include <media/tuner.h> 9#include <media/tuner.h>
10 10
11static int offset = 0;
12module_param(offset, int, 0666);
13MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner");
14
11/* ---------------------------------------------------------------------- */ 15/* ---------------------------------------------------------------------- */
12 16
13/* tv standard selection for Temic 4046 FM5 17/* tv standard selection for Temic 4046 FM5
@@ -75,24 +79,20 @@
75#define TUNER_PLL_LOCKED 0x40 79#define TUNER_PLL_LOCKED 0x40
76#define TUNER_STEREO_MK3 0x04 80#define TUNER_STEREO_MK3 0x04
77 81
82#define TUNER_MAX_RANGES 3
83
78/* ---------------------------------------------------------------------- */ 84/* ---------------------------------------------------------------------- */
79 85
80struct tunertype 86struct tunertype
81{ 87{
82 char *name; 88 char *name;
83 unsigned char Vendor; 89
84 unsigned char Type; 90 int count;
85 91 struct {
86 unsigned short thresh1; /* band switch VHF_LO <=> VHF_HI */ 92 unsigned short thresh;
87 unsigned short thresh2; /* band switch VHF_HI <=> UHF */ 93 unsigned char cb;
88 unsigned char VHF_L; 94 } ranges[TUNER_MAX_RANGES];
89 unsigned char VHF_H;
90 unsigned char UHF;
91 unsigned char config; 95 unsigned char config;
92 unsigned short IFPCoff; /* 622.4=16*38.90 MHz PAL,
93 732 =16*45.75 NTSCi,
94 940 =16*58.75 NTSC-Japan
95 704 =16*44 ATSC */
96}; 96};
97 97
98/* 98/*
@@ -102,158 +102,696 @@ struct tunertype
102 */ 102 */
103static struct tunertype tuners[] = { 103static struct tunertype tuners[] = {
104 /* 0-9 */ 104 /* 0-9 */
105 { "Temic PAL (4002 FH5)", TEMIC, PAL, 105 [TUNER_TEMIC_PAL] = { /* TEMIC PAL */
106 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623}, 106 .name = "Temic PAL (4002 FH5)",
107 { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I, 107 .count = 3,
108 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, 108 .ranges = {
109 { "Philips NTSC (FI1236,FM1236 and compatibles)", Philips, NTSC, 109 { 16 * 140.25 /*MHz*/, 0x02, },
110 16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,732}, 110 { 16 * 463.25 /*MHz*/, 0x04, },
111 { "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", Philips, SECAM, 111 { 16 * 999.99 , 0x01, },
112 16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,623}, 112 },
113 { "NoTuner", NoTuner, NOTUNER, 113 .config = 0x8e,
114 0,0,0x00,0x00,0x00,0x00,0x00}, 114 },
115 { "Philips PAL_BG (FI1216 and compatibles)", Philips, PAL, 115 [TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */
116 16*168.25,16*447.25,0xA0,0x90,0x30,0x8e,623}, 116 .name = "Philips PAL_I (FI1246 and compatibles)",
117 { "Temic NTSC (4032 FY5)", TEMIC, NTSC, 117 .count = 3,
118 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732}, 118 .ranges = {
119 { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I, 119 { 16 * 140.25 /*MHz*/, 0xa0, },
120 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623}, 120 { 16 * 463.25 /*MHz*/, 0x90, },
121 { "Temic NTSC (4036 FY5)", TEMIC, NTSC, 121 { 16 * 999.99 , 0x30, },
122 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732}, 122 },
123 { "Alps HSBH1", TEMIC, NTSC, 123 .config = 0x8e,
124 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, 124 },
125 [TUNER_PHILIPS_NTSC] = { /* Philips NTSC */
126 .name = "Philips NTSC (FI1236,FM1236 and compatibles)",
127 .count = 3,
128 .ranges = {
129 { 16 * 157.25 /*MHz*/, 0xa0, },
130 { 16 * 451.25 /*MHz*/, 0x90, },
131 { 16 * 999.99 , 0x30, },
132 },
133 .config = 0x8e,
134 },
135 [TUNER_PHILIPS_SECAM] = { /* Philips SECAM */
136 .name = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)",
137 .count = 3,
138 .ranges = {
139 { 16 * 168.25 /*MHz*/, 0xa7, },
140 { 16 * 447.25 /*MHz*/, 0x97, },
141 { 16 * 999.99 , 0x37, },
142 },
143 .config = 0x8e,
144 },
145 [TUNER_ABSENT] = { /* Tuner Absent */
146 .name = "NoTuner",
147 .count = 1,
148 .ranges = {
149 { 0, 0x00, },
150 },
151 .config = 0x00,
152 },
153 [TUNER_PHILIPS_PAL] = { /* Philips PAL */
154 .name = "Philips PAL_BG (FI1216 and compatibles)",
155 .count = 3,
156 .ranges = {
157 { 16 * 168.25 /*MHz*/, 0xa0, },
158 { 16 * 447.25 /*MHz*/, 0x90, },
159 { 16 * 999.99 , 0x30, },
160 },
161 .config = 0x8e,
162 },
163 [TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */
164 .name = "Temic NTSC (4032 FY5)",
165 .count = 3,
166 .ranges = {
167 { 16 * 157.25 /*MHz*/, 0x02, },
168 { 16 * 463.25 /*MHz*/, 0x04, },
169 { 16 * 999.99 , 0x01, },
170 },
171 .config = 0x8e,
172 },
173 [TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */
174 .name = "Temic PAL_I (4062 FY5)",
175 .count = 3,
176 .ranges = {
177 { 16 * 170.00 /*MHz*/, 0x02, },
178 { 16 * 450.00 /*MHz*/, 0x04, },
179 { 16 * 999.99 , 0x01, },
180 },
181 .config = 0x8e,
182 },
183 [TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */
184 .name = "Temic NTSC (4036 FY5)",
185 .count = 3,
186 .ranges = {
187 { 16 * 157.25 /*MHz*/, 0xa0, },
188 { 16 * 463.25 /*MHz*/, 0x90, },
189 { 16 * 999.99 , 0x30, },
190 },
191 .config = 0x8e,
192 },
193 [TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */
194 .name = "Alps HSBH1",
195 .count = 3,
196 .ranges = {
197 { 16 * 137.25 /*MHz*/, 0x01, },
198 { 16 * 385.25 /*MHz*/, 0x02, },
199 { 16 * 999.99 , 0x08, },
200 },
201 .config = 0x8e,
202 },
125 203
126 /* 10-19 */ 204 /* 10-19 */
127 { "Alps TSBE1", TEMIC, PAL, 205 [TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */
128 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, 206 .name = "Alps TSBE1",
129 { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */ 207 .count = 3,
130 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632}, 208 .ranges = {
131 { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ 209 { 16 * 137.25 /*MHz*/, 0x01, },
132 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622}, 210 { 16 * 385.25 /*MHz*/, 0x02, },
133 { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ 211 { 16 * 999.99 , 0x08, },
134 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608}, 212 },
135 { "Temic PAL_BG (4006FH5)", TEMIC, PAL, 213 .config = 0x8e,
136 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 214 },
137 { "Alps TSCH6", Alps, NTSC, 215 [TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */
138 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732}, 216 .name = "Alps TSBB5",
139 { "Temic PAL_DK (4016 FY5)", TEMIC, PAL, 217 .count = 3,
140 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623}, 218 .ranges = {
141 { "Philips NTSC_M (MK2)", Philips, NTSC, 219 { 16 * 133.25 /*MHz*/, 0x01, },
142 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, 220 { 16 * 351.25 /*MHz*/, 0x02, },
143 { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I, 221 { 16 * 999.99 , 0x08, },
144 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 222 },
145 { "Temic PAL* auto (4006 FN5)", TEMIC, PAL, 223 .config = 0x8e,
146 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 224 },
225 [TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */
226 .name = "Alps TSBE5",
227 .count = 3,
228 .ranges = {
229 { 16 * 133.25 /*MHz*/, 0x01, },
230 { 16 * 351.25 /*MHz*/, 0x02, },
231 { 16 * 999.99 , 0x08, },
232 },
233 .config = 0x8e,
234 },
235 [TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */
236 .name = "Alps TSBC5",
237 .count = 3,
238 .ranges = {
239 { 16 * 133.25 /*MHz*/, 0x01, },
240 { 16 * 351.25 /*MHz*/, 0x02, },
241 { 16 * 999.99 , 0x08, },
242 },
243 .config = 0x8e,
244 },
245 [TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */
246 .name = "Temic PAL_BG (4006FH5)",
247 .count = 3,
248 .ranges = {
249 { 16 * 170.00 /*MHz*/, 0xa0, },
250 { 16 * 450.00 /*MHz*/, 0x90, },
251 { 16 * 999.99 , 0x30, },
252 },
253 .config = 0x8e,
254 },
255 [TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */
256 .name = "Alps TSCH6",
257 .count = 3,
258 .ranges = {
259 { 16 * 137.25 /*MHz*/, 0x14, },
260 { 16 * 385.25 /*MHz*/, 0x12, },
261 { 16 * 999.99 , 0x11, },
262 },
263 .config = 0x8e,
264 },
265 [TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */
266 .name = "Temic PAL_DK (4016 FY5)",
267 .count = 3,
268 .ranges = {
269 { 16 * 168.25 /*MHz*/, 0xa0, },
270 { 16 * 456.25 /*MHz*/, 0x90, },
271 { 16 * 999.99 , 0x30, },
272 },
273 .config = 0x8e,
274 },
275 [TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */
276 .name = "Philips NTSC_M (MK2)",
277 .count = 3,
278 .ranges = {
279 { 16 * 160.00 /*MHz*/, 0xa0, },
280 { 16 * 454.00 /*MHz*/, 0x90, },
281 { 16 * 999.99 , 0x30, },
282 },
283 .config = 0x8e,
284 },
285 [TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */
286 .name = "Temic PAL_I (4066 FY5)",
287 .count = 3,
288 .ranges = {
289 { 16 * 169.00 /*MHz*/, 0xa0, },
290 { 16 * 454.00 /*MHz*/, 0x90, },
291 { 16 * 999.99 , 0x30, },
292 },
293 .config = 0x8e,
294 },
295 [TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */
296 .name = "Temic PAL* auto (4006 FN5)",
297 .count = 3,
298 .ranges = {
299 { 16 * 169.00 /*MHz*/, 0xa0, },
300 { 16 * 454.00 /*MHz*/, 0x90, },
301 { 16 * 999.99 , 0x30, },
302 },
303 .config = 0x8e,
304 },
147 305
148 /* 20-29 */ 306 /* 20-29 */
149 { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL, 307 [TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */
150 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, 308 .name = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)",
151 { "Temic NTSC (4039 FR5)", TEMIC, NTSC, 309 .count = 3,
152 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, 310 .ranges = {
153 { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL, 311 { 16 * 141.00 /*MHz*/, 0xa0, },
154 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 312 { 16 * 464.00 /*MHz*/, 0x90, },
155 { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL, 313 { 16 * 999.99 , 0x30, },
156 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 314 },
157 { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL, 315 .config = 0x8e,
158 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 316 },
159 { "LG PAL_I+FM (TAPC-I001D)", LGINNOTEK, PAL_I, 317 [TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */
160 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 318 .name = "Temic NTSC (4039 FR5)",
161 { "LG PAL_I (TAPC-I701D)", LGINNOTEK, PAL_I, 319 .count = 3,
162 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 320 .ranges = {
163 { "LG NTSC+FM (TPI8NSR01F)", LGINNOTEK, NTSC, 321 { 16 * 158.00 /*MHz*/, 0xa0, },
164 16*210.00,16*497.00,0xa0,0x90,0x30,0x8e,732}, 322 { 16 * 453.00 /*MHz*/, 0x90, },
165 { "LG PAL_BG+FM (TPI8PSB01D)", LGINNOTEK, PAL, 323 { 16 * 999.99 , 0x30, },
166 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 324 },
167 { "LG PAL_BG (TPI8PSB11D)", LGINNOTEK, PAL, 325 .config = 0x8e,
168 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 326 },
327 [TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */
328 .name = "Temic PAL/SECAM multi (4046 FM5)",
329 .count = 3,
330 .ranges = {
331 { 16 * 169.00 /*MHz*/, 0xa0, },
332 { 16 * 454.00 /*MHz*/, 0x90, },
333 { 16 * 999.99 , 0x30, },
334 },
335 .config = 0x8e,
336 },
337 [TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */
338 .name = "Philips PAL_DK (FI1256 and compatibles)",
339 .count = 3,
340 .ranges = {
341 { 16 * 170.00 /*MHz*/, 0xa0, },
342 { 16 * 450.00 /*MHz*/, 0x90, },
343 { 16 * 999.99 , 0x30, },
344 },
345 .config = 0x8e,
346 },
347 [TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */
348 .name = "Philips PAL/SECAM multi (FQ1216ME)",
349 .count = 3,
350 .ranges = {
351 { 16 * 170.00 /*MHz*/, 0xa0, },
352 { 16 * 450.00 /*MHz*/, 0x90, },
353 { 16 * 999.99 , 0x30, },
354 },
355 .config = 0x8e,
356 },
357 [TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */
358 .name = "LG PAL_I+FM (TAPC-I001D)",
359 .count = 3,
360 .ranges = {
361 { 16 * 170.00 /*MHz*/, 0xa0, },
362 { 16 * 450.00 /*MHz*/, 0x90, },
363 { 16 * 999.99 , 0x30, },
364 },
365 .config = 0x8e,
366 },
367 [TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */
368 .name = "LG PAL_I (TAPC-I701D)",
369 .count = 3,
370 .ranges = {
371 { 16 * 170.00 /*MHz*/, 0xa0, },
372 { 16 * 450.00 /*MHz*/, 0x90, },
373 { 16 * 999.99 , 0x30, },
374 },
375 .config = 0x8e,
376 },
377 [TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */
378 .name = "LG NTSC+FM (TPI8NSR01F)",
379 .count = 3,
380 .ranges = {
381 { 16 * 210.00 /*MHz*/, 0xa0, },
382 { 16 * 497.00 /*MHz*/, 0x90, },
383 { 16 * 999.99 , 0x30, },
384 },
385 .config = 0x8e,
386 },
387 [TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */
388 .name = "LG PAL_BG+FM (TPI8PSB01D)",
389 .count = 3,
390 .ranges = {
391 { 16 * 170.00 /*MHz*/, 0xa0, },
392 { 16 * 450.00 /*MHz*/, 0x90, },
393 { 16 * 999.99 , 0x30, },
394 },
395 .config = 0x8e,
396 },
397 [TUNER_LG_PAL] = { /* LGINNOTEK PAL */
398 .name = "LG PAL_BG (TPI8PSB11D)",
399 .count = 3,
400 .ranges = {
401 { 16 * 170.00 /*MHz*/, 0xa0, },
402 { 16 * 450.00 /*MHz*/, 0x90, },
403 { 16 * 999.99 , 0x30, },
404 },
405 .config = 0x8e,
406 },
169 407
170 /* 30-39 */ 408 /* 30-39 */
171 { "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL, 409 [TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */
172 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, 410 .name = "Temic PAL* auto + FM (4009 FN5)",
173 { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */ 411 .count = 3,
174 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 }, 412 .ranges = {
175 { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */ 413 { 16 * 141.00 /*MHz*/, 0xa0, },
176 16*169,16*464,0xA0,0x90,0x30,0x8e,623}, 414 { 16 * 464.00 /*MHz*/, 0x90, },
177 { "MT20xx universal", Microtune, PAL|NTSC, 415 { 16 * 999.99 , 0x30, },
416 },
417 .config = 0x8e,
418 },
419 [TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */
420 .name = "SHARP NTSC_JP (2U5JF5540)",
421 .count = 3,
422 .ranges = {
423 { 16 * 137.25 /*MHz*/, 0x01, },
424 { 16 * 317.25 /*MHz*/, 0x02, },
425 { 16 * 999.99 , 0x08, },
426 },
427 .config = 0x8e,
428 },
429 [TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */
430 .name = "Samsung PAL TCPM9091PD27",
431 .count = 3,
432 .ranges = {
433 { 16 * 169 /*MHz*/, 0xa0, },
434 { 16 * 464 /*MHz*/, 0x90, },
435 { 16 * 999.99 , 0x30, },
436 },
437 .config = 0x8e,
438 },
439 [TUNER_MT2032] = { /* Microtune PAL|NTSC */
440 .name = "MT20xx universal",
178 /* see mt20xx.c for details */ }, 441 /* see mt20xx.c for details */ },
179 { "Temic PAL_BG (4106 FH5)", TEMIC, PAL, 442 [TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */
180 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, 443 .name = "Temic PAL_BG (4106 FH5)",
181 { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL, 444 .count = 3,
182 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623}, 445 .ranges = {
183 { "Temic NTSC (4136 FY5)", TEMIC, NTSC, 446 { 16 * 141.00 /*MHz*/, 0xa0, },
184 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, 447 { 16 * 464.00 /*MHz*/, 0x90, },
185 { "LG PAL (newer TAPC series)", LGINNOTEK, PAL, 448 { 16 * 999.99 , 0x30, },
186 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623}, 449 },
187 { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL, 450 .config = 0x8e,
188 16*158.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, 451 },
189 { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC, 452 [TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */
190 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732}, 453 .name = "Temic PAL_DK/SECAM_L (4012 FY5)",
454 .count = 3,
455 .ranges = {
456 { 16 * 140.25 /*MHz*/, 0x02, },
457 { 16 * 463.25 /*MHz*/, 0x04, },
458 { 16 * 999.99 , 0x01, },
459 },
460 .config = 0x8e,
461 },
462 [TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */
463 .name = "Temic NTSC (4136 FY5)",
464 .count = 3,
465 .ranges = {
466 { 16 * 158.00 /*MHz*/, 0xa0, },
467 { 16 * 453.00 /*MHz*/, 0x90, },
468 { 16 * 999.99 , 0x30, },
469 },
470 .config = 0x8e,
471 },
472 [TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */
473 .name = "LG PAL (newer TAPC series)",
474 .count = 3,
475 .ranges = {
476 { 16 * 170.00 /*MHz*/, 0x01, },
477 { 16 * 450.00 /*MHz*/, 0x02, },
478 { 16 * 999.99 , 0x08, },
479 },
480 .config = 0x8e,
481 },
482 [TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */
483 .name = "Philips PAL/SECAM multi (FM1216ME MK3)",
484 .count = 3,
485 .ranges = {
486 { 16 * 158.00 /*MHz*/, 0x01, },
487 { 16 * 442.00 /*MHz*/, 0x02, },
488 { 16 * 999.99 , 0x04, },
489 },
490 .config = 0x8e,
491 },
492 [TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */
493 .name = "LG NTSC (newer TAPC series)",
494 .count = 3,
495 .ranges = {
496 { 16 * 170.00 /*MHz*/, 0x01, },
497 { 16 * 450.00 /*MHz*/, 0x02, },
498 { 16 * 999.99 , 0x08, },
499 },
500 .config = 0x8e,
501 },
191 502
192 /* 40-49 */ 503 /* 40-49 */
193 { "HITACHI V7-J180AT", HITACHI, NTSC, 504 [TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */
194 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,940 }, 505 .name = "HITACHI V7-J180AT",
195 { "Philips PAL_MK (FI1216 MK)", Philips, PAL, 506 .count = 3,
196 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623}, 507 .ranges = {
197 { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC, 508 { 16 * 170.00 /*MHz*/, 0x01, },
198 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732}, 509 { 16 * 450.00 /*MHz*/, 0x02, },
199 { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC, 510 { 16 * 999.99 , 0x08, },
200 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, 511 },
201 { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC, 512 .config = 0x8e,
202 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, 513 },
203 { "Microtune 4049 FM5", Microtune, PAL, 514 [TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */
204 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623}, 515 .name = "Philips PAL_MK (FI1216 MK)",
205 { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC, 516 .count = 3,
206 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940}, 517 .ranges = {
207 { "LG NTSC (TAPE series)", LGINNOTEK, NTSC, 518 { 16 * 140.25 /*MHz*/, 0x01, },
208 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, 519 { 16 * 463.25 /*MHz*/, 0xc2, },
209 { "Tenna TNF 8831 BGFF)", Philips, PAL, 520 { 16 * 999.99 , 0xcf, },
210 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, 521 },
211 { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC, 522 .config = 0x8e,
212 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732}, 523 },
524 [TUNER_PHILIPS_ATSC] = { /* Philips ATSC */
525 .name = "Philips 1236D ATSC/NTSC dual in",
526 .count = 3,
527 .ranges = {
528 { 16 * 157.25 /*MHz*/, 0xa0, },
529 { 16 * 454.00 /*MHz*/, 0x90, },
530 { 16 * 999.99 , 0x30, },
531 },
532 .config = 0x8e,
533 },
534 [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */
535 .name = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)",
536 .count = 3,
537 .ranges = {
538 { 16 * 160.00 /*MHz*/, 0x01, },
539 { 16 * 442.00 /*MHz*/, 0x02, },
540 { 16 * 999.99 , 0x04, },
541 },
542 .config = 0x8e,
543 },
544 [TUNER_PHILIPS_4IN1] = { /* Philips NTSC */
545 .name = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)",
546 .count = 3,
547 .ranges = {
548 { 16 * 160.00 /*MHz*/, 0x01, },
549 { 16 * 442.00 /*MHz*/, 0x02, },
550 { 16 * 999.99 , 0x04, },
551 },
552 .config = 0x8e,
553 },
554 [TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */
555 .name = "Microtune 4049 FM5",
556 .count = 3,
557 .ranges = {
558 { 16 * 141.00 /*MHz*/, 0xa0, },
559 { 16 * 464.00 /*MHz*/, 0x90, },
560 { 16 * 999.99 , 0x30, },
561 },
562 .config = 0x8e,
563 },
564 [TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */
565 .name = "Panasonic VP27s/ENGE4324D",
566 .count = 3,
567 .ranges = {
568 { 16 * 160.00 /*MHz*/, 0x01, },
569 { 16 * 454.00 /*MHz*/, 0x02, },
570 { 16 * 999.99 , 0x08, },
571 },
572 .config = 0xce,
573 },
574 [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */
575 .name = "LG NTSC (TAPE series)",
576 .count = 3,
577 .ranges = {
578 { 16 * 160.00 /*MHz*/, 0x01, },
579 { 16 * 442.00 /*MHz*/, 0x02, },
580 { 16 * 999.99 , 0x04, },
581 },
582 .config = 0x8e,
583 },
584 [TUNER_TNF_8831BGFF] = { /* Philips PAL */
585 .name = "Tenna TNF 8831 BGFF)",
586 .count = 3,
587 .ranges = {
588 { 16 * 161.25 /*MHz*/, 0xa0, },
589 { 16 * 463.25 /*MHz*/, 0x90, },
590 { 16 * 999.99 , 0x30, },
591 },
592 .config = 0x8e,
593 },
594 [TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */
595 .name = "Microtune 4042 FI5 ATSC/NTSC dual in",
596 .count = 3,
597 .ranges = {
598 { 16 * 162.00 /*MHz*/, 0xa2, },
599 { 16 * 457.00 /*MHz*/, 0x94, },
600 { 16 * 999.99 , 0x31, },
601 },
602 .config = 0x8e,
603 },
213 604
214 /* 50-59 */ 605 /* 50-59 */
215 { "TCL 2002N", TCL, NTSC, 606 [TUNER_TCL_2002N] = { /* TCL NTSC */
216 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732}, 607 .name = "TCL 2002N",
217 { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL, 608 .count = 3,
218 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, 609 .ranges = {
219 { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC, 610 { 16 * 172.00 /*MHz*/, 0x01, },
220 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, 611 { 16 * 448.00 /*MHz*/, 0x02, },
221 { "Philips FQ1286", Philips, NTSC, 612 { 16 * 999.99 , 0x08, },
222 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */ 613 },
223 { "tda8290+75", Philips, PAL|NTSC, 614 .config = 0x8e,
615 },
616 [TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */
617 .name = "Philips PAL/SECAM_D (FM 1256 I-H3)",
618 .count = 3,
619 .ranges = {
620 { 16 * 160.00 /*MHz*/, 0x01, },
621 { 16 * 442.00 /*MHz*/, 0x02, },
622 { 16 * 999.99 , 0x04, },
623 },
624 .config = 0x8e,
625 },
626 [TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */
627 .name = "Thomson DTT 7610 (ATSC/NTSC)",
628 .count = 3,
629 .ranges = {
630 { 16 * 157.25 /*MHz*/, 0x39, },
631 { 16 * 454.00 /*MHz*/, 0x3a, },
632 { 16 * 999.99 , 0x3c, },
633 },
634 .config = 0x8e,
635 },
636 [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */
637 .name = "Philips FQ1286",
638 .count = 3,
639 .ranges = {
640 { 16 * 160.00 /*MHz*/, 0x41, },
641 { 16 * 454.00 /*MHz*/, 0x42, },
642 { 16 * 999.99 , 0x04, },
643 },
644 .config = 0x8e,
645 },
646 [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */
647 .name = "tda8290+75",
224 /* see tda8290.c for details */ }, 648 /* see tda8290.c for details */ },
225 { "TCL 2002MB", TCL, PAL, 649 [TUNER_TCL_2002MB] = { /* TCL PAL */
226 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, 650 .name = "TCL 2002MB",
227 { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, 651 .count = 3,
228 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, 652 .ranges = {
229 { "Philips FQ1236A MK4", Philips, NTSC, 653 { 16 * 170.00 /*MHz*/, 0x01, },
230 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, 654 { 16 * 450.00 /*MHz*/, 0x02, },
231 { "Ymec TVision TVF-8531MF/8831MF/8731MF", Philips, NTSC, 655 { 16 * 999.99 , 0x08, },
232 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, 656 },
233 { "Ymec TVision TVF-5533MF", Philips, NTSC, 657 .config = 0xce,
234 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, 658 },
659 [TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */
660 .name = "Philips PAL/SECAM multi (FQ1216AME MK4)",
661 .count = 3,
662 .ranges = {
663 { 16 * 160.00 /*MHz*/, 0x01, },
664 { 16 * 442.00 /*MHz*/, 0x02, },
665 { 16 * 999.99 , 0x04, },
666 },
667 .config = 0xce,
668 },
669 [TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */
670 .name = "Philips FQ1236A MK4",
671 .count = 3,
672 .ranges = {
673 { 16 * 160.00 /*MHz*/, 0x01, },
674 { 16 * 442.00 /*MHz*/, 0x02, },
675 { 16 * 999.99 , 0x04, },
676 },
677 .config = 0x8e,
678 },
679 [TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */
680 .name = "Ymec TVision TVF-8531MF/8831MF/8731MF",
681 .count = 3,
682 .ranges = {
683 { 16 * 160.00 /*MHz*/, 0xa0, },
684 { 16 * 454.00 /*MHz*/, 0x90, },
685 { 16 * 999.99 , 0x30, },
686 },
687 .config = 0x8e,
688 },
689 [TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */
690 .name = "Ymec TVision TVF-5533MF",
691 .count = 3,
692 .ranges = {
693 { 16 * 160.00 /*MHz*/, 0x01, },
694 { 16 * 454.00 /*MHz*/, 0x02, },
695 { 16 * 999.99 , 0x04, },
696 },
697 .config = 0x8e,
698 },
235 699
236 /* 60-69 */ 700 /* 60-69 */
237 { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, 701 [TUNER_THOMSON_DTT761X] = { /* THOMSON ATSC */
238 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, 702 /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
239 { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL, 703 .name = "Thomson DTT 761X (ATSC/NTSC)",
240 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623}, 704 .count = 3,
241 { "Philips TEA5767HN FM Radio", Philips, RADIO, 705 .ranges = {
706 { 16 * 145.25 /*MHz*/, 0x39, },
707 { 16 * 415.25 /*MHz*/, 0x3a, },
708 { 16 * 999.99 , 0x3c, },
709 },
710 .config = 0x8e,
711 },
712 [TUNER_TENA_9533_DI] = { /* Philips PAL */
713 .name = "Tena TNF9533-D/IF/TNF9533-B/DF",
714 .count = 3,
715 .ranges = {
716 { 16 * 160.25 /*MHz*/, 0x01, },
717 { 16 * 464.25 /*MHz*/, 0x02, },
718 { 16 * 999.99 , 0x04, },
719 },
720 .config = 0x8e,
721 },
722 [TUNER_TEA5767] = { /* Philips RADIO */
723 .name = "Philips TEA5767HN FM Radio",
242 /* see tea5767.c for details */}, 724 /* see tea5767.c for details */},
243 { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, 725 [TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */
244 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, 726 .name = "Philips FMD1216ME MK3 Hybrid Tuner",
245 { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC, 727 .count = 3,
246 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732}, 728 .ranges = {
247 { "Ymec TVF66T5-B/DFF", Philips, PAL, 729 { 16 * 160.00 /*MHz*/, 0x51, },
248 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623}, 730 { 16 * 442.00 /*MHz*/, 0x52, },
249 { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC, 731 { 16 * 999.99 , 0x54, },
250 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 }, 732 },
251 { "Philips TD1316 Hybrid Tuner", Philips, PAL, 733 .config = 0x86,
252 16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 }, 734 },
253 { "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC, 735 [TUNER_LG_TDVS_H062F] = { /* LGINNOTEK ATSC */
254 16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 }, 736 .name = "LG TDVS-H062F/TUA6034",
255 { "Tena TNF 5335 MF", Philips, NTSC, 737 .count = 3,
256 16*157.25,16*454.00,0x01,0x02,0x04,0x8e,732 }, 738 .ranges = {
739 { 16 * 160.00 /*MHz*/, 0x01 },
740 { 16 * 455.00 /*MHz*/, 0x02 },
741 { 16 * 999.99 , 0x04 },
742 },
743 .config = 0x8e,
744 },
745 [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */
746 .name = "Ymec TVF66T5-B/DFF",
747 .count = 3,
748 .ranges = {
749 { 16 * 160.25 /*MHz*/, 0x01, },
750 { 16 * 464.25 /*MHz*/, 0x02, },
751 { 16 * 999.99 , 0x08, },
752 },
753 .config = 0x8e,
754 },
755 [TUNER_LG_NTSC_TALN_MINI] = { /* LGINNOTEK NTSC */
756 .name = "LG NTSC (TALN mini series)",
757 .count = 3,
758 .ranges = {
759 { 16 * 137.25 /*MHz*/, 0x01, },
760 { 16 * 373.25 /*MHz*/, 0x02, },
761 { 16 * 999.99 , 0x08, },
762 },
763 .config = 0x8e,
764 },
765 [TUNER_PHILIPS_TD1316] = { /* Philips PAL */
766 .name = "Philips TD1316 Hybrid Tuner",
767 .count = 3,
768 .ranges = {
769 { 16 * 160.00 /*MHz*/, 0xa1, },
770 { 16 * 442.00 /*MHz*/, 0xa2, },
771 { 16 * 999.99 , 0xa4, },
772 },
773 .config = 0xc8,
774 },
775 [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */
776 .name = "Philips TUV1236D ATSC/NTSC dual in",
777 .count = 3,
778 .ranges = {
779 { 16 * 157.25 /*MHz*/, 0x01, },
780 { 16 * 454.00 /*MHz*/, 0x02, },
781 { 16 * 999.99 , 0x04, },
782 },
783 .config = 0xce,
784 },
785 [TUNER_TNF_5335MF] = { /* Philips NTSC */
786 .name = "Tena TNF 5335 MF",
787 .count = 3,
788 .ranges = {
789 { 16 * 157.25 /*MHz*/, 0x01, },
790 { 16 * 454.00 /*MHz*/, 0x02, },
791 { 16 * 999.99 , 0x04, },
792 },
793 .config = 0x8e,
794 },
257}; 795};
258 796
259unsigned const int tuner_count = ARRAY_SIZE(tuners); 797unsigned const int tuner_count = ARRAY_SIZE(tuners);
@@ -305,20 +843,19 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
305 u16 div; 843 u16 div;
306 struct tunertype *tun; 844 struct tunertype *tun;
307 unsigned char buffer[4]; 845 unsigned char buffer[4];
308 int rc; 846 int rc, IFPCoff, i;
309 847
310 tun = &tuners[t->type]; 848 tun = &tuners[t->type];
311 if (freq < tun->thresh1) { 849 for (i = 0; i < tun->count; i++) {
312 config = tun->VHF_L; 850 if (freq > tun->ranges[i].thresh)
313 tuner_dbg("tv: VHF lowrange\n"); 851 continue;
314 } else if (freq < tun->thresh2) { 852 break;
315 config = tun->VHF_H;
316 tuner_dbg("tv: VHF high range\n");
317 } else {
318 config = tun->UHF;
319 tuner_dbg("tv: UHF range\n");
320 } 853 }
321 854 config = tun->ranges[i].cb;
855 /* i == 0 -> VHF_LO */
856 /* i == 1 -> VHF_HI */
857 /* i == 2 -> UHF */
858 tuner_dbg("tv: range %d\n",i);
322 859
323 /* tv norm specific stuff for multi-norm tuners */ 860 /* tv norm specific stuff for multi-norm tuners */
324 switch (t->type) { 861 switch (t->type) {
@@ -420,7 +957,37 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
420 * frequency in case (wanted frequency < current frequency). 957 * frequency in case (wanted frequency < current frequency).
421 */ 958 */
422 959
423 div=freq + tun->IFPCoff; 960 /* IFPCoff = Video Intermediate Frequency - Vif:
961 940 =16*58.75 NTSC/J (Japan)
962 732 =16*45.75 M/N STD
963 704 =16*44 ATSC (at DVB code)
964 632 =16*39.50 I U.K.
965 622.4=16*38.90 B/G D/K I, L STD
966 592 =16*37.00 D China
967 590 =16.36.875 B Australia
968 543.2=16*33.95 L' STD
969 171.2=16*10.70 FM Radio (at set_radio_freq)
970 */
971
972 if (t->std == V4L2_STD_NTSC_M_JP) {
973 IFPCoff = 940;
974 } else if ((t->std & V4L2_STD_MN) &&
975 !(t->std & ~V4L2_STD_MN)) {
976 IFPCoff = 732;
977 } else if (t->std == V4L2_STD_SECAM_LC) {
978 IFPCoff = 543;
979 } else {
980 IFPCoff = 623;
981 }
982
983 div=freq + IFPCoff + offset;
984
985 tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n",
986 freq / 16, freq % 16 * 100 / 16,
987 IFPCoff / 16, IFPCoff % 16 * 100 / 16,
988 offset / 16, offset % 16 * 100 / 16,
989 div);
990
424 if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) { 991 if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) {
425 buffer[0] = tun->config; 992 buffer[0] = tun->config;
426 buffer[1] = config; 993 buffer[1] = config;
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 0292c5abf14a..b582943a0d3e 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -31,6 +31,7 @@
31#include <linux/smp_lock.h> 31#include <linux/smp_lock.h>
32 32
33#include <media/audiochip.h> 33#include <media/audiochip.h>
34#include <media/v4l2-common.h>
34 35
35#include "tvaudio.h" 36#include "tvaudio.h"
36 37
@@ -46,17 +47,6 @@ MODULE_LICENSE("GPL");
46 47
47#define UNSET (-1U) 48#define UNSET (-1U)
48 49
49#define tvaudio_info(fmt, arg...) do {\
50 printk(KERN_INFO "tvaudio %d-%04x: " fmt, \
51 chip->c.adapter->nr, chip->c.addr , ##arg); } while (0)
52#define tvaudio_warn(fmt, arg...) do {\
53 printk(KERN_WARNING "tvaudio %d-%04x: " fmt, \
54 chip->c.adapter->nr, chip->c.addr , ##arg); } while (0)
55#define tvaudio_dbg(fmt, arg...) do {\
56 if (debug) \
57 printk(KERN_INFO "tvaudio %d-%04x: " fmt, \
58 chip->c.adapter->nr, chip->c.addr , ##arg); } while (0)
59
60/* ---------------------------------------------------------------------- */ 50/* ---------------------------------------------------------------------- */
61/* our structs */ 51/* our structs */
62 52
@@ -131,7 +121,7 @@ struct CHIPSTATE {
131 /* current settings */ 121 /* current settings */
132 __u16 left,right,treble,bass,mode; 122 __u16 left,right,treble,bass,mode;
133 int prevmode; 123 int prevmode;
134 int norm; 124 int radio;
135 125
136 /* thread */ 126 /* thread */
137 pid_t tpid; 127 pid_t tpid;
@@ -142,8 +132,6 @@ struct CHIPSTATE {
142 int watch_stereo; 132 int watch_stereo;
143}; 133};
144 134
145#define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */
146
147/* ---------------------------------------------------------------------- */ 135/* ---------------------------------------------------------------------- */
148/* i2c addresses */ 136/* i2c addresses */
149 137
@@ -171,23 +159,23 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
171 unsigned char buffer[2]; 159 unsigned char buffer[2];
172 160
173 if (-1 == subaddr) { 161 if (-1 == subaddr) {
174 tvaudio_dbg("%s: chip_write: 0x%x\n", 162 v4l_dbg(1, &chip->c, "%s: chip_write: 0x%x\n",
175 chip->c.name, val); 163 chip->c.name, val);
176 chip->shadow.bytes[1] = val; 164 chip->shadow.bytes[1] = val;
177 buffer[0] = val; 165 buffer[0] = val;
178 if (1 != i2c_master_send(&chip->c,buffer,1)) { 166 if (1 != i2c_master_send(&chip->c,buffer,1)) {
179 tvaudio_warn("%s: I/O error (write 0x%x)\n", 167 v4l_warn(&chip->c, "%s: I/O error (write 0x%x)\n",
180 chip->c.name, val); 168 chip->c.name, val);
181 return -1; 169 return -1;
182 } 170 }
183 } else { 171 } else {
184 tvaudio_dbg("%s: chip_write: reg%d=0x%x\n", 172 v4l_dbg(1, &chip->c, "%s: chip_write: reg%d=0x%x\n",
185 chip->c.name, subaddr, val); 173 chip->c.name, subaddr, val);
186 chip->shadow.bytes[subaddr+1] = val; 174 chip->shadow.bytes[subaddr+1] = val;
187 buffer[0] = subaddr; 175 buffer[0] = subaddr;
188 buffer[1] = val; 176 buffer[1] = val;
189 if (2 != i2c_master_send(&chip->c,buffer,2)) { 177 if (2 != i2c_master_send(&chip->c,buffer,2)) {
190 tvaudio_warn("%s: I/O error (write reg%d=0x%x)\n", 178 v4l_warn(&chip->c, "%s: I/O error (write reg%d=0x%x)\n",
191 chip->c.name, subaddr, val); 179 chip->c.name, subaddr, val);
192 return -1; 180 return -1;
193 } 181 }
@@ -212,11 +200,11 @@ static int chip_read(struct CHIPSTATE *chip)
212 unsigned char buffer; 200 unsigned char buffer;
213 201
214 if (1 != i2c_master_recv(&chip->c,&buffer,1)) { 202 if (1 != i2c_master_recv(&chip->c,&buffer,1)) {
215 tvaudio_warn("%s: I/O error (read)\n", 203 v4l_warn(&chip->c, "%s: I/O error (read)\n",
216 chip->c.name); 204 chip->c.name);
217 return -1; 205 return -1;
218 } 206 }
219 tvaudio_dbg("%s: chip_read: 0x%x\n",chip->c.name, buffer); 207 v4l_dbg(1, &chip->c, "%s: chip_read: 0x%x\n",chip->c.name, buffer);
220 return buffer; 208 return buffer;
221} 209}
222 210
@@ -231,10 +219,10 @@ static int chip_read2(struct CHIPSTATE *chip, int subaddr)
231 write[0] = subaddr; 219 write[0] = subaddr;
232 220
233 if (2 != i2c_transfer(chip->c.adapter,msgs,2)) { 221 if (2 != i2c_transfer(chip->c.adapter,msgs,2)) {
234 tvaudio_warn("%s: I/O error (read2)\n", chip->c.name); 222 v4l_warn(&chip->c, "%s: I/O error (read2)\n", chip->c.name);
235 return -1; 223 return -1;
236 } 224 }
237 tvaudio_dbg("%s: chip_read2: reg%d=0x%x\n", 225 v4l_dbg(1, &chip->c, "%s: chip_read2: reg%d=0x%x\n",
238 chip->c.name, subaddr,read[0]); 226 chip->c.name, subaddr,read[0]);
239 return read[0]; 227 return read[0];
240} 228}
@@ -247,7 +235,7 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
247 return 0; 235 return 0;
248 236
249 /* update our shadow register set; print bytes if (debug > 0) */ 237 /* update our shadow register set; print bytes if (debug > 0) */
250 tvaudio_dbg("%s: chip_cmd(%s): reg=%d, data:", 238 v4l_dbg(1, &chip->c, "%s: chip_cmd(%s): reg=%d, data:",
251 chip->c.name, name,cmd->bytes[0]); 239 chip->c.name, name,cmd->bytes[0]);
252 for (i = 1; i < cmd->count; i++) { 240 for (i = 1; i < cmd->count; i++) {
253 if (debug) 241 if (debug)
@@ -259,7 +247,7 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
259 247
260 /* send data to the chip */ 248 /* send data to the chip */
261 if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) { 249 if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) {
262 tvaudio_warn("%s: I/O error (%s)\n", chip->c.name, name); 250 v4l_warn(&chip->c, "%s: I/O error (%s)\n", chip->c.name, name);
263 return -1; 251 return -1;
264 } 252 }
265 return 0; 253 return 0;
@@ -286,7 +274,7 @@ static int chip_thread(void *data)
286 274
287 daemonize("%s", chip->c.name); 275 daemonize("%s", chip->c.name);
288 allow_signal(SIGTERM); 276 allow_signal(SIGTERM);
289 tvaudio_dbg("%s: thread started\n", chip->c.name); 277 v4l_dbg(1, &chip->c, "%s: thread started\n", chip->c.name);
290 278
291 for (;;) { 279 for (;;) {
292 add_wait_queue(&chip->wq, &wait); 280 add_wait_queue(&chip->wq, &wait);
@@ -298,10 +286,10 @@ static int chip_thread(void *data)
298 try_to_freeze(); 286 try_to_freeze();
299 if (chip->done || signal_pending(current)) 287 if (chip->done || signal_pending(current))
300 break; 288 break;
301 tvaudio_dbg("%s: thread wakeup\n", chip->c.name); 289 v4l_dbg(1, &chip->c, "%s: thread wakeup\n", chip->c.name);
302 290
303 /* don't do anything for radio or if mode != auto */ 291 /* don't do anything for radio or if mode != auto */
304 if (chip->norm == VIDEO_MODE_RADIO || chip->mode != 0) 292 if (chip->radio || chip->mode != 0)
305 continue; 293 continue;
306 294
307 /* have a look what's going on */ 295 /* have a look what's going on */
@@ -311,7 +299,7 @@ static int chip_thread(void *data)
311 mod_timer(&chip->wt, jiffies+2*HZ); 299 mod_timer(&chip->wt, jiffies+2*HZ);
312 } 300 }
313 301
314 tvaudio_dbg("%s: thread exiting\n", chip->c.name); 302 v4l_dbg(1, &chip->c, "%s: thread exiting\n", chip->c.name);
315 complete_and_exit(&chip->texit, 0); 303 complete_and_exit(&chip->texit, 0);
316 return 0; 304 return 0;
317} 305}
@@ -324,7 +312,7 @@ static void generic_checkmode(struct CHIPSTATE *chip)
324 if (mode == chip->prevmode) 312 if (mode == chip->prevmode)
325 return; 313 return;
326 314
327 tvaudio_dbg("%s: thread checkmode\n", chip->c.name); 315 v4l_dbg(1, &chip->c, "%s: thread checkmode\n", chip->c.name);
328 chip->prevmode = mode; 316 chip->prevmode = mode;
329 317
330 if (mode & VIDEO_SOUND_STEREO) 318 if (mode & VIDEO_SOUND_STEREO)
@@ -371,7 +359,7 @@ static int tda9840_getmode(struct CHIPSTATE *chip)
371 if (val & TDA9840_ST_STEREO) 359 if (val & TDA9840_ST_STEREO)
372 mode |= VIDEO_SOUND_STEREO; 360 mode |= VIDEO_SOUND_STEREO;
373 361
374 tvaudio_dbg ("tda9840_getmode(): raw chip read: %d, return: %d\n", 362 v4l_dbg(1, &chip->c, "tda9840_getmode(): raw chip read: %d, return: %d\n",
375 val, mode); 363 val, mode);
376 return mode; 364 return mode;
377} 365}
@@ -667,7 +655,7 @@ static int tda9873_getmode(struct CHIPSTATE *chip)
667 mode |= VIDEO_SOUND_STEREO; 655 mode |= VIDEO_SOUND_STEREO;
668 if (val & TDA9873_DUAL) 656 if (val & TDA9873_DUAL)
669 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; 657 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
670 tvaudio_dbg ("tda9873_getmode(): raw chip read: %d, return: %d\n", 658 v4l_dbg(1, &chip->c, "tda9873_getmode(): raw chip read: %d, return: %d\n",
671 val, mode); 659 val, mode);
672 return mode; 660 return mode;
673} 661}
@@ -678,12 +666,12 @@ static void tda9873_setmode(struct CHIPSTATE *chip, int mode)
678 /* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */ 666 /* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */
679 667
680 if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) { 668 if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) {
681 tvaudio_dbg("tda9873_setmode(): external input\n"); 669 v4l_dbg(1, &chip->c, "tda9873_setmode(): external input\n");
682 return; 670 return;
683 } 671 }
684 672
685 tvaudio_dbg("tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]); 673 v4l_dbg(1, &chip->c, "tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]);
686 tvaudio_dbg("tda9873_setmode(): sw_data = %d\n", sw_data); 674 v4l_dbg(1, &chip->c, "tda9873_setmode(): sw_data = %d\n", sw_data);
687 675
688 switch (mode) { 676 switch (mode) {
689 case VIDEO_SOUND_MONO: 677 case VIDEO_SOUND_MONO:
@@ -704,7 +692,7 @@ static void tda9873_setmode(struct CHIPSTATE *chip, int mode)
704 } 692 }
705 693
706 chip_write(chip, TDA9873_SW, sw_data); 694 chip_write(chip, TDA9873_SW, sw_data);
707 tvaudio_dbg("tda9873_setmode(): req. mode %d; chip_write: %d\n", 695 v4l_dbg(1, &chip->c, "tda9873_setmode(): req. mode %d; chip_write: %d\n",
708 mode, sw_data); 696 mode, sw_data);
709} 697}
710 698
@@ -843,7 +831,7 @@ static int tda9874a_setup(struct CHIPSTATE *chip)
843 chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80); 831 chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80);
844 chip_write(chip, TDA9874A_AOSR, 0x00); /* or 0x10 */ 832 chip_write(chip, TDA9874A_AOSR, 0x00); /* or 0x10 */
845 } 833 }
846 tvaudio_dbg("tda9874a_setup(): %s [0x%02X].\n", 834 v4l_dbg(1, &chip->c, "tda9874a_setup(): %s [0x%02X].\n",
847 tda9874a_modelist[tda9874a_STD].name,tda9874a_STD); 835 tda9874a_modelist[tda9874a_STD].name,tda9874a_STD);
848 return 1; 836 return 1;
849} 837}
@@ -886,7 +874,7 @@ static int tda9874a_getmode(struct CHIPSTATE *chip)
886 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; 874 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
887 } 875 }
888 876
889 tvaudio_dbg("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n", 877 v4l_dbg(1, &chip->c, "tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n",
890 dsr, nsr, necr, mode); 878 dsr, nsr, necr, mode);
891 return mode; 879 return mode;
892} 880}
@@ -932,7 +920,7 @@ static void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
932 chip_write(chip, TDA9874A_AOSR, aosr); 920 chip_write(chip, TDA9874A_AOSR, aosr);
933 chip_write(chip, TDA9874A_MDACOSR, mdacosr); 921 chip_write(chip, TDA9874A_MDACOSR, mdacosr);
934 922
935 tvaudio_dbg("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n", 923 v4l_dbg(1, &chip->c, "tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",
936 mode, aosr, mdacosr); 924 mode, aosr, mdacosr);
937 925
938 } else { /* dic == 0x07 */ 926 } else { /* dic == 0x07 */
@@ -967,7 +955,7 @@ static void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
967 chip_write(chip, TDA9874A_FMMR, fmmr); 955 chip_write(chip, TDA9874A_FMMR, fmmr);
968 chip_write(chip, TDA9874A_AOSR, aosr); 956 chip_write(chip, TDA9874A_AOSR, aosr);
969 957
970 tvaudio_dbg("tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n", 958 v4l_dbg(1, &chip->c, "tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n",
971 mode, fmmr, aosr); 959 mode, fmmr, aosr);
972 } 960 }
973} 961}
@@ -981,10 +969,10 @@ static int tda9874a_checkit(struct CHIPSTATE *chip)
981 if(-1 == (sic = chip_read2(chip,TDA9874A_SIC))) 969 if(-1 == (sic = chip_read2(chip,TDA9874A_SIC)))
982 return 0; 970 return 0;
983 971
984 tvaudio_dbg("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic); 972 v4l_dbg(1, &chip->c, "tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
985 973
986 if((dic == 0x11)||(dic == 0x07)) { 974 if((dic == 0x11)||(dic == 0x07)) {
987 tvaudio_info("found tda9874%s.\n", (dic == 0x11) ? "a":"h"); 975 v4l_info(&chip->c, "found tda9874%s.\n", (dic == 0x11) ? "a":"h");
988 tda9874a_dic = dic; /* remember device id. */ 976 tda9874a_dic = dic; /* remember device id. */
989 return 1; 977 return 1;
990 } 978 }
@@ -1196,7 +1184,7 @@ static int ta8874z_getmode(struct CHIPSTATE *chip)
1196 }else if (!(val & TA8874Z_B0)){ 1184 }else if (!(val & TA8874Z_B0)){
1197 mode |= VIDEO_SOUND_STEREO; 1185 mode |= VIDEO_SOUND_STEREO;
1198 } 1186 }
1199 /* tvaudio_dbg ("ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode); */ 1187 /* v4l_dbg(1, &chip->c, "ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode); */
1200 return mode; 1188 return mode;
1201} 1189}
1202 1190
@@ -1209,7 +1197,7 @@ static void ta8874z_setmode(struct CHIPSTATE *chip, int mode)
1209{ 1197{
1210 int update = 1; 1198 int update = 1;
1211 audiocmd *t = NULL; 1199 audiocmd *t = NULL;
1212 tvaudio_dbg("ta8874z_setmode(): mode: 0x%02x\n", mode); 1200 v4l_dbg(1, &chip->c, "ta8874z_setmode(): mode: 0x%02x\n", mode);
1213 1201
1214 switch(mode){ 1202 switch(mode){
1215 case VIDEO_SOUND_MONO: 1203 case VIDEO_SOUND_MONO:
@@ -1490,7 +1478,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
1490 i2c_set_clientdata(&chip->c, chip); 1478 i2c_set_clientdata(&chip->c, chip);
1491 1479
1492 /* find description for the chip */ 1480 /* find description for the chip */
1493 tvaudio_dbg("chip found @ 0x%x\n", addr<<1); 1481 v4l_dbg(1, &chip->c, "chip found @ 0x%x\n", addr<<1);
1494 for (desc = chiplist; desc->name != NULL; desc++) { 1482 for (desc = chiplist; desc->name != NULL; desc++) {
1495 if (0 == *(desc->insmodopt)) 1483 if (0 == *(desc->insmodopt))
1496 continue; 1484 continue;
@@ -1502,12 +1490,12 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
1502 break; 1490 break;
1503 } 1491 }
1504 if (desc->name == NULL) { 1492 if (desc->name == NULL) {
1505 tvaudio_dbg("no matching chip description found\n"); 1493 v4l_dbg(1, &chip->c, "no matching chip description found\n");
1506 return -EIO; 1494 return -EIO;
1507 } 1495 }
1508 tvaudio_info("%s found @ 0x%x (%s)\n", desc->name, addr<<1, adap->name); 1496 v4l_info(&chip->c, "%s found @ 0x%x (%s)\n", desc->name, addr<<1, adap->name);
1509 if (desc->flags) { 1497 if (desc->flags) {
1510 tvaudio_dbg("matches:%s%s%s.\n", 1498 v4l_dbg(1, &chip->c, "matches:%s%s%s.\n",
1511 (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "", 1499 (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "",
1512 (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "", 1500 (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
1513 (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : ""); 1501 (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : "");
@@ -1550,7 +1538,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
1550 init_completion(&chip->texit); 1538 init_completion(&chip->texit);
1551 chip->tpid = kernel_thread(chip_thread,(void *)chip,0); 1539 chip->tpid = kernel_thread(chip_thread,(void *)chip,0);
1552 if (chip->tpid < 0) 1540 if (chip->tpid < 0)
1553 tvaudio_warn("%s: kernel_thread() failed\n", 1541 v4l_warn(&chip->c, "%s: kernel_thread() failed\n",
1554 chip->c.name); 1542 chip->c.name);
1555 wake_up_interruptible(&chip->wq); 1543 wake_up_interruptible(&chip->wq);
1556 } 1544 }
@@ -1563,17 +1551,8 @@ static int chip_probe(struct i2c_adapter *adap)
1563 because dedicated drivers are used */ 1551 because dedicated drivers are used */
1564 if ((adap->id == I2C_HW_SAA7146)) 1552 if ((adap->id == I2C_HW_SAA7146))
1565 return 0; 1553 return 0;
1566#ifdef I2C_CLASS_TV_ANALOG
1567 if (adap->class & I2C_CLASS_TV_ANALOG) 1554 if (adap->class & I2C_CLASS_TV_ANALOG)
1568 return i2c_probe(adap, &addr_data, chip_attach); 1555 return i2c_probe(adap, &addr_data, chip_attach);
1569#else
1570 switch (adap->id) {
1571 case I2C_HW_B_BT848:
1572 case I2C_HW_B_RIVA:
1573 case I2C_HW_SAA7134:
1574 return i2c_probe(adap, &addr_data, chip_attach);
1575 }
1576#endif
1577 return 0; 1556 return 0;
1578} 1557}
1579 1558
@@ -1604,7 +1583,7 @@ static int chip_command(struct i2c_client *client,
1604 struct CHIPSTATE *chip = i2c_get_clientdata(client); 1583 struct CHIPSTATE *chip = i2c_get_clientdata(client);
1605 struct CHIPDESC *desc = chiplist + chip->type; 1584 struct CHIPDESC *desc = chiplist + chip->type;
1606 1585
1607 tvaudio_dbg("%s: chip_command 0x%x\n", chip->c.name, cmd); 1586 v4l_dbg(1, &chip->c, "%s: chip_command 0x%x\n", chip->c.name, cmd);
1608 1587
1609 switch (cmd) { 1588 switch (cmd) {
1610 case AUDC_SET_INPUT: 1589 case AUDC_SET_INPUT:
@@ -1617,7 +1596,7 @@ static int chip_command(struct i2c_client *client,
1617 break; 1596 break;
1618 1597
1619 case AUDC_SET_RADIO: 1598 case AUDC_SET_RADIO:
1620 chip->norm = VIDEO_MODE_RADIO; 1599 chip->radio = 1;
1621 chip->watch_stereo = 0; 1600 chip->watch_stereo = 0;
1622 /* del_timer(&chip->wt); */ 1601 /* del_timer(&chip->wt); */
1623 break; 1602 break;
@@ -1643,7 +1622,7 @@ static int chip_command(struct i2c_client *client,
1643 va->bass = chip->bass; 1622 va->bass = chip->bass;
1644 va->treble = chip->treble; 1623 va->treble = chip->treble;
1645 } 1624 }
1646 if (chip->norm != VIDEO_MODE_RADIO) { 1625 if (!chip->radio) {
1647 if (desc->getmode) 1626 if (desc->getmode)
1648 va->mode = desc->getmode(chip); 1627 va->mode = desc->getmode(chip);
1649 else 1628 else
@@ -1678,15 +1657,80 @@ static int chip_command(struct i2c_client *client,
1678 } 1657 }
1679 break; 1658 break;
1680 } 1659 }
1681 case VIDIOCSCHAN: 1660
1661 case VIDIOC_S_TUNER:
1682 { 1662 {
1683 struct video_channel *vc = arg; 1663 struct v4l2_tuner *vt = arg;
1664 int mode = 0;
1684 1665
1685 chip->norm = vc->norm; 1666 switch (vt->audmode) {
1667 case V4L2_TUNER_MODE_MONO:
1668 mode = VIDEO_SOUND_MONO;
1669 break;
1670 case V4L2_TUNER_MODE_STEREO:
1671 mode = VIDEO_SOUND_STEREO;
1672 break;
1673 case V4L2_TUNER_MODE_LANG1:
1674 mode = VIDEO_SOUND_LANG1;
1675 break;
1676 case V4L2_TUNER_MODE_LANG2:
1677 mode = VIDEO_SOUND_LANG2;
1678 break;
1679 default:
1680 break;
1681 }
1682
1683 if (desc->setmode && mode) {
1684 chip->watch_stereo = 0;
1685 /* del_timer(&chip->wt); */
1686 chip->mode = mode;
1687 desc->setmode(chip, mode);
1688 }
1686 break; 1689 break;
1687 } 1690 }
1688 case VIDIOCSFREQ: 1691
1692 case VIDIOC_G_TUNER:
1689 { 1693 {
1694 struct v4l2_tuner *vt = arg;
1695 int mode = VIDEO_SOUND_MONO;
1696
1697 if (chip->radio)
1698 break;
1699 vt->audmode = 0;
1700 vt->rxsubchans = 0;
1701 vt->capability = V4L2_TUNER_CAP_STEREO |
1702 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
1703
1704 if (desc->getmode)
1705 mode = desc->getmode(chip);
1706
1707 if (mode & VIDEO_SOUND_MONO)
1708 vt->rxsubchans |= V4L2_TUNER_SUB_MONO;
1709 if (mode & VIDEO_SOUND_STEREO)
1710 vt->rxsubchans |= V4L2_TUNER_SUB_STEREO;
1711 if (mode & VIDEO_SOUND_LANG1)
1712 vt->rxsubchans |= V4L2_TUNER_SUB_LANG1 |
1713 V4L2_TUNER_SUB_LANG2;
1714
1715 mode = chip->mode;
1716 if (mode & VIDEO_SOUND_MONO)
1717 vt->audmode = V4L2_TUNER_MODE_MONO;
1718 if (mode & VIDEO_SOUND_STEREO)
1719 vt->audmode = V4L2_TUNER_MODE_STEREO;
1720 if (mode & VIDEO_SOUND_LANG1)
1721 vt->audmode = V4L2_TUNER_MODE_LANG1;
1722 if (mode & VIDEO_SOUND_LANG2)
1723 vt->audmode = V4L2_TUNER_MODE_LANG2;
1724 break;
1725 }
1726
1727 case VIDIOCSCHAN:
1728 case VIDIOC_S_STD:
1729 chip->radio = 0;
1730 break;
1731
1732 case VIDIOCSFREQ:
1733 case VIDIOC_S_FREQUENCY:
1690 chip->mode = 0; /* automatic */ 1734 chip->mode = 0; /* automatic */
1691 if (desc->checkmode) { 1735 if (desc->checkmode) {
1692 desc->setmode(chip,VIDEO_SOUND_MONO); 1736 desc->setmode(chip,VIDEO_SOUND_MONO);
@@ -1695,15 +1739,14 @@ static int chip_command(struct i2c_client *client,
1695 mod_timer(&chip->wt, jiffies+2*HZ); 1739 mod_timer(&chip->wt, jiffies+2*HZ);
1696 /* the thread will call checkmode() later */ 1740 /* the thread will call checkmode() later */
1697 } 1741 }
1698 } 1742 break;
1699 } 1743 }
1700 return 0; 1744 return 0;
1701} 1745}
1702 1746
1703
1704static struct i2c_driver driver = { 1747static struct i2c_driver driver = {
1705 .driver = { 1748 .driver = {
1706 .name = "generic i2c audio driver", 1749 .name = "tvaudio",
1707 }, 1750 },
1708 .id = I2C_DRIVERID_TVAUDIO, 1751 .id = I2C_DRIVERID_TVAUDIO,
1709 .attach_adapter = chip_probe, 1752 .attach_adapter = chip_probe,
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 8ac4cb82a459..fd0acc5da667 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -40,6 +40,7 @@
40 40
41#include <media/tuner.h> 41#include <media/tuner.h>
42#include <media/tveeprom.h> 42#include <media/tveeprom.h>
43#include <media/v4l2-common.h>
43#include <media/audiochip.h> 44#include <media/audiochip.h>
44 45
45MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver"); 46MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
@@ -52,21 +53,19 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
52 53
53#define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown") 54#define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown")
54 55
55#define tveeprom_info(fmt, arg...) do {\ 56#define tveeprom_info(fmt, arg...) \
56 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ 57 v4l_printk(KERN_INFO, "tveeprom", c->adapter, c->addr, fmt , ## arg)
57 c->adapter->nr, c->addr , ##arg); } while (0) 58#define tveeprom_warn(fmt, arg...) \
58#define tveeprom_warn(fmt, arg...) do {\ 59 v4l_printk(KERN_WARNING, "tveeprom", c->adapter, c->addr, fmt , ## arg)
59 printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \ 60#define tveeprom_dbg(fmt, arg...) do { \
60 c->adapter->nr, c->addr , ##arg); } while (0)
61#define tveeprom_dbg(fmt, arg...) do {\
62 if (debug) \ 61 if (debug) \
63 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ 62 v4l_printk(KERN_DEBUG, "tveeprom", c->adapter, c->addr, fmt , ## arg); \
64 c->adapter->nr, c->addr , ##arg); } while (0) 63 } while (0)
65
66
67/* ----------------------------------------------------------------------- */
68/* some hauppauge specific stuff */
69 64
65/*
66 * The Hauppauge eeprom uses an 8bit field to determine which
67 * tuner formats the tuner supports.
68 */
70static struct HAUPPAUGE_TUNER_FMT 69static struct HAUPPAUGE_TUNER_FMT
71{ 70{
72 int id; 71 int id;
@@ -74,14 +73,14 @@ static struct HAUPPAUGE_TUNER_FMT
74} 73}
75hauppauge_tuner_fmt[] = 74hauppauge_tuner_fmt[] =
76{ 75{
77 { 0x00000000, " unknown1" }, 76 { V4L2_STD_UNKNOWN," UNKNOWN" },
78 { 0x00000000, " unknown2" }, 77 { V4L2_STD_UNKNOWN," FM" },
79 { 0x00000007, " PAL(B/G)" }, 78 { V4L2_STD_PAL_BG, " PAL(B/G)" },
80 { 0x00001000, " NTSC(M)" }, 79 { V4L2_STD_NTSC_M, " NTSC(M)" },
81 { 0x00000010, " PAL(I)" }, 80 { V4L2_STD_PAL_I, " PAL(I)" },
82 { 0x00400000, " SECAM(L/L')" }, 81 { V4L2_STD_SECAM_L," SECAM(L/L')" },
83 { 0x00000e00, " PAL(D/K)" }, 82 { V4L2_STD_PAL_DK, " PAL(D/D1/K)" },
84 { 0x03000000, " ATSC/DVB Digital" }, 83 { V4L2_STD_ATSC, " ATSC/DVB Digital" },
85}; 84};
86 85
87/* This is the full list of possible tuners. Many thanks to Hauppauge for 86/* This is the full list of possible tuners. Many thanks to Hauppauge for
@@ -387,7 +386,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
387 if ((eeprom_data[0] == 0x1a) && (eeprom_data[1] == 0xeb) && 386 if ((eeprom_data[0] == 0x1a) && (eeprom_data[1] == 0xeb) &&
388 (eeprom_data[2] == 0x67) && (eeprom_data[3] == 0x95)) 387 (eeprom_data[2] == 0x67) && (eeprom_data[3] == 0x95))
389 start=0xa0; /* Generic em28xx offset */ 388 start=0xa0; /* Generic em28xx offset */
390 else if (((eeprom_data[0] & 0xf0) == 0x10) && 389 else if (((eeprom_data[0] & 0xe1) == 0x01) &&
391 (eeprom_data[1] == 0x00) && 390 (eeprom_data[1] == 0x00) &&
392 (eeprom_data[2] == 0x00) && 391 (eeprom_data[2] == 0x00) &&
393 (eeprom_data[8] == 0x84)) 392 (eeprom_data[8] == 0x84))
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index e837f9f7fed6..9e86caeb96a7 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -227,13 +227,9 @@ static int tvmixer_release(struct inode *inode, struct file *file)
227} 227}
228 228
229static struct i2c_driver driver = { 229static struct i2c_driver driver = {
230#ifdef I2C_PEC
231 .driver = { 230 .driver = {
232 .name = "tv card mixer driver", 231 .name = "tvmixer",
233 }, 232 },
234#else
235 .name = "tv card mixer driver",
236#endif
237 .id = I2C_DRIVERID_TVMIXER, 233 .id = I2C_DRIVERID_TVMIXER,
238 .detach_adapter = tvmixer_adapters, 234 .detach_adapter = tvmixer_adapters,
239 .attach_adapter = tvmixer_adapters, 235 .attach_adapter = tvmixer_adapters,
@@ -267,22 +263,8 @@ static int tvmixer_clients(struct i2c_client *client)
267 struct video_audio va; 263 struct video_audio va;
268 int i,minor; 264 int i,minor;
269 265
270#ifdef I2C_CLASS_TV_ANALOG
271 if (!(client->adapter->class & I2C_CLASS_TV_ANALOG)) 266 if (!(client->adapter->class & I2C_CLASS_TV_ANALOG))
272 return -1; 267 return -1;
273#else
274 /* TV card ??? */
275 switch (client->adapter->id) {
276 case I2C_HW_SMBUS_VOODOO3:
277 case I2C_HW_B_BT848:
278 case I2C_HW_B_RIVA:
279 /* ok, have a look ... */
280 break;
281 default:
282 /* ignore that one */
283 return -1;
284 }
285#endif
286 268
287 /* unregister ?? */ 269 /* unregister ?? */
288 for (i = 0; i < DEV_MAX; i++) { 270 for (i = 0; i < DEV_MAX; i++) {
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index a60442ea4f94..c35b8042eee5 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -9,6 +9,7 @@
9#include <linux/videodev.h> 9#include <linux/videodev.h>
10#include <linux/delay.h> 10#include <linux/delay.h>
11#include <linux/video_decoder.h> 11#include <linux/video_decoder.h>
12#include <media/v4l2-common.h>
12 13
13#include "tvp5150_reg.h" 14#include "tvp5150_reg.h"
14 15
@@ -28,33 +29,38 @@ static int debug = 0;
28module_param(debug, int, 0); 29module_param(debug, int, 0);
29MODULE_PARM_DESC(debug, "Debug level (0-1)"); 30MODULE_PARM_DESC(debug, "Debug level (0-1)");
30 31
31#define dprintk(num, format, args...) \ 32#define tvp5150_info(fmt, arg...) do { \
33 printk(KERN_INFO "%s %d-%04x: " fmt, c->driver->driver.name, \
34 i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0)
35#define tvp5150_dbg(num, fmt, arg...) \
32 do { \ 36 do { \
33 if (debug >= num) \ 37 if (debug >= num) \
34 printk(format, ##args); \ 38 printk(KERN_DEBUG "%s debug %d-%04x: " fmt,\
35 } while (0) 39 c->driver->driver.name, \
40 i2c_adapter_id(c->adapter), \
41 c->addr , ## arg); } while (0)
36 42
37/* supported controls */ 43/* supported controls */
38static struct v4l2_queryctrl tvp5150_qctrl[] = { 44static struct v4l2_queryctrl tvp5150_qctrl[] = {
39 { 45 {
40 .id = V4L2_CID_BRIGHTNESS, 46 .id = V4L2_CID_BRIGHTNESS,
41 .type = V4L2_CTRL_TYPE_INTEGER, 47 .type = V4L2_CTRL_TYPE_INTEGER,
42 .name = "Brightness", 48 .name = "Brightness",
43 .minimum = 0, 49 .minimum = 0,
44 .maximum = 255, 50 .maximum = 255,
45 .step = 1, 51 .step = 1,
46 .default_value = 0, 52 .default_value = 0,
47 .flags = 0, 53 .flags = 0,
48 }, { 54 }, {
49 .id = V4L2_CID_CONTRAST, 55 .id = V4L2_CID_CONTRAST,
50 .type = V4L2_CTRL_TYPE_INTEGER, 56 .type = V4L2_CTRL_TYPE_INTEGER,
51 .name = "Contrast", 57 .name = "Contrast",
52 .minimum = 0, 58 .minimum = 0,
53 .maximum = 255, 59 .maximum = 255,
54 .step = 0x1, 60 .step = 0x1,
55 .default_value = 0x10, 61 .default_value = 0x10,
56 .flags = 0, 62 .flags = 0,
57 }, { 63 }, {
58 .id = V4L2_CID_SATURATION, 64 .id = V4L2_CID_SATURATION,
59 .type = V4L2_CTRL_TYPE_INTEGER, 65 .type = V4L2_CTRL_TYPE_INTEGER,
60 .name = "Saturation", 66 .name = "Saturation",
@@ -63,16 +69,16 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = {
63 .step = 0x1, 69 .step = 0x1,
64 .default_value = 0x10, 70 .default_value = 0x10,
65 .flags = 0, 71 .flags = 0,
66 }, { 72 }, {
67 .id = V4L2_CID_HUE, 73 .id = V4L2_CID_HUE,
68 .type = V4L2_CTRL_TYPE_INTEGER, 74 .type = V4L2_CTRL_TYPE_INTEGER,
69 .name = "Hue", 75 .name = "Hue",
70 .minimum = -128, 76 .minimum = -128,
71 .maximum = 127, 77 .maximum = 127,
72 .step = 0x1, 78 .step = 0x1,
73 .default_value = 0x10, 79 .default_value = 0x10,
74 .flags = 0, 80 .flags = 0,
75 } 81 }
76}; 82};
77 83
78struct tvp5150 { 84struct tvp5150 {
@@ -94,12 +100,14 @@ static inline int tvp5150_read(struct i2c_client *c, unsigned char addr)
94 100
95 buffer[0] = addr; 101 buffer[0] = addr;
96 if (1 != (rc = i2c_master_send(c, buffer, 1))) 102 if (1 != (rc = i2c_master_send(c, buffer, 1)))
97 dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc); 103 tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
98 104
99 msleep(10); 105 msleep(10);
100 106
101 if (1 != (rc = i2c_master_recv(c, buffer, 1))) 107 if (1 != (rc = i2c_master_recv(c, buffer, 1)))
102 dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc); 108 tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
109
110 tvp5150_dbg(2, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]);
103 111
104 return (buffer[0]); 112 return (buffer[0]);
105} 113}
@@ -109,13 +117,12 @@ static inline void tvp5150_write(struct i2c_client *c, unsigned char addr,
109{ 117{
110 unsigned char buffer[2]; 118 unsigned char buffer[2];
111 int rc; 119 int rc;
112/* struct tvp5150 *core = i2c_get_clientdata(c); */
113 120
114 buffer[0] = addr; 121 buffer[0] = addr;
115 buffer[1] = value; 122 buffer[1] = value;
116 dprintk(1, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]); 123 tvp5150_dbg(2, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]);
117 if (2 != (rc = i2c_master_send(c, buffer, 2))) 124 if (2 != (rc = i2c_master_send(c, buffer, 2)))
118 dprintk(0, "i2c i/o error: rc == %d (should be 2)\n", rc); 125 tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 2)\n", rc);
119} 126}
120 127
121static void dump_reg(struct i2c_client *c) 128static void dump_reg(struct i2c_client *c)
@@ -437,48 +444,346 @@ enum tvp5150_input {
437static inline void tvp5150_selmux(struct i2c_client *c, 444static inline void tvp5150_selmux(struct i2c_client *c,
438 enum tvp5150_input input) 445 enum tvp5150_input input)
439{ 446{
447 int opmode=0;
448
440 struct tvp5150 *decoder = i2c_get_clientdata(c); 449 struct tvp5150 *decoder = i2c_get_clientdata(c);
441 450
442 if (!decoder->enable) 451 if (!decoder->enable)
443 input |= TVP5150_BLACK_SCREEN; 452 input |= TVP5150_BLACK_SCREEN;
444 453
454 switch (input) {
455 case TVP5150_ANALOG_CH0:
456 case TVP5150_ANALOG_CH1:
457 opmode=0x30; /* TV Mode */
458 break;
459 default:
460 opmode=0; /* Auto Mode */
461 break;
462 }
463
464 tvp5150_write(c, TVP5150_OP_MODE_CTL, opmode);
445 tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input); 465 tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input);
446}; 466};
447 467
448static inline void tvp5150_reset(struct i2c_client *c) 468struct i2c_reg_value {
469 unsigned char reg;
470 unsigned char value;
471};
472
473/* Default values as sugested at TVP5150AM1 datasheet */
474static const struct i2c_reg_value tvp5150_init_default[] = {
475 { /* 0x00 */
476 TVP5150_VD_IN_SRC_SEL_1,0x00
477 },
478 { /* 0x01 */
479 TVP5150_ANAL_CHL_CTL,0x15
480 },
481 { /* 0x02 */
482 TVP5150_OP_MODE_CTL,0x00
483 },
484 { /* 0x03 */
485 TVP5150_MISC_CTL,0x01
486 },
487 { /* 0x06 */
488 TVP5150_COLOR_KIL_THSH_CTL,0x10
489 },
490 { /* 0x07 */
491 TVP5150_LUMA_PROC_CTL_1,0x60
492 },
493 { /* 0x08 */
494 TVP5150_LUMA_PROC_CTL_2,0x00
495 },
496 { /* 0x09 */
497 TVP5150_BRIGHT_CTL,0x80
498 },
499 { /* 0x0a */
500 TVP5150_SATURATION_CTL,0x80
501 },
502 { /* 0x0b */
503 TVP5150_HUE_CTL,0x00
504 },
505 { /* 0x0c */
506 TVP5150_CONTRAST_CTL,0x80
507 },
508 { /* 0x0d */
509 TVP5150_DATA_RATE_SEL,0x47
510 },
511 { /* 0x0e */
512 TVP5150_LUMA_PROC_CTL_3,0x00
513 },
514 { /* 0x0f */
515 TVP5150_CONF_SHARED_PIN,0x08
516 },
517 { /* 0x11 */
518 TVP5150_ACT_VD_CROP_ST_MSB,0x00
519 },
520 { /* 0x12 */
521 TVP5150_ACT_VD_CROP_ST_LSB,0x00
522 },
523 { /* 0x13 */
524 TVP5150_ACT_VD_CROP_STP_MSB,0x00
525 },
526 { /* 0x14 */
527 TVP5150_ACT_VD_CROP_STP_LSB,0x00
528 },
529 { /* 0x15 */
530 TVP5150_GENLOCK,0x01
531 },
532 { /* 0x16 */
533 TVP5150_HORIZ_SYNC_START,0x80
534 },
535 { /* 0x18 */
536 TVP5150_VERT_BLANKING_START,0x00
537 },
538 { /* 0x19 */
539 TVP5150_VERT_BLANKING_STOP,0x00
540 },
541 { /* 0x1a */
542 TVP5150_CHROMA_PROC_CTL_1,0x0c
543 },
544 { /* 0x1b */
545 TVP5150_CHROMA_PROC_CTL_2,0x14
546 },
547 { /* 0x1c */
548 TVP5150_INT_RESET_REG_B,0x00
549 },
550 { /* 0x1d */
551 TVP5150_INT_ENABLE_REG_B,0x00
552 },
553 { /* 0x1e */
554 TVP5150_INTT_CONFIG_REG_B,0x00
555 },
556 { /* 0x28 */
557 TVP5150_VIDEO_STD,0x00
558 },
559 { /* 0x2e */
560 TVP5150_MACROVISION_ON_CTR,0x0f
561 },
562 { /* 0x2f */
563 TVP5150_MACROVISION_OFF_CTR,0x01
564 },
565 { /* 0xbb */
566 TVP5150_TELETEXT_FIL_ENA,0x00
567 },
568 { /* 0xc0 */
569 TVP5150_INT_STATUS_REG_A,0x00
570 },
571 { /* 0xc1 */
572 TVP5150_INT_ENABLE_REG_A,0x00
573 },
574 { /* 0xc2 */
575 TVP5150_INT_CONF,0x04
576 },
577 { /* 0xc8 */
578 TVP5150_FIFO_INT_THRESHOLD,0x80
579 },
580 { /* 0xc9 */
581 TVP5150_FIFO_RESET,0x00
582 },
583 { /* 0xca */
584 TVP5150_LINE_NUMBER_INT,0x00
585 },
586 { /* 0xcb */
587 TVP5150_PIX_ALIGN_REG_LOW,0x4e
588 },
589 { /* 0xcc */
590 TVP5150_PIX_ALIGN_REG_HIGH,0x00
591 },
592 { /* 0xcd */
593 TVP5150_FIFO_OUT_CTRL,0x01
594 },
595 { /* 0xcf */
596 TVP5150_FULL_FIELD_ENA_1,0x00
597 },
598 { /* 0xd0 */
599 TVP5150_FULL_FIELD_ENA_2,0x00
600 },
601 { /* 0xfc */
602 TVP5150_FULL_FIELD_MODE_REG,0x7f
603 },
604 { /* end of data */
605 0xff,0xff
606 }
607};
608
609/* Default values as sugested at TVP5150AM1 datasheet */
610static const struct i2c_reg_value tvp5150_init_enable[] = {
611 {
612 TVP5150_CONF_SHARED_PIN, 2
613 },{ /* Automatic offset and AGC enabled */
614 TVP5150_ANAL_CHL_CTL, 0x15
615 },{ /* Activate YCrCb output 0x9 or 0xd ? */
616 TVP5150_MISC_CTL, 0x6f
617 },{ /* Activates video std autodetection for all standards */
618 TVP5150_AUTOSW_MSK, 0x0
619 },{ /* Default format: 0x47. For 4:2:2: 0x40 */
620 TVP5150_DATA_RATE_SEL, 0x47
621 },{
622 TVP5150_CHROMA_PROC_CTL_1, 0x0c
623 },{
624 TVP5150_CHROMA_PROC_CTL_2, 0x54
625 },{ /* Non documented, but initialized on WinTV USB2 */
626 0x27, 0x20
627 },{
628 0xff,0xff
629 }
630};
631
632struct i2c_vbi_ram_value {
633 u16 reg;
634 unsigned char values[26];
635};
636
637struct i2c_vbi_ram_value vbi_ram_default[] =
449{ 638{
450 struct tvp5150 *decoder = i2c_get_clientdata(c); 639 {0x010, /* WST SECAM 6 */
640 { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x26, 0xe6, 0xb4, 0x0e, 0x0, 0x0, 0x0, 0x10, 0x0 }
641 },
642 {0x030, /* WST PAL B 6 */
643 { 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x2b, 0xa6, 0x72, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0 }
644 },
645 {0x050, /* WST PAL C 6 */
646 { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0xa6, 0x98, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 }
647 },
648 {0x070, /* WST NTSC 6 */
649 { 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 }
650 },
651 {0x090, /* NABTS, NTSC 6 */
652 { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x15, 0x0 }
653 },
654 {0x0b0, /* NABTS, NTSC-J 6 */
655 { 0xaa, 0xaa, 0xff, 0xff , 0xa7, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 }
656 },
657 {0x0d0, /* CC, PAL/SECAM 6 */
658 { 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0xa6, 0x7b, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 }
659 },
660 {0x0f0, /* CC, NTSC 6 */
661 { 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0x69, 0x8c, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 }
662 },
663 {0x110, /* WSS, PAL/SECAM 6 */
664 { 0x5b, 0x55, 0xc5, 0xff , 0x0, 0x71, 0x6e, 0x42, 0xa6, 0xcd, 0x0f, 0x0, 0x0, 0x0, 0x3a, 0x0 }
665 },
666 {0x130, /* WSS, NTSC C */
667 { 0x38, 0x00, 0x3f, 0x00 , 0x0, 0x71, 0x6e, 0x43, 0x69, 0x7c, 0x08, 0x0, 0x0, 0x0, 0x39, 0x0 }
668 },
669 {0x150, /* VITC, PAL/SECAM 6 */
670 { 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0xa6, 0x85, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 }
671 },
672 {0x170, /* VITC, NTSC 6 */
673 { 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0x69, 0x94, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 }
674 },
675 { (u16)-1 }
676};
451 677
452 tvp5150_write(c, TVP5150_CONF_SHARED_PIN, 2); 678static int tvp5150_write_inittab(struct i2c_client *c,
679 const struct i2c_reg_value *regs)
680{
681 while (regs->reg != 0xff) {
682 tvp5150_write(c, regs->reg, regs->value);
683 regs++;
684 }
685 return 0;
686}
453 687
454 /* Automatic offset and AGC enabled */ 688static int tvp5150_vdp_init(struct i2c_client *c,
455 tvp5150_write(c, TVP5150_ANAL_CHL_CTL, 0x15); 689 const struct i2c_vbi_ram_value *regs)
690{
691 unsigned int i;
456 692
457 /* Normal Operation */ 693 /* Disable Full Field */
458// tvp5150_write(c, TVP5150_OP_MODE_CTL, 0x00); 694 tvp5150_write(c, TVP5150_FULL_FIELD_ENA_1, 0);
459 695
460 /* Activate YCrCb output 0x9 or 0xd ? */ 696 /* Before programming, Line mode should be at 0xff */
461 tvp5150_write(c, TVP5150_MISC_CTL, 0x6f); 697 for (i=TVP5150_FULL_FIELD_ENA_2; i<=TVP5150_LINE_MODE_REG_44; i++)
698 tvp5150_write(c, i, 0xff);
462 699
463 /* Activates video std autodetection for all standards */ 700 /* Load Ram Table */
464 tvp5150_write(c, TVP5150_AUTOSW_MSK, 0x0); 701 while (regs->reg != (u16)-1 ) {
702 tvp5150_write(c, TVP5150_CONF_RAM_ADDR_HIGH,regs->reg>>8);
703 tvp5150_write(c, TVP5150_CONF_RAM_ADDR_LOW,regs->reg);
465 704
466 /* Default format: 0x47, 4:2:2: 0x40 */ 705 for (i=0;i<16;i++)
467 tvp5150_write(c, TVP5150_DATA_RATE_SEL, 0x47); 706 tvp5150_write(c, TVP5150_VDP_CONF_RAM_DATA,regs->values[i]);
468 707
469 tvp5150_selmux(c, decoder->input); 708 regs++;
709 }
710 return 0;
711}
712
713static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std)
714{
715 struct tvp5150 *decoder = i2c_get_clientdata(c);
716 int fmt=0;
717
718 decoder->norm=std;
719
720 /* First tests should be against specific std */
721
722 if (std == V4L2_STD_ALL) {
723 fmt=0; /* Autodetect mode */
724 } else if (std & V4L2_STD_NTSC_443) {
725 fmt=0xa;
726 } else if (std & V4L2_STD_PAL_M) {
727 fmt=0x6;
728 } else if (std & (V4L2_STD_PAL_N| V4L2_STD_PAL_Nc)) {
729 fmt=0x8;
730 } else {
731 /* Then, test against generic ones */
732 if (std & V4L2_STD_NTSC) {
733 fmt=0x2;
734 } else if (std & V4L2_STD_PAL) {
735 fmt=0x4;
736 } else if (std & V4L2_STD_SECAM) {
737 fmt=0xc;
738 }
739 }
740
741 tvp5150_dbg(1,"Set video std register to %d.\n",fmt);
742 tvp5150_write(c, TVP5150_VIDEO_STD, fmt);
470 743
471 tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_1, 0x0c); 744 return 0;
472 tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_2, 0x54); 745}
473 746
474 tvp5150_write(c, 0x27, 0x20); /* ?????????? */ 747static inline void tvp5150_reset(struct i2c_client *c)
748{
749 u8 type, ver_656, msb_id, lsb_id, msb_rom, lsb_rom;
750 struct tvp5150 *decoder = i2c_get_clientdata(c);
475 751
476 tvp5150_write(c, TVP5150_VIDEO_STD, 0x0); /* Auto switch */ 752 type=tvp5150_read(c,TVP5150_AUTOSW_MSK);
753 msb_id=tvp5150_read(c,TVP5150_MSB_DEV_ID);
754 lsb_id=tvp5150_read(c,TVP5150_LSB_DEV_ID);
755 msb_rom=tvp5150_read(c,TVP5150_ROM_MAJOR_VER);
756 lsb_rom=tvp5150_read(c,TVP5150_ROM_MINOR_VER);
757
758 if (type==0xdc) {
759 ver_656=tvp5150_read(c,TVP5150_REV_SELECT);
760 tvp5150_info("tvp%02x%02xam1 detected 656 version is %d.\n",msb_id, lsb_id,ver_656);
761 } else if (type==0xfc) {
762 tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id);
763 } else {
764 tvp5150_info("unknown tvp%02x%02x chip detected(%d).\n",msb_id,lsb_id,type);
765 }
766 tvp5150_info("Rom ver is %d.%d\n",msb_rom,lsb_rom);
477 767
768 /* Initializes TVP5150 to its default values */
769 tvp5150_write_inittab(c, tvp5150_init_default);
770
771 /* Initializes VDP registers */
772 tvp5150_vdp_init(c, vbi_ram_default);
773
774 /* Selects decoder input */
775 tvp5150_selmux(c, decoder->input);
776
777 /* Initializes TVP5150 to stream enabled values */
778 tvp5150_write_inittab(c, tvp5150_init_enable);
779
780 /* Initialize image preferences */
478 tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright >> 8); 781 tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright >> 8);
479 tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast >> 8); 782 tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast >> 8);
480 tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast >> 8); 783 tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast >> 8);
481 tvp5150_write(c, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8); 784 tvp5150_write(c, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8);
785
786 tvp5150_set_std(c, decoder->norm);
482}; 787};
483 788
484static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) 789static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
@@ -498,9 +803,8 @@ static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
498 case V4L2_CID_HUE: 803 case V4L2_CID_HUE:
499 ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL); 804 ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL);
500 return 0; 805 return 0;
501 default:
502 return -EINVAL;
503 } 806 }
807 return -EINVAL;
504} 808}
505 809
506static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) 810static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
@@ -520,28 +824,59 @@ static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
520 case V4L2_CID_HUE: 824 case V4L2_CID_HUE:
521 tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value); 825 tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value);
522 return 0; 826 return 0;
523 default:
524 return -EINVAL;
525 } 827 }
828 return -EINVAL;
526} 829}
527 830
528/**************************************************************************** 831/****************************************************************************
529 I2C Command 832 I2C Command
530 ****************************************************************************/ 833 ****************************************************************************/
531static int tvp5150_command(struct i2c_client *client, 834static int tvp5150_command(struct i2c_client *c,
532 unsigned int cmd, void *arg) 835 unsigned int cmd, void *arg)
533{ 836{
534 struct tvp5150 *decoder = i2c_get_clientdata(client); 837 struct tvp5150 *decoder = i2c_get_clientdata(c);
535 838
536 switch (cmd) { 839 switch (cmd) {
537 840
538 case 0: 841 case 0:
842 case VIDIOC_INT_RESET:
539 case DECODER_INIT: 843 case DECODER_INIT:
540 tvp5150_reset(client); 844 tvp5150_reset(c);
845 break;
846 case VIDIOC_S_STD:
847 if (decoder->norm == *(v4l2_std_id *)arg)
848 break;
849 return tvp5150_set_std(c, *(v4l2_std_id *)arg);
850 case VIDIOC_G_STD:
851 *(v4l2_std_id *)arg = decoder->norm;
852 break;
853
854#ifdef CONFIG_VIDEO_ADV_DEBUG
855 case VIDIOC_INT_G_REGISTER:
856 {
857 struct v4l2_register *reg = arg;
858
859 if (reg->i2c_id != I2C_DRIVERID_TVP5150)
860 return -EINVAL;
861 reg->val = tvp5150_read(c, reg->reg & 0xff);
862 break;
863 }
864
865 case VIDIOC_INT_S_REGISTER:
866 {
867 struct v4l2_register *reg = arg;
868
869 if (reg->i2c_id != I2C_DRIVERID_TVP5150)
870 return -EINVAL;
871 if (!capable(CAP_SYS_ADMIN))
872 return -EPERM;
873 tvp5150_write(c, reg->reg & 0xff, reg->val & 0xff);
541 break; 874 break;
875 }
876#endif
542 877
543 case DECODER_DUMP: 878 case DECODER_DUMP:
544 dump_reg(client); 879 dump_reg(c);
545 break; 880 break;
546 881
547 case DECODER_GET_CAPABILITIES: 882 case DECODER_GET_CAPABILITIES:
@@ -600,7 +935,7 @@ static int tvp5150_command(struct i2c_client *client,
600 } 935 }
601 936
602 decoder->input = *iarg; 937 decoder->input = *iarg;
603 tvp5150_selmux(client, decoder->input); 938 tvp5150_selmux(c, decoder->input);
604 939
605 break; 940 break;
606 } 941 }
@@ -620,19 +955,18 @@ static int tvp5150_command(struct i2c_client *client,
620 955
621 decoder->enable = (*iarg != 0); 956 decoder->enable = (*iarg != 0);
622 957
623 tvp5150_selmux(client, decoder->input); 958 tvp5150_selmux(c, decoder->input);
624 959
625 break; 960 break;
626 } 961 }
627 case VIDIOC_QUERYCTRL: 962 case VIDIOC_QUERYCTRL:
628 { 963 {
629 struct v4l2_queryctrl *qc = arg; 964 struct v4l2_queryctrl *qc = arg;
630 u8 i, n; 965 int i;
631 966
632 dprintk(1, KERN_DEBUG "VIDIOC_QUERYCTRL"); 967 tvp5150_dbg(1, "VIDIOC_QUERYCTRL called\n");
633 968
634 n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]); 969 for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++)
635 for (i = 0; i < n; i++)
636 if (qc->id && qc->id == tvp5150_qctrl[i].id) { 970 if (qc->id && qc->id == tvp5150_qctrl[i].id) {
637 memcpy(qc, &(tvp5150_qctrl[i]), 971 memcpy(qc, &(tvp5150_qctrl[i]),
638 sizeof(*qc)); 972 sizeof(*qc));
@@ -644,16 +978,14 @@ static int tvp5150_command(struct i2c_client *client,
644 case VIDIOC_G_CTRL: 978 case VIDIOC_G_CTRL:
645 { 979 {
646 struct v4l2_control *ctrl = arg; 980 struct v4l2_control *ctrl = arg;
647 dprintk(1, KERN_DEBUG "VIDIOC_G_CTRL"); 981 tvp5150_dbg(1, "VIDIOC_G_CTRL called\n");
648 982
649 return tvp5150_get_ctrl(client, ctrl); 983 return tvp5150_get_ctrl(c, ctrl);
650 } 984 }
651 case VIDIOC_S_CTRL_OLD: /* ??? */
652 case VIDIOC_S_CTRL: 985 case VIDIOC_S_CTRL:
653 { 986 {
654 struct v4l2_control *ctrl = arg; 987 struct v4l2_control *ctrl = arg;
655 u8 i, n; 988 u8 i, n;
656 dprintk(1, KERN_DEBUG "VIDIOC_S_CTRL");
657 n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]); 989 n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
658 for (i = 0; i < n; i++) 990 for (i = 0; i < n; i++)
659 if (ctrl->id == tvp5150_qctrl[i].id) { 991 if (ctrl->id == tvp5150_qctrl[i].id) {
@@ -662,11 +994,10 @@ static int tvp5150_command(struct i2c_client *client,
662 || ctrl->value > 994 || ctrl->value >
663 tvp5150_qctrl[i].maximum) 995 tvp5150_qctrl[i].maximum)
664 return -ERANGE; 996 return -ERANGE;
665 dprintk(1, 997 tvp5150_dbg(1,
666 KERN_DEBUG 998 "VIDIOC_S_CTRL: id=%d, value=%d\n",
667 "VIDIOC_S_CTRL: id=%d, value=%d",
668 ctrl->id, ctrl->value); 999 ctrl->id, ctrl->value);
669 return tvp5150_set_ctrl(client, ctrl); 1000 return tvp5150_set_ctrl(c, ctrl);
670 } 1001 }
671 return -EINVAL; 1002 return -EINVAL;
672 } 1003 }
@@ -677,25 +1008,25 @@ static int tvp5150_command(struct i2c_client *client,
677 if (decoder->bright != pic->brightness) { 1008 if (decoder->bright != pic->brightness) {
678 /* We want 0 to 255 we get 0-65535 */ 1009 /* We want 0 to 255 we get 0-65535 */
679 decoder->bright = pic->brightness; 1010 decoder->bright = pic->brightness;
680 tvp5150_write(client, TVP5150_BRIGHT_CTL, 1011 tvp5150_write(c, TVP5150_BRIGHT_CTL,
681 decoder->bright >> 8); 1012 decoder->bright >> 8);
682 } 1013 }
683 if (decoder->contrast != pic->contrast) { 1014 if (decoder->contrast != pic->contrast) {
684 /* We want 0 to 255 we get 0-65535 */ 1015 /* We want 0 to 255 we get 0-65535 */
685 decoder->contrast = pic->contrast; 1016 decoder->contrast = pic->contrast;
686 tvp5150_write(client, TVP5150_CONTRAST_CTL, 1017 tvp5150_write(c, TVP5150_CONTRAST_CTL,
687 decoder->contrast >> 8); 1018 decoder->contrast >> 8);
688 } 1019 }
689 if (decoder->sat != pic->colour) { 1020 if (decoder->sat != pic->colour) {
690 /* We want 0 to 255 we get 0-65535 */ 1021 /* We want 0 to 255 we get 0-65535 */
691 decoder->sat = pic->colour; 1022 decoder->sat = pic->colour;
692 tvp5150_write(client, TVP5150_SATURATION_CTL, 1023 tvp5150_write(c, TVP5150_SATURATION_CTL,
693 decoder->contrast >> 8); 1024 decoder->contrast >> 8);
694 } 1025 }
695 if (decoder->hue != pic->hue) { 1026 if (decoder->hue != pic->hue) {
696 /* We want -128 to 127 we get 0-65535 */ 1027 /* We want -128 to 127 we get 0-65535 */
697 decoder->hue = pic->hue; 1028 decoder->hue = pic->hue;
698 tvp5150_write(client, TVP5150_HUE_CTL, 1029 tvp5150_write(c, TVP5150_HUE_CTL,
699 (decoder->hue - 32768) >> 8); 1030 (decoder->hue - 32768) >> 8);
700 } 1031 }
701 break; 1032 break;
@@ -720,12 +1051,12 @@ static struct i2c_client client_template = {
720static int tvp5150_detect_client(struct i2c_adapter *adapter, 1051static int tvp5150_detect_client(struct i2c_adapter *adapter,
721 int address, int kind) 1052 int address, int kind)
722{ 1053{
723 struct i2c_client *client; 1054 struct i2c_client *c;
724 struct tvp5150 *core; 1055 struct tvp5150 *core;
725 int rv; 1056 int rv;
726 1057
727 dprintk(1, 1058 if (debug)
728 KERN_INFO 1059 printk( KERN_INFO
729 "tvp5150.c: detecting tvp5150 client on address 0x%x\n", 1060 "tvp5150.c: detecting tvp5150 client on address 0x%x\n",
730 address << 1); 1061 address << 1);
731 1062
@@ -738,22 +1069,22 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter,
738 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) 1069 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
739 return 0; 1070 return 0;
740 1071
741 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); 1072 c = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
742 if (client == 0) 1073 if (c == 0)
743 return -ENOMEM; 1074 return -ENOMEM;
744 memcpy(client, &client_template, sizeof(struct i2c_client)); 1075 memcpy(c, &client_template, sizeof(struct i2c_client));
745 1076
746 core = kmalloc(sizeof(struct tvp5150), GFP_KERNEL); 1077 core = kmalloc(sizeof(struct tvp5150), GFP_KERNEL);
747 if (core == 0) { 1078 if (core == 0) {
748 kfree(client); 1079 kfree(c);
749 return -ENOMEM; 1080 return -ENOMEM;
750 } 1081 }
751 memset(core, 0, sizeof(struct tvp5150)); 1082 memset(core, 0, sizeof(struct tvp5150));
752 i2c_set_clientdata(client, core); 1083 i2c_set_clientdata(c, core);
753 1084
754 rv = i2c_attach_client(client); 1085 rv = i2c_attach_client(c);
755 1086
756 core->norm = VIDEO_MODE_AUTO; 1087 core->norm = V4L2_STD_ALL;
757 core->input = 2; 1088 core->input = 2;
758 core->enable = 1; 1089 core->enable = 1;
759 core->bright = 32768; 1090 core->bright = 32768;
@@ -762,37 +1093,41 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter,
762 core->sat = 32768; 1093 core->sat = 32768;
763 1094
764 if (rv) { 1095 if (rv) {
765 kfree(client); 1096 kfree(c);
766 kfree(core); 1097 kfree(core);
767 return rv; 1098 return rv;
768 } 1099 }
769 1100
770 if (debug > 1) 1101 if (debug > 1)
771 dump_reg(client); 1102 dump_reg(c);
772 return 0; 1103 return 0;
773} 1104}
774 1105
775static int tvp5150_attach_adapter(struct i2c_adapter *adapter) 1106static int tvp5150_attach_adapter(struct i2c_adapter *adapter)
776{ 1107{
777 dprintk(1, 1108 if (debug)
778 KERN_INFO 1109 printk( KERN_INFO
779 "tvp5150.c: starting probe for adapter %s (0x%x)\n", 1110 "tvp5150.c: starting probe for adapter %s (0x%x)\n",
780 adapter->name, adapter->id); 1111 adapter->name, adapter->id);
781 return i2c_probe(adapter, &addr_data, &tvp5150_detect_client); 1112 return i2c_probe(adapter, &addr_data, &tvp5150_detect_client);
782} 1113}
783 1114
784static int tvp5150_detach_client(struct i2c_client *client) 1115static int tvp5150_detach_client(struct i2c_client *c)
785{ 1116{
786 struct tvp5150 *decoder = i2c_get_clientdata(client); 1117 struct tvp5150 *decoder = i2c_get_clientdata(c);
787 int err; 1118 int err;
788 1119
789 err = i2c_detach_client(client); 1120 tvp5150_dbg(1,
1121 "tvp5150.c: removing tvp5150 adapter on address 0x%x\n",
1122 c->addr << 1);
1123
1124 err = i2c_detach_client(c);
790 if (err) { 1125 if (err) {
791 return err; 1126 return err;
792 } 1127 }
793 1128
794 kfree(decoder); 1129 kfree(decoder);
795 kfree(client); 1130 kfree(c);
796 1131
797 return 0; 1132 return 0;
798} 1133}
@@ -803,9 +1138,7 @@ static struct i2c_driver driver = {
803 .driver = { 1138 .driver = {
804 .name = "tvp5150", 1139 .name = "tvp5150",
805 }, 1140 },
806 1141 .id = I2C_DRIVERID_TVP5150,
807 /* FIXME */
808 .id = I2C_DRIVERID_SAA7110,
809 1142
810 .attach_adapter = tvp5150_attach_adapter, 1143 .attach_adapter = tvp5150_attach_adapter,
811 .detach_client = tvp5150_detach_client, 1144 .detach_client = tvp5150_detach_client,
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 4134549d11a8..2ab5b4093800 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -951,6 +951,10 @@ v4l_compat_translate_ioctl(struct inode *inode,
951 dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err); 951 dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err);
952 break; 952 break;
953 } 953 }
954 if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) {
955 err = -EINVAL;
956 break;
957 }
954 memset(fmt, 0, sizeof(*fmt)); 958 memset(fmt, 0, sizeof(*fmt));
955 fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line; 959 fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
956 fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate; 960 fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate;
@@ -966,6 +970,11 @@ v4l_compat_translate_ioctl(struct inode *inode,
966 { 970 {
967 struct vbi_format *fmt = arg; 971 struct vbi_format *fmt = arg;
968 972
973 if (VIDEO_PALETTE_RAW != fmt->sample_format) {
974 err = -EINVAL;
975 break;
976 }
977
969 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL); 978 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
970 memset(fmt2, 0, sizeof(*fmt2)); 979 memset(fmt2, 0, sizeof(*fmt2));
971 980
@@ -986,7 +995,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
986 995
987 if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line || 996 if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line ||
988 fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate || 997 fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate ||
989 VIDEO_PALETTE_RAW != fmt->sample_format || 998 fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY ||
990 fmt2->fmt.vbi.start[0] != fmt->start[0] || 999 fmt2->fmt.vbi.start[0] != fmt->start[0] ||
991 fmt2->fmt.vbi.count[0] != fmt->count[0] || 1000 fmt2->fmt.vbi.count[0] != fmt->count[0] ||
992 fmt2->fmt.vbi.start[1] != fmt->start[1] || 1001 fmt2->fmt.vbi.start[1] != fmt->start[1] ||
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 597b8db35a13..5dbd7c1b362a 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -58,6 +58,8 @@
58#include <asm/pgtable.h> 58#include <asm/pgtable.h>
59#include <asm/io.h> 59#include <asm/io.h>
60#include <asm/div64.h> 60#include <asm/div64.h>
61#include <linux/video_decoder.h>
62#include <media/v4l2-common.h>
61 63
62#ifdef CONFIG_KMOD 64#ifdef CONFIG_KMOD
63#include <linux/kmod.h> 65#include <linux/kmod.h>
@@ -190,57 +192,174 @@ char *v4l2_type_names[] = {
190 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", 192 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
191}; 193};
192 194
193char *v4l2_ioctl_names[256] = { 195/* ------------------------------------------------------------------ */
194#if __GNUC__ >= 3 196/* debug help functions */
195 [0 ... 255] = "UNKNOWN", 197
198#ifdef HAVE_V4L1
199static const char *v4l1_ioctls[] = {
200 [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
201 [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
202 [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
203 [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
204 [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
205 [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
206 [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
207 [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
208 [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
209 [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
210 [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
211 [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
212 [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
213 [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
214 [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
215 [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
216 [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
217 [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
218 [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
219 [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
220 [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
221 [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
222 [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
223 [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
224 [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
225 [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
226 [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
227 [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
228 [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
229};
230#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
231#endif
232
233static const char *v4l2_ioctls[] = {
234 [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
235 [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
236 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
237 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
238 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
239 [_IOC_NR(VIDIOC_G_MPEGCOMP)] = "VIDIOC_G_MPEGCOMP",
240 [_IOC_NR(VIDIOC_S_MPEGCOMP)] = "VIDIOC_S_MPEGCOMP",
241 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
242 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
243 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
244 [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
245 [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
246 [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
247 [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
248 [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
249 [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
250 [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
251 [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
252 [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
253 [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
254 [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
255 [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
256 [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
257 [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
258 [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
259 [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
260 [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
261 [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
262 [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
263 [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
264 [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
265 [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
266 [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
267 [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
268 [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
269 [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
270 [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
271 [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
272 [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
273 [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
274 [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
275 [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
276 [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
277 [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
278 [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
279 [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
280 [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
281 [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
282 [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
283 [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
284 [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
285 [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
286#if 1
287 [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
196#endif 288#endif
197 [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", 289 [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS"
198 [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
199 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
200 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
201 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
202 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
203 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
204 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
205 [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
206 [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
207 [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
208 [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
209 [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
210 [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
211 [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
212 [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
213 [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
214 [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
215 [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
216 [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
217 [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
218 [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
219 [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
220 [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
221 [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
222 [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
223 [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
224 [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
225 [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
226 [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
227 [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
228 [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
229 [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
230 [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
231 [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
232 [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
233 [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
234 [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
235 [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
236 [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
237 [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
238 [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
239 [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
240 [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
241 [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
242 [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
243}; 290};
291#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
292
293static const char *v4l2_int_ioctls[] = {
294#ifdef HAVE_VIDEO_DECODER
295 [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES",
296 [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS",
297 [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM",
298 [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT",
299 [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT",
300 [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT",
301 [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE",
302 [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO",
303 [_IOC_NR(DECODER_INIT)] = "DECODER_INIT",
304 [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS",
305 [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP",
306#endif
307 [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO",
308 [_IOC_NR(AUDC_SET_INPUT)] = "AUDC_SET_INPUT",
309
310 [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR",
311 [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
312 [_IOC_NR(TDA9887_SET_CONFIG)] = "TDA9887_SET_CONFIG",
313
314 [_IOC_NR(VIDIOC_INT_S_REGISTER)] = "VIDIOC_INT_S_REGISTER",
315 [_IOC_NR(VIDIOC_INT_G_REGISTER)] = "VIDIOC_INT_G_REGISTER",
316 [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
317 [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
318 [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE",
319 [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
320 [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
321 [_IOC_NR(VIDIOC_INT_G_CHIP_IDENT)] = "VIDIOC_INT_G_CHIP_IDENT",
322 [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ"
323};
324#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
325
326/* Common ioctl debug function. This function can be used by
327 external ioctl messages as well as internal V4L ioctl */
328void v4l_printk_ioctl(unsigned int cmd)
329{
330 char *dir;
331
332 switch (_IOC_DIR(cmd)) {
333 case _IOC_NONE: dir = "--"; break;
334 case _IOC_READ: dir = "r-"; break;
335 case _IOC_WRITE: dir = "-w"; break;
336 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
337 default: dir = "*ERR*"; break;
338 }
339 switch (_IOC_TYPE(cmd)) {
340 case 'd':
341 printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n",
342 (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ?
343 v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
344 break;
345#ifdef HAVE_V4L1
346 case 'v':
347 printk("v4l1 ioctl %s, dir=%s (0x%08x)\n",
348 (_IOC_NR(cmd) < V4L1_IOCTLS) ?
349 v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
350 break;
351#endif
352 case 'V':
353 printk("v4l2 ioctl %s, dir=%s (0x%08x)\n",
354 (_IOC_NR(cmd) < V4L2_IOCTLS) ?
355 v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
356 break;
357
358 default:
359 printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n",
360 _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
361 }
362}
244 363
245/* ----------------------------------------------------------------- */ 364/* ----------------------------------------------------------------- */
246 365
@@ -255,7 +374,7 @@ EXPORT_SYMBOL(v4l2_prio_check);
255 374
256EXPORT_SYMBOL(v4l2_field_names); 375EXPORT_SYMBOL(v4l2_field_names);
257EXPORT_SYMBOL(v4l2_type_names); 376EXPORT_SYMBOL(v4l2_type_names);
258EXPORT_SYMBOL(v4l2_ioctl_names); 377EXPORT_SYMBOL(v4l_printk_ioctl);
259 378
260/* 379/*
261 * Local variables: 380 * Local variables:
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 6de5b0094b82..9a9902c56ae7 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -68,7 +68,8 @@ static void video_release(struct class_device *cd)
68{ 68{
69 struct video_device *vfd = container_of(cd, struct video_device, class_dev); 69 struct video_device *vfd = container_of(cd, struct video_device, class_dev);
70 70
71#if 1 /* needed until all drivers are fixed */ 71#if 1
72 /* needed until all drivers are fixed */
72 if (!vfd->release) 73 if (!vfd->release)
73 return; 74 return;
74#endif 75#endif
@@ -338,13 +339,14 @@ int video_register_device(struct video_device *vfd, int type, int nr)
338 if (vfd->dev) 339 if (vfd->dev)
339 vfd->class_dev.dev = vfd->dev; 340 vfd->class_dev.dev = vfd->dev;
340 vfd->class_dev.class = &video_class; 341 vfd->class_dev.class = &video_class;
341 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); 342 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
342 strlcpy(vfd->class_dev.class_id, vfd->devfs_name + 4, BUS_ID_SIZE); 343 strlcpy(vfd->class_dev.class_id, vfd->devfs_name + 4, BUS_ID_SIZE);
343 class_device_register(&vfd->class_dev); 344 class_device_register(&vfd->class_dev);
344 class_device_create_file(&vfd->class_dev, 345 class_device_create_file(&vfd->class_dev,
345 &class_device_attr_name); 346 &class_device_attr_name);
346 347
347#if 1 /* needed until all drivers are fixed */ 348#if 1
349 /* needed until all drivers are fixed */
348 if (!vfd->release) 350 if (!vfd->release)
349 printk(KERN_WARNING "videodev: \"%s\" has no release callback. " 351 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
350 "Please fix your driver for proper sysfs support, see " 352 "Please fix your driver for proper sysfs support, see "
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index c318ba32fbaf..b7b0afffd214 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -187,6 +187,7 @@ static struct file_operations w9966_fops = {
187 .open = video_exclusive_open, 187 .open = video_exclusive_open,
188 .release = video_exclusive_release, 188 .release = video_exclusive_release,
189 .ioctl = w9966_v4l_ioctl, 189 .ioctl = w9966_v4l_ioctl,
190 .compat_ioctl = v4l_compat_ioctl32,
190 .read = w9966_v4l_read, 191 .read = w9966_v4l_read,
191 .llseek = no_llseek, 192 .llseek = no_llseek,
192}; 193};
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index bbfd55cd9948..c2e6d2e9f5f1 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -25,7 +25,6 @@
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */ 26 */
27 27
28
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/types.h> 29#include <linux/types.h>
31#include <linux/ioctl.h> 30#include <linux/ioctl.h>
@@ -33,20 +32,12 @@
33#include <linux/i2c.h> 32#include <linux/i2c.h>
34#include <linux/i2c-id.h> 33#include <linux/i2c-id.h>
35#include <linux/videodev.h> 34#include <linux/videodev.h>
36#include <media/audiochip.h> 35#include <media/v4l2-common.h>
37 36
38MODULE_DESCRIPTION("wm8775 driver"); 37MODULE_DESCRIPTION("wm8775 driver");
39MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); 38MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
40MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
41 40
42#define wm8775_err(fmt, arg...) do { \
43 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
44 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
45#define wm8775_info(fmt, arg...) do { \
46 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
47 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
48
49
50static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END }; 41static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END };
51 42
52 43
@@ -70,7 +61,7 @@ static int wm8775_write(struct i2c_client *client, int reg, u16 val)
70 int i; 61 int i;
71 62
72 if (reg < 0 || reg >= TOT_REGS) { 63 if (reg < 0 || reg >= TOT_REGS) {
73 wm8775_err("Invalid register R%d\n", reg); 64 v4l_err(client, "Invalid register R%d\n", reg);
74 return -1; 65 return -1;
75 } 66 }
76 67
@@ -80,7 +71,7 @@ static int wm8775_write(struct i2c_client *client, int reg, u16 val)
80 return 0; 71 return 0;
81 } 72 }
82 } 73 }
83 wm8775_err("I2C: cannot write %03x to register R%d\n", val, reg); 74 v4l_err(client, "I2C: cannot write %03x to register R%d\n", val, reg);
84 return -1; 75 return -1;
85} 76}
86 77
@@ -88,38 +79,53 @@ static int wm8775_command(struct i2c_client *client, unsigned int cmd,
88 void *arg) 79 void *arg)
89{ 80{
90 struct wm8775_state *state = i2c_get_clientdata(client); 81 struct wm8775_state *state = i2c_get_clientdata(client);
91 int *input = arg; 82 struct v4l2_audio *input = arg;
83 struct v4l2_control *ctrl = arg;
92 84
93 switch (cmd) { 85 switch (cmd) {
94 case AUDC_SET_INPUT: 86 case VIDIOC_S_AUDIO:
87 /* There are 4 inputs and one output. Zero or more inputs
88 are multiplexed together to the output. Hence there are
89 16 combinations.
90 If only one input is active (the normal case) then the
91 input values 1, 2, 4 or 8 should be used. */
92 if (input->index > 15) {
93 v4l_err(client, "Invalid input %d.\n", input->index);
94 return -EINVAL;
95 }
96 state->input = input->index;
97 if (state->muted)
98 break;
95 wm8775_write(client, R21, 0x0c0); 99 wm8775_write(client, R21, 0x0c0);
96 wm8775_write(client, R14, 0x1d4); 100 wm8775_write(client, R14, 0x1d4);
97 wm8775_write(client, R15, 0x1d4); 101 wm8775_write(client, R15, 0x1d4);
102 wm8775_write(client, R21, 0x100 + state->input);
103 break;
98 104
99 if (*input == AUDIO_RADIO) { 105 case VIDIOC_G_AUDIO:
100 wm8775_write(client, R21, 0x108); 106 memset(input, 0, sizeof(*input));
101 state->input = 8; 107 input->index = state->input;
102 state->muted = 0; 108 break;
103 break; 109
104 } 110 case VIDIOC_G_CTRL:
105 if (*input == AUDIO_MUTE) { 111 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
106 state->muted = 1; 112 return -EINVAL;
107 break; 113 ctrl->value = state->muted;
108 } 114 break;
109 if (*input == AUDIO_UNMUTE) { 115
116 case VIDIOC_S_CTRL:
117 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
118 return -EINVAL;
119 state->muted = ctrl->value;
120 wm8775_write(client, R21, 0x0c0);
121 wm8775_write(client, R14, 0x1d4);
122 wm8775_write(client, R15, 0x1d4);
123 if (!state->muted)
110 wm8775_write(client, R21, 0x100 + state->input); 124 wm8775_write(client, R21, 0x100 + state->input);
111 state->muted = 0;
112 break;
113 }
114 /* All other inputs... */
115 wm8775_write(client, R21, 0x102);
116 state->input = 2;
117 state->muted = 0;
118 break; 125 break;
119 126
120 case VIDIOC_LOG_STATUS: 127 case VIDIOC_LOG_STATUS:
121 wm8775_info("Input: %s%s\n", 128 v4l_info(client, "Input: %d%s\n", state->input,
122 state->input == 8 ? "radio" : "default",
123 state->muted ? " (muted)" : ""); 129 state->muted ? " (muted)" : "");
124 break; 130 break;
125 131
@@ -170,7 +176,7 @@ static int wm8775_attach(struct i2c_adapter *adapter, int address, int kind)
170 client->driver = &i2c_driver; 176 client->driver = &i2c_driver;
171 snprintf(client->name, sizeof(client->name) - 1, "wm8775"); 177 snprintf(client->name, sizeof(client->name) - 1, "wm8775");
172 178
173 wm8775_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name); 179 v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name);
174 180
175 state = kmalloc(sizeof(struct wm8775_state), GFP_KERNEL); 181 state = kmalloc(sizeof(struct wm8775_state), GFP_KERNEL);
176 if (state == NULL) { 182 if (state == NULL) {
@@ -206,11 +212,7 @@ static int wm8775_attach(struct i2c_adapter *adapter, int address, int kind)
206 212
207static int wm8775_probe(struct i2c_adapter *adapter) 213static int wm8775_probe(struct i2c_adapter *adapter)
208{ 214{
209#ifdef I2C_CLASS_TV_ANALOG
210 if (adapter->class & I2C_CLASS_TV_ANALOG) 215 if (adapter->class & I2C_CLASS_TV_ANALOG)
211#else
212 if (adapter->id == I2C_HW_B_BT848)
213#endif
214 return i2c_probe(adapter, &addr_data, wm8775_attach); 216 return i2c_probe(adapter, &addr_data, wm8775_attach);
215 return 0; 217 return 0;
216} 218}
@@ -235,12 +237,10 @@ static struct i2c_driver i2c_driver = {
235 .driver = { 237 .driver = {
236 .name = "wm8775", 238 .name = "wm8775",
237 }, 239 },
238 240 .id = I2C_DRIVERID_WM8775,
239 .id = I2C_DRIVERID_WM8775,
240
241 .attach_adapter = wm8775_probe, 241 .attach_adapter = wm8775_probe,
242 .detach_client = wm8775_detach, 242 .detach_client = wm8775_detach,
243 .command = wm8775_command, 243 .command = wm8775_command,
244}; 244};
245 245
246 246
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 4034f1b45366..15283f44e79f 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -4678,6 +4678,7 @@ static struct file_operations zoran_fops = {
4678 .open = zoran_open, 4678 .open = zoran_open,
4679 .release = zoran_close, 4679 .release = zoran_close,
4680 .ioctl = zoran_ioctl, 4680 .ioctl = zoran_ioctl,
4681 .compat_ioctl = v4l_compat_ioctl32,
4681 .llseek = no_llseek, 4682 .llseek = no_llseek,
4682 .read = zoran_read, 4683 .read = zoran_read,
4683 .write = zoran_write, 4684 .write = zoran_write,
diff --git a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c
index 07286816d7df..d4c633b8a7f5 100644
--- a/drivers/media/video/zr36120.c
+++ b/drivers/media/video/zr36120.c
@@ -1490,6 +1490,7 @@ static struct video_device zr36120_template=
1490 .write = zoran_write, 1490 .write = zoran_write,
1491 .poll = zoran_poll, 1491 .poll = zoran_poll,
1492 .ioctl = zoran_ioctl, 1492 .ioctl = zoran_ioctl,
1493 .compat_ioctl = v4l_compat_ioctl32,
1493 .mmap = zoran_mmap, 1494 .mmap = zoran_mmap,
1494 .minor = -1, 1495 .minor = -1,
1495}; 1496};
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 5b1febed3133..b09fb6307153 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -662,6 +662,13 @@ static int i2o_block_release(struct inode *inode, struct file *file)
662 return 0; 662 return 0;
663} 663}
664 664
665static int i2o_block_getgeo(struct block_device *bdev, struct hd_geometry *geo)
666{
667 i2o_block_biosparam(get_capacity(bdev->bd_disk),
668 &geo->cylinders, &geo->heads, &geo->sectors);
669 return 0;
670}
671
665/** 672/**
666 * i2o_block_ioctl - Issue device specific ioctl calls. 673 * i2o_block_ioctl - Issue device specific ioctl calls.
667 * @cmd: ioctl command 674 * @cmd: ioctl command
@@ -676,7 +683,6 @@ static int i2o_block_ioctl(struct inode *inode, struct file *file,
676{ 683{
677 struct gendisk *disk = inode->i_bdev->bd_disk; 684 struct gendisk *disk = inode->i_bdev->bd_disk;
678 struct i2o_block_device *dev = disk->private_data; 685 struct i2o_block_device *dev = disk->private_data;
679 void __user *argp = (void __user *)arg;
680 686
681 /* Anyone capable of this syscall can do *real bad* things */ 687 /* Anyone capable of this syscall can do *real bad* things */
682 688
@@ -684,15 +690,6 @@ static int i2o_block_ioctl(struct inode *inode, struct file *file,
684 return -EPERM; 690 return -EPERM;
685 691
686 switch (cmd) { 692 switch (cmd) {
687 case HDIO_GETGEO:
688 {
689 struct hd_geometry g;
690 i2o_block_biosparam(get_capacity(disk),
691 &g.cylinders, &g.heads, &g.sectors);
692 g.start = get_start_sect(inode->i_bdev);
693 return copy_to_user(argp, &g, sizeof(g)) ? -EFAULT : 0;
694 }
695
696 case BLKI2OGRSTRAT: 693 case BLKI2OGRSTRAT:
697 return put_user(dev->rcache, (int __user *)arg); 694 return put_user(dev->rcache, (int __user *)arg);
698 case BLKI2OGWSTRAT: 695 case BLKI2OGWSTRAT:
@@ -962,6 +959,7 @@ static struct block_device_operations i2o_block_fops = {
962 .open = i2o_block_open, 959 .open = i2o_block_open,
963 .release = i2o_block_release, 960 .release = i2o_block_release,
964 .ioctl = i2o_block_ioctl, 961 .ioctl = i2o_block_ioctl,
962 .getgeo = i2o_block_getgeo,
965 .media_changed = i2o_block_media_changed 963 .media_changed = i2o_block_media_changed
966}; 964};
967 965
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index e335d54c4659..b42e0fbab59b 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -27,7 +27,6 @@
27 27
28#include <asm/dma.h> 28#include <asm/dma.h>
29#include <asm/hardware.h> 29#include <asm/hardware.h>
30#include <asm/irq.h>
31 30
32#include "ucb1x00.h" 31#include "ucb1x00.h"
33 32
@@ -507,14 +506,14 @@ static int ucb1x00_probe(struct mcp *mcp)
507 goto err_free; 506 goto err_free;
508 } 507 }
509 508
510 ret = request_irq(ucb->irq, ucb1x00_irq, 0, "UCB1x00", ucb); 509 ret = request_irq(ucb->irq, ucb1x00_irq, SA_TRIGGER_RISING,
510 "UCB1x00", ucb);
511 if (ret) { 511 if (ret) {
512 printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", 512 printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
513 ucb->irq, ret); 513 ucb->irq, ret);
514 goto err_free; 514 goto err_free;
515 } 515 }
516 516
517 set_irq_type(ucb->irq, IRQT_RISING);
518 mcp_set_drvdata(mcp, ucb); 517 mcp_set_drvdata(mcp, ucb);
519 518
520 ret = class_device_register(&ucb->cdev); 519 ret = class_device_register(&ucb->cdev);
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index 551061c2eadf..79fd062ccb34 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -32,7 +32,6 @@
32#include <linux/suspend.h> 32#include <linux/suspend.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/kthread.h> 34#include <linux/kthread.h>
35#include <linux/delay.h>
36 35
37#include <asm/dma.h> 36#include <asm/dma.h>
38#include <asm/semaphore.h> 37#include <asm/semaphore.h>
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 6696f71363b9..bfca5c176e88 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -495,6 +495,7 @@ static void mmc_decode_cid(struct mmc_card *card)
495 495
496 case 2: /* MMC v2.0 - v2.2 */ 496 case 2: /* MMC v2.0 - v2.2 */
497 case 3: /* MMC v3.1 - v3.3 */ 497 case 3: /* MMC v3.1 - v3.3 */
498 case 4: /* MMC v4 */
498 card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); 499 card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
499 card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); 500 card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
500 card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); 501 card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index 198561d21710..f2c42b13945d 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -113,31 +113,18 @@ static int mmc_blk_release(struct inode *inode, struct file *filp)
113} 113}
114 114
115static int 115static int
116mmc_blk_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) 116mmc_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
117{ 117{
118 struct block_device *bdev = inode->i_bdev; 118 geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
119 119 geo->heads = 4;
120 if (cmd == HDIO_GETGEO) { 120 geo->sectors = 16;
121 struct hd_geometry geo; 121 return 0;
122
123 memset(&geo, 0, sizeof(struct hd_geometry));
124
125 geo.cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
126 geo.heads = 4;
127 geo.sectors = 16;
128 geo.start = get_start_sect(bdev);
129
130 return copy_to_user((void __user *)arg, &geo, sizeof(geo))
131 ? -EFAULT : 0;
132 }
133
134 return -ENOTTY;
135} 122}
136 123
137static struct block_device_operations mmc_bdops = { 124static struct block_device_operations mmc_bdops = {
138 .open = mmc_blk_open, 125 .open = mmc_blk_open,
139 .release = mmc_blk_release, 126 .release = mmc_blk_release,
140 .ioctl = mmc_blk_ioctl, 127 .getgeo = mmc_blk_getgeo,
141 .owner = THIS_MODULE, 128 .owner = THIS_MODULE,
142}; 129};
143 130
@@ -200,7 +187,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
200 brq.data.flags |= MMC_DATA_WRITE; 187 brq.data.flags |= MMC_DATA_WRITE;
201 brq.data.blocks = 1; 188 brq.data.blocks = 1;
202 } 189 }
203 brq.mrq.stop = brq.data.blocks > 1 ? &brq.stop : NULL; 190
191 if (brq.data.blocks > 1) {
192 brq.data.flags |= MMC_DATA_MULTI;
193 brq.mrq.stop = &brq.stop;
194 } else {
195 brq.mrq.stop = NULL;
196 }
204 197
205 brq.data.sg = mq->sg; 198 brq.data.sg = mq->sg;
206 brq.data.sg_len = blk_rq_map_sg(req->q, req, brq.data.sg); 199 brq.data.sg_len = blk_rq_map_sg(req->q, req, brq.data.sg);
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 4f13bd2ccf9a..f25757625361 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -90,7 +90,7 @@ static int dma = 2;
90 * Basic functions 90 * Basic functions
91 */ 91 */
92 92
93static inline void wbsd_unlock_config(struct wbsd_host* host) 93static inline void wbsd_unlock_config(struct wbsd_host *host)
94{ 94{
95 BUG_ON(host->config == 0); 95 BUG_ON(host->config == 0);
96 96
@@ -98,14 +98,14 @@ static inline void wbsd_unlock_config(struct wbsd_host* host)
98 outb(host->unlock_code, host->config); 98 outb(host->unlock_code, host->config);
99} 99}
100 100
101static inline void wbsd_lock_config(struct wbsd_host* host) 101static inline void wbsd_lock_config(struct wbsd_host *host)
102{ 102{
103 BUG_ON(host->config == 0); 103 BUG_ON(host->config == 0);
104 104
105 outb(LOCK_CODE, host->config); 105 outb(LOCK_CODE, host->config);
106} 106}
107 107
108static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value) 108static inline void wbsd_write_config(struct wbsd_host *host, u8 reg, u8 value)
109{ 109{
110 BUG_ON(host->config == 0); 110 BUG_ON(host->config == 0);
111 111
@@ -113,7 +113,7 @@ static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value)
113 outb(value, host->config + 1); 113 outb(value, host->config + 1);
114} 114}
115 115
116static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg) 116static inline u8 wbsd_read_config(struct wbsd_host *host, u8 reg)
117{ 117{
118 BUG_ON(host->config == 0); 118 BUG_ON(host->config == 0);
119 119
@@ -121,13 +121,13 @@ static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg)
121 return inb(host->config + 1); 121 return inb(host->config + 1);
122} 122}
123 123
124static inline void wbsd_write_index(struct wbsd_host* host, u8 index, u8 value) 124static inline void wbsd_write_index(struct wbsd_host *host, u8 index, u8 value)
125{ 125{
126 outb(index, host->base + WBSD_IDXR); 126 outb(index, host->base + WBSD_IDXR);
127 outb(value, host->base + WBSD_DATAR); 127 outb(value, host->base + WBSD_DATAR);
128} 128}
129 129
130static inline u8 wbsd_read_index(struct wbsd_host* host, u8 index) 130static inline u8 wbsd_read_index(struct wbsd_host *host, u8 index)
131{ 131{
132 outb(index, host->base + WBSD_IDXR); 132 outb(index, host->base + WBSD_IDXR);
133 return inb(host->base + WBSD_DATAR); 133 return inb(host->base + WBSD_DATAR);
@@ -137,7 +137,7 @@ static inline u8 wbsd_read_index(struct wbsd_host* host, u8 index)
137 * Common routines 137 * Common routines
138 */ 138 */
139 139
140static void wbsd_init_device(struct wbsd_host* host) 140static void wbsd_init_device(struct wbsd_host *host)
141{ 141{
142 u8 setup, ier; 142 u8 setup, ier;
143 143
@@ -197,7 +197,7 @@ static void wbsd_init_device(struct wbsd_host* host)
197 inb(host->base + WBSD_ISR); 197 inb(host->base + WBSD_ISR);
198} 198}
199 199
200static void wbsd_reset(struct wbsd_host* host) 200static void wbsd_reset(struct wbsd_host *host)
201{ 201{
202 u8 setup; 202 u8 setup;
203 203
@@ -211,14 +211,13 @@ static void wbsd_reset(struct wbsd_host* host)
211 wbsd_write_index(host, WBSD_IDX_SETUP, setup); 211 wbsd_write_index(host, WBSD_IDX_SETUP, setup);
212} 212}
213 213
214static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq) 214static void wbsd_request_end(struct wbsd_host *host, struct mmc_request *mrq)
215{ 215{
216 unsigned long dmaflags; 216 unsigned long dmaflags;
217 217
218 DBGF("Ending request, cmd (%x)\n", mrq->cmd->opcode); 218 DBGF("Ending request, cmd (%x)\n", mrq->cmd->opcode);
219 219
220 if (host->dma >= 0) 220 if (host->dma >= 0) {
221 {
222 /* 221 /*
223 * Release ISA DMA controller. 222 * Release ISA DMA controller.
224 */ 223 */
@@ -247,7 +246,7 @@ static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq)
247 * Scatter/gather functions 246 * Scatter/gather functions
248 */ 247 */
249 248
250static inline void wbsd_init_sg(struct wbsd_host* host, struct mmc_data* data) 249static inline void wbsd_init_sg(struct wbsd_host *host, struct mmc_data *data)
251{ 250{
252 /* 251 /*
253 * Get info. about SG list from data structure. 252 * Get info. about SG list from data structure.
@@ -259,7 +258,7 @@ static inline void wbsd_init_sg(struct wbsd_host* host, struct mmc_data* data)
259 host->remain = host->cur_sg->length; 258 host->remain = host->cur_sg->length;
260} 259}
261 260
262static inline int wbsd_next_sg(struct wbsd_host* host) 261static inline int wbsd_next_sg(struct wbsd_host *host)
263{ 262{
264 /* 263 /*
265 * Skip to next SG entry. 264 * Skip to next SG entry.
@@ -270,33 +269,32 @@ static inline int wbsd_next_sg(struct wbsd_host* host)
270 /* 269 /*
271 * Any entries left? 270 * Any entries left?
272 */ 271 */
273 if (host->num_sg > 0) 272 if (host->num_sg > 0) {
274 { 273 host->offset = 0;
275 host->offset = 0; 274 host->remain = host->cur_sg->length;
276 host->remain = host->cur_sg->length; 275 }
277 }
278 276
279 return host->num_sg; 277 return host->num_sg;
280} 278}
281 279
282static inline char* wbsd_kmap_sg(struct wbsd_host* host) 280static inline char *wbsd_kmap_sg(struct wbsd_host *host)
283{ 281{
284 host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ) + 282 host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ) +
285 host->cur_sg->offset; 283 host->cur_sg->offset;
286 return host->mapped_sg; 284 return host->mapped_sg;
287} 285}
288 286
289static inline void wbsd_kunmap_sg(struct wbsd_host* host) 287static inline void wbsd_kunmap_sg(struct wbsd_host *host)
290{ 288{
291 kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ); 289 kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ);
292} 290}
293 291
294static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data) 292static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
295{ 293{
296 unsigned int len, i, size; 294 unsigned int len, i, size;
297 struct scatterlist* sg; 295 struct scatterlist *sg;
298 char* dmabuf = host->dma_buffer; 296 char *dmabuf = host->dma_buffer;
299 char* sgbuf; 297 char *sgbuf;
300 298
301 size = host->size; 299 size = host->size;
302 300
@@ -308,8 +306,7 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
308 * be the entire list though so make sure that 306 * be the entire list though so make sure that
309 * we do not transfer too much. 307 * we do not transfer too much.
310 */ 308 */
311 for (i = 0;i < len;i++) 309 for (i = 0; i < len; i++) {
312 {
313 sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset; 310 sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset;
314 if (size < sg[i].length) 311 if (size < sg[i].length)
315 memcpy(dmabuf, sgbuf, size); 312 memcpy(dmabuf, sgbuf, size);
@@ -337,12 +334,12 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
337 host->size -= size; 334 host->size -= size;
338} 335}
339 336
340static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data) 337static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data)
341{ 338{
342 unsigned int len, i, size; 339 unsigned int len, i, size;
343 struct scatterlist* sg; 340 struct scatterlist *sg;
344 char* dmabuf = host->dma_buffer; 341 char *dmabuf = host->dma_buffer;
345 char* sgbuf; 342 char *sgbuf;
346 343
347 size = host->size; 344 size = host->size;
348 345
@@ -354,8 +351,7 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data)
354 * be the entire list though so make sure that 351 * be the entire list though so make sure that
355 * we do not transfer too much. 352 * we do not transfer too much.
356 */ 353 */
357 for (i = 0;i < len;i++) 354 for (i = 0; i < len; i++) {
358 {
359 sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset; 355 sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset;
360 if (size < sg[i].length) 356 if (size < sg[i].length)
361 memcpy(sgbuf, dmabuf, size); 357 memcpy(sgbuf, dmabuf, size);
@@ -387,46 +383,38 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data)
387 * Command handling 383 * Command handling
388 */ 384 */
389 385
390static inline void wbsd_get_short_reply(struct wbsd_host* host, 386static inline void wbsd_get_short_reply(struct wbsd_host *host,
391 struct mmc_command* cmd) 387 struct mmc_command *cmd)
392{ 388{
393 /* 389 /*
394 * Correct response type? 390 * Correct response type?
395 */ 391 */
396 if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_SHORT) 392 if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_SHORT) {
397 {
398 cmd->error = MMC_ERR_INVALID; 393 cmd->error = MMC_ERR_INVALID;
399 return; 394 return;
400 } 395 }
401 396
402 cmd->resp[0] = 397 cmd->resp[0] = wbsd_read_index(host, WBSD_IDX_RESP12) << 24;
403 wbsd_read_index(host, WBSD_IDX_RESP12) << 24; 398 cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP13) << 16;
404 cmd->resp[0] |= 399 cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP14) << 8;
405 wbsd_read_index(host, WBSD_IDX_RESP13) << 16; 400 cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP15) << 0;
406 cmd->resp[0] |= 401 cmd->resp[1] = wbsd_read_index(host, WBSD_IDX_RESP16) << 24;
407 wbsd_read_index(host, WBSD_IDX_RESP14) << 8;
408 cmd->resp[0] |=
409 wbsd_read_index(host, WBSD_IDX_RESP15) << 0;
410 cmd->resp[1] =
411 wbsd_read_index(host, WBSD_IDX_RESP16) << 24;
412} 402}
413 403
414static inline void wbsd_get_long_reply(struct wbsd_host* host, 404static inline void wbsd_get_long_reply(struct wbsd_host *host,
415 struct mmc_command* cmd) 405 struct mmc_command *cmd)
416{ 406{
417 int i; 407 int i;
418 408
419 /* 409 /*
420 * Correct response type? 410 * Correct response type?
421 */ 411 */
422 if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_LONG) 412 if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_LONG) {
423 {
424 cmd->error = MMC_ERR_INVALID; 413 cmd->error = MMC_ERR_INVALID;
425 return; 414 return;
426 } 415 }
427 416
428 for (i = 0;i < 4;i++) 417 for (i = 0; i < 4; i++) {
429 {
430 cmd->resp[i] = 418 cmd->resp[i] =
431 wbsd_read_index(host, WBSD_IDX_RESP1 + i * 4) << 24; 419 wbsd_read_index(host, WBSD_IDX_RESP1 + i * 4) << 24;
432 cmd->resp[i] |= 420 cmd->resp[i] |=
@@ -438,7 +426,7 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host,
438 } 426 }
439} 427}
440 428
441static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd) 429static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd)
442{ 430{
443 int i; 431 int i;
444 u8 status, isr; 432 u8 status, isr;
@@ -456,7 +444,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
456 * Send the command (CRC calculated by host). 444 * Send the command (CRC calculated by host).
457 */ 445 */
458 outb(cmd->opcode, host->base + WBSD_CMDR); 446 outb(cmd->opcode, host->base + WBSD_CMDR);
459 for (i = 3;i >= 0;i--) 447 for (i = 3; i >= 0; i--)
460 outb((cmd->arg >> (i * 8)) & 0xff, host->base + WBSD_CMDR); 448 outb((cmd->arg >> (i * 8)) & 0xff, host->base + WBSD_CMDR);
461 449
462 cmd->error = MMC_ERR_NONE; 450 cmd->error = MMC_ERR_NONE;
@@ -471,8 +459,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
471 /* 459 /*
472 * Do we expect a reply? 460 * Do we expect a reply?
473 */ 461 */
474 if ((cmd->flags & MMC_RSP_MASK) != MMC_RSP_NONE) 462 if ((cmd->flags & MMC_RSP_MASK) != MMC_RSP_NONE) {
475 {
476 /* 463 /*
477 * Read back status. 464 * Read back status.
478 */ 465 */
@@ -488,8 +475,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
488 else if ((cmd->flags & MMC_RSP_CRC) && (isr & WBSD_INT_CRC)) 475 else if ((cmd->flags & MMC_RSP_CRC) && (isr & WBSD_INT_CRC))
489 cmd->error = MMC_ERR_BADCRC; 476 cmd->error = MMC_ERR_BADCRC;
490 /* All ok */ 477 /* All ok */
491 else 478 else {
492 {
493 if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) 479 if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT)
494 wbsd_get_short_reply(host, cmd); 480 wbsd_get_short_reply(host, cmd);
495 else 481 else
@@ -504,10 +490,10 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
504 * Data functions 490 * Data functions
505 */ 491 */
506 492
507static void wbsd_empty_fifo(struct wbsd_host* host) 493static void wbsd_empty_fifo(struct wbsd_host *host)
508{ 494{
509 struct mmc_data* data = host->mrq->cmd->data; 495 struct mmc_data *data = host->mrq->cmd->data;
510 char* buffer; 496 char *buffer;
511 int i, fsr, fifo; 497 int i, fsr, fifo;
512 498
513 /* 499 /*
@@ -522,8 +508,7 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
522 * Drain the fifo. This has a tendency to loop longer 508 * Drain the fifo. This has a tendency to loop longer
523 * than the FIFO length (usually one block). 509 * than the FIFO length (usually one block).
524 */ 510 */
525 while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_EMPTY)) 511 while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_EMPTY)) {
526 {
527 /* 512 /*
528 * The size field in the FSR is broken so we have to 513 * The size field in the FSR is broken so we have to
529 * do some guessing. 514 * do some guessing.
@@ -535,8 +520,7 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
535 else 520 else
536 fifo = 1; 521 fifo = 1;
537 522
538 for (i = 0;i < fifo;i++) 523 for (i = 0; i < fifo; i++) {
539 {
540 *buffer = inb(host->base + WBSD_DFR); 524 *buffer = inb(host->base + WBSD_DFR);
541 buffer++; 525 buffer++;
542 host->offset++; 526 host->offset++;
@@ -547,8 +531,7 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
547 /* 531 /*
548 * Transfer done? 532 * Transfer done?
549 */ 533 */
550 if (data->bytes_xfered == host->size) 534 if (data->bytes_xfered == host->size) {
551 {
552 wbsd_kunmap_sg(host); 535 wbsd_kunmap_sg(host);
553 return; 536 return;
554 } 537 }
@@ -556,15 +539,13 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
556 /* 539 /*
557 * End of scatter list entry? 540 * End of scatter list entry?
558 */ 541 */
559 if (host->remain == 0) 542 if (host->remain == 0) {
560 {
561 wbsd_kunmap_sg(host); 543 wbsd_kunmap_sg(host);
562 544
563 /* 545 /*
564 * Get next entry. Check if last. 546 * Get next entry. Check if last.
565 */ 547 */
566 if (!wbsd_next_sg(host)) 548 if (!wbsd_next_sg(host)) {
567 {
568 /* 549 /*
569 * We should never reach this point. 550 * We should never reach this point.
570 * It means that we're trying to 551 * It means that we're trying to
@@ -594,10 +575,10 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
594 tasklet_schedule(&host->fifo_tasklet); 575 tasklet_schedule(&host->fifo_tasklet);
595} 576}
596 577
597static void wbsd_fill_fifo(struct wbsd_host* host) 578static void wbsd_fill_fifo(struct wbsd_host *host)
598{ 579{
599 struct mmc_data* data = host->mrq->cmd->data; 580 struct mmc_data *data = host->mrq->cmd->data;
600 char* buffer; 581 char *buffer;
601 int i, fsr, fifo; 582 int i, fsr, fifo;
602 583
603 /* 584 /*
@@ -613,8 +594,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
613 * Fill the fifo. This has a tendency to loop longer 594 * Fill the fifo. This has a tendency to loop longer
614 * than the FIFO length (usually one block). 595 * than the FIFO length (usually one block).
615 */ 596 */
616 while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_FULL)) 597 while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_FULL)) {
617 {
618 /* 598 /*
619 * The size field in the FSR is broken so we have to 599 * The size field in the FSR is broken so we have to
620 * do some guessing. 600 * do some guessing.
@@ -626,8 +606,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
626 else 606 else
627 fifo = 15; 607 fifo = 15;
628 608
629 for (i = 16;i > fifo;i--) 609 for (i = 16; i > fifo; i--) {
630 {
631 outb(*buffer, host->base + WBSD_DFR); 610 outb(*buffer, host->base + WBSD_DFR);
632 buffer++; 611 buffer++;
633 host->offset++; 612 host->offset++;
@@ -638,8 +617,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
638 /* 617 /*
639 * Transfer done? 618 * Transfer done?
640 */ 619 */
641 if (data->bytes_xfered == host->size) 620 if (data->bytes_xfered == host->size) {
642 {
643 wbsd_kunmap_sg(host); 621 wbsd_kunmap_sg(host);
644 return; 622 return;
645 } 623 }
@@ -647,15 +625,13 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
647 /* 625 /*
648 * End of scatter list entry? 626 * End of scatter list entry?
649 */ 627 */
650 if (host->remain == 0) 628 if (host->remain == 0) {
651 {
652 wbsd_kunmap_sg(host); 629 wbsd_kunmap_sg(host);
653 630
654 /* 631 /*
655 * Get next entry. Check if last. 632 * Get next entry. Check if last.
656 */ 633 */
657 if (!wbsd_next_sg(host)) 634 if (!wbsd_next_sg(host)) {
658 {
659 /* 635 /*
660 * We should never reach this point. 636 * We should never reach this point.
661 * It means that we're trying to 637 * It means that we're trying to
@@ -684,7 +660,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
684 tasklet_schedule(&host->fifo_tasklet); 660 tasklet_schedule(&host->fifo_tasklet);
685} 661}
686 662
687static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) 663static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data)
688{ 664{
689 u16 blksize; 665 u16 blksize;
690 u8 setup; 666 u8 setup;
@@ -706,8 +682,10 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
706 */ 682 */
707 if (data->timeout_ns > 127000000) 683 if (data->timeout_ns > 127000000)
708 wbsd_write_index(host, WBSD_IDX_TAAC, 127); 684 wbsd_write_index(host, WBSD_IDX_TAAC, 127);
709 else 685 else {
710 wbsd_write_index(host, WBSD_IDX_TAAC, data->timeout_ns/1000000); 686 wbsd_write_index(host, WBSD_IDX_TAAC,
687 data->timeout_ns / 1000000);
688 }
711 689
712 if (data->timeout_clks > 255) 690 if (data->timeout_clks > 255)
713 wbsd_write_index(host, WBSD_IDX_NSAC, 255); 691 wbsd_write_index(host, WBSD_IDX_NSAC, 255);
@@ -722,23 +700,18 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
722 * Space for CRC must be included in the size. 700 * Space for CRC must be included in the size.
723 * Two bytes are needed for each data line. 701 * Two bytes are needed for each data line.
724 */ 702 */
725 if (host->bus_width == MMC_BUS_WIDTH_1) 703 if (host->bus_width == MMC_BUS_WIDTH_1) {
726 {
727 blksize = (1 << data->blksz_bits) + 2; 704 blksize = (1 << data->blksz_bits) + 2;
728 705
729 wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0); 706 wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0);
730 wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); 707 wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF);
731 } 708 } else if (host->bus_width == MMC_BUS_WIDTH_4) {
732 else if (host->bus_width == MMC_BUS_WIDTH_4)
733 {
734 blksize = (1 << data->blksz_bits) + 2 * 4; 709 blksize = (1 << data->blksz_bits) + 2 * 4;
735 710
736 wbsd_write_index(host, WBSD_IDX_PBSMSB, ((blksize >> 4) & 0xF0) 711 wbsd_write_index(host, WBSD_IDX_PBSMSB,
737 | WBSD_DATA_WIDTH); 712 ((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH);
738 wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); 713 wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF);
739 } 714 } else {
740 else
741 {
742 data->error = MMC_ERR_INVALID; 715 data->error = MMC_ERR_INVALID;
743 return; 716 return;
744 } 717 }
@@ -755,14 +728,12 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
755 /* 728 /*
756 * DMA transfer? 729 * DMA transfer?
757 */ 730 */
758 if (host->dma >= 0) 731 if (host->dma >= 0) {
759 {
760 /* 732 /*
761 * The buffer for DMA is only 64 kB. 733 * The buffer for DMA is only 64 kB.
762 */ 734 */
763 BUG_ON(host->size > 0x10000); 735 BUG_ON(host->size > 0x10000);
764 if (host->size > 0x10000) 736 if (host->size > 0x10000) {
765 {
766 data->error = MMC_ERR_INVALID; 737 data->error = MMC_ERR_INVALID;
767 return; 738 return;
768 } 739 }
@@ -794,9 +765,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
794 * Enable DMA on the host. 765 * Enable DMA on the host.
795 */ 766 */
796 wbsd_write_index(host, WBSD_IDX_DMA, WBSD_DMA_ENABLE); 767 wbsd_write_index(host, WBSD_IDX_DMA, WBSD_DMA_ENABLE);
797 } 768 } else {
798 else
799 {
800 /* 769 /*
801 * This flag is used to keep printk 770 * This flag is used to keep printk
802 * output to a minimum. 771 * output to a minimum.
@@ -817,13 +786,10 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
817 * Set up FIFO threshold levels (and fill 786 * Set up FIFO threshold levels (and fill
818 * buffer if doing a write). 787 * buffer if doing a write).
819 */ 788 */
820 if (data->flags & MMC_DATA_READ) 789 if (data->flags & MMC_DATA_READ) {
821 {
822 wbsd_write_index(host, WBSD_IDX_FIFOEN, 790 wbsd_write_index(host, WBSD_IDX_FIFOEN,
823 WBSD_FIFOEN_FULL | 8); 791 WBSD_FIFOEN_FULL | 8);
824 } 792 } else {
825 else
826 {
827 wbsd_write_index(host, WBSD_IDX_FIFOEN, 793 wbsd_write_index(host, WBSD_IDX_FIFOEN,
828 WBSD_FIFOEN_EMPTY | 8); 794 WBSD_FIFOEN_EMPTY | 8);
829 wbsd_fill_fifo(host); 795 wbsd_fill_fifo(host);
@@ -833,7 +799,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
833 data->error = MMC_ERR_NONE; 799 data->error = MMC_ERR_NONE;
834} 800}
835 801
836static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) 802static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data)
837{ 803{
838 unsigned long dmaflags; 804 unsigned long dmaflags;
839 int count; 805 int count;
@@ -851,16 +817,14 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
851 * Wait for the controller to leave data 817 * Wait for the controller to leave data
852 * transfer state. 818 * transfer state.
853 */ 819 */
854 do 820 do {
855 {
856 status = wbsd_read_index(host, WBSD_IDX_STATUS); 821 status = wbsd_read_index(host, WBSD_IDX_STATUS);
857 } while (status & (WBSD_BLOCK_READ | WBSD_BLOCK_WRITE)); 822 } while (status & (WBSD_BLOCK_READ | WBSD_BLOCK_WRITE));
858 823
859 /* 824 /*
860 * DMA transfer? 825 * DMA transfer?
861 */ 826 */
862 if (host->dma >= 0) 827 if (host->dma >= 0) {
863 {
864 /* 828 /*
865 * Disable DMA on the host. 829 * Disable DMA on the host.
866 */ 830 */
@@ -878,16 +842,13 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
878 /* 842 /*
879 * Any leftover data? 843 * Any leftover data?
880 */ 844 */
881 if (count) 845 if (count) {
882 {
883 printk(KERN_ERR "%s: Incomplete DMA transfer. " 846 printk(KERN_ERR "%s: Incomplete DMA transfer. "
884 "%d bytes left.\n", 847 "%d bytes left.\n",
885 mmc_hostname(host->mmc), count); 848 mmc_hostname(host->mmc), count);
886 849
887 data->error = MMC_ERR_FAILED; 850 data->error = MMC_ERR_FAILED;
888 } 851 } else {
889 else
890 {
891 /* 852 /*
892 * Transfer data from DMA buffer to 853 * Transfer data from DMA buffer to
893 * SG list. 854 * SG list.
@@ -910,10 +871,10 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
910 * * 871 * *
911\*****************************************************************************/ 872\*****************************************************************************/
912 873
913static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) 874static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
914{ 875{
915 struct wbsd_host* host = mmc_priv(mmc); 876 struct wbsd_host *host = mmc_priv(mmc);
916 struct mmc_command* cmd; 877 struct mmc_command *cmd;
917 878
918 /* 879 /*
919 * Disable tasklets to avoid a deadlock. 880 * Disable tasklets to avoid a deadlock.
@@ -930,8 +891,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
930 * If there is no card in the slot then 891 * If there is no card in the slot then
931 * timeout immediatly. 892 * timeout immediatly.
932 */ 893 */
933 if (!(host->flags & WBSD_FCARD_PRESENT)) 894 if (!(host->flags & WBSD_FCARD_PRESENT)) {
934 {
935 cmd->error = MMC_ERR_TIMEOUT; 895 cmd->error = MMC_ERR_TIMEOUT;
936 goto done; 896 goto done;
937 } 897 }
@@ -939,8 +899,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
939 /* 899 /*
940 * Does the request include data? 900 * Does the request include data?
941 */ 901 */
942 if (cmd->data) 902 if (cmd->data) {
943 {
944 wbsd_prepare_data(host, cmd->data); 903 wbsd_prepare_data(host, cmd->data);
945 904
946 if (cmd->data->error != MMC_ERR_NONE) 905 if (cmd->data->error != MMC_ERR_NONE)
@@ -954,8 +913,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
954 * will be finished after the data has 913 * will be finished after the data has
955 * transfered. 914 * transfered.
956 */ 915 */
957 if (cmd->data && (cmd->error == MMC_ERR_NONE)) 916 if (cmd->data && (cmd->error == MMC_ERR_NONE)) {
958 {
959 /* 917 /*
960 * Dirty fix for hardware bug. 918 * Dirty fix for hardware bug.
961 */ 919 */
@@ -973,14 +931,14 @@ done:
973 spin_unlock_bh(&host->lock); 931 spin_unlock_bh(&host->lock);
974} 932}
975 933
976static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) 934static void wbsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
977{ 935{
978 struct wbsd_host* host = mmc_priv(mmc); 936 struct wbsd_host *host = mmc_priv(mmc);
979 u8 clk, setup, pwr; 937 u8 clk, setup, pwr;
980 938
981 DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", 939 DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n",
982 ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select, 940 ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select,
983 ios->vdd, ios->bus_width); 941 ios->vdd, ios->bus_width);
984 942
985 spin_lock_bh(&host->lock); 943 spin_lock_bh(&host->lock);
986 944
@@ -1004,8 +962,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
1004 * Only write to the clock register when 962 * Only write to the clock register when
1005 * there is an actual change. 963 * there is an actual change.
1006 */ 964 */
1007 if (clk != host->clk) 965 if (clk != host->clk) {
1008 {
1009 wbsd_write_index(host, WBSD_IDX_CLK, clk); 966 wbsd_write_index(host, WBSD_IDX_CLK, clk);
1010 host->clk = clk; 967 host->clk = clk;
1011 } 968 }
@@ -1013,8 +970,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
1013 /* 970 /*
1014 * Power up card. 971 * Power up card.
1015 */ 972 */
1016 if (ios->power_mode != MMC_POWER_OFF) 973 if (ios->power_mode != MMC_POWER_OFF) {
1017 {
1018 pwr = inb(host->base + WBSD_CSR); 974 pwr = inb(host->base + WBSD_CSR);
1019 pwr &= ~WBSD_POWER_N; 975 pwr &= ~WBSD_POWER_N;
1020 outb(pwr, host->base + WBSD_CSR); 976 outb(pwr, host->base + WBSD_CSR);
@@ -1026,23 +982,19 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
1026 * that needs to be disabled. 982 * that needs to be disabled.
1027 */ 983 */
1028 setup = wbsd_read_index(host, WBSD_IDX_SETUP); 984 setup = wbsd_read_index(host, WBSD_IDX_SETUP);
1029 if (ios->chip_select == MMC_CS_HIGH) 985 if (ios->chip_select == MMC_CS_HIGH) {
1030 {
1031 BUG_ON(ios->bus_width != MMC_BUS_WIDTH_1); 986 BUG_ON(ios->bus_width != MMC_BUS_WIDTH_1);
1032 setup |= WBSD_DAT3_H; 987 setup |= WBSD_DAT3_H;
1033 host->flags |= WBSD_FIGNORE_DETECT; 988 host->flags |= WBSD_FIGNORE_DETECT;
1034 } 989 } else {
1035 else 990 if (setup & WBSD_DAT3_H) {
1036 {
1037 if (setup & WBSD_DAT3_H)
1038 {
1039 setup &= ~WBSD_DAT3_H; 991 setup &= ~WBSD_DAT3_H;
1040 992
1041 /* 993 /*
1042 * We cannot resume card detection immediatly 994 * We cannot resume card detection immediatly
1043 * because of capacitance and delays in the chip. 995 * because of capacitance and delays in the chip.
1044 */ 996 */
1045 mod_timer(&host->ignore_timer, jiffies + HZ/100); 997 mod_timer(&host->ignore_timer, jiffies + HZ / 100);
1046 } 998 }
1047 } 999 }
1048 wbsd_write_index(host, WBSD_IDX_SETUP, setup); 1000 wbsd_write_index(host, WBSD_IDX_SETUP, setup);
@@ -1056,9 +1008,9 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
1056 spin_unlock_bh(&host->lock); 1008 spin_unlock_bh(&host->lock);
1057} 1009}
1058 1010
1059static int wbsd_get_ro(struct mmc_host* mmc) 1011static int wbsd_get_ro(struct mmc_host *mmc)
1060{ 1012{
1061 struct wbsd_host* host = mmc_priv(mmc); 1013 struct wbsd_host *host = mmc_priv(mmc);
1062 u8 csr; 1014 u8 csr;
1063 1015
1064 spin_lock_bh(&host->lock); 1016 spin_lock_bh(&host->lock);
@@ -1096,7 +1048,7 @@ static struct mmc_host_ops wbsd_ops = {
1096 1048
1097static void wbsd_reset_ignore(unsigned long data) 1049static void wbsd_reset_ignore(unsigned long data)
1098{ 1050{
1099 struct wbsd_host *host = (struct wbsd_host*)data; 1051 struct wbsd_host *host = (struct wbsd_host *)data;
1100 1052
1101 BUG_ON(host == NULL); 1053 BUG_ON(host == NULL);
1102 1054
@@ -1119,7 +1071,7 @@ static void wbsd_reset_ignore(unsigned long data)
1119 * Tasklets 1071 * Tasklets
1120 */ 1072 */
1121 1073
1122static inline struct mmc_data* wbsd_get_data(struct wbsd_host* host) 1074static inline struct mmc_data *wbsd_get_data(struct wbsd_host *host)
1123{ 1075{
1124 WARN_ON(!host->mrq); 1076 WARN_ON(!host->mrq);
1125 if (!host->mrq) 1077 if (!host->mrq)
@@ -1138,14 +1090,13 @@ static inline struct mmc_data* wbsd_get_data(struct wbsd_host* host)
1138 1090
1139static void wbsd_tasklet_card(unsigned long param) 1091static void wbsd_tasklet_card(unsigned long param)
1140{ 1092{
1141 struct wbsd_host* host = (struct wbsd_host*)param; 1093 struct wbsd_host *host = (struct wbsd_host *)param;
1142 u8 csr; 1094 u8 csr;
1143 int delay = -1; 1095 int delay = -1;
1144 1096
1145 spin_lock(&host->lock); 1097 spin_lock(&host->lock);
1146 1098
1147 if (host->flags & WBSD_FIGNORE_DETECT) 1099 if (host->flags & WBSD_FIGNORE_DETECT) {
1148 {
1149 spin_unlock(&host->lock); 1100 spin_unlock(&host->lock);
1150 return; 1101 return;
1151 } 1102 }
@@ -1153,23 +1104,18 @@ static void wbsd_tasklet_card(unsigned long param)
1153 csr = inb(host->base + WBSD_CSR); 1104 csr = inb(host->base + WBSD_CSR);
1154 WARN_ON(csr == 0xff); 1105 WARN_ON(csr == 0xff);
1155 1106
1156 if (csr & WBSD_CARDPRESENT) 1107 if (csr & WBSD_CARDPRESENT) {
1157 { 1108 if (!(host->flags & WBSD_FCARD_PRESENT)) {
1158 if (!(host->flags & WBSD_FCARD_PRESENT))
1159 {
1160 DBG("Card inserted\n"); 1109 DBG("Card inserted\n");
1161 host->flags |= WBSD_FCARD_PRESENT; 1110 host->flags |= WBSD_FCARD_PRESENT;
1162 1111
1163 delay = 500; 1112 delay = 500;
1164 } 1113 }
1165 } 1114 } else if (host->flags & WBSD_FCARD_PRESENT) {
1166 else if (host->flags & WBSD_FCARD_PRESENT)
1167 {
1168 DBG("Card removed\n"); 1115 DBG("Card removed\n");
1169 host->flags &= ~WBSD_FCARD_PRESENT; 1116 host->flags &= ~WBSD_FCARD_PRESENT;
1170 1117
1171 if (host->mrq) 1118 if (host->mrq) {
1172 {
1173 printk(KERN_ERR "%s: Card removed during transfer!\n", 1119 printk(KERN_ERR "%s: Card removed during transfer!\n",
1174 mmc_hostname(host->mmc)); 1120 mmc_hostname(host->mmc));
1175 wbsd_reset(host); 1121 wbsd_reset(host);
@@ -1193,8 +1139,8 @@ static void wbsd_tasklet_card(unsigned long param)
1193 1139
1194static void wbsd_tasklet_fifo(unsigned long param) 1140static void wbsd_tasklet_fifo(unsigned long param)
1195{ 1141{
1196 struct wbsd_host* host = (struct wbsd_host*)param; 1142 struct wbsd_host *host = (struct wbsd_host *)param;
1197 struct mmc_data* data; 1143 struct mmc_data *data;
1198 1144
1199 spin_lock(&host->lock); 1145 spin_lock(&host->lock);
1200 1146
@@ -1213,8 +1159,7 @@ static void wbsd_tasklet_fifo(unsigned long param)
1213 /* 1159 /*
1214 * Done? 1160 * Done?
1215 */ 1161 */
1216 if (host->size == data->bytes_xfered) 1162 if (host->size == data->bytes_xfered) {
1217 {
1218 wbsd_write_index(host, WBSD_IDX_FIFOEN, 0); 1163 wbsd_write_index(host, WBSD_IDX_FIFOEN, 0);
1219 tasklet_schedule(&host->finish_tasklet); 1164 tasklet_schedule(&host->finish_tasklet);
1220 } 1165 }
@@ -1225,8 +1170,8 @@ end:
1225 1170
1226static void wbsd_tasklet_crc(unsigned long param) 1171static void wbsd_tasklet_crc(unsigned long param)
1227{ 1172{
1228 struct wbsd_host* host = (struct wbsd_host*)param; 1173 struct wbsd_host *host = (struct wbsd_host *)param;
1229 struct mmc_data* data; 1174 struct mmc_data *data;
1230 1175
1231 spin_lock(&host->lock); 1176 spin_lock(&host->lock);
1232 1177
@@ -1249,8 +1194,8 @@ end:
1249 1194
1250static void wbsd_tasklet_timeout(unsigned long param) 1195static void wbsd_tasklet_timeout(unsigned long param)
1251{ 1196{
1252 struct wbsd_host* host = (struct wbsd_host*)param; 1197 struct wbsd_host *host = (struct wbsd_host *)param;
1253 struct mmc_data* data; 1198 struct mmc_data *data;
1254 1199
1255 spin_lock(&host->lock); 1200 spin_lock(&host->lock);
1256 1201
@@ -1273,8 +1218,8 @@ end:
1273 1218
1274static void wbsd_tasklet_finish(unsigned long param) 1219static void wbsd_tasklet_finish(unsigned long param)
1275{ 1220{
1276 struct wbsd_host* host = (struct wbsd_host*)param; 1221 struct wbsd_host *host = (struct wbsd_host *)param;
1277 struct mmc_data* data; 1222 struct mmc_data *data;
1278 1223
1279 spin_lock(&host->lock); 1224 spin_lock(&host->lock);
1280 1225
@@ -1294,14 +1239,13 @@ end:
1294 1239
1295static void wbsd_tasklet_block(unsigned long param) 1240static void wbsd_tasklet_block(unsigned long param)
1296{ 1241{
1297 struct wbsd_host* host = (struct wbsd_host*)param; 1242 struct wbsd_host *host = (struct wbsd_host *)param;
1298 struct mmc_data* data; 1243 struct mmc_data *data;
1299 1244
1300 spin_lock(&host->lock); 1245 spin_lock(&host->lock);
1301 1246
1302 if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) != 1247 if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) !=
1303 WBSD_CRC_OK) 1248 WBSD_CRC_OK) {
1304 {
1305 data = wbsd_get_data(host); 1249 data = wbsd_get_data(host);
1306 if (!data) 1250 if (!data)
1307 goto end; 1251 goto end;
@@ -1323,7 +1267,7 @@ end:
1323 1267
1324static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs) 1268static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
1325{ 1269{
1326 struct wbsd_host* host = dev_id; 1270 struct wbsd_host *host = dev_id;
1327 int isr; 1271 int isr;
1328 1272
1329 isr = inb(host->base + WBSD_ISR); 1273 isr = inb(host->base + WBSD_ISR);
@@ -1365,10 +1309,10 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
1365 * Allocate/free MMC structure. 1309 * Allocate/free MMC structure.
1366 */ 1310 */
1367 1311
1368static int __devinit wbsd_alloc_mmc(struct device* dev) 1312static int __devinit wbsd_alloc_mmc(struct device *dev)
1369{ 1313{
1370 struct mmc_host* mmc; 1314 struct mmc_host *mmc;
1371 struct wbsd_host* host; 1315 struct wbsd_host *host;
1372 1316
1373 /* 1317 /*
1374 * Allocate MMC structure. 1318 * Allocate MMC structure.
@@ -1388,7 +1332,7 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
1388 mmc->ops = &wbsd_ops; 1332 mmc->ops = &wbsd_ops;
1389 mmc->f_min = 375000; 1333 mmc->f_min = 375000;
1390 mmc->f_max = 24000000; 1334 mmc->f_max = 24000000;
1391 mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; 1335 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
1392 mmc->caps = MMC_CAP_4_BIT_DATA; 1336 mmc->caps = MMC_CAP_4_BIT_DATA;
1393 1337
1394 spin_lock_init(&host->lock); 1338 spin_lock_init(&host->lock);
@@ -1424,10 +1368,10 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
1424 return 0; 1368 return 0;
1425} 1369}
1426 1370
1427static void __devexit wbsd_free_mmc(struct device* dev) 1371static void __devexit wbsd_free_mmc(struct device *dev)
1428{ 1372{
1429 struct mmc_host* mmc; 1373 struct mmc_host *mmc;
1430 struct wbsd_host* host; 1374 struct wbsd_host *host;
1431 1375
1432 mmc = dev_get_drvdata(dev); 1376 mmc = dev_get_drvdata(dev);
1433 if (!mmc) 1377 if (!mmc)
@@ -1447,7 +1391,7 @@ static void __devexit wbsd_free_mmc(struct device* dev)
1447 * Scan for known chip id:s 1391 * Scan for known chip id:s
1448 */ 1392 */
1449 1393
1450static int __devinit wbsd_scan(struct wbsd_host* host) 1394static int __devinit wbsd_scan(struct wbsd_host *host)
1451{ 1395{
1452 int i, j, k; 1396 int i, j, k;
1453 int id; 1397 int id;
@@ -1477,16 +1421,14 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
1477 wbsd_lock_config(host); 1421 wbsd_lock_config(host);
1478 1422
1479 for (k = 0; k < ARRAY_SIZE(valid_ids); k++) { 1423 for (k = 0; k < ARRAY_SIZE(valid_ids); k++) {
1480 if (id == valid_ids[k]) 1424 if (id == valid_ids[k]) {
1481 {
1482 host->chip_id = id; 1425 host->chip_id = id;
1483 1426
1484 return 0; 1427 return 0;
1485 } 1428 }
1486 } 1429 }
1487 1430
1488 if (id != 0xFFFF) 1431 if (id != 0xFFFF) {
1489 {
1490 DBG("Unknown hardware (id %x) found at %x\n", 1432 DBG("Unknown hardware (id %x) found at %x\n",
1491 id, config_ports[i]); 1433 id, config_ports[i]);
1492 } 1434 }
@@ -1505,7 +1447,7 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
1505 * Allocate/free io port ranges 1447 * Allocate/free io port ranges
1506 */ 1448 */
1507 1449
1508static int __devinit wbsd_request_region(struct wbsd_host* host, int base) 1450static int __devinit wbsd_request_region(struct wbsd_host *host, int base)
1509{ 1451{
1510 if (io & 0x7) 1452 if (io & 0x7)
1511 return -EINVAL; 1453 return -EINVAL;
@@ -1518,7 +1460,7 @@ static int __devinit wbsd_request_region(struct wbsd_host* host, int base)
1518 return 0; 1460 return 0;
1519} 1461}
1520 1462
1521static void __devexit wbsd_release_regions(struct wbsd_host* host) 1463static void __devexit wbsd_release_regions(struct wbsd_host *host)
1522{ 1464{
1523 if (host->base) 1465 if (host->base)
1524 release_region(host->base, 8); 1466 release_region(host->base, 8);
@@ -1535,7 +1477,7 @@ static void __devexit wbsd_release_regions(struct wbsd_host* host)
1535 * Allocate/free DMA port and buffer 1477 * Allocate/free DMA port and buffer
1536 */ 1478 */
1537 1479
1538static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma) 1480static void __devinit wbsd_request_dma(struct wbsd_host *host, int dma)
1539{ 1481{
1540 if (dma < 0) 1482 if (dma < 0)
1541 return; 1483 return;
@@ -1579,8 +1521,8 @@ kfree:
1579 */ 1521 */
1580 BUG_ON(1); 1522 BUG_ON(1);
1581 1523
1582 dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, 1524 dma_unmap_single(host->mmc->dev, host->dma_addr,
1583 DMA_BIDIRECTIONAL); 1525 WBSD_DMA_SIZE, DMA_BIDIRECTIONAL);
1584 host->dma_addr = (dma_addr_t)NULL; 1526 host->dma_addr = (dma_addr_t)NULL;
1585 1527
1586 kfree(host->dma_buffer); 1528 kfree(host->dma_buffer);
@@ -1594,11 +1536,12 @@ err:
1594 "Falling back on FIFO.\n", dma); 1536 "Falling back on FIFO.\n", dma);
1595} 1537}
1596 1538
1597static void __devexit wbsd_release_dma(struct wbsd_host* host) 1539static void __devexit wbsd_release_dma(struct wbsd_host *host)
1598{ 1540{
1599 if (host->dma_addr) 1541 if (host->dma_addr) {
1600 dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, 1542 dma_unmap_single(host->mmc->dev, host->dma_addr,
1601 DMA_BIDIRECTIONAL); 1543 WBSD_DMA_SIZE, DMA_BIDIRECTIONAL);
1544 }
1602 kfree(host->dma_buffer); 1545 kfree(host->dma_buffer);
1603 if (host->dma >= 0) 1546 if (host->dma >= 0)
1604 free_dma(host->dma); 1547 free_dma(host->dma);
@@ -1612,7 +1555,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host)
1612 * Allocate/free IRQ. 1555 * Allocate/free IRQ.
1613 */ 1556 */
1614 1557
1615static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq) 1558static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq)
1616{ 1559{
1617 int ret; 1560 int ret;
1618 1561
@@ -1629,17 +1572,23 @@ static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq)
1629 /* 1572 /*
1630 * Set up tasklets. 1573 * Set up tasklets.
1631 */ 1574 */
1632 tasklet_init(&host->card_tasklet, wbsd_tasklet_card, (unsigned long)host); 1575 tasklet_init(&host->card_tasklet, wbsd_tasklet_card,
1633 tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo, (unsigned long)host); 1576 (unsigned long)host);
1634 tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc, (unsigned long)host); 1577 tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo,
1635 tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host); 1578 (unsigned long)host);
1636 tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host); 1579 tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc,
1637 tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host); 1580 (unsigned long)host);
1581 tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout,
1582 (unsigned long)host);
1583 tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish,
1584 (unsigned long)host);
1585 tasklet_init(&host->block_tasklet, wbsd_tasklet_block,
1586 (unsigned long)host);
1638 1587
1639 return 0; 1588 return 0;
1640} 1589}
1641 1590
1642static void __devexit wbsd_release_irq(struct wbsd_host* host) 1591static void __devexit wbsd_release_irq(struct wbsd_host *host)
1643{ 1592{
1644 if (!host->irq) 1593 if (!host->irq)
1645 return; 1594 return;
@@ -1660,7 +1609,7 @@ static void __devexit wbsd_release_irq(struct wbsd_host* host)
1660 * Allocate all resources for the host. 1609 * Allocate all resources for the host.
1661 */ 1610 */
1662 1611
1663static int __devinit wbsd_request_resources(struct wbsd_host* host, 1612static int __devinit wbsd_request_resources(struct wbsd_host *host,
1664 int base, int irq, int dma) 1613 int base, int irq, int dma)
1665{ 1614{
1666 int ret; 1615 int ret;
@@ -1691,7 +1640,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host* host,
1691 * Release all resources for the host. 1640 * Release all resources for the host.
1692 */ 1641 */
1693 1642
1694static void __devexit wbsd_release_resources(struct wbsd_host* host) 1643static void __devexit wbsd_release_resources(struct wbsd_host *host)
1695{ 1644{
1696 wbsd_release_dma(host); 1645 wbsd_release_dma(host);
1697 wbsd_release_irq(host); 1646 wbsd_release_irq(host);
@@ -1702,7 +1651,7 @@ static void __devexit wbsd_release_resources(struct wbsd_host* host)
1702 * Configure the resources the chip should use. 1651 * Configure the resources the chip should use.
1703 */ 1652 */
1704 1653
1705static void wbsd_chip_config(struct wbsd_host* host) 1654static void wbsd_chip_config(struct wbsd_host *host)
1706{ 1655{
1707 wbsd_unlock_config(host); 1656 wbsd_unlock_config(host);
1708 1657
@@ -1746,7 +1695,7 @@ static void wbsd_chip_config(struct wbsd_host* host)
1746 * Check that configured resources are correct. 1695 * Check that configured resources are correct.
1747 */ 1696 */
1748 1697
1749static int wbsd_chip_validate(struct wbsd_host* host) 1698static int wbsd_chip_validate(struct wbsd_host *host)
1750{ 1699{
1751 int base, irq, dma; 1700 int base, irq, dma;
1752 1701
@@ -1786,7 +1735,7 @@ static int wbsd_chip_validate(struct wbsd_host* host)
1786 * Powers down the SD function 1735 * Powers down the SD function
1787 */ 1736 */
1788 1737
1789static void wbsd_chip_poweroff(struct wbsd_host* host) 1738static void wbsd_chip_poweroff(struct wbsd_host *host)
1790{ 1739{
1791 wbsd_unlock_config(host); 1740 wbsd_unlock_config(host);
1792 1741
@@ -1802,11 +1751,11 @@ static void wbsd_chip_poweroff(struct wbsd_host* host)
1802 * * 1751 * *
1803\*****************************************************************************/ 1752\*****************************************************************************/
1804 1753
1805static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, 1754static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma,
1806 int pnp) 1755 int pnp)
1807{ 1756{
1808 struct wbsd_host* host = NULL; 1757 struct wbsd_host *host = NULL;
1809 struct mmc_host* mmc = NULL; 1758 struct mmc_host *mmc = NULL;
1810 int ret; 1759 int ret;
1811 1760
1812 ret = wbsd_alloc_mmc(dev); 1761 ret = wbsd_alloc_mmc(dev);
@@ -1820,16 +1769,12 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
1820 * Scan for hardware. 1769 * Scan for hardware.
1821 */ 1770 */
1822 ret = wbsd_scan(host); 1771 ret = wbsd_scan(host);
1823 if (ret) 1772 if (ret) {
1824 { 1773 if (pnp && (ret == -ENODEV)) {
1825 if (pnp && (ret == -ENODEV))
1826 {
1827 printk(KERN_WARNING DRIVER_NAME 1774 printk(KERN_WARNING DRIVER_NAME
1828 ": Unable to confirm device presence. You may " 1775 ": Unable to confirm device presence. You may "
1829 "experience lock-ups.\n"); 1776 "experience lock-ups.\n");
1830 } 1777 } else {
1831 else
1832 {
1833 wbsd_free_mmc(dev); 1778 wbsd_free_mmc(dev);
1834 return ret; 1779 return ret;
1835 } 1780 }
@@ -1839,8 +1784,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
1839 * Request resources. 1784 * Request resources.
1840 */ 1785 */
1841 ret = wbsd_request_resources(host, io, irq, dma); 1786 ret = wbsd_request_resources(host, io, irq, dma);
1842 if (ret) 1787 if (ret) {
1843 {
1844 wbsd_release_resources(host); 1788 wbsd_release_resources(host);
1845 wbsd_free_mmc(dev); 1789 wbsd_free_mmc(dev);
1846 return ret; 1790 return ret;
@@ -1849,18 +1793,15 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
1849 /* 1793 /*
1850 * See if chip needs to be configured. 1794 * See if chip needs to be configured.
1851 */ 1795 */
1852 if (pnp) 1796 if (pnp) {
1853 { 1797 if ((host->config != 0) && !wbsd_chip_validate(host)) {
1854 if ((host->config != 0) && !wbsd_chip_validate(host))
1855 {
1856 printk(KERN_WARNING DRIVER_NAME 1798 printk(KERN_WARNING DRIVER_NAME
1857 ": PnP active but chip not configured! " 1799 ": PnP active but chip not configured! "
1858 "You probably have a buggy BIOS. " 1800 "You probably have a buggy BIOS. "
1859 "Configuring chip manually.\n"); 1801 "Configuring chip manually.\n");
1860 wbsd_chip_config(host); 1802 wbsd_chip_config(host);
1861 } 1803 }
1862 } 1804 } else
1863 else
1864 wbsd_chip_config(host); 1805 wbsd_chip_config(host);
1865 1806
1866 /* 1807 /*
@@ -1868,8 +1809,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
1868 * Not tested. 1809 * Not tested.
1869 */ 1810 */
1870#ifdef CONFIG_PM 1811#ifdef CONFIG_PM
1871 if (host->config) 1812 if (host->config) {
1872 {
1873 wbsd_unlock_config(host); 1813 wbsd_unlock_config(host);
1874 wbsd_write_config(host, WBSD_CONF_PME, 0xA0); 1814 wbsd_write_config(host, WBSD_CONF_PME, 0xA0);
1875 wbsd_lock_config(host); 1815 wbsd_lock_config(host);
@@ -1902,10 +1842,10 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
1902 return 0; 1842 return 0;
1903} 1843}
1904 1844
1905static void __devexit wbsd_shutdown(struct device* dev, int pnp) 1845static void __devexit wbsd_shutdown(struct device *dev, int pnp)
1906{ 1846{
1907 struct mmc_host* mmc = dev_get_drvdata(dev); 1847 struct mmc_host *mmc = dev_get_drvdata(dev);
1908 struct wbsd_host* host; 1848 struct wbsd_host *host;
1909 1849
1910 if (!mmc) 1850 if (!mmc)
1911 return; 1851 return;
@@ -1929,12 +1869,12 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp)
1929 * Non-PnP 1869 * Non-PnP
1930 */ 1870 */
1931 1871
1932static int __devinit wbsd_probe(struct platform_device* dev) 1872static int __devinit wbsd_probe(struct platform_device *dev)
1933{ 1873{
1934 return wbsd_init(&dev->dev, io, irq, dma, 0); 1874 return wbsd_init(&dev->dev, io, irq, dma, 0);
1935} 1875}
1936 1876
1937static int __devexit wbsd_remove(struct platform_device* dev) 1877static int __devexit wbsd_remove(struct platform_device *dev)
1938{ 1878{
1939 wbsd_shutdown(&dev->dev, 0); 1879 wbsd_shutdown(&dev->dev, 0);
1940 1880
@@ -1948,7 +1888,7 @@ static int __devexit wbsd_remove(struct platform_device* dev)
1948#ifdef CONFIG_PNP 1888#ifdef CONFIG_PNP
1949 1889
1950static int __devinit 1890static int __devinit
1951wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id) 1891wbsd_pnp_probe(struct pnp_dev *pnpdev, const struct pnp_device_id *dev_id)
1952{ 1892{
1953 int io, irq, dma; 1893 int io, irq, dma;
1954 1894
@@ -1967,7 +1907,7 @@ wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id)
1967 return wbsd_init(&pnpdev->dev, io, irq, dma, 1); 1907 return wbsd_init(&pnpdev->dev, io, irq, dma, 1);
1968} 1908}
1969 1909
1970static void __devexit wbsd_pnp_remove(struct pnp_dev * dev) 1910static void __devexit wbsd_pnp_remove(struct pnp_dev *dev)
1971{ 1911{
1972 wbsd_shutdown(&dev->dev, 1); 1912 wbsd_shutdown(&dev->dev, 1);
1973} 1913}
@@ -1980,37 +1920,54 @@ static void __devexit wbsd_pnp_remove(struct pnp_dev * dev)
1980 1920
1981#ifdef CONFIG_PM 1921#ifdef CONFIG_PM
1982 1922
1983static int wbsd_suspend(struct platform_device *dev, pm_message_t state) 1923static int wbsd_suspend(struct wbsd_host *host, pm_message_t state)
1924{
1925 BUG_ON(host == NULL);
1926
1927 return mmc_suspend_host(host->mmc, state);
1928}
1929
1930static int wbsd_resume(struct wbsd_host *host)
1931{
1932 BUG_ON(host == NULL);
1933
1934 wbsd_init_device(host);
1935
1936 return mmc_resume_host(host->mmc);
1937}
1938
1939static int wbsd_platform_suspend(struct platform_device *dev,
1940 pm_message_t state)
1984{ 1941{
1985 struct mmc_host *mmc = platform_get_drvdata(dev); 1942 struct mmc_host *mmc = platform_get_drvdata(dev);
1986 struct wbsd_host *host; 1943 struct wbsd_host *host;
1987 int ret; 1944 int ret;
1988 1945
1989 if (!mmc) 1946 if (mmc == NULL)
1990 return 0; 1947 return 0;
1991 1948
1992 DBG("Suspending...\n"); 1949 DBGF("Suspending...\n");
1993
1994 ret = mmc_suspend_host(mmc, state);
1995 if (!ret)
1996 return ret;
1997 1950
1998 host = mmc_priv(mmc); 1951 host = mmc_priv(mmc);
1999 1952
1953 ret = wbsd_suspend(host, state);
1954 if (ret)
1955 return ret;
1956
2000 wbsd_chip_poweroff(host); 1957 wbsd_chip_poweroff(host);
2001 1958
2002 return 0; 1959 return 0;
2003} 1960}
2004 1961
2005static int wbsd_resume(struct platform_device *dev) 1962static int wbsd_platform_resume(struct platform_device *dev)
2006{ 1963{
2007 struct mmc_host *mmc = platform_get_drvdata(dev); 1964 struct mmc_host *mmc = platform_get_drvdata(dev);
2008 struct wbsd_host *host; 1965 struct wbsd_host *host;
2009 1966
2010 if (!mmc) 1967 if (mmc == NULL)
2011 return 0; 1968 return 0;
2012 1969
2013 DBG("Resuming...\n"); 1970 DBGF("Resuming...\n");
2014 1971
2015 host = mmc_priv(mmc); 1972 host = mmc_priv(mmc);
2016 1973
@@ -2021,15 +1978,68 @@ static int wbsd_resume(struct platform_device *dev)
2021 */ 1978 */
2022 mdelay(5); 1979 mdelay(5);
2023 1980
2024 wbsd_init_device(host); 1981 return wbsd_resume(host);
1982}
1983
1984#ifdef CONFIG_PNP
1985
1986static int wbsd_pnp_suspend(struct pnp_dev *pnp_dev, pm_message_t state)
1987{
1988 struct mmc_host *mmc = dev_get_drvdata(&pnp_dev->dev);
1989 struct wbsd_host *host;
1990
1991 if (mmc == NULL)
1992 return 0;
1993
1994 DBGF("Suspending...\n");
1995
1996 host = mmc_priv(mmc);
1997
1998 return wbsd_suspend(host, state);
1999}
2000
2001static int wbsd_pnp_resume(struct pnp_dev *pnp_dev)
2002{
2003 struct mmc_host *mmc = dev_get_drvdata(&pnp_dev->dev);
2004 struct wbsd_host *host;
2005
2006 if (mmc == NULL)
2007 return 0;
2008
2009 DBGF("Resuming...\n");
2025 2010
2026 return mmc_resume_host(mmc); 2011 host = mmc_priv(mmc);
2012
2013 /*
2014 * See if chip needs to be configured.
2015 */
2016 if (host->config != 0) {
2017 if (!wbsd_chip_validate(host)) {
2018 printk(KERN_WARNING DRIVER_NAME
2019 ": PnP active but chip not configured! "
2020 "You probably have a buggy BIOS. "
2021 "Configuring chip manually.\n");
2022 wbsd_chip_config(host);
2023 }
2024 }
2025
2026 /*
2027 * Allow device to initialise itself properly.
2028 */
2029 mdelay(5);
2030
2031 return wbsd_resume(host);
2027} 2032}
2028 2033
2034#endif /* CONFIG_PNP */
2035
2029#else /* CONFIG_PM */ 2036#else /* CONFIG_PM */
2030 2037
2031#define wbsd_suspend NULL 2038#define wbsd_platform_suspend NULL
2032#define wbsd_resume NULL 2039#define wbsd_platform_resume NULL
2040
2041#define wbsd_pnp_suspend NULL
2042#define wbsd_pnp_resume NULL
2033 2043
2034#endif /* CONFIG_PM */ 2044#endif /* CONFIG_PM */
2035 2045
@@ -2039,8 +2049,8 @@ static struct platform_driver wbsd_driver = {
2039 .probe = wbsd_probe, 2049 .probe = wbsd_probe,
2040 .remove = __devexit_p(wbsd_remove), 2050 .remove = __devexit_p(wbsd_remove),
2041 2051
2042 .suspend = wbsd_suspend, 2052 .suspend = wbsd_platform_suspend,
2043 .resume = wbsd_resume, 2053 .resume = wbsd_platform_resume,
2044 .driver = { 2054 .driver = {
2045 .name = DRIVER_NAME, 2055 .name = DRIVER_NAME,
2046 }, 2056 },
@@ -2053,6 +2063,9 @@ static struct pnp_driver wbsd_pnp_driver = {
2053 .id_table = pnp_dev_table, 2063 .id_table = pnp_dev_table,
2054 .probe = wbsd_pnp_probe, 2064 .probe = wbsd_pnp_probe,
2055 .remove = __devexit_p(wbsd_pnp_remove), 2065 .remove = __devexit_p(wbsd_pnp_remove),
2066
2067 .suspend = wbsd_pnp_suspend,
2068 .resume = wbsd_pnp_resume,
2056}; 2069};
2057 2070
2058#endif /* CONFIG_PNP */ 2071#endif /* CONFIG_PNP */
@@ -2072,31 +2085,26 @@ static int __init wbsd_drv_init(void)
2072 2085
2073#ifdef CONFIG_PNP 2086#ifdef CONFIG_PNP
2074 2087
2075 if (!nopnp) 2088 if (!nopnp) {
2076 {
2077 result = pnp_register_driver(&wbsd_pnp_driver); 2089 result = pnp_register_driver(&wbsd_pnp_driver);
2078 if (result < 0) 2090 if (result < 0)
2079 return result; 2091 return result;
2080 } 2092 }
2081
2082#endif /* CONFIG_PNP */ 2093#endif /* CONFIG_PNP */
2083 2094
2084 if (nopnp) 2095 if (nopnp) {
2085 {
2086 result = platform_driver_register(&wbsd_driver); 2096 result = platform_driver_register(&wbsd_driver);
2087 if (result < 0) 2097 if (result < 0)
2088 return result; 2098 return result;
2089 2099
2090 wbsd_device = platform_device_alloc(DRIVER_NAME, -1); 2100 wbsd_device = platform_device_alloc(DRIVER_NAME, -1);
2091 if (!wbsd_device) 2101 if (!wbsd_device) {
2092 {
2093 platform_driver_unregister(&wbsd_driver); 2102 platform_driver_unregister(&wbsd_driver);
2094 return -ENOMEM; 2103 return -ENOMEM;
2095 } 2104 }
2096 2105
2097 result = platform_device_add(wbsd_device); 2106 result = platform_device_add(wbsd_device);
2098 if (result) 2107 if (result) {
2099 {
2100 platform_device_put(wbsd_device); 2108 platform_device_put(wbsd_device);
2101 platform_driver_unregister(&wbsd_driver); 2109 platform_driver_unregister(&wbsd_driver);
2102 return result; 2110 return result;
@@ -2115,8 +2123,7 @@ static void __exit wbsd_drv_exit(void)
2115 2123
2116#endif /* CONFIG_PNP */ 2124#endif /* CONFIG_PNP */
2117 2125
2118 if (nopnp) 2126 if (nopnp) {
2119 {
2120 platform_device_unregister(wbsd_device); 2127 platform_device_unregister(wbsd_device);
2121 2128
2122 platform_driver_unregister(&wbsd_driver); 2129 platform_driver_unregister(&wbsd_driver);
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 339cb1218eaa..7f3ff500b68e 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -194,6 +194,14 @@ static int blktrans_release(struct inode *i, struct file *f)
194 return ret; 194 return ret;
195} 195}
196 196
197static int blktrans_getgeo(struct block_device *bdev, struct hd_geometry *geo)
198{
199 struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
200
201 if (dev->tr->getgeo)
202 return dev->tr->getgeo(dev, geo);
203 return -ENOTTY;
204}
197 205
198static int blktrans_ioctl(struct inode *inode, struct file *file, 206static int blktrans_ioctl(struct inode *inode, struct file *file,
199 unsigned int cmd, unsigned long arg) 207 unsigned int cmd, unsigned long arg)
@@ -207,22 +215,6 @@ static int blktrans_ioctl(struct inode *inode, struct file *file,
207 return tr->flush(dev); 215 return tr->flush(dev);
208 /* The core code did the work, we had nothing to do. */ 216 /* The core code did the work, we had nothing to do. */
209 return 0; 217 return 0;
210
211 case HDIO_GETGEO:
212 if (tr->getgeo) {
213 struct hd_geometry g;
214 int ret;
215
216 memset(&g, 0, sizeof(g));
217 ret = tr->getgeo(dev, &g);
218 if (ret)
219 return ret;
220
221 g.start = get_start_sect(inode->i_bdev);
222 if (copy_to_user((void __user *)arg, &g, sizeof(g)))
223 return -EFAULT;
224 return 0;
225 } /* else */
226 default: 218 default:
227 return -ENOTTY; 219 return -ENOTTY;
228 } 220 }
@@ -233,6 +225,7 @@ struct block_device_operations mtd_blktrans_ops = {
233 .open = blktrans_open, 225 .open = blktrans_open,
234 .release = blktrans_release, 226 .release = blktrans_release,
235 .ioctl = blktrans_ioctl, 227 .ioctl = blktrans_ioctl,
228 .getgeo = blktrans_getgeo,
236}; 229};
237 230
238int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) 231int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
index 45c077d0f063..af06a80f44de 100644
--- a/drivers/mtd/onenand/generic.c
+++ b/drivers/mtd/onenand/generic.c
@@ -14,6 +14,7 @@
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/slab.h>
17#include <linux/platform_device.h> 18#include <linux/platform_device.h>
18#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
19#include <linux/mtd/onenand.h> 20#include <linux/mtd/onenand.h>
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index 20ce212638fc..a3e00a4635a5 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -18,6 +18,7 @@
18#include <linux/mtd/blktrans.h> 18#include <linux/mtd/blktrans.h>
19#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
20#include <linux/vmalloc.h> 20#include <linux/vmalloc.h>
21#include <linux/slab.h>
21#include <linux/jiffies.h> 22#include <linux/jiffies.h>
22 23
23#include <asm/types.h> 24#include <asm/types.h>
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index 5c5eebdb6914..dcc98afa65d7 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -148,14 +148,6 @@ el2_pio_probe(struct net_device *dev)
148 return -ENODEV; 148 return -ENODEV;
149} 149}
150 150
151static void cleanup_card(struct net_device *dev)
152{
153 /* NB: el2_close() handles free_irq */
154 release_region(dev->base_addr, EL2_IO_EXTENT);
155 if (ei_status.mem)
156 iounmap(ei_status.mem);
157}
158
159#ifndef MODULE 151#ifndef MODULE
160struct net_device * __init el2_probe(int unit) 152struct net_device * __init el2_probe(int unit)
161{ 153{
@@ -726,6 +718,14 @@ init_module(void)
726 return -ENXIO; 718 return -ENXIO;
727} 719}
728 720
721static void cleanup_card(struct net_device *dev)
722{
723 /* NB: el2_close() handles free_irq */
724 release_region(dev->base_addr, EL2_IO_EXTENT);
725 if (ei_status.mem)
726 iounmap(ei_status.mem);
727}
728
729void 729void
730cleanup_module(void) 730cleanup_module(void)
731{ 731{
diff --git a/drivers/net/3c527.h b/drivers/net/3c527.h
index c10f009ce9b6..53b5b071df08 100644
--- a/drivers/net/3c527.h
+++ b/drivers/net/3c527.h
@@ -32,43 +32,43 @@
32 32
33struct mc32_mailbox 33struct mc32_mailbox
34{ 34{
35 u16 mbox __attribute((packed)); 35 u16 mbox;
36 u16 data[1] __attribute((packed)); 36 u16 data[1];
37}; 37} __attribute((packed));
38 38
39struct skb_header 39struct skb_header
40{ 40{
41 u8 status __attribute((packed)); 41 u8 status;
42 u8 control __attribute((packed)); 42 u8 control;
43 u16 next __attribute((packed)); /* Do not change! */ 43 u16 next; /* Do not change! */
44 u16 length __attribute((packed)); 44 u16 length;
45 u32 data __attribute((packed)); 45 u32 data;
46}; 46} __attribute((packed));
47 47
48struct mc32_stats 48struct mc32_stats
49{ 49{
50 /* RX Errors */ 50 /* RX Errors */
51 u32 rx_crc_errors __attribute((packed)); 51 u32 rx_crc_errors;
52 u32 rx_alignment_errors __attribute((packed)); 52 u32 rx_alignment_errors;
53 u32 rx_overrun_errors __attribute((packed)); 53 u32 rx_overrun_errors;
54 u32 rx_tooshort_errors __attribute((packed)); 54 u32 rx_tooshort_errors;
55 u32 rx_toolong_errors __attribute((packed)); 55 u32 rx_toolong_errors;
56 u32 rx_outofresource_errors __attribute((packed)); 56 u32 rx_outofresource_errors;
57 57
58 u32 rx_discarded __attribute((packed)); /* via card pattern match filter */ 58 u32 rx_discarded; /* via card pattern match filter */
59 59
60 /* TX Errors */ 60 /* TX Errors */
61 u32 tx_max_collisions __attribute((packed)); 61 u32 tx_max_collisions;
62 u32 tx_carrier_errors __attribute((packed)); 62 u32 tx_carrier_errors;
63 u32 tx_underrun_errors __attribute((packed)); 63 u32 tx_underrun_errors;
64 u32 tx_cts_errors __attribute((packed)); 64 u32 tx_cts_errors;
65 u32 tx_timeout_errors __attribute((packed)) ; 65 u32 tx_timeout_errors;
66 66
67 /* various cruft */ 67 /* various cruft */
68 u32 dataA[6] __attribute((packed)); 68 u32 dataA[6];
69 u16 dataB[5] __attribute((packed)); 69 u16 dataB[5];
70 u32 dataC[14] __attribute((packed)); 70 u32 dataC[14];
71}; 71} __attribute((packed));
72 72
73#define STATUS_MASK 0x0F 73#define STATUS_MASK 0x0F
74#define COMPLETED (1<<7) 74#define COMPLETED (1<<7)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index e2fa29b612cd..733bc25b2bf9 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -129,7 +129,7 @@ config NET_SB1000
129 129
130 If you don't have this card, of course say N. 130 If you don't have this card, of course say N.
131 131
132 source "drivers/net/arcnet/Kconfig" 132source "drivers/net/arcnet/Kconfig"
133 133
134source "drivers/net/phy/Kconfig" 134source "drivers/net/phy/Kconfig"
135 135
@@ -844,7 +844,7 @@ config SMC9194
844 844
845config DM9000 845config DM9000
846 tristate "DM9000 support" 846 tristate "DM9000 support"
847 depends on ARM && NET_ETHERNET 847 depends on (ARM || MIPS) && NET_ETHERNET
848 select CRC32 848 select CRC32
849 select MII 849 select MII
850 ---help--- 850 ---help---
@@ -1374,7 +1374,7 @@ config FORCEDETH
1374 1374
1375config CS89x0 1375config CS89x0
1376 tristate "CS89x0 support" 1376 tristate "CS89x0 support"
1377 depends on (NET_PCI && (ISA || ARCH_IXDP2X01)) || ARCH_PNX0105 1377 depends on NET_PCI && (ISA || ARCH_IXDP2X01 || ARCH_PNX010X)
1378 ---help--- 1378 ---help---
1379 Support for CS89x0 chipset based Ethernet cards. If you have a 1379 Support for CS89x0 chipset based Ethernet cards. If you have a
1380 network (Ethernet) card of this type, say Y and read the 1380 network (Ethernet) card of this type, say Y and read the
diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c
index 8a0af5453e21..7952dc6d77e3 100644
--- a/drivers/net/ac3200.c
+++ b/drivers/net/ac3200.c
@@ -123,14 +123,6 @@ static int __init do_ac3200_probe(struct net_device *dev)
123 return -ENODEV; 123 return -ENODEV;
124} 124}
125 125
126static void cleanup_card(struct net_device *dev)
127{
128 /* Someday free_irq may be in ac_close_card() */
129 free_irq(dev->irq, dev);
130 release_region(dev->base_addr, AC_IO_EXTENT);
131 iounmap(ei_status.mem);
132}
133
134#ifndef MODULE 126#ifndef MODULE
135struct net_device * __init ac3200_probe(int unit) 127struct net_device * __init ac3200_probe(int unit)
136{ 128{
@@ -406,6 +398,14 @@ init_module(void)
406 return -ENXIO; 398 return -ENXIO;
407} 399}
408 400
401static void cleanup_card(struct net_device *dev)
402{
403 /* Someday free_irq may be in ac_close_card() */
404 free_irq(dev->irq, dev);
405 release_region(dev->base_addr, AC_IO_EXTENT);
406 iounmap(ei_status.mem);
407}
408
409void 409void
410cleanup_module(void) 410cleanup_module(void)
411{ 411{
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 015c7f1d1bc0..f20bb85c1ea5 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -205,7 +205,7 @@ struct bonding {
205 * 205 *
206 * Caller must hold bond lock for read 206 * Caller must hold bond lock for read
207 */ 207 */
208extern inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev) 208static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev)
209{ 209{
210 struct slave *slave = NULL; 210 struct slave *slave = NULL;
211 int i; 211 int i;
@@ -219,7 +219,7 @@ extern inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct n
219 return slave; 219 return slave;
220} 220}
221 221
222extern inline struct bonding *bond_get_bond_by_slave(struct slave *slave) 222static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
223{ 223{
224 if (!slave || !slave->dev->master) { 224 if (!slave || !slave->dev->master) {
225 return NULL; 225 return NULL;
@@ -228,13 +228,13 @@ extern inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
228 return (struct bonding *)slave->dev->master->priv; 228 return (struct bonding *)slave->dev->master->priv;
229} 229}
230 230
231extern inline void bond_set_slave_inactive_flags(struct slave *slave) 231static inline void bond_set_slave_inactive_flags(struct slave *slave)
232{ 232{
233 slave->state = BOND_STATE_BACKUP; 233 slave->state = BOND_STATE_BACKUP;
234 slave->dev->flags |= IFF_NOARP; 234 slave->dev->flags |= IFF_NOARP;
235} 235}
236 236
237extern inline void bond_set_slave_active_flags(struct slave *slave) 237static inline void bond_set_slave_active_flags(struct slave *slave)
238{ 238{
239 slave->state = BOND_STATE_ACTIVE; 239 slave->state = BOND_STATE_ACTIVE;
240 slave->dev->flags &= ~IFF_NOARP; 240 slave->dev->flags &= ~IFF_NOARP;
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index a6078ad9b654..907c01009746 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -175,7 +175,7 @@ static unsigned int cs8900_irq_map[] = {1,0,0,0};
175#include <asm/irq.h> 175#include <asm/irq.h>
176static unsigned int netcard_portlist[] __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0}; 176static unsigned int netcard_portlist[] __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
177static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0}; 177static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
178#elif defined(CONFIG_ARCH_PNX0105) 178#elif defined(CONFIG_ARCH_PNX010X)
179#include <asm/irq.h> 179#include <asm/irq.h>
180#include <asm/arch/gpio.h> 180#include <asm/arch/gpio.h>
181#define CIRRUS_DEFAULT_BASE IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000) /* = Physical address 0x48200000 */ 181#define CIRRUS_DEFAULT_BASE IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000) /* = Physical address 0x48200000 */
@@ -338,30 +338,86 @@ out:
338} 338}
339#endif 339#endif
340 340
341#if defined(CONFIG_ARCH_IXDP2X01)
341static int 342static int
342readreg(struct net_device *dev, int portno) 343readword(unsigned long base_addr, int portno)
343{ 344{
344 outw(portno, dev->base_addr + ADD_PORT); 345 return (u16)__raw_readl(base_addr + (portno << 1));
345 return inw(dev->base_addr + DATA_PORT);
346} 346}
347 347
348static void 348static void
349writereg(struct net_device *dev, int portno, int value) 349writeword(unsigned long base_addr, int portno, int value)
350{ 350{
351 outw(portno, dev->base_addr + ADD_PORT); 351 __raw_writel((u16)value, base_addr + (portno << 1));
352 outw(value, dev->base_addr + DATA_PORT); 352}
353#else
354#if defined(CONFIG_ARCH_PNX010X)
355static int
356readword(unsigned long base_addr, int portno)
357{
358 return inw(base_addr + (portno << 1));
359}
360
361static void
362writeword(unsigned long base_addr, int portno, int value)
363{
364 outw(value, base_addr + (portno << 1));
365}
366#else
367static int
368readword(unsigned long base_addr, int portno)
369{
370 return inw(base_addr + portno);
371}
372
373static void
374writeword(unsigned long base_addr, int portno, int value)
375{
376 outw(value, base_addr + portno);
377}
378#endif
379#endif
380
381static void
382readwords(unsigned long base_addr, int portno, void *buf, int length)
383{
384 u8 *buf8 = (u8 *)buf;
385
386 do {
387 u32 tmp32;
388
389 tmp32 = readword(base_addr, portno);
390 *buf8++ = (u8)tmp32;
391 *buf8++ = (u8)(tmp32 >> 8);
392 } while (--length);
393}
394
395static void
396writewords(unsigned long base_addr, int portno, void *buf, int length)
397{
398 u8 *buf8 = (u8 *)buf;
399
400 do {
401 u32 tmp32;
402
403 tmp32 = *buf8++;
404 tmp32 |= (*buf8++) << 8;
405 writeword(base_addr, portno, tmp32);
406 } while (--length);
353} 407}
354 408
355static int 409static int
356readword(struct net_device *dev, int portno) 410readreg(struct net_device *dev, int regno)
357{ 411{
358 return inw(dev->base_addr + portno); 412 writeword(dev->base_addr, ADD_PORT, regno);
413 return readword(dev->base_addr, DATA_PORT);
359} 414}
360 415
361static void 416static void
362writeword(struct net_device *dev, int portno, int value) 417writereg(struct net_device *dev, int regno, int value)
363{ 418{
364 outw(value, dev->base_addr + portno); 419 writeword(dev->base_addr, ADD_PORT, regno);
420 writeword(dev->base_addr, DATA_PORT, value);
365} 421}
366 422
367static int __init 423static int __init
@@ -456,7 +512,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
456#endif 512#endif
457 } 513 }
458 514
459#ifdef CONFIG_ARCH_PNX0105 515#ifdef CONFIG_ARCH_PNX010X
460 initialize_ebi(); 516 initialize_ebi();
461 517
462 /* Map GPIO registers for the pins connected to the CS8900a. */ 518 /* Map GPIO registers for the pins connected to the CS8900a. */
@@ -491,8 +547,8 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
491 547
492#ifdef CONFIG_SH_HICOSH4 548#ifdef CONFIG_SH_HICOSH4
493 /* truely reset the chip */ 549 /* truely reset the chip */
494 outw(0x0114, ioaddr + ADD_PORT); 550 writeword(ioaddr, ADD_PORT, 0x0114);
495 outw(0x0040, ioaddr + DATA_PORT); 551 writeword(ioaddr, DATA_PORT, 0x0040);
496#endif 552#endif
497 553
498 /* if they give us an odd I/O address, then do ONE write to 554 /* if they give us an odd I/O address, then do ONE write to
@@ -503,24 +559,24 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
503 if (net_debug > 1) 559 if (net_debug > 1)
504 printk(KERN_INFO "%s: odd ioaddr 0x%x\n", dev->name, ioaddr); 560 printk(KERN_INFO "%s: odd ioaddr 0x%x\n", dev->name, ioaddr);
505 if ((ioaddr & 2) != 2) 561 if ((ioaddr & 2) != 2)
506 if ((inw((ioaddr & ~3)+ ADD_PORT) & ADD_MASK) != ADD_SIG) { 562 if ((readword(ioaddr & ~3, ADD_PORT) & ADD_MASK) != ADD_SIG) {
507 printk(KERN_ERR "%s: bad signature 0x%x\n", 563 printk(KERN_ERR "%s: bad signature 0x%x\n",
508 dev->name, inw((ioaddr & ~3)+ ADD_PORT)); 564 dev->name, readword(ioaddr & ~3, ADD_PORT));
509 retval = -ENODEV; 565 retval = -ENODEV;
510 goto out2; 566 goto out2;
511 } 567 }
512 } 568 }
513 printk(KERN_DEBUG "PP_addr at %x: 0x%x\n", 569 printk(KERN_DEBUG "PP_addr at %x[%x]: 0x%x\n",
514 ioaddr + ADD_PORT, inw(ioaddr + ADD_PORT)); 570 ioaddr, ADD_PORT, readword(ioaddr, ADD_PORT));
515 571
516 ioaddr &= ~3; 572 ioaddr &= ~3;
517 outw(PP_ChipID, ioaddr + ADD_PORT); 573 writeword(ioaddr, ADD_PORT, PP_ChipID);
518 574
519 tmp = inw(ioaddr + DATA_PORT); 575 tmp = readword(ioaddr, DATA_PORT);
520 if (tmp != CHIP_EISA_ID_SIG) { 576 if (tmp != CHIP_EISA_ID_SIG) {
521 printk(KERN_DEBUG "%s: incorrect signature at %x: 0x%x!=" 577 printk(KERN_DEBUG "%s: incorrect signature at %x[%x]: 0x%x!="
522 CHIP_EISA_ID_SIG_STR "\n", 578 CHIP_EISA_ID_SIG_STR "\n",
523 dev->name, ioaddr + DATA_PORT, tmp); 579 dev->name, ioaddr, DATA_PORT, tmp);
524 retval = -ENODEV; 580 retval = -ENODEV;
525 goto out2; 581 goto out2;
526 } 582 }
@@ -724,7 +780,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
724 } else { 780 } else {
725 i = lp->isa_config & INT_NO_MASK; 781 i = lp->isa_config & INT_NO_MASK;
726 if (lp->chip_type == CS8900) { 782 if (lp->chip_type == CS8900) {
727#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105) 783#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX010X)
728 i = cs8900_irq_map[0]; 784 i = cs8900_irq_map[0];
729#else 785#else
730 /* Translate the IRQ using the IRQ mapping table. */ 786 /* Translate the IRQ using the IRQ mapping table. */
@@ -790,7 +846,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
790 goto out3; 846 goto out3;
791 return 0; 847 return 0;
792out3: 848out3:
793 outw(PP_ChipID, dev->base_addr + ADD_PORT); 849 writeword(dev->base_addr, ADD_PORT, PP_ChipID);
794out2: 850out2:
795 release_region(ioaddr & ~3, NETCARD_IO_EXTENT); 851 release_region(ioaddr & ~3, NETCARD_IO_EXTENT);
796out1: 852out1:
@@ -970,11 +1026,11 @@ void __init reset_chip(struct net_device *dev)
970#ifndef CONFIG_ARCH_IXDP2X01 1026#ifndef CONFIG_ARCH_IXDP2X01
971 if (lp->chip_type != CS8900) { 1027 if (lp->chip_type != CS8900) {
972 /* Hardware problem requires PNP registers to be reconfigured after a reset */ 1028 /* Hardware problem requires PNP registers to be reconfigured after a reset */
973 outw(PP_CS8920_ISAINT, ioaddr + ADD_PORT); 1029 writeword(ioaddr, ADD_PORT, PP_CS8920_ISAINT);
974 outb(dev->irq, ioaddr + DATA_PORT); 1030 outb(dev->irq, ioaddr + DATA_PORT);
975 outb(0, ioaddr + DATA_PORT + 1); 1031 outb(0, ioaddr + DATA_PORT + 1);
976 1032
977 outw(PP_CS8920_ISAMemB, ioaddr + ADD_PORT); 1033 writeword(ioaddr, ADD_PORT, PP_CS8920_ISAMemB);
978 outb((dev->mem_start >> 16) & 0xff, ioaddr + DATA_PORT); 1034 outb((dev->mem_start >> 16) & 0xff, ioaddr + DATA_PORT);
979 outb((dev->mem_start >> 8) & 0xff, ioaddr + DATA_PORT + 1); 1035 outb((dev->mem_start >> 8) & 0xff, ioaddr + DATA_PORT + 1);
980 } 1036 }
@@ -1104,8 +1160,8 @@ send_test_pkt(struct net_device *dev)
1104 memcpy(test_packet, dev->dev_addr, ETH_ALEN); 1160 memcpy(test_packet, dev->dev_addr, ETH_ALEN);
1105 memcpy(test_packet+ETH_ALEN, dev->dev_addr, ETH_ALEN); 1161 memcpy(test_packet+ETH_ALEN, dev->dev_addr, ETH_ALEN);
1106 1162
1107 writeword(dev, TX_CMD_PORT, TX_AFTER_ALL); 1163 writeword(dev->base_addr, TX_CMD_PORT, TX_AFTER_ALL);
1108 writeword(dev, TX_LEN_PORT, ETH_ZLEN); 1164 writeword(dev->base_addr, TX_LEN_PORT, ETH_ZLEN);
1109 1165
1110 /* Test to see if the chip has allocated memory for the packet */ 1166 /* Test to see if the chip has allocated memory for the packet */
1111 while (jiffies - timenow < 5) 1167 while (jiffies - timenow < 5)
@@ -1115,7 +1171,7 @@ send_test_pkt(struct net_device *dev)
1115 return 0; /* this shouldn't happen */ 1171 return 0; /* this shouldn't happen */
1116 1172
1117 /* Write the contents of the packet */ 1173 /* Write the contents of the packet */
1118 outsw(dev->base_addr + TX_FRAME_PORT,test_packet,(ETH_ZLEN+1) >>1); 1174 writewords(dev->base_addr, TX_FRAME_PORT,test_packet,(ETH_ZLEN+1) >>1);
1119 1175
1120 if (net_debug > 1) printk("Sending test packet "); 1176 if (net_debug > 1) printk("Sending test packet ");
1121 /* wait a couple of jiffies for packet to be received */ 1177 /* wait a couple of jiffies for packet to be received */
@@ -1200,7 +1256,7 @@ net_open(struct net_device *dev)
1200 int i; 1256 int i;
1201 int ret; 1257 int ret;
1202 1258
1203#if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX0105) /* uses irq#1, so this won't work */ 1259#if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX010X) /* uses irq#1, so this won't work */
1204 if (dev->irq < 2) { 1260 if (dev->irq < 2) {
1205 /* Allow interrupts to be generated by the chip */ 1261 /* Allow interrupts to be generated by the chip */
1206/* Cirrus' release had this: */ 1262/* Cirrus' release had this: */
@@ -1231,7 +1287,7 @@ net_open(struct net_device *dev)
1231 else 1287 else
1232#endif 1288#endif
1233 { 1289 {
1234#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX0105) 1290#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X)
1235 if (((1 << dev->irq) & lp->irq_map) == 0) { 1291 if (((1 << dev->irq) & lp->irq_map) == 0) {
1236 printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n", 1292 printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
1237 dev->name, dev->irq, lp->irq_map); 1293 dev->name, dev->irq, lp->irq_map);
@@ -1316,7 +1372,7 @@ net_open(struct net_device *dev)
1316 case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break; 1372 case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break;
1317 default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2); 1373 default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2);
1318 } 1374 }
1319#ifdef CONFIG_ARCH_PNX0105 1375#ifdef CONFIG_ARCH_PNX010X
1320 result = A_CNF_10B_T; 1376 result = A_CNF_10B_T;
1321#endif 1377#endif
1322 if (!result) { 1378 if (!result) {
@@ -1457,8 +1513,8 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
1457 netif_stop_queue(dev); 1513 netif_stop_queue(dev);
1458 1514
1459 /* initiate a transmit sequence */ 1515 /* initiate a transmit sequence */
1460 writeword(dev, TX_CMD_PORT, lp->send_cmd); 1516 writeword(dev->base_addr, TX_CMD_PORT, lp->send_cmd);
1461 writeword(dev, TX_LEN_PORT, skb->len); 1517 writeword(dev->base_addr, TX_LEN_PORT, skb->len);
1462 1518
1463 /* Test to see if the chip has allocated memory for the packet */ 1519 /* Test to see if the chip has allocated memory for the packet */
1464 if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) { 1520 if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
@@ -1472,7 +1528,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
1472 return 1; 1528 return 1;
1473 } 1529 }
1474 /* Write the contents of the packet */ 1530 /* Write the contents of the packet */
1475 outsw(dev->base_addr + TX_FRAME_PORT,skb->data,(skb->len+1) >>1); 1531 writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
1476 spin_unlock_irq(&lp->lock); 1532 spin_unlock_irq(&lp->lock);
1477 lp->stats.tx_bytes += skb->len; 1533 lp->stats.tx_bytes += skb->len;
1478 dev->trans_start = jiffies; 1534 dev->trans_start = jiffies;
@@ -1512,7 +1568,7 @@ static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
1512 course, if you're on a slow machine, and packets are arriving 1568 course, if you're on a slow machine, and packets are arriving
1513 faster than you can read them off, you're screwed. Hasta la 1569 faster than you can read them off, you're screwed. Hasta la
1514 vista, baby! */ 1570 vista, baby! */
1515 while ((status = readword(dev, ISQ_PORT))) { 1571 while ((status = readword(dev->base_addr, ISQ_PORT))) {
1516 if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status); 1572 if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status);
1517 handled = 1; 1573 handled = 1;
1518 switch(status & ISQ_EVENT_MASK) { 1574 switch(status & ISQ_EVENT_MASK) {
@@ -1606,8 +1662,8 @@ net_rx(struct net_device *dev)
1606 int status, length; 1662 int status, length;
1607 1663
1608 int ioaddr = dev->base_addr; 1664 int ioaddr = dev->base_addr;
1609 status = inw(ioaddr + RX_FRAME_PORT); 1665 status = readword(ioaddr, RX_FRAME_PORT);
1610 length = inw(ioaddr + RX_FRAME_PORT); 1666 length = readword(ioaddr, RX_FRAME_PORT);
1611 1667
1612 if ((status & RX_OK) == 0) { 1668 if ((status & RX_OK) == 0) {
1613 count_rx_errors(status, lp); 1669 count_rx_errors(status, lp);
@@ -1626,9 +1682,9 @@ net_rx(struct net_device *dev)
1626 skb_reserve(skb, 2); /* longword align L3 header */ 1682 skb_reserve(skb, 2); /* longword align L3 header */
1627 skb->dev = dev; 1683 skb->dev = dev;
1628 1684
1629 insw(ioaddr + RX_FRAME_PORT, skb_put(skb, length), length >> 1); 1685 readwords(ioaddr, RX_FRAME_PORT, skb_put(skb, length), length >> 1);
1630 if (length & 1) 1686 if (length & 1)
1631 skb->data[length-1] = inw(ioaddr + RX_FRAME_PORT); 1687 skb->data[length-1] = readword(ioaddr, RX_FRAME_PORT);
1632 1688
1633 if (net_debug > 3) { 1689 if (net_debug > 3) {
1634 printk( "%s: received %d byte packet of type %x\n", 1690 printk( "%s: received %d byte packet of type %x\n",
@@ -1901,7 +1957,7 @@ void
1901cleanup_module(void) 1957cleanup_module(void)
1902{ 1958{
1903 unregister_netdev(dev_cs89x0); 1959 unregister_netdev(dev_cs89x0);
1904 outw(PP_ChipID, dev_cs89x0->base_addr + ADD_PORT); 1960 writeword(dev_cs89x0->base_addr, ADD_PORT, PP_ChipID);
1905 release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT); 1961 release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
1906 free_netdev(dev_cs89x0); 1962 free_netdev(dev_cs89x0);
1907} 1963}
diff --git a/drivers/net/cs89x0.h b/drivers/net/cs89x0.h
index decea264f121..bd954aaa636f 100644
--- a/drivers/net/cs89x0.h
+++ b/drivers/net/cs89x0.h
@@ -16,13 +16,6 @@
16 16
17#include <linux/config.h> 17#include <linux/config.h>
18 18
19#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105)
20/* IXDP2401/IXDP2801 uses dword-aligned register addressing */
21#define CS89x0_PORT(reg) ((reg) * 2)
22#else
23#define CS89x0_PORT(reg) (reg)
24#endif
25
26#define PP_ChipID 0x0000 /* offset 0h -> Corp -ID */ 19#define PP_ChipID 0x0000 /* offset 0h -> Corp -ID */
27 /* offset 2h -> Model/Product Number */ 20 /* offset 2h -> Model/Product Number */
28 /* offset 3h -> Chip Revision Number */ 21 /* offset 3h -> Chip Revision Number */
@@ -332,16 +325,16 @@
332#define RAM_SIZE 0x1000 /* The card has 4k bytes or RAM */ 325#define RAM_SIZE 0x1000 /* The card has 4k bytes or RAM */
333#define PKT_START PP_TxFrame /* Start of packet RAM */ 326#define PKT_START PP_TxFrame /* Start of packet RAM */
334 327
335#define RX_FRAME_PORT CS89x0_PORT(0x0000) 328#define RX_FRAME_PORT 0x0000
336#define TX_FRAME_PORT RX_FRAME_PORT 329#define TX_FRAME_PORT RX_FRAME_PORT
337#define TX_CMD_PORT CS89x0_PORT(0x0004) 330#define TX_CMD_PORT 0x0004
338#define TX_NOW 0x0000 /* Tx packet after 5 bytes copied */ 331#define TX_NOW 0x0000 /* Tx packet after 5 bytes copied */
339#define TX_AFTER_381 0x0040 /* Tx packet after 381 bytes copied */ 332#define TX_AFTER_381 0x0040 /* Tx packet after 381 bytes copied */
340#define TX_AFTER_ALL 0x00c0 /* Tx packet after all bytes copied */ 333#define TX_AFTER_ALL 0x00c0 /* Tx packet after all bytes copied */
341#define TX_LEN_PORT CS89x0_PORT(0x0006) 334#define TX_LEN_PORT 0x0006
342#define ISQ_PORT CS89x0_PORT(0x0008) 335#define ISQ_PORT 0x0008
343#define ADD_PORT CS89x0_PORT(0x000A) 336#define ADD_PORT 0x000A
344#define DATA_PORT CS89x0_PORT(0x000C) 337#define DATA_PORT 0x000C
345 338
346#define EEPROM_WRITE_EN 0x00F0 339#define EEPROM_WRITE_EN 0x00F0
347#define EEPROM_WRITE_DIS 0x0000 340#define EEPROM_WRITE_DIS 0x0000
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index 38695d5b4637..ccbbe5ad8e0f 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -545,7 +545,7 @@ e1000_check_fiber_options(struct e1000_adapter *adapter)
545static void __devinit 545static void __devinit
546e1000_check_copper_options(struct e1000_adapter *adapter) 546e1000_check_copper_options(struct e1000_adapter *adapter)
547{ 547{
548 int speed, dplx; 548 int speed, dplx, an;
549 int bd = adapter->bd_number; 549 int bd = adapter->bd_number;
550 550
551 { /* Speed */ 551 { /* Speed */
@@ -641,8 +641,12 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
641 .p = an_list }} 641 .p = an_list }}
642 }; 642 };
643 643
644 int an = AutoNeg[bd]; 644 if (num_AutoNeg > bd) {
645 e1000_validate_option(&an, &opt, adapter); 645 an = AutoNeg[bd];
646 e1000_validate_option(&an, &opt, adapter);
647 } else {
648 an = opt.def;
649 }
646 adapter->hw.autoneg_advertised = an; 650 adapter->hw.autoneg_advertised = an;
647 } 651 }
648 652
diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c
index f5a4dd7d8564..e5c5cd2a2712 100644
--- a/drivers/net/e2100.c
+++ b/drivers/net/e2100.c
@@ -140,13 +140,6 @@ static int __init do_e2100_probe(struct net_device *dev)
140 return -ENODEV; 140 return -ENODEV;
141} 141}
142 142
143static void cleanup_card(struct net_device *dev)
144{
145 /* NB: e21_close() handles free_irq */
146 iounmap(ei_status.mem);
147 release_region(dev->base_addr, E21_IO_EXTENT);
148}
149
150#ifndef MODULE 143#ifndef MODULE
151struct net_device * __init e2100_probe(int unit) 144struct net_device * __init e2100_probe(int unit)
152{ 145{
@@ -463,6 +456,13 @@ init_module(void)
463 return -ENXIO; 456 return -ENXIO;
464} 457}
465 458
459static void cleanup_card(struct net_device *dev)
460{
461 /* NB: e21_close() handles free_irq */
462 iounmap(ei_status.mem);
463 release_region(dev->base_addr, E21_IO_EXTENT);
464}
465
466void 466void
467cleanup_module(void) 467cleanup_module(void)
468{ 468{
diff --git a/drivers/net/es3210.c b/drivers/net/es3210.c
index 50f8e23bb9e5..6b0ab1eac3fb 100644
--- a/drivers/net/es3210.c
+++ b/drivers/net/es3210.c
@@ -155,13 +155,6 @@ static int __init do_es_probe(struct net_device *dev)
155 return -ENODEV; 155 return -ENODEV;
156} 156}
157 157
158static void cleanup_card(struct net_device *dev)
159{
160 free_irq(dev->irq, dev);
161 release_region(dev->base_addr, ES_IO_EXTENT);
162 iounmap(ei_status.mem);
163}
164
165#ifndef MODULE 158#ifndef MODULE
166struct net_device * __init es_probe(int unit) 159struct net_device * __init es_probe(int unit)
167{ 160{
@@ -456,6 +449,13 @@ init_module(void)
456 return -ENXIO; 449 return -ENXIO;
457} 450}
458 451
452static void cleanup_card(struct net_device *dev)
453{
454 free_irq(dev->irq, dev);
455 release_region(dev->base_addr, ES_IO_EXTENT);
456 iounmap(ei_status.mem);
457}
458
459void 459void
460cleanup_module(void) 460cleanup_module(void)
461{ 461{
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index c39344adecce..3682ec61e8a8 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -101,6 +101,7 @@
101 * 0.46: 20 Oct 2005: Add irq optimization modes. 101 * 0.46: 20 Oct 2005: Add irq optimization modes.
102 * 0.47: 26 Oct 2005: Add phyaddr 0 in phy scan. 102 * 0.47: 26 Oct 2005: Add phyaddr 0 in phy scan.
103 * 0.48: 24 Dec 2005: Disable TSO, bugfix for pci_map_single 103 * 0.48: 24 Dec 2005: Disable TSO, bugfix for pci_map_single
104 * 0.49: 10 Dec 2005: Fix tso for large buffers.
104 * 105 *
105 * Known bugs: 106 * Known bugs:
106 * We suspect that on some hardware no TX done interrupts are generated. 107 * We suspect that on some hardware no TX done interrupts are generated.
@@ -112,7 +113,7 @@
112 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few 113 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
113 * superfluous timer interrupts from the nic. 114 * superfluous timer interrupts from the nic.
114 */ 115 */
115#define FORCEDETH_VERSION "0.48" 116#define FORCEDETH_VERSION "0.49"
116#define DRV_NAME "forcedeth" 117#define DRV_NAME "forcedeth"
117 118
118#include <linux/module.h> 119#include <linux/module.h>
@@ -349,6 +350,8 @@ typedef union _ring_type {
349#define NV_TX2_VALID (1<<31) 350#define NV_TX2_VALID (1<<31)
350#define NV_TX2_TSO (1<<28) 351#define NV_TX2_TSO (1<<28)
351#define NV_TX2_TSO_SHIFT 14 352#define NV_TX2_TSO_SHIFT 14
353#define NV_TX2_TSO_MAX_SHIFT 14
354#define NV_TX2_TSO_MAX_SIZE (1<<NV_TX2_TSO_MAX_SHIFT)
352#define NV_TX2_CHECKSUM_L3 (1<<27) 355#define NV_TX2_CHECKSUM_L3 (1<<27)
353#define NV_TX2_CHECKSUM_L4 (1<<26) 356#define NV_TX2_CHECKSUM_L4 (1<<26)
354 357
@@ -408,15 +411,15 @@ typedef union _ring_type {
408#define NV_WATCHDOG_TIMEO (5*HZ) 411#define NV_WATCHDOG_TIMEO (5*HZ)
409 412
410#define RX_RING 128 413#define RX_RING 128
411#define TX_RING 64 414#define TX_RING 256
412/* 415/*
413 * If your nic mysteriously hangs then try to reduce the limits 416 * If your nic mysteriously hangs then try to reduce the limits
414 * to 1/0: It might be required to set NV_TX_LASTPACKET in the 417 * to 1/0: It might be required to set NV_TX_LASTPACKET in the
415 * last valid ring entry. But this would be impossible to 418 * last valid ring entry. But this would be impossible to
416 * implement - probably a disassembly error. 419 * implement - probably a disassembly error.
417 */ 420 */
418#define TX_LIMIT_STOP 63 421#define TX_LIMIT_STOP 255
419#define TX_LIMIT_START 62 422#define TX_LIMIT_START 254
420 423
421/* rx/tx mac addr + type + vlan + align + slack*/ 424/* rx/tx mac addr + type + vlan + align + slack*/
422#define NV_RX_HEADERS (64) 425#define NV_RX_HEADERS (64)
@@ -535,6 +538,7 @@ struct fe_priv {
535 unsigned int next_tx, nic_tx; 538 unsigned int next_tx, nic_tx;
536 struct sk_buff *tx_skbuff[TX_RING]; 539 struct sk_buff *tx_skbuff[TX_RING];
537 dma_addr_t tx_dma[TX_RING]; 540 dma_addr_t tx_dma[TX_RING];
541 unsigned int tx_dma_len[TX_RING];
538 u32 tx_flags; 542 u32 tx_flags;
539}; 543};
540 544
@@ -935,6 +939,7 @@ static void nv_init_tx(struct net_device *dev)
935 else 939 else
936 np->tx_ring.ex[i].FlagLen = 0; 940 np->tx_ring.ex[i].FlagLen = 0;
937 np->tx_skbuff[i] = NULL; 941 np->tx_skbuff[i] = NULL;
942 np->tx_dma[i] = 0;
938 } 943 }
939} 944}
940 945
@@ -945,30 +950,27 @@ static int nv_init_ring(struct net_device *dev)
945 return nv_alloc_rx(dev); 950 return nv_alloc_rx(dev);
946} 951}
947 952
948static void nv_release_txskb(struct net_device *dev, unsigned int skbnr) 953static int nv_release_txskb(struct net_device *dev, unsigned int skbnr)
949{ 954{
950 struct fe_priv *np = netdev_priv(dev); 955 struct fe_priv *np = netdev_priv(dev);
951 struct sk_buff *skb = np->tx_skbuff[skbnr]; 956
952 unsigned int j, entry, fragments; 957 dprintk(KERN_INFO "%s: nv_release_txskb for skbnr %d\n",
953 958 dev->name, skbnr);
954 dprintk(KERN_INFO "%s: nv_release_txskb for skbnr %d, skb %p\n", 959
955 dev->name, skbnr, np->tx_skbuff[skbnr]); 960 if (np->tx_dma[skbnr]) {
956 961 pci_unmap_page(np->pci_dev, np->tx_dma[skbnr],
957 entry = skbnr; 962 np->tx_dma_len[skbnr],
958 if ((fragments = skb_shinfo(skb)->nr_frags) != 0) { 963 PCI_DMA_TODEVICE);
959 for (j = fragments; j >= 1; j--) { 964 np->tx_dma[skbnr] = 0;
960 skb_frag_t *frag = &skb_shinfo(skb)->frags[j-1]; 965 }
961 pci_unmap_page(np->pci_dev, np->tx_dma[entry], 966
962 frag->size, 967 if (np->tx_skbuff[skbnr]) {
963 PCI_DMA_TODEVICE); 968 dev_kfree_skb_irq(np->tx_skbuff[skbnr]);
964 entry = (entry - 1) % TX_RING; 969 np->tx_skbuff[skbnr] = NULL;
965 } 970 return 1;
971 } else {
972 return 0;
966 } 973 }
967 pci_unmap_single(np->pci_dev, np->tx_dma[entry],
968 skb->len - skb->data_len,
969 PCI_DMA_TODEVICE);
970 dev_kfree_skb_irq(skb);
971 np->tx_skbuff[skbnr] = NULL;
972} 974}
973 975
974static void nv_drain_tx(struct net_device *dev) 976static void nv_drain_tx(struct net_device *dev)
@@ -981,10 +983,8 @@ static void nv_drain_tx(struct net_device *dev)
981 np->tx_ring.orig[i].FlagLen = 0; 983 np->tx_ring.orig[i].FlagLen = 0;
982 else 984 else
983 np->tx_ring.ex[i].FlagLen = 0; 985 np->tx_ring.ex[i].FlagLen = 0;
984 if (np->tx_skbuff[i]) { 986 if (nv_release_txskb(dev, i))
985 nv_release_txskb(dev, i);
986 np->stats.tx_dropped++; 987 np->stats.tx_dropped++;
987 }
988 } 988 }
989} 989}
990 990
@@ -1021,68 +1021,105 @@ static void drain_ring(struct net_device *dev)
1021static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) 1021static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
1022{ 1022{
1023 struct fe_priv *np = netdev_priv(dev); 1023 struct fe_priv *np = netdev_priv(dev);
1024 u32 tx_flags = 0;
1024 u32 tx_flags_extra = (np->desc_ver == DESC_VER_1 ? NV_TX_LASTPACKET : NV_TX2_LASTPACKET); 1025 u32 tx_flags_extra = (np->desc_ver == DESC_VER_1 ? NV_TX_LASTPACKET : NV_TX2_LASTPACKET);
1025 unsigned int fragments = skb_shinfo(skb)->nr_frags; 1026 unsigned int fragments = skb_shinfo(skb)->nr_frags;
1026 unsigned int nr = (np->next_tx + fragments) % TX_RING; 1027 unsigned int nr = (np->next_tx - 1) % TX_RING;
1028 unsigned int start_nr = np->next_tx % TX_RING;
1027 unsigned int i; 1029 unsigned int i;
1030 u32 offset = 0;
1031 u32 bcnt;
1032 u32 size = skb->len-skb->data_len;
1033 u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
1034
1035 /* add fragments to entries count */
1036 for (i = 0; i < fragments; i++) {
1037 entries += (skb_shinfo(skb)->frags[i].size >> NV_TX2_TSO_MAX_SHIFT) +
1038 ((skb_shinfo(skb)->frags[i].size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
1039 }
1028 1040
1029 spin_lock_irq(&np->lock); 1041 spin_lock_irq(&np->lock);
1030 1042
1031 if ((np->next_tx - np->nic_tx + fragments) > TX_LIMIT_STOP) { 1043 if ((np->next_tx - np->nic_tx + entries - 1) > TX_LIMIT_STOP) {
1032 spin_unlock_irq(&np->lock); 1044 spin_unlock_irq(&np->lock);
1033 netif_stop_queue(dev); 1045 netif_stop_queue(dev);
1034 return NETDEV_TX_BUSY; 1046 return NETDEV_TX_BUSY;
1035 } 1047 }
1036 1048
1037 np->tx_skbuff[nr] = skb; 1049 /* setup the header buffer */
1038 1050 do {
1039 if (fragments) { 1051 bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size;
1040 dprintk(KERN_DEBUG "%s: nv_start_xmit: buffer contains %d fragments\n", dev->name, fragments); 1052 nr = (nr + 1) % TX_RING;
1041 /* setup descriptors in reverse order */ 1053
1042 for (i = fragments; i >= 1; i--) { 1054 np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data + offset, bcnt,
1043 skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1]; 1055 PCI_DMA_TODEVICE);
1044 np->tx_dma[nr] = pci_map_page(np->pci_dev, frag->page, frag->page_offset, frag->size, 1056 np->tx_dma_len[nr] = bcnt;
1045 PCI_DMA_TODEVICE); 1057
1058 if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
1059 np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
1060 np->tx_ring.orig[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags);
1061 } else {
1062 np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
1063 np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
1064 np->tx_ring.ex[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags);
1065 }
1066 tx_flags = np->tx_flags;
1067 offset += bcnt;
1068 size -= bcnt;
1069 } while(size);
1070
1071 /* setup the fragments */
1072 for (i = 0; i < fragments; i++) {
1073 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
1074 u32 size = frag->size;
1075 offset = 0;
1076
1077 do {
1078 bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size;
1079 nr = (nr + 1) % TX_RING;
1080
1081 np->tx_dma[nr] = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt,
1082 PCI_DMA_TODEVICE);
1083 np->tx_dma_len[nr] = bcnt;
1046 1084
1047 if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { 1085 if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
1048 np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); 1086 np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
1049 np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra); 1087 np->tx_ring.orig[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags);
1050 } else { 1088 } else {
1051 np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32; 1089 np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
1052 np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF; 1090 np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
1053 np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra); 1091 np->tx_ring.ex[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags);
1054 } 1092 }
1055 1093 offset += bcnt;
1056 nr = (nr - 1) % TX_RING; 1094 size -= bcnt;
1095 } while (size);
1096 }
1057 1097
1058 if (np->desc_ver == DESC_VER_1) 1098 /* set last fragment flag */
1059 tx_flags_extra &= ~NV_TX_LASTPACKET; 1099 if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
1060 else 1100 np->tx_ring.orig[nr].FlagLen |= cpu_to_le32(tx_flags_extra);
1061 tx_flags_extra &= ~NV_TX2_LASTPACKET; 1101 } else {
1062 } 1102 np->tx_ring.ex[nr].FlagLen |= cpu_to_le32(tx_flags_extra);
1063 } 1103 }
1064 1104
1105 np->tx_skbuff[nr] = skb;
1106
1065#ifdef NETIF_F_TSO 1107#ifdef NETIF_F_TSO
1066 if (skb_shinfo(skb)->tso_size) 1108 if (skb_shinfo(skb)->tso_size)
1067 tx_flags_extra |= NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT); 1109 tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT);
1068 else 1110 else
1069#endif 1111#endif
1070 tx_flags_extra |= (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0); 1112 tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
1071 1113
1072 np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len-skb->data_len, 1114 /* set tx flags */
1073 PCI_DMA_TODEVICE);
1074
1075 if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { 1115 if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
1076 np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); 1116 np->tx_ring.orig[start_nr].FlagLen |= cpu_to_le32(tx_flags | tx_flags_extra);
1077 np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra);
1078 } else { 1117 } else {
1079 np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32; 1118 np->tx_ring.ex[start_nr].FlagLen |= cpu_to_le32(tx_flags | tx_flags_extra);
1080 np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
1081 np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra);
1082 } 1119 }
1083 1120
1084 dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission. tx_flags_extra: %x\n", 1121 dprintk(KERN_DEBUG "%s: nv_start_xmit: packet %d (entries %d) queued for transmission. tx_flags_extra: %x\n",
1085 dev->name, np->next_tx, tx_flags_extra); 1122 dev->name, np->next_tx, entries, tx_flags_extra);
1086 { 1123 {
1087 int j; 1124 int j;
1088 for (j=0; j<64; j++) { 1125 for (j=0; j<64; j++) {
@@ -1093,7 +1130,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
1093 dprintk("\n"); 1130 dprintk("\n");
1094 } 1131 }
1095 1132
1096 np->next_tx += 1 + fragments; 1133 np->next_tx += entries;
1097 1134
1098 dev->trans_start = jiffies; 1135 dev->trans_start = jiffies;
1099 spin_unlock_irq(&np->lock); 1136 spin_unlock_irq(&np->lock);
@@ -1140,7 +1177,6 @@ static void nv_tx_done(struct net_device *dev)
1140 np->stats.tx_packets++; 1177 np->stats.tx_packets++;
1141 np->stats.tx_bytes += skb->len; 1178 np->stats.tx_bytes += skb->len;
1142 } 1179 }
1143 nv_release_txskb(dev, i);
1144 } 1180 }
1145 } else { 1181 } else {
1146 if (Flags & NV_TX2_LASTPACKET) { 1182 if (Flags & NV_TX2_LASTPACKET) {
@@ -1156,9 +1192,9 @@ static void nv_tx_done(struct net_device *dev)
1156 np->stats.tx_packets++; 1192 np->stats.tx_packets++;
1157 np->stats.tx_bytes += skb->len; 1193 np->stats.tx_bytes += skb->len;
1158 } 1194 }
1159 nv_release_txskb(dev, i);
1160 } 1195 }
1161 } 1196 }
1197 nv_release_txskb(dev, i);
1162 np->nic_tx++; 1198 np->nic_tx++;
1163 } 1199 }
1164 if (np->next_tx - np->nic_tx < TX_LIMIT_START) 1200 if (np->next_tx - np->nic_tx < TX_LIMIT_START)
@@ -2456,7 +2492,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
2456 np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; 2492 np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
2457 dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG; 2493 dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
2458#ifdef NETIF_F_TSO 2494#ifdef NETIF_F_TSO
2459 /* disabled dev->features |= NETIF_F_TSO; */ 2495 dev->features |= NETIF_F_TSO;
2460#endif 2496#endif
2461 } 2497 }
2462 2498
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 94a91da84fbb..cb9d66ac3ab9 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -718,14 +718,14 @@ struct gfar_private {
718 uint32_t msg_enable; 718 uint32_t msg_enable;
719}; 719};
720 720
721extern inline u32 gfar_read(volatile unsigned *addr) 721static inline u32 gfar_read(volatile unsigned *addr)
722{ 722{
723 u32 val; 723 u32 val;
724 val = in_be32(addr); 724 val = in_be32(addr);
725 return val; 725 return val;
726} 726}
727 727
728extern inline void gfar_write(volatile unsigned *addr, u32 val) 728static inline void gfar_write(volatile unsigned *addr, u32 val)
729{ 729{
730 out_be32(addr, val); 730 out_be32(addr, val);
731} 731}
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 3e9accf137e7..41b3d83c2ab8 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -524,6 +524,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
524 ax->dev->trans_start = jiffies; 524 ax->dev->trans_start = jiffies;
525 ax->xleft = count - actual; 525 ax->xleft = count - actual;
526 ax->xhead = ax->xbuff + actual; 526 ax->xhead = ax->xbuff + actual;
527 spin_unlock_bh(&ax->buflock);
527} 528}
528 529
529/* Encapsulate an AX.25 packet and kick it into a TTY queue. */ 530/* Encapsulate an AX.25 packet and kick it into a TTY queue. */
diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c
index 0abf5dd08b4c..74e167e7dea7 100644
--- a/drivers/net/hp-plus.c
+++ b/drivers/net/hp-plus.c
@@ -138,12 +138,6 @@ static int __init do_hpp_probe(struct net_device *dev)
138 return -ENODEV; 138 return -ENODEV;
139} 139}
140 140
141static void cleanup_card(struct net_device *dev)
142{
143 /* NB: hpp_close() handles free_irq */
144 release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
145}
146
147#ifndef MODULE 141#ifndef MODULE
148struct net_device * __init hp_plus_probe(int unit) 142struct net_device * __init hp_plus_probe(int unit)
149{ 143{
@@ -473,6 +467,12 @@ init_module(void)
473 return -ENXIO; 467 return -ENXIO;
474} 468}
475 469
470static void cleanup_card(struct net_device *dev)
471{
472 /* NB: hpp_close() handles free_irq */
473 release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
474}
475
476void 476void
477cleanup_module(void) 477cleanup_module(void)
478{ 478{
diff --git a/drivers/net/hp.c b/drivers/net/hp.c
index 59cf841b14ab..cf9fb3698a6b 100644
--- a/drivers/net/hp.c
+++ b/drivers/net/hp.c
@@ -102,12 +102,6 @@ static int __init do_hp_probe(struct net_device *dev)
102 return -ENODEV; 102 return -ENODEV;
103} 103}
104 104
105static void cleanup_card(struct net_device *dev)
106{
107 free_irq(dev->irq, dev);
108 release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
109}
110
111#ifndef MODULE 105#ifndef MODULE
112struct net_device * __init hp_probe(int unit) 106struct net_device * __init hp_probe(int unit)
113{ 107{
@@ -444,6 +438,12 @@ init_module(void)
444 return -ENXIO; 438 return -ENXIO;
445} 439}
446 440
441static void cleanup_card(struct net_device *dev)
442{
443 free_irq(dev->irq, dev);
444 release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
445}
446
447void 447void
448cleanup_module(void) 448cleanup_module(void)
449{ 449{
diff --git a/drivers/net/ibm_emac/ibm_emac.h b/drivers/net/ibm_emac/ibm_emac.h
index 644edbff4f94..c2dae6092c4c 100644
--- a/drivers/net/ibm_emac/ibm_emac.h
+++ b/drivers/net/ibm_emac/ibm_emac.h
@@ -110,6 +110,7 @@ struct emac_regs {
110#define EMAC_MR1_TFS_2K 0x00080000 110#define EMAC_MR1_TFS_2K 0x00080000
111#define EMAC_MR1_TR0_MULT 0x00008000 111#define EMAC_MR1_TR0_MULT 0x00008000
112#define EMAC_MR1_JPSM 0x00000000 112#define EMAC_MR1_JPSM 0x00000000
113#define EMAC_MR1_MWSW_001 0x00000000
113#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR0_MULT) 114#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR0_MULT)
114#else 115#else
115#define EMAC_MR1_RFS_4K 0x00180000 116#define EMAC_MR1_RFS_4K 0x00180000
@@ -130,7 +131,7 @@ struct emac_regs {
130 (freq) <= 83 ? EMAC_MR1_OBCI_83 : \ 131 (freq) <= 83 ? EMAC_MR1_OBCI_83 : \
131 (freq) <= 100 ? EMAC_MR1_OBCI_100 : EMAC_MR1_OBCI_100P) 132 (freq) <= 100 ? EMAC_MR1_OBCI_100 : EMAC_MR1_OBCI_100P)
132#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR | \ 133#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR | \
133 EMAC_MR1_MWSW_001 | EMAC_MR1_OBCI(opb)) 134 EMAC_MR1_OBCI(opb))
134#endif 135#endif
135 136
136/* EMACx_TMR0 */ 137/* EMACx_TMR0 */
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c
index 1da8a66f91e1..591c5864ffb1 100644
--- a/drivers/net/ibm_emac/ibm_emac_core.c
+++ b/drivers/net/ibm_emac/ibm_emac_core.c
@@ -408,7 +408,7 @@ static int emac_configure(struct ocp_enet_private *dev)
408 /* Mode register */ 408 /* Mode register */
409 r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST; 409 r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST;
410 if (dev->phy.duplex == DUPLEX_FULL) 410 if (dev->phy.duplex == DUPLEX_FULL)
411 r |= EMAC_MR1_FDE; 411 r |= EMAC_MR1_FDE | EMAC_MR1_MWSW_001;
412 dev->stop_timeout = STOP_TIMEOUT_10; 412 dev->stop_timeout = STOP_TIMEOUT_10;
413 switch (dev->phy.speed) { 413 switch (dev->phy.speed) {
414 case SPEED_1000: 414 case SPEED_1000:
diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h
index 741aecc655df..a82a4ba8de4f 100644
--- a/drivers/net/irda/vlsi_ir.h
+++ b/drivers/net/irda/vlsi_ir.h
@@ -577,8 +577,8 @@ struct ring_descr_hw {
577 struct { 577 struct {
578 u8 addr_res[3]; 578 u8 addr_res[3];
579 volatile u8 status; /* descriptor status */ 579 volatile u8 status; /* descriptor status */
580 } rd_s __attribute__((packed)); 580 } __attribute__((packed)) rd_s;
581 } rd_u __attribute((packed)); 581 } __attribute((packed)) rd_u;
582} __attribute__ ((packed)); 582} __attribute__ ((packed));
583 583
584#define rd_addr rd_u.addr 584#define rd_addr rd_u.addr
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index 1d75ca0bb939..d1d714faa6ce 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -309,17 +309,6 @@ static void lance_tx_timeout (struct net_device *dev);
309 309
310 310
311 311
312static void cleanup_card(struct net_device *dev)
313{
314 struct lance_private *lp = dev->priv;
315 if (dev->dma != 4)
316 free_dma(dev->dma);
317 release_region(dev->base_addr, LANCE_TOTAL_SIZE);
318 kfree(lp->tx_bounce_buffs);
319 kfree((void*)lp->rx_buffs);
320 kfree(lp);
321}
322
323#ifdef MODULE 312#ifdef MODULE
324#define MAX_CARDS 8 /* Max number of interfaces (cards) per module */ 313#define MAX_CARDS 8 /* Max number of interfaces (cards) per module */
325 314
@@ -367,6 +356,17 @@ int init_module(void)
367 return -ENXIO; 356 return -ENXIO;
368} 357}
369 358
359static void cleanup_card(struct net_device *dev)
360{
361 struct lance_private *lp = dev->priv;
362 if (dev->dma != 4)
363 free_dma(dev->dma);
364 release_region(dev->base_addr, LANCE_TOTAL_SIZE);
365 kfree(lp->tx_bounce_buffs);
366 kfree((void*)lp->rx_buffs);
367 kfree(lp);
368}
369
370void cleanup_module(void) 370void cleanup_module(void)
371{ 371{
372 int this_dev; 372 int this_dev;
diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c
index 309d254842cf..646e89fc3562 100644
--- a/drivers/net/lne390.c
+++ b/drivers/net/lne390.c
@@ -145,13 +145,6 @@ static int __init do_lne390_probe(struct net_device *dev)
145 return -ENODEV; 145 return -ENODEV;
146} 146}
147 147
148static void cleanup_card(struct net_device *dev)
149{
150 free_irq(dev->irq, dev);
151 release_region(dev->base_addr, LNE390_IO_EXTENT);
152 iounmap(ei_status.mem);
153}
154
155#ifndef MODULE 148#ifndef MODULE
156struct net_device * __init lne390_probe(int unit) 149struct net_device * __init lne390_probe(int unit)
157{ 150{
@@ -440,6 +433,13 @@ int init_module(void)
440 return -ENXIO; 433 return -ENXIO;
441} 434}
442 435
436static void cleanup_card(struct net_device *dev)
437{
438 free_irq(dev->irq, dev);
439 release_region(dev->base_addr, LNE390_IO_EXTENT);
440 iounmap(ei_status.mem);
441}
442
443void cleanup_module(void) 443void cleanup_module(void)
444{ 444{
445 int this_dev; 445 int this_dev;
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 3cb9b3fe0cf1..22c3a37bba5a 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -6,7 +6,7 @@
6 * Copyright (C) 2002 rabeeh@galileo.co.il 6 * Copyright (C) 2002 rabeeh@galileo.co.il
7 * 7 *
8 * Copyright (C) 2003 PMC-Sierra, Inc., 8 * Copyright (C) 2003 PMC-Sierra, Inc.,
9 * written by Manish Lachwani (lachwani@pmc-sierra.com) 9 * written by Manish Lachwani
10 * 10 *
11 * Copyright (C) 2003 Ralf Baechle <ralf@linux-mips.org> 11 * Copyright (C) 2003 Ralf Baechle <ralf@linux-mips.org>
12 * 12 *
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index 0de8fdd2aa86..94f782d51f0f 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -212,15 +212,6 @@ static int __init do_ne_probe(struct net_device *dev)
212 return -ENODEV; 212 return -ENODEV;
213} 213}
214 214
215static void cleanup_card(struct net_device *dev)
216{
217 struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
218 if (idev)
219 pnp_device_detach(idev);
220 free_irq(dev->irq, dev);
221 release_region(dev->base_addr, NE_IO_EXTENT);
222}
223
224#ifndef MODULE 215#ifndef MODULE
225struct net_device * __init ne_probe(int unit) 216struct net_device * __init ne_probe(int unit)
226{ 217{
@@ -859,6 +850,15 @@ int init_module(void)
859 return -ENODEV; 850 return -ENODEV;
860} 851}
861 852
853static void cleanup_card(struct net_device *dev)
854{
855 struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
856 if (idev)
857 pnp_device_detach(idev);
858 free_irq(dev->irq, dev);
859 release_region(dev->base_addr, NE_IO_EXTENT);
860}
861
862void cleanup_module(void) 862void cleanup_module(void)
863{ 863{
864 int this_dev; 864 int this_dev;
diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c
index 6d62ada85de6..e6df375a1d4b 100644
--- a/drivers/net/ne2.c
+++ b/drivers/net/ne2.c
@@ -278,14 +278,6 @@ static int __init do_ne2_probe(struct net_device *dev)
278 return -ENODEV; 278 return -ENODEV;
279} 279}
280 280
281static void cleanup_card(struct net_device *dev)
282{
283 mca_mark_as_unused(ei_status.priv);
284 mca_set_adapter_procfn( ei_status.priv, NULL, NULL);
285 free_irq(dev->irq, dev);
286 release_region(dev->base_addr, NE_IO_EXTENT);
287}
288
289#ifndef MODULE 281#ifndef MODULE
290struct net_device * __init ne2_probe(int unit) 282struct net_device * __init ne2_probe(int unit)
291{ 283{
@@ -812,6 +804,14 @@ int init_module(void)
812 return -ENXIO; 804 return -ENXIO;
813} 805}
814 806
807static void cleanup_card(struct net_device *dev)
808{
809 mca_mark_as_unused(ei_status.priv);
810 mca_set_adapter_procfn( ei_status.priv, NULL, NULL);
811 free_irq(dev->irq, dev);
812 release_region(dev->base_addr, NE_IO_EXTENT);
813}
814
815void cleanup_module(void) 815void cleanup_module(void)
816{ 816{
817 int this_dev; 817 int this_dev;
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index 9a76ac180b11..197edd74fbb5 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -282,26 +282,22 @@ SK_U32 Val) /* pointer to store the read value */
282 * Description: 282 * Description:
283 * This function initialize the PCI resources and IO 283 * This function initialize the PCI resources and IO
284 * 284 *
285 * Returns: N/A 285 * Returns:
286 * 286 * 0 - indicate everything worked ok.
287 * != 0 - error indication
287 */ 288 */
288int SkGeInitPCI(SK_AC *pAC) 289static __devinit int SkGeInitPCI(SK_AC *pAC)
289{ 290{
290 struct SK_NET_DEVICE *dev = pAC->dev[0]; 291 struct SK_NET_DEVICE *dev = pAC->dev[0];
291 struct pci_dev *pdev = pAC->PciDev; 292 struct pci_dev *pdev = pAC->PciDev;
292 int retval; 293 int retval;
293 294
294 if (pci_enable_device(pdev) != 0) {
295 return 1;
296 }
297
298 dev->mem_start = pci_resource_start (pdev, 0); 295 dev->mem_start = pci_resource_start (pdev, 0);
299 pci_set_master(pdev); 296 pci_set_master(pdev);
300 297
301 if (pci_request_regions(pdev, "sk98lin") != 0) { 298 retval = pci_request_regions(pdev, "sk98lin");
302 retval = 2; 299 if (retval)
303 goto out_disable; 300 goto out;
304 }
305 301
306#ifdef SK_BIG_ENDIAN 302#ifdef SK_BIG_ENDIAN
307 /* 303 /*
@@ -320,9 +316,8 @@ int SkGeInitPCI(SK_AC *pAC)
320 * Remap the regs into kernel space. 316 * Remap the regs into kernel space.
321 */ 317 */
322 pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000); 318 pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000);
323 319 if (!pAC->IoBase) {
324 if (!pAC->IoBase){ 320 retval = -EIO;
325 retval = 3;
326 goto out_release; 321 goto out_release;
327 } 322 }
328 323
@@ -330,8 +325,7 @@ int SkGeInitPCI(SK_AC *pAC)
330 325
331 out_release: 326 out_release:
332 pci_release_regions(pdev); 327 pci_release_regions(pdev);
333 out_disable: 328 out:
334 pci_disable_device(pdev);
335 return retval; 329 return retval;
336} 330}
337 331
@@ -492,7 +486,7 @@ module_param_array(AutoSizing, charp, NULL, 0);
492 * 0, if everything is ok 486 * 0, if everything is ok
493 * !=0, on error 487 * !=0, on error
494 */ 488 */
495static int __init SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC) 489static int __devinit SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC)
496{ 490{
497short i; 491short i;
498unsigned long Flags; 492unsigned long Flags;
@@ -529,7 +523,7 @@ SK_BOOL DualNet;
529 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) { 523 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) {
530 printk("HWInit (0) failed.\n"); 524 printk("HWInit (0) failed.\n");
531 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); 525 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
532 return(-EAGAIN); 526 return -EIO;
533 } 527 }
534 SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA); 528 SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA);
535 SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA); 529 SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA);
@@ -551,7 +545,7 @@ SK_BOOL DualNet;
551 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) { 545 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
552 printk("sk98lin: HWInit (1) failed.\n"); 546 printk("sk98lin: HWInit (1) failed.\n");
553 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); 547 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
554 return(-EAGAIN); 548 return -EIO;
555 } 549 }
556 SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO); 550 SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO);
557 SkEventInit(pAC, pAC->IoBase, SK_INIT_IO); 551 SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
@@ -583,20 +577,20 @@ SK_BOOL DualNet;
583 } else { 577 } else {
584 printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n", 578 printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
585 pAC->GIni.GIMacsFound); 579 pAC->GIni.GIMacsFound);
586 return -EAGAIN; 580 return -EIO;
587 } 581 }
588 582
589 if (Ret) { 583 if (Ret) {
590 printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n", 584 printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n",
591 dev->irq); 585 dev->irq);
592 return -EAGAIN; 586 return Ret;
593 } 587 }
594 pAC->AllocFlag |= SK_ALLOC_IRQ; 588 pAC->AllocFlag |= SK_ALLOC_IRQ;
595 589
596 /* Alloc memory for this board (Mem for RxD/TxD) : */ 590 /* Alloc memory for this board (Mem for RxD/TxD) : */
597 if(!BoardAllocMem(pAC)) { 591 if(!BoardAllocMem(pAC)) {
598 printk("No memory for descriptor rings.\n"); 592 printk("No memory for descriptor rings.\n");
599 return(-EAGAIN); 593 return -ENOMEM;
600 } 594 }
601 595
602 BoardInitMem(pAC); 596 BoardInitMem(pAC);
@@ -612,7 +606,7 @@ SK_BOOL DualNet;
612 DualNet)) { 606 DualNet)) {
613 BoardFreeMem(pAC); 607 BoardFreeMem(pAC);
614 printk("sk98lin: SkGeInitAssignRamToQueues failed.\n"); 608 printk("sk98lin: SkGeInitAssignRamToQueues failed.\n");
615 return(-EAGAIN); 609 return -EIO;
616 } 610 }
617 611
618 return (0); 612 return (0);
@@ -633,8 +627,7 @@ SK_BOOL DualNet;
633 * SK_TRUE, if all memory could be allocated 627 * SK_TRUE, if all memory could be allocated
634 * SK_FALSE, if not 628 * SK_FALSE, if not
635 */ 629 */
636static SK_BOOL BoardAllocMem( 630static __devinit SK_BOOL BoardAllocMem(SK_AC *pAC)
637SK_AC *pAC)
638{ 631{
639caddr_t pDescrMem; /* pointer to descriptor memory area */ 632caddr_t pDescrMem; /* pointer to descriptor memory area */
640size_t AllocLength; /* length of complete descriptor area */ 633size_t AllocLength; /* length of complete descriptor area */
@@ -727,8 +720,7 @@ size_t AllocLength; /* length of complete descriptor area */
727 * 720 *
728 * Returns: N/A 721 * Returns: N/A
729 */ 722 */
730static void BoardInitMem( 723static __devinit void BoardInitMem(SK_AC *pAC)
731SK_AC *pAC) /* pointer to adapter context */
732{ 724{
733int i; /* loop counter */ 725int i; /* loop counter */
734int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/ 726int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/
@@ -4776,32 +4768,47 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
4776 struct net_device *dev = NULL; 4768 struct net_device *dev = NULL;
4777 static int boards_found = 0; 4769 static int boards_found = 0;
4778 int error = -ENODEV; 4770 int error = -ENODEV;
4771 int using_dac = 0;
4779 char DeviceStr[80]; 4772 char DeviceStr[80];
4780 4773
4781 if (pci_enable_device(pdev)) 4774 if (pci_enable_device(pdev))
4782 goto out; 4775 goto out;
4783 4776
4784 /* Configure DMA attributes. */ 4777 /* Configure DMA attributes. */
4785 if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) && 4778 if (sizeof(dma_addr_t) > sizeof(u32) &&
4786 pci_set_dma_mask(pdev, DMA_32BIT_MASK)) 4779 !(error = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
4787 goto out_disable_device; 4780 using_dac = 1;
4788 4781 error = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
4782 if (error < 0) {
4783 printk(KERN_ERR "sk98lin %s unable to obtain 64 bit DMA "
4784 "for consistent allocations\n", pci_name(pdev));
4785 goto out_disable_device;
4786 }
4787 } else {
4788 error = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
4789 if (error) {
4790 printk(KERN_ERR "sk98lin %s no usable DMA configuration\n",
4791 pci_name(pdev));
4792 goto out_disable_device;
4793 }
4794 }
4789 4795
4790 if ((dev = alloc_etherdev(sizeof(DEV_NET))) == NULL) { 4796 error = -ENOMEM;
4791 printk(KERN_ERR "Unable to allocate etherdev " 4797 dev = alloc_etherdev(sizeof(DEV_NET));
4798 if (!dev) {
4799 printk(KERN_ERR "sk98lin: unable to allocate etherdev "
4792 "structure!\n"); 4800 "structure!\n");
4793 goto out_disable_device; 4801 goto out_disable_device;
4794 } 4802 }
4795 4803
4796 pNet = netdev_priv(dev); 4804 pNet = netdev_priv(dev);
4797 pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); 4805 pNet->pAC = kzalloc(sizeof(SK_AC), GFP_KERNEL);
4798 if (!pNet->pAC) { 4806 if (!pNet->pAC) {
4799 printk(KERN_ERR "Unable to allocate adapter " 4807 printk(KERN_ERR "sk98lin: unable to allocate adapter "
4800 "structure!\n"); 4808 "structure!\n");
4801 goto out_free_netdev; 4809 goto out_free_netdev;
4802 } 4810 }
4803 4811
4804 memset(pNet->pAC, 0, sizeof(SK_AC));
4805 pAC = pNet->pAC; 4812 pAC = pNet->pAC;
4806 pAC->PciDev = pdev; 4813 pAC->PciDev = pdev;
4807 4814
@@ -4810,6 +4817,7 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
4810 pAC->CheckQueue = SK_FALSE; 4817 pAC->CheckQueue = SK_FALSE;
4811 4818
4812 dev->irq = pdev->irq; 4819 dev->irq = pdev->irq;
4820
4813 error = SkGeInitPCI(pAC); 4821 error = SkGeInitPCI(pAC);
4814 if (error) { 4822 if (error) {
4815 printk(KERN_ERR "sk98lin: PCI setup failed: %i\n", error); 4823 printk(KERN_ERR "sk98lin: PCI setup failed: %i\n", error);
@@ -4844,19 +4852,25 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
4844#endif 4852#endif
4845 } 4853 }
4846 4854
4855 if (using_dac)
4856 dev->features |= NETIF_F_HIGHDMA;
4857
4847 pAC->Index = boards_found++; 4858 pAC->Index = boards_found++;
4848 4859
4849 if (SkGeBoardInit(dev, pAC)) 4860 error = SkGeBoardInit(dev, pAC);
4861 if (error)
4850 goto out_free_netdev; 4862 goto out_free_netdev;
4851 4863
4852 /* Read Adapter name from VPD */ 4864 /* Read Adapter name from VPD */
4853 if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) { 4865 if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) {
4866 error = -EIO;
4854 printk(KERN_ERR "sk98lin: Could not read VPD data.\n"); 4867 printk(KERN_ERR "sk98lin: Could not read VPD data.\n");
4855 goto out_free_resources; 4868 goto out_free_resources;
4856 } 4869 }
4857 4870
4858 /* Register net device */ 4871 /* Register net device */
4859 if (register_netdev(dev)) { 4872 error = register_netdev(dev);
4873 if (error) {
4860 printk(KERN_ERR "sk98lin: Could not register device.\n"); 4874 printk(KERN_ERR "sk98lin: Could not register device.\n");
4861 goto out_free_resources; 4875 goto out_free_resources;
4862 } 4876 }
@@ -4883,15 +4897,17 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
4883 4897
4884 boards_found++; 4898 boards_found++;
4885 4899
4900 pci_set_drvdata(pdev, dev);
4901
4886 /* More then one port found */ 4902 /* More then one port found */
4887 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { 4903 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
4888 if ((dev = alloc_etherdev(sizeof(DEV_NET))) == 0) { 4904 dev = alloc_etherdev(sizeof(DEV_NET));
4889 printk(KERN_ERR "Unable to allocate etherdev " 4905 if (!dev) {
4906 printk(KERN_ERR "sk98lin: unable to allocate etherdev "
4890 "structure!\n"); 4907 "structure!\n");
4891 goto out; 4908 goto single_port;
4892 } 4909 }
4893 4910
4894 pAC->dev[1] = dev;
4895 pNet = netdev_priv(dev); 4911 pNet = netdev_priv(dev);
4896 pNet->PortNr = 1; 4912 pNet->PortNr = 1;
4897 pNet->NetNr = 1; 4913 pNet->NetNr = 1;
@@ -4920,20 +4936,28 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
4920#endif 4936#endif
4921 } 4937 }
4922 4938
4923 if (register_netdev(dev)) { 4939 if (using_dac)
4924 printk(KERN_ERR "sk98lin: Could not register device for seconf port.\n"); 4940 dev->features |= NETIF_F_HIGHDMA;
4941
4942 error = register_netdev(dev);
4943 if (error) {
4944 printk(KERN_ERR "sk98lin: Could not register device"
4945 " for second port. (%d)\n", error);
4925 free_netdev(dev); 4946 free_netdev(dev);
4926 pAC->dev[1] = pAC->dev[0]; 4947 goto single_port;
4927 } else {
4928 memcpy(&dev->dev_addr,
4929 &pAC->Addr.Net[1].CurrentMacAddress, 6);
4930 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
4931
4932 printk("%s: %s\n", dev->name, DeviceStr);
4933 printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
4934 } 4948 }
4949
4950 pAC->dev[1] = dev;
4951 memcpy(&dev->dev_addr,
4952 &pAC->Addr.Net[1].CurrentMacAddress, 6);
4953 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
4954
4955 printk("%s: %s\n", dev->name, DeviceStr);
4956 printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
4935 } 4957 }
4936 4958
4959single_port:
4960
4937 /* Save the hardware revision */ 4961 /* Save the hardware revision */
4938 pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) + 4962 pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
4939 (pAC->GIni.GIPciHwRev & 0x0F); 4963 (pAC->GIni.GIPciHwRev & 0x0F);
@@ -4945,7 +4969,6 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
4945 memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA)); 4969 memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA));
4946 memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA)); 4970 memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA));
4947 4971
4948 pci_set_drvdata(pdev, dev);
4949 return 0; 4972 return 0;
4950 4973
4951 out_free_resources: 4974 out_free_resources:
diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
index ba8593ac3f8a..3db30cd0625e 100644
--- a/drivers/net/smc-ultra.c
+++ b/drivers/net/smc-ultra.c
@@ -168,18 +168,6 @@ static int __init do_ultra_probe(struct net_device *dev)
168 return -ENODEV; 168 return -ENODEV;
169} 169}
170 170
171static void cleanup_card(struct net_device *dev)
172{
173 /* NB: ultra_close_card() does free_irq */
174#ifdef __ISAPNP__
175 struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
176 if (idev)
177 pnp_device_detach(idev);
178#endif
179 release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT);
180 iounmap(ei_status.mem);
181}
182
183#ifndef MODULE 171#ifndef MODULE
184struct net_device * __init ultra_probe(int unit) 172struct net_device * __init ultra_probe(int unit)
185{ 173{
@@ -594,6 +582,18 @@ init_module(void)
594 return -ENXIO; 582 return -ENXIO;
595} 583}
596 584
585static void cleanup_card(struct net_device *dev)
586{
587 /* NB: ultra_close_card() does free_irq */
588#ifdef __ISAPNP__
589 struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
590 if (idev)
591 pnp_device_detach(idev);
592#endif
593 release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT);
594 iounmap(ei_status.mem);
595}
596
597void 597void
598cleanup_module(void) 598cleanup_module(void)
599{ 599{
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 28bf2e69eb5e..7ec08127c9d6 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -88,7 +88,6 @@ static const char version[] =
88#include <linux/skbuff.h> 88#include <linux/skbuff.h>
89 89
90#include <asm/io.h> 90#include <asm/io.h>
91#include <asm/irq.h>
92 91
93#include "smc91x.h" 92#include "smc91x.h"
94 93
@@ -2007,12 +2006,10 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
2007 } 2006 }
2008 2007
2009 /* Grab the IRQ */ 2008 /* Grab the IRQ */
2010 retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev); 2009 retval = request_irq(dev->irq, &smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev);
2011 if (retval) 2010 if (retval)
2012 goto err_out; 2011 goto err_out;
2013 2012
2014 set_irq_type(dev->irq, SMC_IRQ_TRIGGER_TYPE);
2015
2016#ifdef SMC_USE_PXA_DMA 2013#ifdef SMC_USE_PXA_DMA
2017 { 2014 {
2018 int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW, 2015 int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW,
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 5c2824be4ee6..e0efd1964e72 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -90,7 +90,7 @@
90 __l--; \ 90 __l--; \
91 } \ 91 } \
92 } while (0) 92 } while (0)
93#define set_irq_type(irq, type) 93#define SMC_IRQ_FLAGS (0)
94 94
95#elif defined(CONFIG_SA1100_PLEB) 95#elif defined(CONFIG_SA1100_PLEB)
96/* We can only do 16-bit reads and writes in the static memory space. */ 96/* We can only do 16-bit reads and writes in the static memory space. */
@@ -109,7 +109,7 @@
109#define SMC_outw(v, a, r) writew(v, (a) + (r)) 109#define SMC_outw(v, a, r) writew(v, (a) + (r))
110#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) 110#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
111 111
112#define set_irq_type(irq, type) do {} while (0) 112#define SMC_IRQ_FLAGS (0)
113 113
114#elif defined(CONFIG_SA1100_ASSABET) 114#elif defined(CONFIG_SA1100_ASSABET)
115 115
@@ -185,11 +185,11 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
185#include <asm/mach-types.h> 185#include <asm/mach-types.h>
186#include <asm/arch/cpu.h> 186#include <asm/arch/cpu.h>
187 187
188#define SMC_IRQ_TRIGGER_TYPE (( \ 188#define SMC_IRQ_FLAGS (( \
189 machine_is_omap_h2() \ 189 machine_is_omap_h2() \
190 || machine_is_omap_h3() \ 190 || machine_is_omap_h3() \
191 || (machine_is_omap_innovator() && !cpu_is_omap1510()) \ 191 || (machine_is_omap_innovator() && !cpu_is_omap1510()) \
192 ) ? IRQT_FALLING : IRQT_RISING) 192 ) ? SA_TRIGGER_FALLING : SA_TRIGGER_RISING)
193 193
194 194
195#elif defined(CONFIG_SH_SH4202_MICRODEV) 195#elif defined(CONFIG_SH_SH4202_MICRODEV)
@@ -209,7 +209,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
209#define SMC_insw(a, r, p, l) insw((a) + (r) - 0xa0000000, p, l) 209#define SMC_insw(a, r, p, l) insw((a) + (r) - 0xa0000000, p, l)
210#define SMC_outsw(a, r, p, l) outsw((a) + (r) - 0xa0000000, p, l) 210#define SMC_outsw(a, r, p, l) outsw((a) + (r) - 0xa0000000, p, l)
211 211
212#define set_irq_type(irq, type) do {} while(0) 212#define SMC_IRQ_FLAGS (0)
213 213
214#elif defined(CONFIG_ISA) 214#elif defined(CONFIG_ISA)
215 215
@@ -237,7 +237,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
237#define SMC_insw(a, r, p, l) insw(((u32)a) + (r), p, l) 237#define SMC_insw(a, r, p, l) insw(((u32)a) + (r), p, l)
238#define SMC_outsw(a, r, p, l) outsw(((u32)a) + (r), p, l) 238#define SMC_outsw(a, r, p, l) outsw(((u32)a) + (r), p, l)
239 239
240#define set_irq_type(irq, type) do {} while(0) 240#define SMC_IRQ_FLAGS (0)
241 241
242#define RPC_LSA_DEFAULT RPC_LED_TX_RX 242#define RPC_LSA_DEFAULT RPC_LED_TX_RX
243#define RPC_LSB_DEFAULT RPC_LED_100_10 243#define RPC_LSB_DEFAULT RPC_LED_100_10
@@ -319,7 +319,7 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l)
319 au_writew(*_p++ , _a); \ 319 au_writew(*_p++ , _a); \
320 } while(0) 320 } while(0)
321 321
322#define set_irq_type(irq, type) do {} while (0) 322#define SMC_IRQ_FLAGS (0)
323 323
324#else 324#else
325 325
@@ -342,8 +342,8 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l)
342 342
343#endif 343#endif
344 344
345#ifndef SMC_IRQ_TRIGGER_TYPE 345#ifndef SMC_IRQ_FLAGS
346#define SMC_IRQ_TRIGGER_TYPE IRQT_RISING 346#define SMC_IRQ_FLAGS SA_TRIGGER_RISING
347#endif 347#endif
348 348
349#ifdef SMC_USE_PXA_DMA 349#ifdef SMC_USE_PXA_DMA
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 125ed00e95a5..c67c91251d04 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -1564,7 +1564,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
1564 dev->dev_addr, 6); 1564 dev->dev_addr, 6);
1565 } 1565 }
1566#endif 1566#endif
1567#if defined(__i386__) /* Patch up x86 BIOS bug. */ 1567#if defined(__i386__) || defined(__x86_64__) /* Patch up x86 BIOS bug. */
1568 if (last_irq) 1568 if (last_irq)
1569 irq = last_irq; 1569 irq = last_irq;
1570#endif 1570#endif
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index 036adc4f8ba7..22e794071cf4 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -329,9 +329,9 @@ static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr)
329 329
330struct _dlci_stat 330struct _dlci_stat
331{ 331{
332 short dlci __attribute__((packed)); 332 short dlci;
333 char flags __attribute__((packed)); 333 char flags;
334}; 334} __attribute__((packed));
335 335
336struct _frad_stat 336struct _frad_stat
337{ 337{
diff --git a/drivers/net/wd.c b/drivers/net/wd.c
index b03feae459fc..7caa8dc88a58 100644
--- a/drivers/net/wd.c
+++ b/drivers/net/wd.c
@@ -127,13 +127,6 @@ static int __init do_wd_probe(struct net_device *dev)
127 return -ENODEV; 127 return -ENODEV;
128} 128}
129 129
130static void cleanup_card(struct net_device *dev)
131{
132 free_irq(dev->irq, dev);
133 release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT);
134 iounmap(ei_status.mem);
135}
136
137#ifndef MODULE 130#ifndef MODULE
138struct net_device * __init wd_probe(int unit) 131struct net_device * __init wd_probe(int unit)
139{ 132{
@@ -538,6 +531,13 @@ init_module(void)
538 return -ENXIO; 531 return -ENXIO;
539} 532}
540 533
534static void cleanup_card(struct net_device *dev)
535{
536 free_irq(dev->irq, dev);
537 release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT);
538 iounmap(ei_status.mem);
539}
540
541void 541void
542cleanup_module(void) 542cleanup_module(void)
543{ 543{
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 44cd3fcd1572..cf05661fb1bd 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -7153,7 +7153,7 @@ static int ipw2100_wx_get_range(struct net_device *dev,
7153 7153
7154 /* Set the Wireless Extension versions */ 7154 /* Set the Wireless Extension versions */
7155 range->we_version_compiled = WIRELESS_EXT; 7155 range->we_version_compiled = WIRELESS_EXT;
7156 range->we_version_source = 16; 7156 range->we_version_source = 18;
7157 7157
7158// range->retry_capa; /* What retry options are supported */ 7158// range->retry_capa; /* What retry options are supported */
7159// range->retry_flags; /* How to decode max/min retry limit */ 7159// range->retry_flags; /* How to decode max/min retry limit */
@@ -7184,6 +7184,9 @@ static int ipw2100_wx_get_range(struct net_device *dev,
7184 IW_EVENT_CAPA_MASK(SIOCGIWAP)); 7184 IW_EVENT_CAPA_MASK(SIOCGIWAP));
7185 range->event_capa[1] = IW_EVENT_CAPA_K_1; 7185 range->event_capa[1] = IW_EVENT_CAPA_K_1;
7186 7186
7187 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
7188 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
7189
7187 IPW_DEBUG_WX("GET Range\n"); 7190 IPW_DEBUG_WX("GET Range\n");
7188 7191
7189 return 0; 7192 return 0;
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index 531b07313141..b2e8e49c8659 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -43,13 +43,16 @@ static void process_task_mortuary(void);
43 * list for processing. Only after two full buffer syncs 43 * list for processing. Only after two full buffer syncs
44 * does the task eventually get freed, because by then 44 * does the task eventually get freed, because by then
45 * we are sure we will not reference it again. 45 * we are sure we will not reference it again.
46 * Can be invoked from softirq via RCU callback due to
47 * call_rcu() of the task struct, hence the _irqsave.
46 */ 48 */
47static int task_free_notify(struct notifier_block * self, unsigned long val, void * data) 49static int task_free_notify(struct notifier_block * self, unsigned long val, void * data)
48{ 50{
51 unsigned long flags;
49 struct task_struct * task = data; 52 struct task_struct * task = data;
50 spin_lock(&task_mortuary); 53 spin_lock_irqsave(&task_mortuary, flags);
51 list_add(&task->tasks, &dying_tasks); 54 list_add(&task->tasks, &dying_tasks);
52 spin_unlock(&task_mortuary); 55 spin_unlock_irqrestore(&task_mortuary, flags);
53 return NOTIFY_OK; 56 return NOTIFY_OK;
54} 57}
55 58
@@ -431,25 +434,22 @@ static void increment_tail(struct oprofile_cpu_buffer * b)
431 */ 434 */
432static void process_task_mortuary(void) 435static void process_task_mortuary(void)
433{ 436{
434 struct list_head * pos; 437 unsigned long flags;
435 struct list_head * pos2; 438 LIST_HEAD(local_dead_tasks);
436 struct task_struct * task; 439 struct task_struct * task;
440 struct task_struct * ttask;
437 441
438 spin_lock(&task_mortuary); 442 spin_lock_irqsave(&task_mortuary, flags);
439 443
440 list_for_each_safe(pos, pos2, &dead_tasks) { 444 list_splice_init(&dead_tasks, &local_dead_tasks);
441 task = list_entry(pos, struct task_struct, tasks); 445 list_splice_init(&dying_tasks, &dead_tasks);
442 list_del(&task->tasks);
443 free_task(task);
444 }
445 446
446 list_for_each_safe(pos, pos2, &dying_tasks) { 447 spin_unlock_irqrestore(&task_mortuary, flags);
447 task = list_entry(pos, struct task_struct, tasks); 448
449 list_for_each_entry_safe(task, ttask, &local_dead_tasks, tasks) {
448 list_del(&task->tasks); 450 list_del(&task->tasks);
449 list_add_tail(&task->tasks, &dead_tasks); 451 free_task(task);
450 } 452 }
451
452 spin_unlock(&task_mortuary);
453} 453}
454 454
455 455
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index 026f671ea558..78193e4bbdb5 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -52,7 +52,8 @@ int alloc_cpu_buffers(void)
52 for_each_online_cpu(i) { 52 for_each_online_cpu(i) {
53 struct oprofile_cpu_buffer * b = &cpu_buffer[i]; 53 struct oprofile_cpu_buffer * b = &cpu_buffer[i];
54 54
55 b->buffer = vmalloc(sizeof(struct op_sample) * buffer_size); 55 b->buffer = vmalloc_node(sizeof(struct op_sample) * buffer_size,
56 cpu_to_node(i));
56 if (!b->buffer) 57 if (!b->buffer)
57 goto fail; 58 goto fail;
58 59
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
index b8241561da45..a665951b1586 100644
--- a/drivers/parport/Kconfig
+++ b/drivers/parport/Kconfig
@@ -34,7 +34,7 @@ config PARPORT
34 34
35config PARPORT_PC 35config PARPORT_PC
36 tristate "PC-style hardware" 36 tristate "PC-style hardware"
37 depends on PARPORT && (!SPARC64 || PCI) && !SPARC32 && !M32R 37 depends on PARPORT && (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV
38 ---help--- 38 ---help---
39 You should say Y here if you have a PC-style parallel port. All 39 You should say Y here if you have a PC-style parallel port. All
40 IBM PC compatible computers and some Alphas have PC-style 40 IBM PC compatible computers and some Alphas have PC-style
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 18e85ccdae67..9302b8fd7461 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -2371,8 +2371,10 @@ void parport_pc_unregister_port (struct parport *p)
2371 spin_lock(&ports_lock); 2371 spin_lock(&ports_lock);
2372 list_del_init(&priv->list); 2372 list_del_init(&priv->list);
2373 spin_unlock(&ports_lock); 2373 spin_unlock(&ports_lock);
2374#if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA)
2374 if (p->dma != PARPORT_DMA_NONE) 2375 if (p->dma != PARPORT_DMA_NONE)
2375 free_dma(p->dma); 2376 free_dma(p->dma);
2377#endif
2376 if (p->irq != PARPORT_IRQ_NONE) 2378 if (p->irq != PARPORT_IRQ_NONE)
2377 free_irq(p->irq, p); 2379 free_irq(p->irq, p);
2378 release_region(p->base, 3); 2380 release_region(p->base, 3);
@@ -2380,14 +2382,12 @@ void parport_pc_unregister_port (struct parport *p)
2380 release_region(p->base + 3, p->size - 3); 2382 release_region(p->base + 3, p->size - 3);
2381 if (p->modes & PARPORT_MODE_ECP) 2383 if (p->modes & PARPORT_MODE_ECP)
2382 release_region(p->base_hi, 3); 2384 release_region(p->base_hi, 3);
2383#ifdef CONFIG_PARPORT_PC_FIFO 2385#if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA)
2384#ifdef HAS_DMA
2385 if (priv->dma_buf) 2386 if (priv->dma_buf)
2386 pci_free_consistent(priv->dev, PAGE_SIZE, 2387 pci_free_consistent(priv->dev, PAGE_SIZE,
2387 priv->dma_buf, 2388 priv->dma_buf,
2388 priv->dma_handle); 2389 priv->dma_handle);
2389#endif 2390#endif
2390#endif
2391 kfree (p->private_data); 2391 kfree (p->private_data);
2392 parport_put_port(p); 2392 parport_put_port(p);
2393 kfree (ops); /* hope no-one cached it */ 2393 kfree (ops); /* hope no-one cached it */
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 6a61b9f286e1..0aac6a61337d 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -32,6 +32,7 @@
32#include <linux/types.h> 32#include <linux/types.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/delay.h> 34#include <linux/delay.h>
35#include <linux/sched.h> /* signal_pending() */
35#include <linux/pcieport_if.h> 36#include <linux/pcieport_if.h>
36#include "pci_hotplug.h" 37#include "pci_hotplug.h"
37 38
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 0b8b26beb163..ac1e495c314e 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -30,6 +30,9 @@
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/types.h> 32#include <linux/types.h>
33#include <linux/signal.h>
34#include <linux/jiffies.h>
35#include <linux/timer.h>
33#include <linux/pci.h> 36#include <linux/pci.h>
34#include <linux/interrupt.h> 37#include <linux/interrupt.h>
35 38
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 4f7ed4bd3be9..94e30fe4b8f3 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -24,6 +24,8 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/spinlock.h> 25#include <linux/spinlock.h>
26#include <linux/timer.h> 26#include <linux/timer.h>
27#include <linux/jiffies.h>
28#include <linux/slab.h>
27 29
28#include "rio.h" 30#include "rio.h"
29 31
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 30a11436e241..bef9316e95df 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -15,6 +15,7 @@
15#include <linux/rio.h> 15#include <linux/rio.h>
16#include <linux/rio_drv.h> 16#include <linux/rio_drv.h>
17#include <linux/stat.h> 17#include <linux/stat.h>
18#include <linux/sched.h> /* for capable() */
18 19
19#include "rio.h" 20#include "rio.h"
20 21
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 3ca1011ceaac..5e382470faa2 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -23,6 +23,7 @@
23#include <linux/rio_regs.h> 23#include <linux/rio_regs.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/spinlock.h> 25#include <linux/spinlock.h>
26#include <linux/slab.h>
26 27
27#include "rio.h" 28#include "rio.h"
28 29
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index f779f674dfa0..2472fa1a1be1 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -18,6 +18,7 @@
18#include <linux/major.h> 18#include <linux/major.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/buffer_head.h> 20#include <linux/buffer_head.h>
21#include <linux/hdreg.h>
21 22
22#include <asm/ccwdev.h> 23#include <asm/ccwdev.h>
23#include <asm/ebcdic.h> 24#include <asm/ebcdic.h>
@@ -1723,12 +1724,34 @@ dasd_release(struct inode *inp, struct file *filp)
1723 return 0; 1724 return 0;
1724} 1725}
1725 1726
1727/*
1728 * Return disk geometry.
1729 */
1730static int
1731dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1732{
1733 struct dasd_device *device;
1734
1735 device = bdev->bd_disk->private_data;
1736 if (!device)
1737 return -ENODEV;
1738
1739 if (!device->discipline ||
1740 !device->discipline->fill_geometry)
1741 return -EINVAL;
1742
1743 device->discipline->fill_geometry(device, geo);
1744 geo->start = get_start_sect(bdev) >> device->s2b_shift;
1745 return 0;
1746}
1747
1726struct block_device_operations 1748struct block_device_operations
1727dasd_device_operations = { 1749dasd_device_operations = {
1728 .owner = THIS_MODULE, 1750 .owner = THIS_MODULE,
1729 .open = dasd_open, 1751 .open = dasd_open,
1730 .release = dasd_release, 1752 .release = dasd_release,
1731 .ioctl = dasd_ioctl, 1753 .ioctl = dasd_ioctl,
1754 .getgeo = dasd_getgeo,
1732}; 1755};
1733 1756
1734 1757
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 044b75371990..8e4dcd58599e 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -486,33 +486,6 @@ dasd_ioctl_set_ro(struct block_device *bdev, int no, long args)
486} 486}
487 487
488/* 488/*
489 * Return disk geometry.
490 */
491static int
492dasd_ioctl_getgeo(struct block_device *bdev, int no, long args)
493{
494 struct hd_geometry geo = { 0, };
495 struct dasd_device *device;
496
497 device = bdev->bd_disk->private_data;
498 if (device == NULL)
499 return -ENODEV;
500
501 if (device == NULL || device->discipline == NULL ||
502 device->discipline->fill_geometry == NULL)
503 return -EINVAL;
504
505 geo = (struct hd_geometry) {};
506 device->discipline->fill_geometry(device, &geo);
507 geo.start = get_start_sect(bdev) >> device->s2b_shift;
508 if (copy_to_user((struct hd_geometry __user *) args, &geo,
509 sizeof (struct hd_geometry)))
510 return -EFAULT;
511
512 return 0;
513}
514
515/*
516 * List of static ioctls. 489 * List of static ioctls.
517 */ 490 */
518static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] = 491static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] =
@@ -528,7 +501,6 @@ static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] =
528 { BIODASDPRRST, dasd_ioctl_reset_profile }, 501 { BIODASDPRRST, dasd_ioctl_reset_profile },
529 { BLKROSET, dasd_ioctl_set_ro }, 502 { BLKROSET, dasd_ioctl_set_ro },
530 { DASDAPIVER, dasd_ioctl_api_version }, 503 { DASDAPIVER, dasd_ioctl_api_version },
531 { HDIO_GETGEO, dasd_ioctl_getgeo },
532 { -1, NULL } 504 { -1, NULL }
533}; 505};
534 506
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index bf3a67c3cc5e..54ecd548c318 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -328,31 +328,27 @@ fail:
328 return 0; 328 return 0;
329} 329}
330 330
331static int xpram_ioctl (struct inode *inode, struct file *filp, 331static int xpram_getgeo(struct block_device *bdev, struct hd_geometry *geo)
332 unsigned int cmd, unsigned long arg)
333{ 332{
334 struct hd_geometry __user *geo;
335 unsigned long size; 333 unsigned long size;
336 if (cmd != HDIO_GETGEO) 334
337 return -EINVAL;
338 /* 335 /*
339 * get geometry: we have to fake one... trim the size to a 336 * get geometry: we have to fake one... trim the size to a
340 * multiple of 64 (32k): tell we have 16 sectors, 4 heads, 337 * multiple of 64 (32k): tell we have 16 sectors, 4 heads,
341 * whatever cylinders. Tell also that data starts at sector. 4. 338 * whatever cylinders. Tell also that data starts at sector. 4.
342 */ 339 */
343 geo = (struct hd_geometry __user *) arg;
344 size = (xpram_pages * 8) & ~0x3f; 340 size = (xpram_pages * 8) & ~0x3f;
345 put_user(size >> 6, &geo->cylinders); 341 geo->cylinders = size >> 6;
346 put_user(4, &geo->heads); 342 geo->heads = 4;
347 put_user(16, &geo->sectors); 343 geo->sectors = 16;
348 put_user(4, &geo->start); 344 geo->start = 4;
349 return 0; 345 return 0;
350} 346}
351 347
352static struct block_device_operations xpram_devops = 348static struct block_device_operations xpram_devops =
353{ 349{
354 .owner = THIS_MODULE, 350 .owner = THIS_MODULE,
355 .ioctl = xpram_ioctl, 351 .getgeo = xpram_getgeo,
356}; 352};
357 353
358/* 354/*
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index 932dcf0366eb..311a4122bd70 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -432,11 +432,12 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat
432 struct Scsi_Host *host; 432 struct Scsi_Host *host;
433 void *dma_cmd_space; 433 void *dma_cmd_space;
434 unsigned char *clkprop; 434 unsigned char *clkprop;
435 int proplen; 435 int proplen, rc = -ENODEV;
436 436
437 if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) { 437 if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) {
438 printk(KERN_ERR "mac53c94: expected 2 addrs and intrs (got %d/%d)\n", 438 printk(KERN_ERR "mac53c94: expected 2 addrs and intrs"
439 node->n_addrs, node->n_intrs); 439 " (got %d/%d)\n",
440 macio_resource_count(mdev), macio_irq_count(mdev));
440 return -ENODEV; 441 return -ENODEV;
441 } 442 }
442 443
@@ -448,6 +449,7 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat
448 host = scsi_host_alloc(&mac53c94_template, sizeof(struct fsc_state)); 449 host = scsi_host_alloc(&mac53c94_template, sizeof(struct fsc_state));
449 if (host == NULL) { 450 if (host == NULL) {
450 printk(KERN_ERR "mac53c94: couldn't register host"); 451 printk(KERN_ERR "mac53c94: couldn't register host");
452 rc = -ENOMEM;
451 goto out_release; 453 goto out_release;
452 } 454 }
453 455
@@ -486,6 +488,7 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat
486 if (dma_cmd_space == 0) { 488 if (dma_cmd_space == 0) {
487 printk(KERN_ERR "mac53c94: couldn't allocate dma " 489 printk(KERN_ERR "mac53c94: couldn't allocate dma "
488 "command space for %s\n", node->full_name); 490 "command space for %s\n", node->full_name);
491 rc = -ENOMEM;
489 goto out_free; 492 goto out_free;
490 } 493 }
491 state->dma_cmds = (struct dbdma_cmd *)DBDMA_ALIGN(dma_cmd_space); 494 state->dma_cmds = (struct dbdma_cmd *)DBDMA_ALIGN(dma_cmd_space);
@@ -495,18 +498,21 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat
495 498
496 mac53c94_init(state); 499 mac53c94_init(state);
497 500
498 if (request_irq(state->intr, do_mac53c94_interrupt, 0, "53C94", state)) { 501 if (request_irq(state->intr, do_mac53c94_interrupt, 0, "53C94",state)) {
499 printk(KERN_ERR "mac53C94: can't get irq %d for %s\n", 502 printk(KERN_ERR "mac53C94: can't get irq %d for %s\n",
500 state->intr, node->full_name); 503 state->intr, node->full_name);
501 goto out_free_dma; 504 goto out_free_dma;
502 } 505 }
503 506
504 /* XXX FIXME: handle failure */ 507 rc = scsi_add_host(host, &mdev->ofdev.dev);
505 scsi_add_host(host, &mdev->ofdev.dev); 508 if (rc != 0)
506 scsi_scan_host(host); 509 goto out_release_irq;
507 510
511 scsi_scan_host(host);
508 return 0; 512 return 0;
509 513
514 out_release_irq:
515 free_irq(state->intr, state);
510 out_free_dma: 516 out_free_dma:
511 kfree(state->dma_cmd_space); 517 kfree(state->dma_cmd_space);
512 out_free: 518 out_free:
@@ -518,7 +524,7 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat
518 out_release: 524 out_release:
519 macio_release_resources(mdev); 525 macio_release_resources(mdev);
520 526
521 return -ENODEV; 527 return rc;
522} 528}
523 529
524static int mac53c94_remove(struct macio_dev *mdev) 530static int mac53c94_remove(struct macio_dev *mdev)
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index bdccf73cf9fe..d6d2125f9044 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1869,7 +1869,8 @@ static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
1869 1869
1870 if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) { 1870 if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) {
1871 printk(KERN_ERR "mesh: expected 2 addrs and 2 intrs" 1871 printk(KERN_ERR "mesh: expected 2 addrs and 2 intrs"
1872 " (got %d,%d)\n", mesh->n_addrs, mesh->n_intrs); 1872 " (got %d,%d)\n", macio_resource_count(mdev),
1873 macio_irq_count(mdev));
1873 return -ENODEV; 1874 return -ENODEV;
1874 } 1875 }
1875 1876
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index c0cf52cb975a..bbbb55eeb73a 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -29,6 +29,12 @@
29 * NV-specific details such as register offsets, SATA phy location, 29 * NV-specific details such as register offsets, SATA phy location,
30 * hotplug info, etc. 30 * hotplug info, etc.
31 * 31 *
32 * 0.10
33 * - Fixed spurious interrupts issue seen with the Maxtor 6H500F0 500GB
34 * drive. Also made the check_hotplug() callbacks return whether there
35 * was a hotplug interrupt or not. This was not the source of the
36 * spurious interrupts, but is the right thing to do anyway.
37 *
32 * 0.09 38 * 0.09
33 * - Fixed bug introduced by 0.08's MCP51 and MCP55 support. 39 * - Fixed bug introduced by 0.08's MCP51 and MCP55 support.
34 * 40 *
@@ -124,10 +130,10 @@ static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
124static void nv_host_stop (struct ata_host_set *host_set); 130static void nv_host_stop (struct ata_host_set *host_set);
125static void nv_enable_hotplug(struct ata_probe_ent *probe_ent); 131static void nv_enable_hotplug(struct ata_probe_ent *probe_ent);
126static void nv_disable_hotplug(struct ata_host_set *host_set); 132static void nv_disable_hotplug(struct ata_host_set *host_set);
127static void nv_check_hotplug(struct ata_host_set *host_set); 133static int nv_check_hotplug(struct ata_host_set *host_set);
128static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent); 134static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent);
129static void nv_disable_hotplug_ck804(struct ata_host_set *host_set); 135static void nv_disable_hotplug_ck804(struct ata_host_set *host_set);
130static void nv_check_hotplug_ck804(struct ata_host_set *host_set); 136static int nv_check_hotplug_ck804(struct ata_host_set *host_set);
131 137
132enum nv_host_type 138enum nv_host_type
133{ 139{
@@ -176,7 +182,7 @@ struct nv_host_desc
176 enum nv_host_type host_type; 182 enum nv_host_type host_type;
177 void (*enable_hotplug)(struct ata_probe_ent *probe_ent); 183 void (*enable_hotplug)(struct ata_probe_ent *probe_ent);
178 void (*disable_hotplug)(struct ata_host_set *host_set); 184 void (*disable_hotplug)(struct ata_host_set *host_set);
179 void (*check_hotplug)(struct ata_host_set *host_set); 185 int (*check_hotplug)(struct ata_host_set *host_set);
180 186
181}; 187};
182static struct nv_host_desc nv_device_tbl[] = { 188static struct nv_host_desc nv_device_tbl[] = {
@@ -309,12 +315,16 @@ static irqreturn_t nv_interrupt (int irq, void *dev_instance,
309 qc = ata_qc_from_tag(ap, ap->active_tag); 315 qc = ata_qc_from_tag(ap, ap->active_tag);
310 if (qc && (!(qc->tf.ctl & ATA_NIEN))) 316 if (qc && (!(qc->tf.ctl & ATA_NIEN)))
311 handled += ata_host_intr(ap, qc); 317 handled += ata_host_intr(ap, qc);
318 else
319 // No request pending? Clear interrupt status
320 // anyway, in case there's one pending.
321 ap->ops->check_status(ap);
312 } 322 }
313 323
314 } 324 }
315 325
316 if (host->host_desc->check_hotplug) 326 if (host->host_desc->check_hotplug)
317 host->host_desc->check_hotplug(host_set); 327 handled += host->host_desc->check_hotplug(host_set);
318 328
319 spin_unlock_irqrestore(&host_set->lock, flags); 329 spin_unlock_irqrestore(&host_set->lock, flags);
320 330
@@ -497,7 +507,7 @@ static void nv_disable_hotplug(struct ata_host_set *host_set)
497 outb(intr_mask, host_set->ports[0]->ioaddr.scr_addr + NV_INT_ENABLE); 507 outb(intr_mask, host_set->ports[0]->ioaddr.scr_addr + NV_INT_ENABLE);
498} 508}
499 509
500static void nv_check_hotplug(struct ata_host_set *host_set) 510static int nv_check_hotplug(struct ata_host_set *host_set)
501{ 511{
502 u8 intr_status; 512 u8 intr_status;
503 513
@@ -522,7 +532,11 @@ static void nv_check_hotplug(struct ata_host_set *host_set)
522 if (intr_status & NV_INT_STATUS_SDEV_REMOVED) 532 if (intr_status & NV_INT_STATUS_SDEV_REMOVED)
523 printk(KERN_WARNING "nv_sata: " 533 printk(KERN_WARNING "nv_sata: "
524 "Secondary device removed\n"); 534 "Secondary device removed\n");
535
536 return 1;
525 } 537 }
538
539 return 0;
526} 540}
527 541
528static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent) 542static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent)
@@ -560,7 +574,7 @@ static void nv_disable_hotplug_ck804(struct ata_host_set *host_set)
560 pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval); 574 pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
561} 575}
562 576
563static void nv_check_hotplug_ck804(struct ata_host_set *host_set) 577static int nv_check_hotplug_ck804(struct ata_host_set *host_set)
564{ 578{
565 u8 intr_status; 579 u8 intr_status;
566 580
@@ -585,7 +599,11 @@ static void nv_check_hotplug_ck804(struct ata_host_set *host_set)
585 if (intr_status & NV_INT_STATUS_SDEV_REMOVED) 599 if (intr_status & NV_INT_STATUS_SDEV_REMOVED)
586 printk(KERN_WARNING "nv_sata: " 600 printk(KERN_WARNING "nv_sata: "
587 "Secondary device removed\n"); 601 "Secondary device removed\n");
602
603 return 1;
588 } 604 }
605
606 return 0;
589} 607}
590 608
591static int __init nv_init(void) 609static int __init nv_init(void)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 180676d7115a..ee5f4dfdab14 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -69,7 +69,6 @@
69#include "scsi_logging.h" 69#include "scsi_logging.h"
70 70
71static void scsi_done(struct scsi_cmnd *cmd); 71static void scsi_done(struct scsi_cmnd *cmd);
72static int scsi_retry_command(struct scsi_cmnd *cmd);
73 72
74/* 73/*
75 * Definitions and constants. 74 * Definitions and constants.
@@ -752,7 +751,7 @@ static void scsi_done(struct scsi_cmnd *cmd)
752 * isn't running --- used by scsi_times_out */ 751 * isn't running --- used by scsi_times_out */
753void __scsi_done(struct scsi_cmnd *cmd) 752void __scsi_done(struct scsi_cmnd *cmd)
754{ 753{
755 unsigned long flags; 754 struct request *rq = cmd->request;
756 755
757 /* 756 /*
758 * Set the serial numbers back to zero 757 * Set the serial numbers back to zero
@@ -763,71 +762,14 @@ void __scsi_done(struct scsi_cmnd *cmd)
763 if (cmd->result) 762 if (cmd->result)
764 atomic_inc(&cmd->device->ioerr_cnt); 763 atomic_inc(&cmd->device->ioerr_cnt);
765 764
765 BUG_ON(!rq);
766
766 /* 767 /*
767 * Next, enqueue the command into the done queue. 768 * The uptodate/nbytes values don't matter, as we allow partial
768 * It is a per-CPU queue, so we just disable local interrupts 769 * completes and thus will check this in the softirq callback
769 * and need no spinlock.
770 */ 770 */
771 local_irq_save(flags); 771 rq->completion_data = cmd;
772 list_add_tail(&cmd->eh_entry, &__get_cpu_var(scsi_done_q)); 772 blk_complete_request(rq);
773 raise_softirq_irqoff(SCSI_SOFTIRQ);
774 local_irq_restore(flags);
775}
776
777/**
778 * scsi_softirq - Perform post-interrupt processing of finished SCSI commands.
779 *
780 * This is the consumer of the done queue.
781 *
782 * This is called with all interrupts enabled. This should reduce
783 * interrupt latency, stack depth, and reentrancy of the low-level
784 * drivers.
785 */
786static void scsi_softirq(struct softirq_action *h)
787{
788 int disposition;
789 LIST_HEAD(local_q);
790
791 local_irq_disable();
792 list_splice_init(&__get_cpu_var(scsi_done_q), &local_q);
793 local_irq_enable();
794
795 while (!list_empty(&local_q)) {
796 struct scsi_cmnd *cmd = list_entry(local_q.next,
797 struct scsi_cmnd, eh_entry);
798 /* The longest time any command should be outstanding is the
799 * per command timeout multiplied by the number of retries.
800 *
801 * For a typical command, this is 2.5 minutes */
802 unsigned long wait_for
803 = cmd->allowed * cmd->timeout_per_command;
804 list_del_init(&cmd->eh_entry);
805
806 disposition = scsi_decide_disposition(cmd);
807 if (disposition != SUCCESS &&
808 time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) {
809 sdev_printk(KERN_ERR, cmd->device,
810 "timing out command, waited %lus\n",
811 wait_for/HZ);
812 disposition = SUCCESS;
813 }
814
815 scsi_log_completion(cmd, disposition);
816 switch (disposition) {
817 case SUCCESS:
818 scsi_finish_command(cmd);
819 break;
820 case NEEDS_RETRY:
821 scsi_retry_command(cmd);
822 break;
823 case ADD_TO_MLQUEUE:
824 scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);
825 break;
826 default:
827 if (!scsi_eh_scmd_add(cmd, 0))
828 scsi_finish_command(cmd);
829 }
830 }
831} 773}
832 774
833/* 775/*
@@ -840,7 +782,7 @@ static void scsi_softirq(struct softirq_action *h)
840 * level drivers should not become re-entrant as a result of 782 * level drivers should not become re-entrant as a result of
841 * this. 783 * this.
842 */ 784 */
843static int scsi_retry_command(struct scsi_cmnd *cmd) 785int scsi_retry_command(struct scsi_cmnd *cmd)
844{ 786{
845 /* 787 /*
846 * Restore the SCSI command state. 788 * Restore the SCSI command state.
@@ -1273,38 +1215,6 @@ int scsi_device_cancel(struct scsi_device *sdev, int recovery)
1273} 1215}
1274EXPORT_SYMBOL(scsi_device_cancel); 1216EXPORT_SYMBOL(scsi_device_cancel);
1275 1217
1276#ifdef CONFIG_HOTPLUG_CPU
1277static int scsi_cpu_notify(struct notifier_block *self,
1278 unsigned long action, void *hcpu)
1279{
1280 int cpu = (unsigned long)hcpu;
1281
1282 switch(action) {
1283 case CPU_DEAD:
1284 /* Drain scsi_done_q. */
1285 local_irq_disable();
1286 list_splice_init(&per_cpu(scsi_done_q, cpu),
1287 &__get_cpu_var(scsi_done_q));
1288 raise_softirq_irqoff(SCSI_SOFTIRQ);
1289 local_irq_enable();
1290 break;
1291 default:
1292 break;
1293 }
1294 return NOTIFY_OK;
1295}
1296
1297static struct notifier_block __devinitdata scsi_cpu_nb = {
1298 .notifier_call = scsi_cpu_notify,
1299};
1300
1301#define register_scsi_cpu() register_cpu_notifier(&scsi_cpu_nb)
1302#define unregister_scsi_cpu() unregister_cpu_notifier(&scsi_cpu_nb)
1303#else
1304#define register_scsi_cpu()
1305#define unregister_scsi_cpu()
1306#endif /* CONFIG_HOTPLUG_CPU */
1307
1308MODULE_DESCRIPTION("SCSI core"); 1218MODULE_DESCRIPTION("SCSI core");
1309MODULE_LICENSE("GPL"); 1219MODULE_LICENSE("GPL");
1310 1220
@@ -1338,8 +1248,6 @@ static int __init init_scsi(void)
1338 INIT_LIST_HEAD(&per_cpu(scsi_done_q, i)); 1248 INIT_LIST_HEAD(&per_cpu(scsi_done_q, i));
1339 1249
1340 devfs_mk_dir("scsi"); 1250 devfs_mk_dir("scsi");
1341 open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL);
1342 register_scsi_cpu();
1343 printk(KERN_NOTICE "SCSI subsystem initialized\n"); 1251 printk(KERN_NOTICE "SCSI subsystem initialized\n");
1344 return 0; 1252 return 0;
1345 1253
@@ -1367,7 +1275,6 @@ static void __exit exit_scsi(void)
1367 devfs_remove("scsi"); 1275 devfs_remove("scsi");
1368 scsi_exit_procfs(); 1276 scsi_exit_procfs();
1369 scsi_exit_queue(); 1277 scsi_exit_queue();
1370 unregister_scsi_cpu();
1371} 1278}
1372 1279
1373subsys_initcall(init_scsi); 1280subsys_initcall(init_scsi);
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index ba93d6e66d48..00c9bf383e23 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1493,6 +1493,41 @@ static void scsi_kill_request(struct request *req, request_queue_t *q)
1493 __scsi_done(cmd); 1493 __scsi_done(cmd);
1494} 1494}
1495 1495
1496static void scsi_softirq_done(struct request *rq)
1497{
1498 struct scsi_cmnd *cmd = rq->completion_data;
1499 unsigned long wait_for = cmd->allowed * cmd->timeout_per_command;
1500 int disposition;
1501
1502 INIT_LIST_HEAD(&cmd->eh_entry);
1503
1504 disposition = scsi_decide_disposition(cmd);
1505 if (disposition != SUCCESS &&
1506 time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) {
1507 sdev_printk(KERN_ERR, cmd->device,
1508 "timing out command, waited %lus\n",
1509 wait_for/HZ);
1510 disposition = SUCCESS;
1511 }
1512
1513 scsi_log_completion(cmd, disposition);
1514
1515 switch (disposition) {
1516 case SUCCESS:
1517 scsi_finish_command(cmd);
1518 break;
1519 case NEEDS_RETRY:
1520 scsi_retry_command(cmd);
1521 break;
1522 case ADD_TO_MLQUEUE:
1523 scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);
1524 break;
1525 default:
1526 if (!scsi_eh_scmd_add(cmd, 0))
1527 scsi_finish_command(cmd);
1528 }
1529}
1530
1496/* 1531/*
1497 * Function: scsi_request_fn() 1532 * Function: scsi_request_fn()
1498 * 1533 *
@@ -1667,6 +1702,7 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
1667 blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost)); 1702 blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));
1668 blk_queue_segment_boundary(q, shost->dma_boundary); 1703 blk_queue_segment_boundary(q, shost->dma_boundary);
1669 blk_queue_issue_flush_fn(q, scsi_issue_flush_fn); 1704 blk_queue_issue_flush_fn(q, scsi_issue_flush_fn);
1705 blk_queue_softirq_done(q, scsi_softirq_done);
1670 1706
1671 if (!shost->use_clustering) 1707 if (!shost->use_clustering)
1672 clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); 1708 clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index f04e7e11f57a..14a6198cb8d2 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -44,6 +44,7 @@ extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
44 struct scsi_request *sreq); 44 struct scsi_request *sreq);
45extern void __scsi_release_request(struct scsi_request *sreq); 45extern void __scsi_release_request(struct scsi_request *sreq);
46extern void __scsi_done(struct scsi_cmnd *cmd); 46extern void __scsi_done(struct scsi_cmnd *cmd);
47extern int scsi_retry_command(struct scsi_cmnd *cmd);
47#ifdef CONFIG_SCSI_LOGGING 48#ifdef CONFIG_SCSI_LOGGING
48void scsi_log_send(struct scsi_cmnd *cmd); 49void scsi_log_send(struct scsi_cmnd *cmd);
49void scsi_log_completion(struct scsi_cmnd *cmd, int disposition); 50void scsi_log_completion(struct scsi_cmnd *cmd, int disposition);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 32d4d8d7b9f3..4c5127ed379c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -527,7 +527,7 @@ static int sd_release(struct inode *inode, struct file *filp)
527 return 0; 527 return 0;
528} 528}
529 529
530static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry __user *loc) 530static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
531{ 531{
532 struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk); 532 struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
533 struct scsi_device *sdp = sdkp->device; 533 struct scsi_device *sdp = sdkp->device;
@@ -545,15 +545,9 @@ static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry __user *
545 else 545 else
546 scsicam_bios_param(bdev, sdkp->capacity, diskinfo); 546 scsicam_bios_param(bdev, sdkp->capacity, diskinfo);
547 547
548 if (put_user(diskinfo[0], &loc->heads)) 548 geo->heads = diskinfo[0];
549 return -EFAULT; 549 geo->sectors = diskinfo[1];
550 if (put_user(diskinfo[1], &loc->sectors)) 550 geo->cylinders = diskinfo[2];
551 return -EFAULT;
552 if (put_user(diskinfo[2], &loc->cylinders))
553 return -EFAULT;
554 if (put_user((unsigned)get_start_sect(bdev),
555 (unsigned long __user *)&loc->start))
556 return -EFAULT;
557 return 0; 551 return 0;
558} 552}
559 553
@@ -593,12 +587,6 @@ static int sd_ioctl(struct inode * inode, struct file * filp,
593 if (!scsi_block_when_processing_errors(sdp) || !error) 587 if (!scsi_block_when_processing_errors(sdp) || !error)
594 return error; 588 return error;
595 589
596 if (cmd == HDIO_GETGEO) {
597 if (!arg)
598 return -EINVAL;
599 return sd_hdio_getgeo(bdev, p);
600 }
601
602 /* 590 /*
603 * Send SCSI addressing ioctls directly to mid level, send other 591 * Send SCSI addressing ioctls directly to mid level, send other
604 * ioctls to block level and then onto mid level if they can't be 592 * ioctls to block level and then onto mid level if they can't be
@@ -800,6 +788,7 @@ static struct block_device_operations sd_fops = {
800 .open = sd_open, 788 .open = sd_open,
801 .release = sd_release, 789 .release = sd_release,
802 .ioctl = sd_ioctl, 790 .ioctl = sd_ioctl,
791 .getgeo = sd_getgeo,
803#ifdef CONFIG_COMPAT 792#ifdef CONFIG_COMPAT
804 .compat_ioctl = sd_compat_ioctl, 793 .compat_ioctl = sd_compat_ioctl,
805#endif 794#endif
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 221e96e2620a..78aad9582bcf 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -2493,7 +2493,7 @@ sg_page_malloc(int rqSz, int lowDma, int *retSzp)
2493 } 2493 }
2494 if (resp) { 2494 if (resp) {
2495 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) 2495 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
2496 memset(resp, 0, resSz); 2496 memset(page_address(resp), 0, resSz);
2497 if (retSzp) 2497 if (retSzp)
2498 *retSzp = resSz; 2498 *retSzp = resSz;
2499 } 2499 }
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 987d22b53c22..16af5626c243 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -608,7 +608,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)
608 608
609 p = cpm2cpu_addr(bdp->cbd_bufaddr); 609 p = cpm2cpu_addr(bdp->cbd_bufaddr);
610 610
611 *p++ = xmit->buf[xmit->tail]; 611 *p++ = port->x_char;
612 bdp->cbd_datlen = 1; 612 bdp->cbd_datlen = 1;
613 bdp->cbd_sc |= BD_SC_READY; 613 bdp->cbd_sc |= BD_SC_READY;
614 /* Get next BD. */ 614 /* Get next BD. */
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 5ddd8ab1f108..ea24129eb6b9 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -1431,11 +1431,14 @@ static int __init pmz_init_port(struct uart_pmac_port *uap)
1431 char name[1]; 1431 char name[1];
1432 } *slots; 1432 } *slots;
1433 int len; 1433 int len;
1434 struct resource r_ports, r_rxdma, r_txdma;
1434 1435
1435 /* 1436 /*
1436 * Request & map chip registers 1437 * Request & map chip registers
1437 */ 1438 */
1438 uap->port.mapbase = np->addrs[0].address; 1439 if (of_address_to_resource(np, 0, &r_ports))
1440 return -ENODEV;
1441 uap->port.mapbase = r_ports.start;
1439 uap->port.membase = ioremap(uap->port.mapbase, 0x1000); 1442 uap->port.membase = ioremap(uap->port.mapbase, 0x1000);
1440 1443
1441 uap->control_reg = uap->port.membase; 1444 uap->control_reg = uap->port.membase;
@@ -1445,16 +1448,20 @@ static int __init pmz_init_port(struct uart_pmac_port *uap)
1445 * Request & map DBDMA registers 1448 * Request & map DBDMA registers
1446 */ 1449 */
1447#ifdef HAS_DBDMA 1450#ifdef HAS_DBDMA
1448 if (np->n_addrs >= 3 && np->n_intrs >= 3) 1451 if (of_address_to_resource(np, 1, &r_txdma) == 0 &&
1452 of_address_to_resource(np, 2, &r_rxdma) == 0)
1449 uap->flags |= PMACZILOG_FLAG_HAS_DMA; 1453 uap->flags |= PMACZILOG_FLAG_HAS_DMA;
1454#else
1455 memset(&r_txdma, 0, sizeof(struct resource));
1456 memset(&r_rxdma, 0, sizeof(struct resource));
1450#endif 1457#endif
1451 if (ZS_HAS_DMA(uap)) { 1458 if (ZS_HAS_DMA(uap)) {
1452 uap->tx_dma_regs = ioremap(np->addrs[np->n_addrs - 2].address, 0x1000); 1459 uap->tx_dma_regs = ioremap(r_txdma.start, 0x100);
1453 if (uap->tx_dma_regs == NULL) { 1460 if (uap->tx_dma_regs == NULL) {
1454 uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; 1461 uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
1455 goto no_dma; 1462 goto no_dma;
1456 } 1463 }
1457 uap->rx_dma_regs = ioremap(np->addrs[np->n_addrs - 1].address, 0x1000); 1464 uap->rx_dma_regs = ioremap(r_rxdma.start, 0x100);
1458 if (uap->rx_dma_regs == NULL) { 1465 if (uap->rx_dma_regs == NULL) {
1459 iounmap(uap->tx_dma_regs); 1466 iounmap(uap->tx_dma_regs);
1460 uap->tx_dma_regs = NULL; 1467 uap->tx_dma_regs = NULL;
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index c44bbedec817..4ddc453023a2 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -186,7 +186,7 @@ static void update_bus(struct dentry *bus)
186 186
187 down(&bus->d_inode->i_sem); 187 down(&bus->d_inode->i_sem);
188 188
189 list_for_each_entry(dev, &bus->d_subdirs, d_child) 189 list_for_each_entry(dev, &bus->d_subdirs, d_u.d_child)
190 if (dev->d_inode) 190 if (dev->d_inode)
191 update_dev(dev); 191 update_dev(dev);
192 192
@@ -203,7 +203,7 @@ static void update_sb(struct super_block *sb)
203 203
204 down(&root->d_inode->i_sem); 204 down(&root->d_inode->i_sem);
205 205
206 list_for_each_entry(bus, &root->d_subdirs, d_child) { 206 list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) {
207 if (bus->d_inode) { 207 if (bus->d_inode) {
208 switch (S_IFMT & bus->d_inode->i_mode) { 208 switch (S_IFMT & bus->d_inode->i_mode) {
209 case S_IFDIR: 209 case S_IFDIR:
@@ -319,7 +319,7 @@ static int usbfs_empty (struct dentry *dentry)
319 spin_lock(&dcache_lock); 319 spin_lock(&dcache_lock);
320 320
321 list_for_each(list, &dentry->d_subdirs) { 321 list_for_each(list, &dentry->d_subdirs) {
322 struct dentry *de = list_entry(list, struct dentry, d_child); 322 struct dentry *de = list_entry(list, struct dentry, d_u.d_child);
323 if (usbfs_positive(de)) { 323 if (usbfs_positive(de)) {
324 spin_unlock(&dcache_lock); 324 spin_unlock(&dcache_lock);
325 return 0; 325 return 0;
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
index d9cf3b327d96..77cd6ac07e3c 100644
--- a/drivers/usb/host/ohci-au1xxx.c
+++ b/drivers/usb/host/ohci-au1xxx.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/signal.h>
22 23
23#include <asm/mach-au1x00/au1000.h> 24#include <asm/mach-au1x00/au1000.h>
24 25
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
index 3959ccc88332..0020ed7a39d0 100644
--- a/drivers/usb/host/ohci-lh7a404.c
+++ b/drivers/usb/host/ohci-lh7a404.c
@@ -17,6 +17,7 @@
17 */ 17 */
18 18
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/signal.h>
20 21
21#include <asm/hardware.h> 22#include <asm/hardware.h>
22 23
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
index 2ec6a78bd65e..b2a8dfa48870 100644
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ b/drivers/usb/host/ohci-ppc-soc.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/signal.h>
18 19
19/* configure so an HC device and id are always provided */ 20/* configure so an HC device and id are always provided */
20/* always called with process context; sleeping is OK */ 21/* always called with process context; sleeping is OK */
diff --git a/drivers/usb/media/dsbr100.c b/drivers/usb/media/dsbr100.c
index 6a5700e9d428..25646804d5be 100644
--- a/drivers/usb/media/dsbr100.c
+++ b/drivers/usb/media/dsbr100.c
@@ -127,6 +127,7 @@ static struct file_operations usb_dsbr100_fops = {
127 .open = usb_dsbr100_open, 127 .open = usb_dsbr100_open,
128 .release = usb_dsbr100_close, 128 .release = usb_dsbr100_close,
129 .ioctl = usb_dsbr100_ioctl, 129 .ioctl = usb_dsbr100_ioctl,
130 .compat_ioctl = v4l_compat_ioctl32,
130 .llseek = no_llseek, 131 .llseek = no_llseek,
131}; 132};
132 133
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
index 3a0e8ce67ebe..8af665bbe330 100644
--- a/drivers/usb/media/ov511.c
+++ b/drivers/usb/media/ov511.c
@@ -4774,6 +4774,7 @@ static struct file_operations ov511_fops = {
4774 .read = ov51x_v4l1_read, 4774 .read = ov51x_v4l1_read,
4775 .mmap = ov51x_v4l1_mmap, 4775 .mmap = ov51x_v4l1_mmap,
4776 .ioctl = ov51x_v4l1_ioctl, 4776 .ioctl = ov51x_v4l1_ioctl,
4777 .compat_ioctl = v4l_compat_ioctl32,
4777 .llseek = no_llseek, 4778 .llseek = no_llseek,
4778}; 4779};
4779 4780
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c
index 09ca6128ac20..4f9b0dc6fd7b 100644
--- a/drivers/usb/media/pwc/pwc-if.c
+++ b/drivers/usb/media/pwc/pwc-if.c
@@ -154,6 +154,7 @@ static struct file_operations pwc_fops = {
154 .poll = pwc_video_poll, 154 .poll = pwc_video_poll,
155 .mmap = pwc_video_mmap, 155 .mmap = pwc_video_mmap,
156 .ioctl = pwc_video_ioctl, 156 .ioctl = pwc_video_ioctl,
157 .compat_ioctl = v4l_compat_ioctl32,
157 .llseek = no_llseek, 158 .llseek = no_llseek,
158}; 159};
159static struct video_device pwc_template = { 160static struct video_device pwc_template = {
diff --git a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c
index b2ae29af5940..2ba562285fda 100644
--- a/drivers/usb/media/se401.c
+++ b/drivers/usb/media/se401.c
@@ -1193,6 +1193,7 @@ static struct file_operations se401_fops = {
1193 .read = se401_read, 1193 .read = se401_read,
1194 .mmap = se401_mmap, 1194 .mmap = se401_mmap,
1195 .ioctl = se401_ioctl, 1195 .ioctl = se401_ioctl,
1196 .compat_ioctl = v4l_compat_ioctl32,
1196 .llseek = no_llseek, 1197 .llseek = no_llseek,
1197}; 1198};
1198static struct video_device se401_template = { 1199static struct video_device se401_template = {
diff --git a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c
index 774038b352cd..b497a6a0a206 100644
--- a/drivers/usb/media/stv680.c
+++ b/drivers/usb/media/stv680.c
@@ -1343,6 +1343,7 @@ static struct file_operations stv680_fops = {
1343 .read = stv680_read, 1343 .read = stv680_read,
1344 .mmap = stv680_mmap, 1344 .mmap = stv680_mmap,
1345 .ioctl = stv680_ioctl, 1345 .ioctl = stv680_ioctl,
1346 .compat_ioctl = v4l_compat_ioctl32,
1346 .llseek = no_llseek, 1347 .llseek = no_llseek,
1347}; 1348};
1348static struct video_device stv680_template = { 1349static struct video_device stv680_template = {
diff --git a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c
index 4bd113325ef9..63a72e550a1b 100644
--- a/drivers/usb/media/usbvideo.c
+++ b/drivers/usb/media/usbvideo.c
@@ -953,6 +953,7 @@ static struct file_operations usbvideo_fops = {
953 .read = usbvideo_v4l_read, 953 .read = usbvideo_v4l_read,
954 .mmap = usbvideo_v4l_mmap, 954 .mmap = usbvideo_v4l_mmap,
955 .ioctl = usbvideo_v4l_ioctl, 955 .ioctl = usbvideo_v4l_ioctl,
956 .compat_ioctl = v4l_compat_ioctl32,
956 .llseek = no_llseek, 957 .llseek = no_llseek,
957}; 958};
958static const struct video_device usbvideo_template = { 959static const struct video_device usbvideo_template = {
diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c
index 1c73155c8d77..5df144073871 100644
--- a/drivers/usb/media/vicam.c
+++ b/drivers/usb/media/vicam.c
@@ -1236,6 +1236,7 @@ static struct file_operations vicam_fops = {
1236 .read = vicam_read, 1236 .read = vicam_read,
1237 .mmap = vicam_mmap, 1237 .mmap = vicam_mmap,
1238 .ioctl = vicam_ioctl, 1238 .ioctl = vicam_ioctl,
1239 .compat_ioctl = v4l_compat_ioctl32,
1239 .llseek = no_llseek, 1240 .llseek = no_llseek,
1240}; 1241};
1241 1242
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
index 3605a6f3067b..bff9434c8e55 100644
--- a/drivers/usb/media/w9968cf.c
+++ b/drivers/usb/media/w9968cf.c
@@ -3490,6 +3490,7 @@ static struct file_operations w9968cf_fops = {
3490 .release = w9968cf_release, 3490 .release = w9968cf_release,
3491 .read = w9968cf_read, 3491 .read = w9968cf_read,
3492 .ioctl = w9968cf_ioctl, 3492 .ioctl = w9968cf_ioctl,
3493 .compat_ioctl = v4l_compat_ioctl32,
3493 .mmap = w9968cf_mmap, 3494 .mmap = w9968cf_mmap,
3494 .llseek = no_llseek, 3495 .llseek = no_llseek,
3495}; 3496};
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index cc8e3bf5001b..3f04427c9026 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1151,7 +1151,7 @@ config FB_VOODOO1
1151 1151
1152config FB_CYBLA 1152config FB_CYBLA
1153 tristate "Cyberblade/i1 support" 1153 tristate "Cyberblade/i1 support"
1154 depends on FB && PCI 1154 depends on FB && PCI && X86_32 && !64BIT
1155 select FB_CFB_IMAGEBLIT 1155 select FB_CFB_IMAGEBLIT
1156 select VIDEO_SELECT 1156 select VIDEO_SELECT
1157 ---help--- 1157 ---help---
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index a5d09e159cd1..6ee449858a5c 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -6,7 +6,7 @@ menu "Console display driver support"
6 6
7config VGA_CONSOLE 7config VGA_CONSOLE
8 bool "VGA text console" if EMBEDDED || !X86 8 bool "VGA text console" if EMBEDDED || !X86
9 depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !ARCH_VERSATILE 9 depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !ARCH_VERSATILE
10 default y 10 default y
11 help 11 help
12 Saying Y here will allow you to use Linux in text mode through a 12 Saying Y here will allow you to use Linux in text mode through a
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 167de397e4b4..12d9329d1408 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -56,6 +56,8 @@
56static DEFINE_SPINLOCK(vga_lock); 56static DEFINE_SPINLOCK(vga_lock);
57static int cursor_size_lastfrom; 57static int cursor_size_lastfrom;
58static int cursor_size_lastto; 58static int cursor_size_lastto;
59static u32 vgacon_xres;
60static u32 vgacon_yres;
59static struct vgastate state; 61static struct vgastate state;
60 62
61#define BLANK 0x0020 63#define BLANK 0x0020
@@ -69,7 +71,7 @@ static struct vgastate state;
69 * appear. 71 * appear.
70 */ 72 */
71#undef TRIDENT_GLITCH 73#undef TRIDENT_GLITCH
72 74#define VGA_FONTWIDTH 8 /* VGA does not support fontwidths != 8 */
73/* 75/*
74 * Interface used by the world 76 * Interface used by the world
75 */ 77 */
@@ -325,6 +327,10 @@ static const char __init *vgacon_startup(void)
325 vga_scan_lines = 327 vga_scan_lines =
326 vga_video_font_height * vga_video_num_lines; 328 vga_video_font_height * vga_video_num_lines;
327 } 329 }
330
331 vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH;
332 vgacon_yres = vga_scan_lines;
333
328 return display_desc; 334 return display_desc;
329} 335}
330 336
@@ -503,10 +509,18 @@ static int vgacon_doresize(struct vc_data *c,
503{ 509{
504 unsigned long flags; 510 unsigned long flags;
505 unsigned int scanlines = height * c->vc_font.height; 511 unsigned int scanlines = height * c->vc_font.height;
506 u8 scanlines_lo, r7, vsync_end, mode; 512 u8 scanlines_lo, r7, vsync_end, mode, max_scan;
507 513
508 spin_lock_irqsave(&vga_lock, flags); 514 spin_lock_irqsave(&vga_lock, flags);
509 515
516 outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg);
517 max_scan = inb_p(vga_video_port_val);
518
519 if (max_scan & 0x80)
520 scanlines <<= 1;
521
522 vgacon_xres = width * VGA_FONTWIDTH;
523 vgacon_yres = height * c->vc_font.height;
510 outb_p(VGA_CRTC_MODE, vga_video_port_reg); 524 outb_p(VGA_CRTC_MODE, vga_video_port_reg);
511 mode = inb_p(vga_video_port_val); 525 mode = inb_p(vga_video_port_val);
512 526
@@ -551,6 +565,10 @@ static int vgacon_doresize(struct vc_data *c,
551 565
552static int vgacon_switch(struct vc_data *c) 566static int vgacon_switch(struct vc_data *c)
553{ 567{
568 int x = c->vc_cols * VGA_FONTWIDTH;
569 int y = c->vc_rows * c->vc_font.height;
570 int rows = ORIG_VIDEO_LINES * vga_default_font_height/
571 c->vc_font.height;
554 /* 572 /*
555 * We need to save screen size here as it's the only way 573 * We need to save screen size here as it's the only way
556 * we can spot the screen has been resized and we need to 574 * we can spot the screen has been resized and we need to
@@ -566,10 +584,11 @@ static int vgacon_switch(struct vc_data *c)
566 scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, 584 scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
567 c->vc_screenbuf_size > vga_vram_size ? 585 c->vc_screenbuf_size > vga_vram_size ?
568 vga_vram_size : c->vc_screenbuf_size); 586 vga_vram_size : c->vc_screenbuf_size);
569 if (!(vga_video_num_columns % 2) && 587
570 vga_video_num_columns <= ORIG_VIDEO_COLS && 588 if ((vgacon_xres != x || vgacon_yres != y) &&
571 vga_video_num_lines <= (ORIG_VIDEO_LINES * 589 (!(vga_video_num_columns % 2) &&
572 vga_default_font_height) / c->vc_font.height) 590 vga_video_num_columns <= ORIG_VIDEO_COLS &&
591 vga_video_num_lines <= rows))
573 vgacon_doresize(c, c->vc_cols, c->vc_rows); 592 vgacon_doresize(c, c->vc_cols, c->vc_rows);
574 } 593 }
575 594
@@ -993,7 +1012,8 @@ static int vgacon_font_set(struct vc_data *c, struct console_font *font, unsigne
993 if (vga_video_type < VIDEO_TYPE_EGAM) 1012 if (vga_video_type < VIDEO_TYPE_EGAM)
994 return -EINVAL; 1013 return -EINVAL;
995 1014
996 if (font->width != 8 || (charcount != 256 && charcount != 512)) 1015 if (font->width != VGA_FONTWIDTH ||
1016 (charcount != 256 && charcount != 512))
997 return -EINVAL; 1017 return -EINVAL;
998 1018
999 rc = vgacon_do_font_op(&state, font->data, 1, charcount == 512); 1019 rc = vgacon_do_font_op(&state, font->data, 1, charcount == 512);
@@ -1010,7 +1030,7 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font)
1010 if (vga_video_type < VIDEO_TYPE_EGAM) 1030 if (vga_video_type < VIDEO_TYPE_EGAM)
1011 return -EINVAL; 1031 return -EINVAL;
1012 1032
1013 font->width = 8; 1033 font->width = VGA_FONTWIDTH;
1014 font->height = c->vc_font.height; 1034 font->height = c->vc_font.height;
1015 font->charcount = vga_512_chars ? 512 : 256; 1035 font->charcount = vga_512_chars ? 512 : 256;
1016 if (!font->data) 1036 if (!font->data)
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 403d17377f8d..03798e9c882d 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -133,12 +133,6 @@ static int controlfb_mmap(struct fb_info *info, struct file *file,
133static int controlfb_set_par (struct fb_info *info); 133static int controlfb_set_par (struct fb_info *info);
134static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info); 134static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info);
135 135
136/*
137 * inititialization
138 */
139int control_init(void);
140void control_setup(char *);
141
142/******************** Prototypes for internal functions **********************/ 136/******************** Prototypes for internal functions **********************/
143 137
144static void set_control_clock(unsigned char *params); 138static void set_control_clock(unsigned char *params);
@@ -550,9 +544,46 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro
550 544
551 545
552/* 546/*
553 * Called from fbmem.c for probing & initializing 547 * Parse user speficied options (`video=controlfb:')
554 */ 548 */
555int __init control_init(void) 549static void __init control_setup(char *options)
550{
551 char *this_opt;
552
553 if (!options || !*options)
554 return;
555
556 while ((this_opt = strsep(&options, ",")) != NULL) {
557 if (!strncmp(this_opt, "vmode:", 6)) {
558 int vmode = simple_strtoul(this_opt+6, NULL, 0);
559 if (vmode > 0 && vmode <= VMODE_MAX &&
560 control_mac_modes[vmode - 1].m[1] >= 0)
561 default_vmode = vmode;
562 } else if (!strncmp(this_opt, "cmode:", 6)) {
563 int depth = simple_strtoul(this_opt+6, NULL, 0);
564 switch (depth) {
565 case CMODE_8:
566 case CMODE_16:
567 case CMODE_32:
568 default_cmode = depth;
569 break;
570 case 8:
571 default_cmode = CMODE_8;
572 break;
573 case 15:
574 case 16:
575 default_cmode = CMODE_16;
576 break;
577 case 24:
578 case 32:
579 default_cmode = CMODE_32;
580 break;
581 }
582 }
583 }
584}
585
586static int __init control_init(void)
556{ 587{
557 struct device_node *dp; 588 struct device_node *dp;
558 char *option = NULL; 589 char *option = NULL;
@@ -651,15 +682,16 @@ static void __init find_vram_size(struct fb_info_control *p)
651static int __init control_of_init(struct device_node *dp) 682static int __init control_of_init(struct device_node *dp)
652{ 683{
653 struct fb_info_control *p; 684 struct fb_info_control *p;
654 unsigned long addr; 685 struct resource fb_res, reg_res;
655 int i;
656 686
657 if (control_fb) { 687 if (control_fb) {
658 printk(KERN_ERR "controlfb: only one control is supported\n"); 688 printk(KERN_ERR "controlfb: only one control is supported\n");
659 return -ENXIO; 689 return -ENXIO;
660 } 690 }
661 if(dp->n_addrs != 2) { 691
662 printk(KERN_ERR "expecting 2 address for control (got %d)", dp->n_addrs); 692 if (of_pci_address_to_resource(dp, 2, &fb_res) ||
693 of_pci_address_to_resource(dp, 1, &reg_res)) {
694 printk(KERN_ERR "can't get 2 addresses for control\n");
663 return -ENXIO; 695 return -ENXIO;
664 } 696 }
665 p = kmalloc(sizeof(*p), GFP_KERNEL); 697 p = kmalloc(sizeof(*p), GFP_KERNEL);
@@ -669,18 +701,12 @@ static int __init control_of_init(struct device_node *dp)
669 memset(p, 0, sizeof(*p)); 701 memset(p, 0, sizeof(*p));
670 702
671 /* Map in frame buffer and registers */ 703 /* Map in frame buffer and registers */
672 for (i = 0; i < dp->n_addrs; ++i) { 704 p->fb_orig_base = fb_res.start;
673 addr = dp->addrs[i].address; 705 p->fb_orig_size = fb_res.end - fb_res.start + 1;
674 if (dp->addrs[i].size >= 0x800000) { 706 /* use the big-endian aperture (??) */
675 p->fb_orig_base = addr; 707 p->frame_buffer_phys = fb_res.start + 0x800000;
676 p->fb_orig_size = dp->addrs[i].size; 708 p->control_regs_phys = reg_res.start;
677 /* use the big-endian aperture (??) */ 709 p->control_regs_size = reg_res.end - reg_res.start + 1;
678 p->frame_buffer_phys = addr + 0x800000;
679 } else {
680 p->control_regs_phys = addr;
681 p->control_regs_size = dp->addrs[i].size;
682 }
683 }
684 710
685 if (!p->fb_orig_base || 711 if (!p->fb_orig_base ||
686 !request_mem_region(p->fb_orig_base,p->fb_orig_size,"controlfb")) { 712 !request_mem_region(p->fb_orig_base,p->fb_orig_size,"controlfb")) {
@@ -1059,43 +1085,3 @@ static void control_cleanup(void)
1059} 1085}
1060 1086
1061 1087
1062/*
1063 * Parse user speficied options (`video=controlfb:')
1064 */
1065void __init control_setup(char *options)
1066{
1067 char *this_opt;
1068
1069 if (!options || !*options)
1070 return;
1071
1072 while ((this_opt = strsep(&options, ",")) != NULL) {
1073 if (!strncmp(this_opt, "vmode:", 6)) {
1074 int vmode = simple_strtoul(this_opt+6, NULL, 0);
1075 if (vmode > 0 && vmode <= VMODE_MAX &&
1076 control_mac_modes[vmode - 1].m[1] >= 0)
1077 default_vmode = vmode;
1078 } else if (!strncmp(this_opt, "cmode:", 6)) {
1079 int depth = simple_strtoul(this_opt+6, NULL, 0);
1080 switch (depth) {
1081 case CMODE_8:
1082 case CMODE_16:
1083 case CMODE_32:
1084 default_cmode = depth;
1085 break;
1086 case 8:
1087 default_cmode = CMODE_8;
1088 break;
1089 case 15:
1090 case 16:
1091 default_cmode = CMODE_16;
1092 break;
1093 case 24:
1094 case 32:
1095 default_cmode = CMODE_32;
1096 break;
1097 }
1098 }
1099 }
1100}
1101
diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c
index 03fbe83d71a8..e9f5dee67e3c 100644
--- a/drivers/video/cyblafb.c
+++ b/drivers/video/cyblafb.c
@@ -7,11 +7,12 @@
7 * tridentfb.c by Jani Monoses 7 * tridentfb.c by Jani Monoses
8 * see files above for further credits 8 * see files above for further credits
9 * 9 *
10 * TODO:
11 *
12 */ 10 */
13 11
14#define CYBLAFB_DEBUG 0 12#define CYBLAFB_DEBUG 0
13#define CYBLAFB_KD_GRAPHICS_QUIRK 1
14
15#define CYBLAFB_PIXMAPSIZE 8192
15 16
16#include <linux/config.h> 17#include <linux/config.h>
17#include <linux/module.h> 18#include <linux/module.h>
@@ -22,7 +23,7 @@
22#include <asm/types.h> 23#include <asm/types.h>
23#include <video/cyblafb.h> 24#include <video/cyblafb.h>
24 25
25#define VERSION "0.54" 26#define VERSION "0.62"
26 27
27struct cyblafb_par { 28struct cyblafb_par {
28 u32 pseudo_pal[16]; 29 u32 pseudo_pal[16];
@@ -32,7 +33,9 @@ struct cyblafb_par {
32static struct fb_fix_screeninfo cyblafb_fix __devinitdata = { 33static struct fb_fix_screeninfo cyblafb_fix __devinitdata = {
33 .id = "CyBla", 34 .id = "CyBla",
34 .type = FB_TYPE_PACKED_PIXELS, 35 .type = FB_TYPE_PACKED_PIXELS,
36 .xpanstep = 1,
35 .ypanstep = 1, 37 .ypanstep = 1,
38 .ywrapstep = 1,
36 .visual = FB_VISUAL_PSEUDOCOLOR, 39 .visual = FB_VISUAL_PSEUDOCOLOR,
37 .accel = FB_ACCEL_NONE, 40 .accel = FB_ACCEL_NONE,
38}; 41};
@@ -43,8 +46,9 @@ static int ref __devinitdata = 75;
43static int fp __devinitdata; 46static int fp __devinitdata;
44static int crt __devinitdata; 47static int crt __devinitdata;
45static int memsize __devinitdata; 48static int memsize __devinitdata;
46static int vesafb __devinitdata;
47 49
50static int basestride;
51static int vesafb;
48static int nativex; 52static int nativex;
49static int center; 53static int center;
50static int stretch; 54static int stretch;
@@ -52,26 +56,50 @@ static int pciwb = 1;
52static int pcirb = 1; 56static int pcirb = 1;
53static int pciwr = 1; 57static int pciwr = 1;
54static int pcirr = 1; 58static int pcirr = 1;
59static int disabled;
55static int verbosity; 60static int verbosity;
56static int displaytype; 61static int displaytype;
57 62
58static void __iomem * io_virt; // iospace virtual memory address 63static void __iomem *io_virt; // iospace virtual memory address
59 64
60module_param(mode,charp,0); 65module_param(mode, charp, 0);
61module_param(bpp,int,0); 66module_param(bpp, int, 0);
62module_param(ref,int,0); 67module_param(ref, int, 0);
63module_param(fp,int,0); 68module_param(fp, int, 0);
64module_param(crt,int,0); 69module_param(crt, int, 0);
65module_param(nativex,int,0); 70module_param(nativex, int, 0);
66module_param(center,int,0); 71module_param(center, int, 0);
67module_param(stretch,int,0); 72module_param(stretch, int, 0);
68module_param(pciwb,int,0); 73module_param(pciwb, int, 0);
69module_param(pcirb,int,0); 74module_param(pcirb, int, 0);
70module_param(pciwr,int,0); 75module_param(pciwr, int, 0);
71module_param(pcirr,int,0); 76module_param(pcirr, int, 0);
72module_param(memsize,int,0); 77module_param(memsize, int, 0);
73module_param(verbosity,int,0); 78module_param(verbosity, int, 0);
74module_param(vesafb,int,0); 79
80//=========================================
81//
82// Well, we have to fix the upper layers.
83// Until this has been done, we work around
84// the bugs.
85//
86//=========================================
87
88#if (CYBLAFB_KD_GRAPHICS_QUIRK && CYBLAFB_DEBUG)
89 if (disabled) { \
90 printk("********\n");\
91 dump_stack();\
92 return val;\
93 }
94
95#elif CYBLAFB_KD_GRAPHICS_QUIRK
96#define KD_GRAPHICS_RETURN(val)\
97 if (disabled) {\
98 return val;\
99 }
100#else
101#define KD_GRAPHICS_RETURN(val)
102#endif
75 103
76//========================================= 104//=========================================
77// 105//
@@ -79,10 +107,10 @@ module_param(vesafb,int,0);
79// 107//
80//========================================= 108//=========================================
81 109
82#define out8(r,v) writeb(v,io_virt+r) 110#define out8(r, v) writeb(v, io_virt + r)
83#define out32(r,v) writel(v,io_virt+r) 111#define out32(r, v) writel(v, io_virt + r)
84#define in8(r) readb(io_virt+r) 112#define in8(r) readb(io_virt + r)
85#define in32(r) readl(io_virt+r) 113#define in32(r) readl(io_virt + r)
86 114
87//====================================== 115//======================================
88// 116//
@@ -90,47 +118,47 @@ module_param(vesafb,int,0);
90// 118//
91//====================================== 119//======================================
92 120
93static inline unsigned char read3X4(int reg) 121static inline u8 read3X4(u32 reg)
94{ 122{
95 out8(0x3D4,reg); 123 out8(0x3D4, reg);
96 return in8(0x3D5); 124 return in8(0x3D5);
97} 125}
98 126
99static inline unsigned char read3C4(int reg) 127static inline u8 read3C4(u32 reg)
100{ 128{
101 out8(0x3C4,reg); 129 out8(0x3C4, reg);
102 return in8(0x3C5); 130 return in8(0x3C5);
103} 131}
104 132
105static inline unsigned char read3CE(int reg) 133static inline u8 read3CE(u32 reg)
106{ 134{
107 out8(0x3CE,reg); 135 out8(0x3CE, reg);
108 return in8(0x3CF); 136 return in8(0x3CF);
109} 137}
110 138
111static inline void write3X4(int reg,unsigned char val) 139static inline void write3X4(u32 reg, u8 val)
112{ 140{
113 out8(0x3D4,reg); 141 out8(0x3D4, reg);
114 out8(0x3D5,val); 142 out8(0x3D5, val);
115} 143}
116 144
117static inline void write3C4(int reg,unsigned char val) 145static inline void write3C4(u32 reg, u8 val)
118{ 146{
119 out8(0x3C4,reg); 147 out8(0x3C4, reg);
120 out8(0x3C5,val); 148 out8(0x3C5, val);
121} 149}
122 150
123static inline void write3CE(int reg,unsigned char val) 151static inline void write3CE(u32 reg, u8 val)
124{ 152{
125 out8(0x3CE,reg); 153 out8(0x3CE, reg);
126 out8(0x3CF,val); 154 out8(0x3CF, val);
127} 155}
128 156
129static inline void write3C0(int reg,unsigned char val) 157static inline void write3C0(u32 reg, u8 val)
130{ 158{
131 in8(0x3DA); // read to reset index 159 in8(0x3DA); // read to reset index
132 out8(0x3C0,reg); 160 out8(0x3C0, reg);
133 out8(0x3C0,val); 161 out8(0x3C0, val);
134} 162}
135 163
136//================================================= 164//=================================================
@@ -139,58 +167,62 @@ static inline void write3C0(int reg,unsigned char val)
139// 167//
140//================================================= 168//=================================================
141 169
142static inline void enable_mmio(void) 170static void enable_mmio(void)
143{ 171{
144 int tmp; 172 u8 tmp;
145 173
146 outb(0x0B,0x3C4); 174 outb(0x0B, 0x3C4);
147 inb(0x3C5); // Set NEW mode 175 inb(0x3C5); // Set NEW mode
148 outb(SR0E,0x3C4); // write enable a lot of extended ports 176 outb(SR0E, 0x3C4); // write enable a lot of extended ports
149 outb(0x80,0x3C5); 177 outb(0x80, 0x3C5);
150 178
151 outb(SR11,0x3C4); // write enable those extended ports that 179 outb(SR11, 0x3C4); // write enable those extended ports that
152 outb(0x87,0x3C5); // are not affected by SR0E_New 180 outb(0x87, 0x3C5); // are not affected by SR0E_New
153 181
154 outb(CR1E,0x3d4); // clear write protect bit for port 0x3c2 182 outb(CR1E, 0x3d4); // clear write protect bit for port 0x3c2
155 tmp=inb(0x3d5) & 0xBF; 183 tmp = inb(0x3d5) & 0xBF;
156 outb(CR1E,0x3d4); 184 outb(CR1E, 0x3d4);
157 outb(tmp,0x3d5); 185 outb(tmp, 0x3d5);
158 186
159 outb(CR39,0x3D4); 187 outb(CR39, 0x3D4);
160 outb(inb(0x3D5)|0x01,0x3D5); // Enable mmio, everything else untouched 188 outb(inb(0x3D5) | 0x01, 0x3D5); // Enable mmio
161} 189}
162 190
163//================================================= 191//=================================================
164// 192//
165// Set pixel clock VCLK1 193// Set pixel clock VCLK1
166// - multipliers set elswhere 194// - multipliers set elswhere
167// - freq in units of 0.01 MHz 195// - freq in units of 0.01 MHz
196//
197// Hardware bug: SR18 >= 250 is broken for the
198// cyberblade/i1
168// 199//
169//================================================= 200//=================================================
170 201
171static void set_vclk(struct cyblafb_par *par, int freq) 202static void set_vclk(struct cyblafb_par *par, int freq)
172{ 203{
173 u32 m,n,k; 204 u32 m, n, k;
174 int f,fi,d,di; 205 int f, fi, d, di;
175 u8 lo=0,hi=0; 206 u8 lo = 0, hi = 0;
176 207
177 d = 2000; 208 d = 2000;
178 k = freq >= 10000 ? 0 : freq >= 5000 ? 1 : freq >= 2500 ? 2 : 3; 209 k = freq >= 10000 ? 0 : freq >= 5000 ? 1 : freq >= 2500 ? 2 : 3;
179 for(m = 0;m<64;m++) 210 for (m = 0; m < 64; m++)
180 for(n = 0;n<250;n++) { // max 249 is a hardware limit for cybla/i1 ! 211 for (n = 0; n < 250; n++) {
181 fi = (int)(((5864727*(n+8))/((m+2)*(1<<k)))>>12); 212 fi = (int)(((5864727 * (n + 8)) /
182 if ((di = abs(fi - freq)) < d) { 213 ((m + 2) * (1 << k))) >> 12);
183 d = di; 214 if ((di = abs(fi - freq)) < d) {
184 f = fi; 215 d = di;
185 lo = (u8) n; 216 f = fi;
186 hi = (u8) ((k<<6) | m); 217 lo = (u8) n;
218 hi = (u8) ((k << 6) | m);
219 }
187 } 220 }
188 } 221 write3C4(SR19, hi);
189 write3C4(SR19,hi); 222 write3C4(SR18, lo);
190 write3C4(SR18,lo); 223 if (verbosity > 0)
191 if(verbosity > 1)
192 output("pixclock = %d.%02d MHz, k/m/n %x %x %x\n", 224 output("pixclock = %d.%02d MHz, k/m/n %x %x %x\n",
193 freq/100,freq%100,(hi&0xc0)>>6,hi&0x3f,lo); 225 freq / 100, freq % 100, (hi & 0xc0) >> 6, hi & 0x3f, lo);
194} 226}
195 227
196//================================================ 228//================================================
@@ -199,83 +231,83 @@ static void set_vclk(struct cyblafb_par *par, int freq)
199// 231//
200//================================================ 232//================================================
201 233
202static void cyblafb_setup_GE(int pitch,int bpp) 234static void cyblafb_setup_GE(int pitch, int bpp)
203{ 235{
204 int base = (pitch>>3)<<20; 236 KD_GRAPHICS_RETURN();
205 237
206 switch (bpp) { 238 switch (bpp) {
207 case 8: base |= (0<<29); break; 239 case 8:
208 case 15: base |= (5<<29); break; 240 basestride = ((pitch >> 3) << 20) | (0 << 29);
209 case 16: base |= (1<<29); break; 241 break;
210 case 24: 242 case 15:
211 case 32: base |= (2<<29); break; 243 basestride = ((pitch >> 3) << 20) | (5 << 29);
244 break;
245 case 16:
246 basestride = ((pitch >> 3) << 20) | (1 << 29);
247 break;
248 case 24:
249 case 32:
250 basestride = ((pitch >> 3) << 20) | (2 << 29);
251 break;
212 } 252 }
213 253
214 write3X4(CR36,0x90); // reset GE 254 write3X4(CR36, 0x90); // reset GE
215 write3X4(CR36,0x80); // enable GE 255 write3X4(CR36, 0x80); // enable GE
216 256 out32(GE24, 1 << 7); // reset all GE pointers by toggling
217 out32(GE24,1<<7); // reset all GE pointers 257 out32(GE24, 0); // d7 of GE24
218 out32(GE24,0); 258 write3X4(CR2D, 0x00); // GE Timinigs, no delays
219 259 out32(GE6C, 0); // Pattern and Style, p 129, ok
220 write3X4(CR2D,0x00); // GE Timinigs, no delays
221
222 out32(GEB8,base); // Destination Stride / Buffer Base 0, p 133
223 out32(GEBC,base); // Destination Stride / Buffer Base 1, p 133
224 out32(GEC0,base); // Destination Stride / Buffer Base 2, p 133
225 out32(GEC4,base); // Destination Stride / Buffer Base 3, p 133
226 out32(GEC8,base); // Source Stride / Buffer Base 0, p 133
227 out32(GECC,base); // Source Stride / Buffer Base 1, p 133
228 out32(GED0,base); // Source Stride / Buffer Base 2, p 133
229 out32(GED4,base); // Source Stride / Buffer Base 3, p 133
230 out32(GE6C,0); // Pattern and Style, p 129, ok
231} 260}
232 261
233//===================================================================== 262//=====================================================================
234// 263//
235// Although this is a .fb_sync function that could be enabled in 264// Cyberblade specific syncing
236// cyblafb_ops, we do not include it there. We sync immediately before 265//
237// new GE operations to improve performance. 266// A timeout might be caused by disabled mmio.
267// Cause:
268// - bit CR39 & 1 == 0 upon return, X trident driver bug
269// - kdm bug (KD_GRAPHICS not set on first switch)
270// - kernel design flaw (it believes in the correctness
271// of kdm/X
272// First we try to sync ignoring that problem, as most of the
273// time that will succeed immediately and the enable_mmio()
274// would only degrade performance.
238// 275//
239//===================================================================== 276//=====================================================================
240 277
241static int cyblafb_sync(struct fb_info *info) 278static int cyblafb_sync(struct fb_info *info)
242{ 279{
243 int status, i=100000; 280 u32 status, i = 100000;
244 while( ((status=in32(GE20)) & 0xFA800000) && i != 0) 281
282 KD_GRAPHICS_RETURN(0);
283
284 while (((status = in32(GE20)) & 0xFe800000) && i != 0)
245 i--; 285 i--;
246 286
247 if (i == 0) { 287 if (i == 0) {
248 // The timeout might be caused by disabled mmio.
249 // Cause:
250 // - bit CR39 & 1 == 0 upon return, X trident driver bug
251 // - kdm bug (KD_GRAPHICS not set on first switch)
252 // - kernel design flaw (it believes in the correctness
253 // of kdm/X
254 // So we make sure that mmio is enabled first ...
255 enable_mmio(); 288 enable_mmio();
256// show_trace(NULL,&status); 289 i = 1000000;
257 i=1000000; 290 while (((status = in32(GE20)) & 0xFA800000) && i != 0)
258 while( ((status=in32(GE20)) & 0xFA800000) && i != 0)
259 i--; 291 i--;
260 if (i == 0) { 292 if (i == 0) {
261 output("GE Timeout, status: %x\n",status); 293 output("GE Timeout, status: %x\n", status);
262 if(status & 0x80000000) 294 if (status & 0x80000000)
263 output("Bresenham Engine : Busy\n"); 295 output("Bresenham Engine : Busy\n");
264 if(status & 0x40000000) 296 if (status & 0x40000000)
265 output("Setup Engine : Busy\n"); 297 output("Setup Engine : Busy\n");
266 if(status & 0x20000000) 298 if (status & 0x20000000)
267 output("SP / DPE : Busy\n"); 299 output("SP / DPE : Busy\n");
268 if(status & 0x10000000) 300 if (status & 0x10000000)
269 output("Memory Interface : Busy\n"); 301 output("Memory Interface : Busy\n");
270 if(status & 0x08000000) 302 if (status & 0x08000000)
271 output("Com Lst Proc : Busy\n"); 303 output("Com Lst Proc : Busy\n");
272 if(status & 0x04000000) 304 if (status & 0x04000000)
273 output("Block Write : Busy\n"); 305 output("Block Write : Busy\n");
274 if(status & 0x02000000) 306 if (status & 0x02000000)
275 output("Command Buffer : Full\n"); 307 output("Command Buffer : Full\n");
276 if(status & 0x01000000) 308 if (status & 0x01000000)
277 output("RESERVED : Busy\n"); 309 output("RESERVED : Busy\n");
278 if(status & 0x00800000) 310 if (status & 0x00800000)
279 output("PCI Write Buffer : Busy\n"); 311 output("PCI Write Buffer : Busy\n");
280 cyblafb_setup_GE(info->var.xres, 312 cyblafb_setup_GE(info->var.xres,
281 info->var.bits_per_pixel); 313 info->var.bits_per_pixel);
@@ -291,142 +323,193 @@ static int cyblafb_sync(struct fb_info *info)
291// 323//
292//============================== 324//==============================
293 325
294static void cyblafb_fillrect(struct fb_info * info, 326static void cyblafb_fillrect(struct fb_info *info, const struct fb_fillrect *fr)
295 const struct fb_fillrect *fr)
296{ 327{
297 int bpp = info->var.bits_per_pixel; 328 u32 bpp = info->var.bits_per_pixel, col, desty, height;
298 int col; 329
330 KD_GRAPHICS_RETURN();
299 331
300 switch (bpp) { 332 switch (bpp) {
301 default: 333 default:
302 case 8: col = fr->color; 334 case 8:
303 col |= col <<8; 335 col = fr->color;
304 col |= col <<16; 336 col |= col << 8;
305 break; 337 col |= col << 16;
306 case 16: col = ((u32 *)(info->pseudo_palette))[fr->color]; 338 break;
307 col |= col <<16; 339 case 16:
308 break; 340 col = ((u32 *) (info->pseudo_palette))[fr->color];
309 case 32: col = ((u32 *)(info->pseudo_palette))[fr->color]; 341 col |= col << 16;
310 break; 342 break;
343 case 32:
344 col = ((u32 *) (info->pseudo_palette))[fr->color];
345 break;
311 } 346 }
312 347
313 cyblafb_sync(info); 348 desty = fr->dy;
314 349 height = fr->height;
315 out32(GE60,col); 350 while (height) {
316 out32(GE48,fr->rop ? 0x66:ROP_S); 351 out32(GEB8, basestride | ((desty * info->var.xres_virtual *
317 out32(GE44,0x20000000|1<<19|1<<4|2<<2); 352 bpp) >> 6));
318 out32(GE08,point(fr->dx,fr->dy)); 353 out32(GE60, col);
319 out32(GE0C,point(fr->dx+fr->width-1,fr->dy+fr->height-1)); 354 out32(GE48, fr->rop ? 0x66 : ROP_S);
320 355 out32(GE44, 0x20000000 | 1 << 19 | 1 << 4 | 2 << 2);
356 out32(GE08, point(fr->dx, 0));
357 out32(GE0C, point(fr->dx + fr->width - 1,
358 height > 4096 ? 4095 : height - 1));
359 if (likely(height <= 4096))
360 return;
361 desty += 4096;
362 height -= 4096;
363 }
321} 364}
322 365
323//============================== 366//================================================
324// 367//
325// Cyberblade specific copyarea 368// Cyberblade specific copyarea
326// 369//
327//============================== 370// This function silently assumes that it never
371// will be called with width or height exceeding
372// 4096.
373//
374//================================================
328 375
329static void cyblafb_copyarea(struct fb_info *info, 376static void cyblafb_copyarea(struct fb_info *info, const struct fb_copyarea *ca)
330 const struct fb_copyarea *ca)
331{ 377{
332 __u32 s1,s2,d1,d2; 378 u32 s1, s2, d1, d2, direction;
333 int direction; 379
380 KD_GRAPHICS_RETURN();
381
382 s1 = point(ca->sx, 0);
383 s2 = point(ca->sx + ca->width - 1, ca->height - 1);
384 d1 = point(ca->dx, 0);
385 d2 = point(ca->dx + ca->width - 1, ca->height - 1);
334 386
335 s1 = point(ca->sx,ca->sy);
336 s2 = point(ca->sx+ca->width-1,ca->sy+ca->height-1);
337 d1 = point(ca->dx,ca->dy);
338 d2 = point(ca->dx+ca->width-1,ca->dy+ca->height-1);
339 if ((ca->sy > ca->dy) || ((ca->sy == ca->dy) && (ca->sx > ca->dx))) 387 if ((ca->sy > ca->dy) || ((ca->sy == ca->dy) && (ca->sx > ca->dx)))
340 direction = 0; 388 direction = 0;
341 else 389 else
342 direction = 2; 390 direction = 2;
343 391
344 cyblafb_sync(info); 392 out32(GEB8, basestride | ((ca->dy * info->var.xres_virtual *
345 393 info->var.bits_per_pixel) >> 6));
346 out32(GE44,0xa0000000|1<<19|1<<2|direction); 394 out32(GEC8, basestride | ((ca->sy * info->var.xres_virtual *
347 out32(GE00,direction?s2:s1); 395 info->var.bits_per_pixel) >> 6));
348 out32(GE04,direction?s1:s2); 396 out32(GE44, 0xa0000000 | 1 << 19 | 1 << 2 | direction);
349 out32(GE08,direction?d2:d1); 397 out32(GE00, direction ? s2 : s1);
350 out32(GE0C,direction?d1:d2); 398 out32(GE04, direction ? s1 : s2);
351 399 out32(GE08, direction ? d2 : d1);
400 out32(GE0C, direction ? d1 : d2);
352} 401}
353 402
354//======================================================================= 403//=======================================================================
355// 404//
356// Cyberblade specific imageblit 405// Cyberblade specific imageblit
357// 406//
358// Accelerated for the most usual case, blitting 1-bit deep character 407// Accelerated for the most usual case, blitting 1 - bit deep
359// character images. Everything else is passed to the generic imageblit. 408// character images. Everything else is passed to the generic imageblit
409// unless it is so insane that it is better to printk an alert.
410//
411// Hardware bug: _Never_ blit across pixel column 2048, that will lock
412// the system. We split those blit requests into three blitting
413// operations.
360// 414//
361//======================================================================= 415//=======================================================================
362 416
363static void cyblafb_imageblit(struct fb_info *info, 417static void cyblafb_imageblit(struct fb_info *info,
364 const struct fb_image *image) 418 const struct fb_image *image)
365{ 419{
366
367 u32 fgcol, bgcol; 420 u32 fgcol, bgcol;
421 u32 *pd = (u32 *) image->data;
422 u32 bpp = info->var.bits_per_pixel;
368 423
369 int i; 424 KD_GRAPHICS_RETURN();
370 int bpp = info->var.bits_per_pixel; 425
371 int index = 0; 426 // Used only for drawing the penguine (image->depth > 1)
372 int index_end=image->height * image->width / 8; 427 if (image->depth != 1) {
373 int width_dds=image->width / 32; 428 cfb_imageblit(info, image);
374 int width_dbs=image->width % 32; 429 return;
375 430 }
376 if (image->depth != 1 || bpp < 8 || bpp > 32 || bpp % 8 != 0 || 431 // That should never happen, but it would be fatal
377 image->width % 8 != 0 || image->width == 0 || image->height == 0) { 432 if (image->width == 0 || image->height == 0) {
378 cfb_imageblit(info,image); 433 output("imageblit: width/height 0 detected\n");
379 return; 434 return;
380 } 435 }
381 436
382 if (info->fix.visual == FB_VISUAL_TRUECOLOR || 437 if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
383 info->fix.visual == FB_VISUAL_DIRECTCOLOR) { 438 info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
384 fgcol = ((u32*)(info->pseudo_palette))[image->fg_color]; 439 fgcol = ((u32 *) (info->pseudo_palette))[image->fg_color];
385 bgcol = ((u32*)(info->pseudo_palette))[image->bg_color]; 440 bgcol = ((u32 *) (info->pseudo_palette))[image->bg_color];
386 } else { 441 } else {
387 fgcol = image->fg_color; 442 fgcol = image->fg_color;
388 bgcol = image->bg_color; 443 bgcol = image->bg_color;
389 } 444 }
390 445
391 switch (bpp) { 446 switch (bpp) {
392 case 8: 447 case 8:
393 fgcol |= fgcol <<8; fgcol |= fgcol <<16; 448 fgcol |= fgcol << 8;
394 bgcol |= bgcol <<8; bgcol |= bgcol <<16; 449 bgcol |= bgcol << 8;
395 break; 450 case 16:
396 case 16: 451 fgcol |= fgcol << 16;
397 fgcol |= fgcol <<16; 452 bgcol |= bgcol << 16;
398 bgcol |= bgcol <<16; 453 default:
399 break; 454 break;
400 default:
401 break;
402 } 455 }
403 456
404 cyblafb_sync(info); 457 out32(GEB8, basestride | ((image->dy * info->var.xres_virtual *
405 458 bpp) >> 6));
406 out32(GE60,fgcol); 459 out32(GE60, fgcol);
407 out32(GE64,bgcol); 460 out32(GE64, bgcol);
408 out32(GE44,0xa0000000 | 1<<20 | 1<<19); 461
409 out32(GE08,point(image->dx,image->dy)); 462 if (!(image->dx < 2048 && (image->dx + image->width - 1) >= 2048)) {
410 out32(GE0C,point(image->dx+image->width-1,image->dy+image->height-1)); 463 u32 dds = ((image->width + 31) >> 5) * image->height;
464 out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
465 out32(GE08, point(image->dx, 0));
466 out32(GE0C, point(image->dx + image->width - 1,
467 image->height - 1));
468 while (dds--)
469 out32(GE9C, *pd++);
470 } else {
471 int i, j;
472 u32 ddstotal = (image->width + 31) >> 5;
473 u32 ddsleft = (2048 - image->dx + 31) >> 5;
474 u32 skipleft = ddstotal - ddsleft;
475
476 out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
477 out32(GE08, point(image->dx, 0));
478 out32(GE0C, point(2048 - 1, image->height - 1));
479 for (i = 0; i < image->height; i++) {
480 for (j = 0; j < ddsleft; j++)
481 out32(GE9C, *pd++);
482 pd += skipleft;
483 }
411 484
412 while(index < index_end) { 485 if (image->dx % 32) {
413 const char *p = image->data + index; 486 out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
414 for(i=0;i<width_dds;i++) { 487 out32(GE08, point(2048, 0));
415 out32(GE9C,*(u32*)p); 488 if (image->width > ddsleft << 5)
416 p+=4; 489 out32(GE0C, point(image->dx + (ddsleft << 5) -
417 index+=4; 490 1, image->height - 1));
491 else
492 out32(GE0C, point(image->dx + image->width - 1,
493 image->height - 1));
494 pd = ((u32 *) image->data) + ddstotal - skipleft - 1;
495 for (i = 0; i < image->height; i++) {
496 out32(GE9C, swab32(swab32(*pd) << ((32 -
497 (image->dx & 31)) & 31)));
498 pd += ddstotal;
499 }
418 } 500 }
419 switch(width_dbs) { 501
420 case 0: break; 502 if (skipleft) {
421 case 8: out32(GE9C,*(u8*)p); 503 out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
422 index+=1; 504 out32(GE08, point(image->dx + (ddsleft << 5), 0));
423 break; 505 out32(GE0C, point(image->dx + image->width - 1,
424 case 16: out32(GE9C,*(u16*)p); 506 image->height - 1));
425 index+=2; 507 pd = (u32 *) image->data;
426 break; 508 for (i = 0; i < image->height; i++) {
427 case 24: out32(GE9C,*(u16*)p | *(u8*)(p+2)<<16); 509 pd += ddsleft;
428 index+=3; 510 for (j = 0; j < skipleft; j++)
429 break; 511 out32(GE9C, *pd++);
512 }
430 } 513 }
431 } 514 }
432} 515}
@@ -443,7 +526,6 @@ static int cyblafb_check_var(struct fb_var_screeninfo *var,
443 struct fb_info *info) 526 struct fb_info *info)
444{ 527{
445 int bpp = var->bits_per_pixel; 528 int bpp = var->bits_per_pixel;
446 int s,t,maxvyres;
447 529
448 // 530 //
449 // we try to support 8, 16, 24 and 32 bpp modes, 531 // we try to support 8, 16, 24 and 32 bpp modes,
@@ -453,9 +535,9 @@ static int cyblafb_check_var(struct fb_var_screeninfo *var,
453 // (This is what tridentfb does ... will be changed in the future) 535 // (This is what tridentfb does ... will be changed in the future)
454 // 536 //
455 // 537 //
456 if ( bpp % 8 != 0 || bpp < 8 || bpp >32) 538 if (bpp % 8 != 0 || bpp < 8 || bpp > 32)
457 bpp = 8; 539 bpp = 8;
458 if (bpp == 24 ) 540 if (bpp == 24)
459 bpp = var->bits_per_pixel = 32; 541 bpp = var->bits_per_pixel = 32;
460 542
461 // 543 //
@@ -472,65 +554,93 @@ static int cyblafb_check_var(struct fb_var_screeninfo *var,
472 return -EINVAL; 554 return -EINVAL;
473 555
474 // 556 //
475 // xres != xres_virtual is broken, fail if such an 557 // we do not allow vclk to exceed 230 MHz. If the requested
476 // unusual mode is requested 558 // vclk is too high, we default to 200 MHz
477 // 559 //
478 if (var->xres != var->xres_virtual) 560 if ((bpp == 32 ? 200000000 : 100000000) / var->pixclock > 23000)
479 return -EINVAL; 561 var->pixclock = (bpp == 32 ? 200000000 : 100000000) / 20000;
480 562
481 // 563 //
482 // we do not allow vclk to exceed 230 MHz 564 // enforce (h|v)sync_len limits
483 // 565 //
484 if ((bpp==32 ? 200000000 : 100000000) / var->pixclock > 23000) 566 var->hsync_len &= ~7;
485 return -EINVAL; 567 if(var->hsync_len > 248)
568 var->hsync_len = 248;
569
570 var->vsync_len &= 15;
486 571
487 // 572 //
488 // calc max yres_virtual that would fit in memory 573 // Enforce horizontal and vertical hardware limits.
489 // and max yres_virtual that could be used for scrolling 574 // 1600x1200 is mentioned as a maximum, but higher resolutions could
490 // and use minimum of the results as maxvyres 575 // work with slow refresh, small margins and short sync.
491 //
492 // adjust vyres_virtual to maxvyres if necessary
493 // fail if requested yres is bigger than maxvyres
494 // 576 //
495 s = (0x1fffff / (var->xres * bpp/8)) + var->yres; 577 var->xres &= ~7;
496 t = info->fix.smem_len / (var->xres * bpp/8); 578
497 maxvyres = t < s ? t : s; 579 if (((var->xres + var->left_margin + var->right_margin +
498 if (maxvyres < var->yres_virtual) 580 var->hsync_len) > (bpp == 32 ? 2040 : 4088)) ||
499 var->yres_virtual=maxvyres; 581 ((var->yres + var->upper_margin + var->lower_margin +
500 if (maxvyres < var->yres) 582 var->vsync_len) > 2047))
501 return -EINVAL; 583 return -EINVAL;
502 584
503 switch (bpp) { 585 if ((var->xres > 1600) || (var->yres > 1200))
504 case 8: 586 output("Mode %dx%d exceeds documented limits.\n",
505 var->red.offset = 0; 587 var->xres, var->yres);
506 var->green.offset = 0; 588 //
507 var->blue.offset = 0; 589 // try to be smart about (x|y)res_virtual problems.
508 var->red.length = 6; 590 //
509 var->green.length = 6; 591 if (var->xres > var->xres_virtual)
510 var->blue.length = 6; 592 var->xres_virtual = var->xres;
511 break; 593 if (var->yres > var->yres_virtual)
512 case 16: 594 var->yres_virtual = var->yres;
513 var->red.offset = 11; 595
514 var->green.offset = 5; 596 if (bpp == 8 || bpp == 16) {
515 var->blue.offset = 0; 597 if (var->xres_virtual > 4088)
516 var->red.length = 5; 598 var->xres_virtual = 4088;
517 var->green.length = 6; 599 } else {
518 var->blue.length = 5; 600 if (var->xres_virtual > 2040)
519 break; 601 var->xres_virtual = 2040;
520 case 32: 602 }
521 var->red.offset = 16; 603 var->xres_virtual &= ~7;
522 var->green.offset = 8; 604 while (var->xres_virtual * var->yres_virtual * bpp / 8 >
523 var->blue.offset = 0; 605 info->fix.smem_len) {
524 var->red.length = 8; 606 if (var->yres_virtual > var->yres)
525 var->green.length = 8; 607 var->yres_virtual--;
526 var->blue.length = 8; 608 else if (var->xres_virtual > var->xres)
527 break; 609 var->xres_virtual -= 8;
528 default: 610 else
529 return -EINVAL; 611 return -EINVAL;
530 } 612 }
531 613
532 return 0; 614 switch (bpp) {
615 case 8:
616 var->red.offset = 0;
617 var->green.offset = 0;
618 var->blue.offset = 0;
619 var->red.length = 6;
620 var->green.length = 6;
621 var->blue.length = 6;
622 break;
623 case 16:
624 var->red.offset = 11;
625 var->green.offset = 5;
626 var->blue.offset = 0;
627 var->red.length = 5;
628 var->green.length = 6;
629 var->blue.length = 5;
630 break;
631 case 32:
632 var->red.offset = 16;
633 var->green.offset = 8;
634 var->blue.offset = 0;
635 var->red.length = 8;
636 var->green.length = 8;
637 var->blue.length = 8;
638 break;
639 default:
640 return -EINVAL;
641 }
533 642
643 return 0;
534} 644}
535 645
536//===================================================================== 646//=====================================================================
@@ -543,23 +653,25 @@ static int cyblafb_check_var(struct fb_var_screeninfo *var,
543// it, so it is also safe to be used here. BTW: datasheet CR0E on page 653// it, so it is also safe to be used here. BTW: datasheet CR0E on page
544// 90 really is CR1E, the real CRE is documented on page 72. 654// 90 really is CR1E, the real CRE is documented on page 72.
545// 655//
656// BUT:
657//
658// As of internal version 0.60 we do not use vga panning any longer.
659// Vga panning did not allow us the use of all available video memory
660// and thus prevented ywrap scrolling. We do use the "right view"
661// register now.
662//
663//
546//===================================================================== 664//=====================================================================
547 665
548static int cyblafb_pan_display(struct fb_var_screeninfo *var, 666static int cyblafb_pan_display(struct fb_var_screeninfo *var,
549 struct fb_info *info) 667 struct fb_info *info)
550{ 668{
551 unsigned int offset; 669 KD_GRAPHICS_RETURN(0);
552 670
553 offset=(var->xoffset+(var->yoffset*var->xres))*var->bits_per_pixel/32;
554 info->var.xoffset = var->xoffset; 671 info->var.xoffset = var->xoffset;
555 info->var.yoffset = var->yoffset; 672 info->var.yoffset = var->yoffset;
556 673 out32(GE10, 0x80000000 | ((var->xoffset + (var->yoffset *
557 write3X4(CR0D,offset & 0xFF); 674 var->xres_virtual)) * var->bits_per_pixel / 32));
558 write3X4(CR0C,(offset & 0xFF00) >> 8);
559 write3X4(CR1E,(read3X4(CR1E) & 0xDF) | ((offset & 0x10000) >> 11));
560 write3X4(CR27,(read3X4(CR27) & 0xF8) | ((offset & 0xE0000) >> 17));
561 write3X4(CR2B,(read3X4(CR2B) & 0xDF) | ((offset & 0x100000) >> 15));
562
563 return 0; 675 return 0;
564} 676}
565 677
@@ -578,56 +690,96 @@ static void regdump(struct cyblafb_par *par)
578 return; 690 return;
579 691
580 printk("\n"); 692 printk("\n");
581 for(i=0; i<=0xff; i++) { 693 for (i = 0; i <= 0xff; i++) {
582 outb(i,0x3d4); 694 outb(i, 0x3d4);
583 printk("CR%02x=%02x ",i,inb(0x3d5)); 695 printk("CR%02x=%02x ", i, inb(0x3d5));
584 if (i%16==15) 696 if (i % 16 == 15)
585 printk("\n"); 697 printk("\n");
586 } 698 }
587 699
588 outb(0x30,0x3ce); 700 outb(0x30, 0x3ce);
589 outb(inb(0x3cf) | 0x40,0x3cf); 701 outb(inb(0x3cf) | 0x40, 0x3cf);
590 for(i=0; i<=0x1f; i++) { 702 for (i = 0; i <= 0x1f; i++) {
591 if (i==0 || (i>2 && i<8) || i==0x10 || i==0x11 || i==0x16) { 703 if (i == 0 || (i > 2 && i < 8) || i == 0x10 || i == 0x11
592 outb(i,0x3d4); 704 || i == 0x16) {
593 printk("CR%02x=%02x ",i,inb(0x3d5)); 705 outb(i, 0x3d4);
706 printk("CR%02x=%02x ", i, inb(0x3d5));
594 } else 707 } else
595 printk("------- "); 708 printk("------- ");
596 if (i%16==15) 709 if (i % 16 == 15)
597 printk("\n"); 710 printk("\n");
598 } 711 }
599 outb(0x30,0x3ce); 712 outb(0x30, 0x3ce);
600 outb(inb(0x3cf) & 0xbf,0x3cf); 713 outb(inb(0x3cf) & 0xbf, 0x3cf);
601 714
602 printk("\n"); 715 printk("\n");
603 for(i=0; i<=0x7f; i++) { 716 for (i = 0; i <= 0x7f; i++) {
604 outb(i,0x3ce); 717 outb(i, 0x3ce);
605 printk("GR%02x=%02x ",i,inb(0x3cf)); 718 printk("GR%02x=%02x ", i, inb(0x3cf));
606 if (i%16==15) 719 if (i % 16 == 15)
607 printk("\n"); 720 printk("\n");
608 } 721 }
609 722
610 printk("\n"); 723 printk("\n");
611 for(i=0; i<=0xff; i++) { 724 for (i = 0; i <= 0xff; i++) {
612 outb(i,0x3c4); 725 outb(i, 0x3c4);
613 printk("SR%02x=%02x ",i,inb(0x3c5)); 726 printk("SR%02x=%02x ", i, inb(0x3c5));
614 if (i%16==15) 727 if (i % 16 == 15)
615 printk("\n"); 728 printk("\n");
616 } 729 }
617 730
618 printk("\n"); 731 printk("\n");
619 for(i=0; i <= 0x1F; i++) { 732 for (i = 0; i <= 0x1F; i++) {
620 inb(0x3da); // next access is index! 733 inb(0x3da); // next access is index!
621 outb(i,0x3c0); 734 outb(i, 0x3c0);
622 printk("AR%02x=%02x ",i,inb(0x3c1)); 735 printk("AR%02x=%02x ", i, inb(0x3c1));
623 if (i%16==15) 736 if (i % 16 == 15)
624 printk("\n"); 737 printk("\n");
625 } 738 }
626 printk("\n"); 739 printk("\n");
627 740
628 inb(0x3DA); // reset internal flag to 3c0 index 741 inb(0x3DA); // reset internal flag to 3c0 index
629 outb(0x20,0x3C0); // enable attr 742 outb(0x20, 0x3C0); // enable attr
743
744 return;
745}
746
747//=======================================================================
748//
749// Save State
750//
751// This function is called while a switch to KD_TEXT is in progress,
752// before any of the other functions are called.
753//
754//=======================================================================
630 755
756static void cyblafb_save_state(struct fb_info *info)
757{
758 struct cyblafb_par *par = info->par;
759 if (verbosity > 0)
760 output("Switching to KD_TEXT\n");
761 disabled = 0;
762 regdump(par);
763 enable_mmio();
764 return;
765}
766
767//=======================================================================
768//
769// Restore State
770//
771// This function is called while a switch to KD_GRAPHICS is in progress,
772// We have to turn on vga style panning registers again because the
773// trident driver of X does not know about GE10.
774//
775//=======================================================================
776
777static void cyblafb_restore_state(struct fb_info *info)
778{
779 if (verbosity > 0)
780 output("Switching to KD_GRAPHICS\n");
781 out32(GE10, 0);
782 disabled = 1;
631 return; 783 return;
632} 784}
633 785
@@ -640,32 +792,34 @@ static void regdump(struct cyblafb_par *par)
640static int cyblafb_set_par(struct fb_info *info) 792static int cyblafb_set_par(struct fb_info *info)
641{ 793{
642 struct cyblafb_par *par = info->par; 794 struct cyblafb_par *par = info->par;
643 u32 795 u32 htotal, hdispend, hsyncstart, hsyncend, hblankstart,
644 htotal,hdispend,hsyncstart,hsyncend,hblankstart,hblankend,preendfetch, 796 hblankend, preendfetch, vtotal, vdispend, vsyncstart,
645 vtotal,vdispend,vsyncstart,vsyncend,vblankstart,vblankend; 797 vsyncend, vblankstart, vblankend;
646 struct fb_var_screeninfo *var = &info->var; 798 struct fb_var_screeninfo *var = &info->var;
647 int bpp = var->bits_per_pixel; 799 int bpp = var->bits_per_pixel;
648 int i; 800 int i;
649 801
802 KD_GRAPHICS_RETURN(0);
803
650 if (verbosity > 0) 804 if (verbosity > 0)
651 output("Switching to new mode: " 805 output("Switching to new mode: "
652 "fbset -g %d %d %d %d %d -t %d %d %d %d %d %d %d\n", 806 "fbset -g %d %d %d %d %d -t %d %d %d %d %d %d %d\n",
653 var->xres,var->yres,var->xres_virtual, 807 var->xres, var->yres, var->xres_virtual,
654 var->yres_virtual,var->bits_per_pixel,var->pixclock, 808 var->yres_virtual, var->bits_per_pixel, var->pixclock,
655 var->left_margin,var->right_margin,var->upper_margin, 809 var->left_margin, var->right_margin, var->upper_margin,
656 var->lower_margin,var->hsync_len,var->vsync_len); 810 var->lower_margin, var->hsync_len, var->vsync_len);
657 811
658 htotal = (var->xres + var->left_margin + var->right_margin + 812 htotal = (var->xres + var->left_margin + var->right_margin +
659 var->hsync_len) / 8 - 5; 813 var->hsync_len) / 8 - 5;
660 hdispend = var->xres/8 - 1; 814 hdispend = var->xres / 8 - 1;
661 hsyncstart = (var->xres + var->right_margin)/8; 815 hsyncstart = (var->xres + var->right_margin) / 8;
662 hsyncend = var->hsync_len/8; 816 hsyncend = var->hsync_len / 8;
663 hblankstart = hdispend + 1; 817 hblankstart = hdispend + 1;
664 hblankend = htotal + 3; // should be htotal + 5, bios does it this way 818 hblankend = htotal + 3; // should be htotal + 5, bios does it this way
665 preendfetch = ((var->xres >> 3) + 1) * ((bpp+1) >> 3); 819 preendfetch = ((var->xres >> 3) + 1) * ((bpp + 1) >> 3);
666 820
667 vtotal = var->yres + var->upper_margin + var->lower_margin + 821 vtotal = var->yres + var->upper_margin + var->lower_margin +
668 var->vsync_len - 2; 822 var->vsync_len - 2;
669 vdispend = var->yres - 1; 823 vdispend = var->yres - 1;
670 vsyncstart = var->yres + var->lower_margin; 824 vsyncstart = var->yres + var->lower_margin;
671 vblankstart = var->yres; 825 vblankstart = var->yres;
@@ -674,101 +828,99 @@ static int cyblafb_set_par(struct fb_info *info)
674 828
675 enable_mmio(); // necessary! ... check X ... 829 enable_mmio(); // necessary! ... check X ...
676 830
677 write3X4(CR11,read3X4(CR11) & 0x7F); // unlock cr00 .. cr07 831 write3X4(CR11, read3X4(CR11) & 0x7F); // unlock cr00 .. cr07
678 832
679 write3CE(GR30,8); 833 write3CE(GR30, 8);
680 834
681 if ((displaytype == DISPLAY_FP) && var->xres < nativex) { 835 if ((displaytype == DISPLAY_FP) && var->xres < nativex) {
682 836
683 // stretch or center ? 837 // stretch or center ?
684 838
685 out8(0x3C2,0xEB); 839 out8(0x3C2, 0xEB);
686 840
687 write3CE(GR30,read3CE(GR30) | 0x81); // shadow mode on 841 write3CE(GR30, read3CE(GR30) | 0x81); // shadow mode on
688 842
689 if (center) { 843 if (center) {
690 write3CE(GR52,(read3CE(GR52) & 0x7C) | 0x80); 844 write3CE(GR52, (read3CE(GR52) & 0x7C) | 0x80);
691 write3CE(GR53,(read3CE(GR53) & 0x7C) | 0x80); 845 write3CE(GR53, (read3CE(GR53) & 0x7C) | 0x80);
692 } 846 } else if (stretch) {
693 else if (stretch) { 847 write3CE(GR5D, 0);
694 write3CE(GR5D,0); 848 write3CE(GR52, (read3CE(GR52) & 0x7C) | 1);
695 write3CE(GR52,(read3CE(GR52) & 0x7C) | 1); 849 write3CE(GR53, (read3CE(GR53) & 0x7C) | 1);
696 write3CE(GR53,(read3CE(GR53) & 0x7C) | 1);
697 } 850 }
698 851
699 } else { 852 } else {
700 out8(0x3C2,0x2B); 853 out8(0x3C2, 0x2B);
701 write3CE(GR30,8); 854 write3CE(GR30, 8);
702 } 855 }
703 856
704 // 857 //
705 // Setup CRxx regs 858 // Setup CRxx regs
706 // 859 //
707 860
708 write3X4(CR00,htotal & 0xFF); 861 write3X4(CR00, htotal & 0xFF);
709 write3X4(CR01,hdispend & 0xFF); 862 write3X4(CR01, hdispend & 0xFF);
710 write3X4(CR02,hblankstart & 0xFF); 863 write3X4(CR02, hblankstart & 0xFF);
711 write3X4(CR03,hblankend & 0x1F); 864 write3X4(CR03, hblankend & 0x1F);
712 write3X4(CR04,hsyncstart & 0xFF); 865 write3X4(CR04, hsyncstart & 0xFF);
713 write3X4(CR05,(hsyncend & 0x1F) | ((hblankend & 0x20)<<2)); 866 write3X4(CR05, (hsyncend & 0x1F) | ((hblankend & 0x20) << 2));
714 write3X4(CR06,vtotal & 0xFF); 867 write3X4(CR06, vtotal & 0xFF);
715 write3X4(CR07,(vtotal & 0x100) >> 8 | 868 write3X4(CR07, (vtotal & 0x100) >> 8 |
716 (vdispend & 0x100) >> 7 | 869 (vdispend & 0x100) >> 7 |
717 (vsyncstart & 0x100) >> 6 | 870 (vsyncstart & 0x100) >> 6 |
718 (vblankstart & 0x100) >> 5 | 871 (vblankstart & 0x100) >> 5 |
719 0x10 | 872 0x10 |
720 (vtotal & 0x200) >> 4 | 873 (vtotal & 0x200) >> 4 |
721 (vdispend & 0x200) >> 3 | 874 (vdispend & 0x200) >> 3 | (vsyncstart & 0x200) >> 2);
722 (vsyncstart & 0x200) >> 2); 875 write3X4(CR08, 0);
723 write3X4(CR08,0); 876 write3X4(CR09, (vblankstart & 0x200) >> 4 | 0x40 | // FIX !!!
724 write3X4(CR09,(vblankstart & 0x200) >> 4 | 0x40 | // FIX !!! 877 ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0));
725 ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0)); 878 write3X4(CR0A, 0); // Init to some reasonable default
726 write3X4(CR0A,0); // Init to some reasonable default 879 write3X4(CR0B, 0); // Init to some reasonable default
727 write3X4(CR0B,0); // Init to some reasonable default 880 write3X4(CR0C, 0); // Offset 0
728 write3X4(CR0C,0); // Offset 0 881 write3X4(CR0D, 0); // Offset 0
729 write3X4(CR0D,0); // Offset 0 882 write3X4(CR0E, 0); // Init to some reasonable default
730 write3X4(CR0E,0); // Init to some reasonable default 883 write3X4(CR0F, 0); // Init to some reasonable default
731 write3X4(CR0F,0); // Init to some reasonable default 884 write3X4(CR10, vsyncstart & 0xFF);
732 write3X4(CR10,vsyncstart & 0xFF); 885 write3X4(CR11, (vsyncend & 0x0F));
733 write3X4(CR11,(vsyncend & 0x0F)); 886 write3X4(CR12, vdispend & 0xFF);
734 write3X4(CR12,vdispend & 0xFF); 887 write3X4(CR13, ((info->var.xres_virtual * bpp) / (4 * 16)) & 0xFF);
735 write3X4(CR13,((info->var.xres * bpp)/(4*16)) & 0xFF); 888 write3X4(CR14, 0x40); // double word mode
736 write3X4(CR14,0x40); // double word mode 889 write3X4(CR15, vblankstart & 0xFF);
737 write3X4(CR15,vblankstart & 0xFF); 890 write3X4(CR16, vblankend & 0xFF);
738 write3X4(CR16,vblankend & 0xFF); 891 write3X4(CR17, 0xE3);
739 write3X4(CR17,0xC3); 892 write3X4(CR18, 0xFF);
740 write3X4(CR18,0xFF);
741 // CR19: needed for interlaced modes ... ignore it for now 893 // CR19: needed for interlaced modes ... ignore it for now
742 write3X4(CR1A,0x07); // Arbitration Control Counter 1 894 write3X4(CR1A, 0x07); // Arbitration Control Counter 1
743 write3X4(CR1B,0x07); // Arbitration Control Counter 2 895 write3X4(CR1B, 0x07); // Arbitration Control Counter 2
744 write3X4(CR1C,0x07); // Arbitration Control Counter 3 896 write3X4(CR1C, 0x07); // Arbitration Control Counter 3
745 write3X4(CR1D,0x00); // Don't know, doesn't hurt ;-) 897 write3X4(CR1D, 0x00); // Don't know, doesn't hurt ; -)
746 write3X4(CR1E,(info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80); 898 write3X4(CR1E, (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80);
747 // CR1F: do not set, contains BIOS info about memsize 899 // CR1F: do not set, contains BIOS info about memsize
748 write3X4(CR20,0x20); // enabe wr buf, disable 16bit planar mode 900 write3X4(CR20, 0x20); // enabe wr buf, disable 16bit planar mode
749 write3X4(CR21,0x20); // enable linear memory access 901 write3X4(CR21, 0x20); // enable linear memory access
750 // CR22: RO cpu latch readback 902 // CR22: RO cpu latch readback
751 // CR23: ??? 903 // CR23: ???
752 // CR24: RO AR flag state 904 // CR24: RO AR flag state
753 // CR25: RAMDAC rw timing, pclk buffer tristate control ???? 905 // CR25: RAMDAC rw timing, pclk buffer tristate control ????
754 // CR26: ??? 906 // CR26: ???
755 write3X4(CR27,(vdispend & 0x400) >> 6 | 907 write3X4(CR27, (vdispend & 0x400) >> 6 |
756 (vsyncstart & 0x400) >> 5 | 908 (vsyncstart & 0x400) >> 5 |
757 (vblankstart & 0x400) >> 4 | 909 (vblankstart & 0x400) >> 4 |
758 (vtotal & 0x400) >> 3 | 910 (vtotal & 0x400) >> 3 |
759 0x8); 911 0x8);
760 // CR28: ??? 912 // CR28: ???
761 write3X4(CR29,(read3X4(CR29) & 0xCF) | 913 write3X4(CR29, (read3X4(CR29) & 0xCF) | ((((info->var.xres_virtual *
762 ((((info->var.xres * bpp) / (4*16)) & 0x300) >>4)); 914 bpp) / (4 * 16)) & 0x300) >> 4));
763 write3X4(CR2A,read3X4(CR2A) | 0x40); 915 write3X4(CR2A, read3X4(CR2A) | 0x40);
764 write3X4(CR2B,(htotal & 0x100) >> 8 | 916 write3X4(CR2B, (htotal & 0x100) >> 8 |
765 (hdispend & 0x100) >> 7 | 917 (hdispend & 0x100) >> 7 |
766 // (0x00 & 0x100) >> 6 | hinterlace para bit 8 ??? 918 // (0x00 & 0x100) >> 6 | hinterlace para bit 8 ???
767 (hsyncstart & 0x100) >> 5 | 919 (hsyncstart & 0x100) >> 5 |
768 (hblankstart & 0x100) >> 4); 920 (hblankstart & 0x100) >> 4);
769 // CR2C: ??? 921 // CR2C: ???
770 // CR2D: initialized in cyblafb_setup_GE() 922 // CR2D: initialized in cyblafb_setup_GE()
771 write3X4(CR2F,0x92); // conservative, better signal quality 923 write3X4(CR2F, 0x92); // conservative, better signal quality
772 // CR30: reserved 924 // CR30: reserved
773 // CR31: reserved 925 // CR31: reserved
774 // CR32: reserved 926 // CR32: reserved
@@ -777,96 +929,116 @@ static int cyblafb_set_par(struct fb_info *info)
777 // CR35: disabled in CR36 929 // CR35: disabled in CR36
778 // CR36: initialized in cyblafb_setup_GE 930 // CR36: initialized in cyblafb_setup_GE
779 // CR37: i2c, ignore for now 931 // CR37: i2c, ignore for now
780 write3X4(CR38,(bpp == 8) ? 0x00 : // 932 write3X4(CR38, (bpp == 8) ? 0x00 : //
781 (bpp == 16) ? 0x05 : // highcolor 933 (bpp == 16) ? 0x05 : // highcolor
782 (bpp == 24) ? 0x29 : // packed 24bit truecolor 934 (bpp == 24) ? 0x29 : // packed 24bit truecolor
783 (bpp == 32) ? 0x09 : 0); // truecolor, 16 bit pixelbus 935 (bpp == 32) ? 0x09 : 0); // truecolor, 16 bit pixelbus
784 write3X4(CR39,0x01 | // MMIO enable 936 write3X4(CR39, 0x01 | // MMIO enable
785 (pcirb ? 0x02 : 0) | // pci read burst enable 937 (pcirb ? 0x02 : 0) | // pci read burst enable
786 (pciwb ? 0x04 : 0)); // pci write burst enable 938 (pciwb ? 0x04 : 0)); // pci write burst enable
787 write3X4(CR55,0x1F | // pci clocks * 2 for STOP# during 1st data phase 939 write3X4(CR55, 0x1F | // pci clocks * 2 for STOP# during 1st data phase
788 (pcirr ? 0x40 : 0) | // pci read retry enable 940 (pcirr ? 0x40 : 0) | // pci read retry enable
789 (pciwr ? 0x80 : 0)); // pci write retry enable 941 (pciwr ? 0x80 : 0)); // pci write retry enable
790 write3X4(CR56,preendfetch >> 8 < 2 ? (preendfetch >> 8 & 0x01)|2 : 0); 942 write3X4(CR56, preendfetch >> 8 < 2 ? (preendfetch >> 8 & 0x01) | 2
791 write3X4(CR57,preendfetch >> 8 < 2 ? preendfetch & 0xff : 0); 943 : 0);
792 write3X4(CR58,0x82); // Bios does this .... don't know more 944 write3X4(CR57, preendfetch >> 8 < 2 ? preendfetch & 0xff : 0);
945 write3X4(CR58, 0x82); // Bios does this .... don't know more
793 // 946 //
794 // Setup SRxx regs 947 // Setup SRxx regs
795 // 948 //
796 write3C4(SR00,3); 949 write3C4(SR00, 3);
797 write3C4(SR01,1); //set char clock 8 dots wide 950 write3C4(SR01, 1); //set char clock 8 dots wide
798 write3C4(SR02,0x0F); //enable 4 maps needed in chain4 mode 951 write3C4(SR02, 0x0F); //enable 4 maps needed in chain4 mode
799 write3C4(SR03,0); //no character map select 952 write3C4(SR03, 0); //no character map select
800 write3C4(SR04,0x0E); //memory mode: ext mem, even, chain4 953 write3C4(SR04, 0x0E); //memory mode: ext mem, even, chain4
801 954
802 out8(0x3C4,0x0b); 955 out8(0x3C4, 0x0b);
803 in8(0x3C5); // Set NEW mode 956 in8(0x3C5); // Set NEW mode
804 write3C4(SR0D,0x00); // test ... check 957 write3C4(SR0D, 0x00); // test ... check
805 958
806 set_vclk(par,(bpp==32 ? 200000000 : 100000000)/ 959 set_vclk(par, (bpp == 32 ? 200000000 : 100000000)
807 info->var.pixclock); //SR18,SR19 960 / info->var.pixclock); //SR18, SR19
808 961
809 // 962 //
810 // Setup GRxx regs 963 // Setup GRxx regs
811 // 964 //
812 write3CE(GR00,0x00); // test ... check 965 write3CE(GR00, 0x00); // test ... check
813 write3CE(GR01,0x00); // test ... check 966 write3CE(GR01, 0x00); // test ... check
814 write3CE(GR02,0x00); // test ... check 967 write3CE(GR02, 0x00); // test ... check
815 write3CE(GR03,0x00); // test ... check 968 write3CE(GR03, 0x00); // test ... check
816 write3CE(GR04,0x00); // test ... check 969 write3CE(GR04, 0x00); // test ... check
817 write3CE(GR05,0x40); // no CGA compat,allow 256 col 970 write3CE(GR05, 0x40); // no CGA compat, allow 256 col
818 write3CE(GR06,0x05); // graphics mode 971 write3CE(GR06, 0x05); // graphics mode
819 write3CE(GR07,0x0F); // planes? 972 write3CE(GR07, 0x0F); // planes?
820 write3CE(GR08,0xFF); // test ... check 973 write3CE(GR08, 0xFF); // test ... check
821 write3CE(GR0F,(bpp==32)?0x1A:0x12); // div vclk by 2 if 32bpp, chain4 974 write3CE(GR0F, (bpp == 32) ? 0x1A : 0x12); // vclk / 2 if 32bpp, chain4
822 write3CE(GR20,0xC0); // test ... check 975 write3CE(GR20, 0xC0); // test ... check
823 write3CE(GR2F,0xA0); // PCLK = VCLK, no skew, 976 write3CE(GR2F, 0xA0); // PCLK = VCLK, no skew,
824 977
825 // 978 //
826 // Setup ARxx regs 979 // Setup ARxx regs
827 // 980 //
828 for(i = 0;i < 0x10;i++) // set AR00 .. AR0f 981 for (i = 0; i < 0x10; i++) // set AR00 .. AR0f
829 write3C0(i,i); 982 write3C0(i, i);
830 write3C0(AR10,0x41); // graphics mode and support 256 color modes 983 write3C0(AR10, 0x41); // graphics mode and support 256 color modes
831 write3C0(AR12,0x0F); // planes 984 write3C0(AR12, 0x0F); // planes
832 write3C0(AR13,0); // horizontal pel panning 985 write3C0(AR13, 0); // horizontal pel panning
833 in8(0x3DA); // reset internal flag to 3c0 index 986 in8(0x3DA); // reset internal flag to 3c0 index
834 out8(0x3C0,0x20); // enable attr 987 out8(0x3C0, 0x20); // enable attr
835 988
836 // 989 //
837 // Setup hidden RAMDAC command register 990 // Setup hidden RAMDAC command register
838 // 991 //
839 in8(0x3C8); // these reads are 992 in8(0x3C8); // these reads are
840 in8(0x3C6); // necessary to 993 in8(0x3C6); // necessary to
841 in8(0x3C6); // unmask the RAMDAC 994 in8(0x3C6); // unmask the RAMDAC
842 in8(0x3C6); // command reg, otherwise 995 in8(0x3C6); // command reg, otherwise
843 in8(0x3C6); // we would write the pixelmask reg! 996 in8(0x3C6); // we would write the pixelmask reg!
844 out8(0x3C6,(bpp == 8) ? 0x00 : // 256 colors 997 out8(0x3C6, (bpp == 8) ? 0x00 : // 256 colors
845 (bpp == 15) ? 0x10 : // 998 (bpp == 15) ? 0x10 : //
846 (bpp == 16) ? 0x30 : // hicolor 999 (bpp == 16) ? 0x30 : // hicolor
847 (bpp == 24) ? 0xD0 : // truecolor 1000 (bpp == 24) ? 0xD0 : // truecolor
848 (bpp == 32) ? 0xD0 : 0); // truecolor 1001 (bpp == 32) ? 0xD0 : 0); // truecolor
849 in8(0x3C8); 1002 in8(0x3C8);
850 1003
851 // 1004 //
852 // GR31 is not mentioned in the datasheet 1005 // GR31 is not mentioned in the datasheet
853 // 1006 //
854 if (displaytype == DISPLAY_FP) 1007 if (displaytype == DISPLAY_FP)
855 write3CE(GR31,(read3CE(GR31) & 0x8F) | 1008 write3CE(GR31, (read3CE(GR31) & 0x8F) |
856 ((info->var.yres > 1024) ? 0x50 : 1009 ((info->var.yres > 1024) ? 0x50 :
857 (info->var.yres > 768) ? 0x30 : 1010 (info->var.yres > 768) ? 0x30 :
858 (info->var.yres > 600) ? 0x20 : 1011 (info->var.yres > 600) ? 0x20 :
859 (info->var.yres > 480) ? 0x10 : 0)); 1012 (info->var.yres > 480) ? 0x10 : 0));
860 1013
861 info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR 1014 info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR
862 : FB_VISUAL_TRUECOLOR; 1015 : FB_VISUAL_TRUECOLOR;
863 info->fix.line_length = info->var.xres * (bpp >> 3); 1016 info->fix.line_length = info->var.xres_virtual * (bpp >> 3);
864 info->cmap.len = (bpp == 8) ? 256: 16; 1017 info->cmap.len = (bpp == 8) ? 256 : 16;
865 1018
866 // 1019 //
867 // init acceleration engine 1020 // init acceleration engine
868 // 1021 //
869 cyblafb_setup_GE(info->var.xres,info->var.bits_per_pixel); 1022 cyblafb_setup_GE(info->var.xres_virtual, info->var.bits_per_pixel);
1023
1024 //
1025 // Set/clear flags to allow proper scroll mode selection.
1026 //
1027 if (var->xres == var->xres_virtual)
1028 info->flags &= ~FBINFO_HWACCEL_XPAN;
1029 else
1030 info->flags |= FBINFO_HWACCEL_XPAN;
1031
1032 if (var->yres == var->yres_virtual)
1033 info->flags &= ~FBINFO_HWACCEL_YPAN;
1034 else
1035 info->flags |= FBINFO_HWACCEL_YPAN;
1036
1037 if (info->fix.smem_len !=
1038 var->xres_virtual * var->yres_virtual * bpp / 8)
1039 info->flags &= ~FBINFO_HWACCEL_YWRAP;
1040 else
1041 info->flags |= FBINFO_HWACCEL_YWRAP;
870 1042
871 regdump(par); 1043 regdump(par);
872 1044
@@ -885,27 +1057,27 @@ static int cyblafb_setcolreg(unsigned regno, unsigned red, unsigned green,
885{ 1057{
886 int bpp = info->var.bits_per_pixel; 1058 int bpp = info->var.bits_per_pixel;
887 1059
1060 KD_GRAPHICS_RETURN(0);
1061
888 if (regno >= info->cmap.len) 1062 if (regno >= info->cmap.len)
889 return 1; 1063 return 1;
890 1064
891 if (bpp == 8) { 1065 if (bpp == 8) {
892 out8(0x3C6,0xFF); 1066 out8(0x3C6, 0xFF);
893 out8(0x3C8,regno); 1067 out8(0x3C8, regno);
894 out8(0x3C9,red>>10); 1068 out8(0x3C9, red >> 10);
895 out8(0x3C9,green>>10); 1069 out8(0x3C9, green >> 10);
896 out8(0x3C9,blue>>10); 1070 out8(0x3C9, blue >> 10);
897 1071
898 } else if (bpp == 16) // RGB 565 1072 } else if (bpp == 16) // RGB 565
899 ((u32*)info->pseudo_palette)[regno] = 1073 ((u32 *) info->pseudo_palette)[regno] =
900 (red & 0xF800) | 1074 (red & 0xF800) |
901 ((green & 0xFC00) >> 5) | 1075 ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11);
902 ((blue & 0xF800) >> 11); 1076 else if (bpp == 32) // ARGB 8888
903 else if (bpp == 32) // ARGB 8888 1077 ((u32 *) info->pseudo_palette)[regno] =
904 ((u32*)info->pseudo_palette)[regno] = 1078 ((transp & 0xFF00) << 16) |
905 ((transp & 0xFF00) <<16) | 1079 ((red & 0xFF00) << 8) |
906 ((red & 0xFF00) << 8) | 1080 ((green & 0xFF00)) | ((blue & 0xFF00) >> 8);
907 ((green & 0xFF00)) |
908 ((blue & 0xFF00)>>8);
909 1081
910 return 0; 1082 return 0;
911} 1083}
@@ -918,40 +1090,41 @@ static int cyblafb_setcolreg(unsigned regno, unsigned red, unsigned green,
918 1090
919static int cyblafb_blank(int blank_mode, struct fb_info *info) 1091static int cyblafb_blank(int blank_mode, struct fb_info *info)
920{ 1092{
921 unsigned char PMCont,DPMSCont; 1093 unsigned char PMCont, DPMSCont;
1094
1095 KD_GRAPHICS_RETURN(0);
922 1096
923 if (displaytype == DISPLAY_FP) 1097 if (displaytype == DISPLAY_FP)
924 return 0; 1098 return 0;
925 1099
926 out8(0x83C8,0x04); // DPMS Control 1100 out8(0x83C8, 0x04); // DPMS Control
927 PMCont = in8(0x83C6) & 0xFC; 1101 PMCont = in8(0x83C6) & 0xFC;
928 1102
929 DPMSCont = read3CE(GR23) & 0xFC; 1103 DPMSCont = read3CE(GR23) & 0xFC;
930 1104
931 switch (blank_mode) 1105 switch (blank_mode) {
932 { 1106 case FB_BLANK_UNBLANK: // Screen: On, HSync: On, VSync: On
933 case FB_BLANK_UNBLANK: // Screen: On, HSync: On, VSync: On 1107 case FB_BLANK_NORMAL: // Screen: Off, HSync: On, VSync: On
934 case FB_BLANK_NORMAL: // Screen: Off, HSync: On, VSync: On
935 PMCont |= 0x03; 1108 PMCont |= 0x03;
936 DPMSCont |= 0x00; 1109 DPMSCont |= 0x00;
937 break; 1110 break;
938 case FB_BLANK_HSYNC_SUSPEND: // Screen: Off, HSync: Off, VSync: On 1111 case FB_BLANK_HSYNC_SUSPEND: // Screen: Off, HSync: Off, VSync: On
939 PMCont |= 0x02; 1112 PMCont |= 0x02;
940 DPMSCont |= 0x01; 1113 DPMSCont |= 0x01;
941 break; 1114 break;
942 case FB_BLANK_VSYNC_SUSPEND: // Screen: Off, HSync: On, VSync: Off 1115 case FB_BLANK_VSYNC_SUSPEND: // Screen: Off, HSync: On, VSync: Off
943 PMCont |= 0x02; 1116 PMCont |= 0x02;
944 DPMSCont |= 0x02; 1117 DPMSCont |= 0x02;
945 break; 1118 break;
946 case FB_BLANK_POWERDOWN: // Screen: Off, HSync: Off, VSync: Off 1119 case FB_BLANK_POWERDOWN: // Screen: Off, HSync: Off, VSync: Off
947 PMCont |= 0x00; 1120 PMCont |= 0x00;
948 DPMSCont |= 0x03; 1121 DPMSCont |= 0x03;
949 break; 1122 break;
950 } 1123 }
951 1124
952 write3CE(GR23,DPMSCont); 1125 write3CE(GR23, DPMSCont);
953 out8(0x83C8,4); 1126 out8(0x83C8, 4);
954 out8(0x83C6,PMCont); 1127 out8(0x83C6, PMCont);
955 // 1128 //
956 // let fbcon do a softblank for us 1129 // let fbcon do a softblank for us
957 // 1130 //
@@ -959,15 +1132,18 @@ static int cyblafb_blank(int blank_mode, struct fb_info *info)
959} 1132}
960 1133
961static struct fb_ops cyblafb_ops __devinitdata = { 1134static struct fb_ops cyblafb_ops __devinitdata = {
962 .owner = THIS_MODULE, 1135 .owner = THIS_MODULE,
963 .fb_setcolreg = cyblafb_setcolreg, 1136 .fb_setcolreg = cyblafb_setcolreg,
964 .fb_pan_display = cyblafb_pan_display, 1137 .fb_pan_display = cyblafb_pan_display,
965 .fb_blank = cyblafb_blank, 1138 .fb_blank = cyblafb_blank,
966 .fb_check_var = cyblafb_check_var, 1139 .fb_check_var = cyblafb_check_var,
967 .fb_set_par = cyblafb_set_par, 1140 .fb_set_par = cyblafb_set_par,
968 .fb_fillrect = cyblafb_fillrect, 1141 .fb_fillrect = cyblafb_fillrect,
969 .fb_copyarea= cyblafb_copyarea, 1142 .fb_copyarea = cyblafb_copyarea,
970 .fb_imageblit = cyblafb_imageblit, 1143 .fb_imageblit = cyblafb_imageblit,
1144 .fb_sync = cyblafb_sync,
1145 .fb_restore_state = cyblafb_restore_state,
1146 .fb_save_state = cyblafb_save_state,
971}; 1147};
972 1148
973//========================================================================== 1149//==========================================================================
@@ -986,74 +1162,89 @@ static struct fb_ops cyblafb_ops __devinitdata = {
986 1162
987static int __devinit getstartupmode(struct fb_info *info) 1163static int __devinit getstartupmode(struct fb_info *info)
988{ 1164{
989 u32 htotal,hdispend,hsyncstart,hsyncend,hblankstart,hblankend, 1165 u32 htotal, hdispend, hsyncstart, hsyncend, hblankstart, hblankend,
990 vtotal,vdispend,vsyncstart,vsyncend,vblankstart,vblankend, 1166 vtotal, vdispend, vsyncstart, vsyncend, vblankstart, vblankend,
991 cr00,cr01,cr02,cr03,cr04,cr05,cr2b, 1167 cr00, cr01, cr02, cr03, cr04, cr05, cr2b,
992 cr06,cr07,cr09,cr10,cr11,cr12,cr15,cr16,cr27, 1168 cr06, cr07, cr09, cr10, cr11, cr12, cr15, cr16, cr27,
993 cr38, 1169 cr38, sr0d, sr18, sr19, gr0f, fi, pxclkdiv, vclkdiv, tmp, i;
994 sr0d,sr18,sr19,
995 gr0f,
996 fi,pxclkdiv,vclkdiv,tmp,i;
997 1170
998 struct modus { 1171 struct modus {
999 int xres; int yres; int vyres; int bpp; int pxclk; 1172 int xres; int vxres; int yres; int vyres;
1000 int left_margin; int right_margin; int upper_margin; 1173 int bpp; int pxclk;
1001 int lower_margin; int hsync_len; int vsync_len; 1174 int left_margin; int right_margin;
1002 } modedb[5] = { 1175 int upper_margin; int lower_margin;
1003 { 0, 0, 8000, 0, 0, 0, 0, 0, 0, 0, 0}, 1176 int hsync_len; int vsync_len;
1004 { 640, 480, 3756, 0, 0, -40, 24, 17, 0, 216, 3}, 1177 } modedb[5] = {
1005 { 800, 600, 3221, 0, 0, 96, 24, 14, 0, 136, 11}, 1178 {
1006 {1024, 768, 2815, 0, 0, 144, 24, 29, 0, 120, 3}, 1179 0, 2048, 0, 4096, 0, 0, 0, 0, 0, 0, 0, 0}, {
1007 {1280, 1024, 2662, 0, 0, 232, 16, 39, 0, 160, 3} 1180 640, 2048, 480, 4096, 0, 0, -40, 24, 17, 0, 216, 3}, {
1181 800, 2048, 600, 4096, 0, 0, 96, 24, 14, 0, 136, 11}, {
1182 1024, 2048, 768, 4096, 0, 0, 144, 24, 29, 0, 120, 3}, {
1183 1280, 2048, 1024, 4096, 0, 0, 232, 16, 39, 0, 160, 3}
1008 }; 1184 };
1009 1185
1010 outb(0x00,0x3d4); cr00=inb(0x3d5); outb(0x01,0x3d4); cr01=inb(0x3d5); 1186 outb(0x00, 0x3d4); cr00 = inb(0x3d5);
1011 outb(0x02,0x3d4); cr02=inb(0x3d5); outb(0x03,0x3d4); cr03=inb(0x3d5); 1187 outb(0x01, 0x3d4); cr01 = inb(0x3d5);
1012 outb(0x04,0x3d4); cr04=inb(0x3d5); outb(0x05,0x3d4); cr05=inb(0x3d5); 1188 outb(0x02, 0x3d4); cr02 = inb(0x3d5);
1013 outb(0x06,0x3d4); cr06=inb(0x3d5); outb(0x07,0x3d4); cr07=inb(0x3d5); 1189 outb(0x03, 0x3d4); cr03 = inb(0x3d5);
1014 outb(0x09,0x3d4); cr09=inb(0x3d5); outb(0x10,0x3d4); cr10=inb(0x3d5); 1190 outb(0x04, 0x3d4); cr04 = inb(0x3d5);
1015 outb(0x11,0x3d4); cr11=inb(0x3d5); outb(0x12,0x3d4); cr12=inb(0x3d5); 1191 outb(0x05, 0x3d4); cr05 = inb(0x3d5);
1016 outb(0x15,0x3d4); cr15=inb(0x3d5); outb(0x16,0x3d4); cr16=inb(0x3d5); 1192 outb(0x06, 0x3d4); cr06 = inb(0x3d5);
1017 outb(0x27,0x3d4); cr27=inb(0x3d5); outb(0x2b,0x3d4); cr2b=inb(0x3d5); 1193 outb(0x07, 0x3d4); cr07 = inb(0x3d5);
1018 outb(0x38,0x3d4); cr38=inb(0x3d5); outb(0x0b,0x3c4); inb(0x3c5); 1194 outb(0x09, 0x3d4); cr09 = inb(0x3d5);
1019 outb(0x0d,0x3c4); sr0d=inb(0x3c5); outb(0x18,0x3c4); sr18=inb(0x3c5); 1195 outb(0x10, 0x3d4); cr10 = inb(0x3d5);
1020 outb(0x19,0x3c4); sr19=inb(0x3c5); outb(0x0f,0x3ce); gr0f=inb(0x3cf); 1196 outb(0x11, 0x3d4); cr11 = inb(0x3d5);
1021 1197 outb(0x12, 0x3d4); cr12 = inb(0x3d5);
1022 htotal = cr00 | (cr2b & 0x01) << 8; 1198 outb(0x15, 0x3d4); cr15 = inb(0x3d5);
1023 hdispend = cr01 | (cr2b & 0x02) << 7; 1199 outb(0x16, 0x3d4); cr16 = inb(0x3d5);
1200 outb(0x27, 0x3d4); cr27 = inb(0x3d5);
1201 outb(0x2b, 0x3d4); cr2b = inb(0x3d5);
1202 outb(0x38, 0x3d4); cr38 = inb(0x3d5);
1203
1204 outb(0x0b, 0x3c4);
1205 inb(0x3c5);
1206
1207 outb(0x0d, 0x3c4); sr0d = inb(0x3c5);
1208 outb(0x18, 0x3c4); sr18 = inb(0x3c5);
1209 outb(0x19, 0x3c4); sr19 = inb(0x3c5);
1210 outb(0x0f, 0x3ce); gr0f = inb(0x3cf);
1211
1212 htotal = cr00 | (cr2b & 0x01) << 8;
1213 hdispend = cr01 | (cr2b & 0x02) << 7;
1024 hblankstart = cr02 | (cr2b & 0x10) << 4; 1214 hblankstart = cr02 | (cr2b & 0x10) << 4;
1025 hblankend = (cr03 & 0x1f) | (cr05 & 0x80) >> 2; 1215 hblankend = (cr03 & 0x1f) | (cr05 & 0x80) >> 2;
1026 hsyncstart = cr04 | (cr2b & 0x08) << 5; 1216 hsyncstart = cr04 | (cr2b & 0x08) << 5;
1027 hsyncend = cr05 & 0x1f; 1217 hsyncend = cr05 & 0x1f;
1028 1218
1029 modedb[0].xres = hblankstart * 8; 1219 modedb[0].xres = hblankstart * 8;
1030 modedb[0].hsync_len = hsyncend * 8; 1220 modedb[0].hsync_len = hsyncend * 8;
1031 modedb[0].right_margin = hsyncstart * 8 - modedb[0].xres; 1221 modedb[0].right_margin = hsyncstart * 8 - modedb[0].xres;
1032 modedb[0].left_margin = (htotal + 5) * 8 - modedb[0].xres - 1222 modedb[0].left_margin = (htotal + 5) * 8 - modedb[0].xres -
1033 modedb[0].right_margin - modedb[0].hsync_len; 1223 modedb[0].right_margin - modedb[0].hsync_len;
1034 1224
1035 vtotal = cr06 | (cr07 & 0x01) << 8 | (cr07 & 0x20) << 4 1225 vtotal = cr06 | (cr07 & 0x01) << 8 | (cr07 & 0x20) << 4
1036 | (cr27 & 0x80) << 3; 1226 | (cr27 & 0x80) << 3;
1037 vdispend = cr12 | (cr07 & 0x02) << 7 | (cr07 & 0x40) << 3 1227 vdispend = cr12 | (cr07 & 0x02) << 7 | (cr07 & 0x40) << 3
1038 | (cr27 & 0x10) << 6; 1228 | (cr27 & 0x10) << 6;
1039 vsyncstart = cr10 | (cr07 & 0x04) << 6 | (cr07 & 0x80) << 2 1229 vsyncstart = cr10 | (cr07 & 0x04) << 6 | (cr07 & 0x80) << 2
1040 | (cr27 & 0x20) << 5; 1230 | (cr27 & 0x20) << 5;
1041 vsyncend = cr11 & 0x0f; 1231 vsyncend = cr11 & 0x0f;
1042 vblankstart = cr15 | (cr07 & 0x08) << 5 | (cr09 & 0x20) << 4 1232 vblankstart = cr15 | (cr07 & 0x08) << 5 | (cr09 & 0x20) << 4
1043 | (cr27 & 0x40) << 4; 1233 | (cr27 & 0x40) << 4;
1044 vblankend = cr16; 1234 vblankend = cr16;
1045 1235
1046 modedb[0].yres = vdispend + 1; 1236 modedb[0].yres = vdispend + 1;
1047 modedb[0].vsync_len = vsyncend; 1237 modedb[0].vsync_len = vsyncend;
1048 modedb[0].lower_margin = vsyncstart - modedb[0].yres; 1238 modedb[0].lower_margin = vsyncstart - modedb[0].yres;
1049 modedb[0].upper_margin = vtotal - modedb[0].yres - 1239 modedb[0].upper_margin = vtotal - modedb[0].yres -
1050 modedb[0].lower_margin - modedb[0].vsync_len + 2; 1240 modedb[0].lower_margin - modedb[0].vsync_len + 2;
1051 1241
1052 tmp = cr38 & 0x3c; 1242 tmp = cr38 & 0x3c;
1053 modedb[0].bpp = tmp == 0 ? 8 : tmp == 4 ? 16 : tmp == 28 ? 24 : 1243 modedb[0].bpp = tmp == 0 ? 8 : tmp == 4 ? 16 : tmp == 28 ? 24 :
1054 tmp == 8 ? 32 : 8; 1244 tmp == 8 ? 32 : 8;
1055 1245
1056 fi = ((5864727*(sr18+8))/(((sr19&0x3f)+2)*(1<<((sr19&0xc0)>>6))))>>12; 1246 fi = ((5864727 * (sr18 + 8)) /
1247 (((sr19 & 0x3f) + 2) * (1 << ((sr19 & 0xc0) >> 6)))) >> 12;
1057 pxclkdiv = ((gr0f & 0x08) >> 3 | (gr0f & 0x40) >> 5) + 1; 1248 pxclkdiv = ((gr0f & 0x08) >> 3 | (gr0f & 0x40) >> 5) + 1;
1058 tmp = sr0d & 0x06; 1249 tmp = sr0d & 0x06;
1059 vclkdiv = tmp == 0 ? 2 : tmp == 2 ? 4 : tmp == 4 ? 8 : 3; // * 2 ! 1250 vclkdiv = tmp == 0 ? 2 : tmp == 2 ? 4 : tmp == 4 ? 8 : 3; // * 2 !
@@ -1062,10 +1253,10 @@ static int __devinit getstartupmode(struct fb_info *info)
1062 if (verbosity > 0) 1253 if (verbosity > 0)
1063 output("detected startup mode: " 1254 output("detected startup mode: "
1064 "fbset -g %d %d %d ??? %d -t %d %d %d %d %d %d %d\n", 1255 "fbset -g %d %d %d ??? %d -t %d %d %d %d %d %d %d\n",
1065 modedb[0].xres,modedb[0].yres,modedb[0].xres, 1256 modedb[0].xres, modedb[0].yres, modedb[0].xres,
1066 modedb[0].bpp,modedb[0].pxclk,modedb[0].left_margin, 1257 modedb[0].bpp, modedb[0].pxclk, modedb[0].left_margin,
1067 modedb[0].right_margin,modedb[0].upper_margin, 1258 modedb[0].right_margin, modedb[0].upper_margin,
1068 modedb[0].lower_margin,modedb[0].hsync_len, 1259 modedb[0].lower_margin, modedb[0].hsync_len,
1069 modedb[0].vsync_len); 1260 modedb[0].vsync_len);
1070 1261
1071 // 1262 //
@@ -1073,36 +1264,39 @@ static int __devinit getstartupmode(struct fb_info *info)
1073 // do not want to do it in another way! 1264 // do not want to do it in another way!
1074 // 1265 //
1075 1266
1076 tryagain: 1267 tryagain:
1077 1268
1078 i = (mode == NULL) ? 0 : 1269 i = (mode == NULL) ? 0 :
1079 !strncmp(mode,"640x480",7) ? 1 : 1270 !strncmp(mode, "640x480", 7) ? 1 :
1080 !strncmp(mode,"800x600",7) ? 2 : 1271 !strncmp(mode, "800x600", 7) ? 2 :
1081 !strncmp(mode,"1024x768",8) ? 3 : 1272 !strncmp(mode, "1024x768", 8) ? 3 :
1082 !strncmp(mode,"1280x1024",9) ? 4 : 0; 1273 !strncmp(mode, "1280x1024", 9) ? 4 : 0;
1083 1274
1084 ref = (ref < 50) ? 50 : (ref > 85) ? 85 : ref; 1275 ref = (ref < 50) ? 50 : (ref > 85) ? 85 : ref;
1085 1276
1086 if(i==0) { 1277 if (i == 0) {
1087 info->var.pixclock = modedb[i].pxclk; 1278 info->var.pixclock = modedb[i].pxclk;
1088 info->var.bits_per_pixel = modedb[i].bpp; 1279 info->var.bits_per_pixel = modedb[i].bpp;
1089 } else { 1280 } else {
1090 info->var.pixclock = (100000000 / 1281 info->var.pixclock = (100000000 /
1091 ((modedb[i].left_margin + modedb[i].xres + 1282 ((modedb[i].left_margin +
1092 modedb[i].right_margin + modedb[i].hsync_len 1283 modedb[i].xres +
1093 ) * ( 1284 modedb[i].right_margin +
1094 modedb[i].upper_margin + modedb[i].yres + 1285 modedb[i].hsync_len) *
1095 modedb[i].lower_margin + modedb[i].vsync_len 1286 (modedb[i].upper_margin +
1096 ) * 1287 modedb[i].yres +
1097 ref / 10000 1288 modedb[i].lower_margin +
1098 )); 1289 modedb[i].vsync_len) * ref / 10000));
1099 info->var.bits_per_pixel = bpp; 1290 info->var.bits_per_pixel = bpp;
1100 } 1291 }
1101 1292
1102 info->var.left_margin = modedb[i].left_margin; 1293 info->var.left_margin = modedb[i].left_margin;
1103 info->var.right_margin = modedb[i].right_margin; 1294 info->var.right_margin = modedb[i].right_margin;
1104 info->var.xres = modedb[i].xres; 1295 info->var.xres = modedb[i].xres;
1105 info->var.xres_virtual = modedb[i].xres; 1296 if (!(modedb[i].yres == 1280 && modedb[i].bpp == 32))
1297 info->var.xres_virtual = modedb[i].vxres;
1298 else
1299 info->var.xres_virtual = modedb[i].xres;
1106 info->var.xoffset = 0; 1300 info->var.xoffset = 0;
1107 info->var.hsync_len = modedb[i].hsync_len; 1301 info->var.hsync_len = modedb[i].hsync_len;
1108 info->var.upper_margin = modedb[i].upper_margin; 1302 info->var.upper_margin = modedb[i].upper_margin;
@@ -1114,33 +1308,32 @@ static int __devinit getstartupmode(struct fb_info *info)
1114 info->var.sync = 0; 1308 info->var.sync = 0;
1115 info->var.vmode = FB_VMODE_NONINTERLACED; 1309 info->var.vmode = FB_VMODE_NONINTERLACED;
1116 1310
1117 if(cyblafb_check_var(&info->var,info)) { 1311 if (cyblafb_check_var(&info->var, info)) {
1118 // 640x480-8@75 should really never fail. One case would 1312 // 640x480 - 8@75 should really never fail. One case would
1119 // be fp == 1 and nativex < 640 ... give up then 1313 // be fp == 1 and nativex < 640 ... give up then
1120 if(i==1 && bpp == 8 && ref == 75){ 1314 if (i == 1 && bpp == 8 && ref == 75) {
1121 output("Can't find a valid mode :-(\n"); 1315 output("Can't find a valid mode :-(\n");
1122 return -EINVAL; 1316 return -EINVAL;
1123 } 1317 }
1124 // Our detected mode is unlikely to fail. If it does, 1318 // Our detected mode is unlikely to fail. If it does,
1125 // try 640x480-8@75 ... 1319 // try 640x480 - 8@75 ...
1126 if(i==0) { 1320 if (i == 0) {
1127 mode="640x480"; 1321 mode = "640x480";
1128 bpp=8; 1322 bpp = 8;
1129 ref=75; 1323 ref = 75;
1130 output("Detected mode failed check_var! " 1324 output("Detected mode failed check_var! "
1131 "Trying 640x480-8@75\n"); 1325 "Trying 640x480 - 8@75\n");
1132 goto tryagain; 1326 goto tryagain;
1133 } 1327 }
1134 // A specified video mode failed for some reason. 1328 // A specified video mode failed for some reason.
1135 // Try the startup mode first 1329 // Try the startup mode first
1136 output("Specified mode '%s' failed check! " 1330 output("Specified mode '%s' failed check! "
1137 "Falling back to startup mode.\n",mode); 1331 "Falling back to startup mode.\n", mode);
1138 mode=NULL; 1332 mode = NULL;
1139 goto tryagain; 1333 goto tryagain;
1140 } 1334 }
1141 1335
1142 return 0; 1336 return 0;
1143
1144} 1337}
1145 1338
1146//======================================================== 1339//========================================================
@@ -1160,21 +1353,28 @@ static unsigned int __devinit get_memsize(void)
1160 else { 1353 else {
1161 tmp = read3X4(CR1F) & 0x0F; 1354 tmp = read3X4(CR1F) & 0x0F;
1162 switch (tmp) { 1355 switch (tmp) {
1163 case 0x03: k = 1 * Mb; break; 1356 case 0x03:
1164 case 0x07: k = 2 * Mb; break; 1357 k = 1 * 1024 * 1024;
1165 case 0x0F: k = 4 * Mb; break; 1358 break;
1166 case 0x04: k = 8 * Mb; break; 1359 case 0x07:
1167 default: 1360 k = 2 * 1024 * 1024;
1168 k = 1 * Mb; 1361 break;
1169 output("Unknown memory size code %x in CR1F." 1362 case 0x0F:
1170 " We default to 1 Mb for now, please" 1363 k = 4 * 1024 * 1024;
1171 " do provide a memsize parameter!\n", 1364 break;
1172 tmp); 1365 case 0x04:
1366 k = 8 * 1024 * 1024;
1367 break;
1368 default:
1369 k = 1 * 1024 * 1024;
1370 output("Unknown memory size code %x in CR1F."
1371 " We default to 1 Mb for now, please"
1372 " do provide a memsize parameter!\n", tmp);
1173 } 1373 }
1174 } 1374 }
1175 1375
1176 if (verbosity > 0) 1376 if (verbosity > 0)
1177 output("framebuffer size = %d Kb\n",k/Kb); 1377 output("framebuffer size = %d Kb\n", k / Kb);
1178 return k; 1378 return k;
1179} 1379}
1180 1380
@@ -1192,7 +1392,7 @@ static unsigned int __devinit get_displaytype(void)
1192 return DISPLAY_FP; 1392 return DISPLAY_FP;
1193 if (crt) 1393 if (crt)
1194 return DISPLAY_CRT; 1394 return DISPLAY_CRT;
1195 return (read3CE(GR33) & 0x10)?DISPLAY_FP:DISPLAY_CRT; 1395 return (read3CE(GR33) & 0x10) ? DISPLAY_FP : DISPLAY_CRT;
1196} 1396}
1197 1397
1198//===================================== 1398//=====================================
@@ -1203,7 +1403,7 @@ static unsigned int __devinit get_displaytype(void)
1203 1403
1204static int __devinit get_nativex(void) 1404static int __devinit get_nativex(void)
1205{ 1405{
1206 int x,y,tmp; 1406 int x, y, tmp;
1207 1407
1208 if (nativex) 1408 if (nativex)
1209 return nativex; 1409 return nativex;
@@ -1211,29 +1411,45 @@ static int __devinit get_nativex(void)
1211 tmp = (read3CE(GR52) >> 4) & 3; 1411 tmp = (read3CE(GR52) >> 4) & 3;
1212 1412
1213 switch (tmp) { 1413 switch (tmp) {
1214 case 0: x = 1280; y = 1024; break; 1414 case 0: x = 1280; y = 1024;
1215 case 2: x = 1024; y = 768; break; 1415 break;
1216 case 3: x = 800; y = 600; break; 1416 case 2: x = 1024; y = 768;
1217 case 4: x = 1400; y = 1050; break; 1417 break;
1218 case 1: 1418 case 3: x = 800; y = 600;
1219 default: x = 640; y = 480; break; 1419 break;
1420 case 4: x = 1400; y = 1050;
1421 break;
1422 case 1:
1423 default:
1424 x = 640; y = 480;
1425 break;
1220 } 1426 }
1221 1427
1222 if (verbosity > 0) 1428 if (verbosity > 0)
1223 output("%dx%d flat panel found\n",x,y); 1429 output("%dx%d flat panel found\n", x, y);
1224 return x; 1430 return x;
1225} 1431}
1226 1432
1227static int __devinit cybla_pci_probe(struct pci_dev * dev, 1433static int __devinit cybla_pci_probe(struct pci_dev *dev,
1228 const struct pci_device_id * id) 1434 const struct pci_device_id *id)
1229{ 1435{
1230 struct fb_info *info; 1436 struct fb_info *info;
1231 struct cyblafb_par *par; 1437 struct cyblafb_par *par;
1232 1438
1233 info = framebuffer_alloc(sizeof(struct cyblafb_par),&dev->dev); 1439 info = framebuffer_alloc(sizeof(struct cyblafb_par), &dev->dev);
1234
1235 if (!info) 1440 if (!info)
1236 goto errout_alloc; 1441 goto errout_alloc_info;
1442
1443 info->pixmap.addr = kzalloc(CYBLAFB_PIXMAPSIZE, GFP_KERNEL);
1444 if (!info->pixmap.addr) {
1445 output("allocation of pixmap buffer failed!\n");
1446 goto errout_alloc_pixmap;
1447 }
1448 info->pixmap.size = CYBLAFB_PIXMAPSIZE - 4;
1449 info->pixmap.buf_align = 4;
1450 info->pixmap.access_align = 32;
1451 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1452 info->pixmap.scan_align = 4;
1237 1453
1238 par = info->par; 1454 par = info->par;
1239 par->ops = cyblafb_ops; 1455 par->ops = cyblafb_ops;
@@ -1246,26 +1462,31 @@ static int __devinit cybla_pci_probe(struct pci_dev * dev,
1246 output("could not enable device!\n"); 1462 output("could not enable device!\n");
1247 goto errout_enable; 1463 goto errout_enable;
1248 } 1464 }
1249
1250 // might already be requested by vga console or vesafb, 1465 // might already be requested by vga console or vesafb,
1251 // so we do care about success 1466 // so we do care about success
1252 request_region(0x3c0,32,"cyblafb"); 1467 if (!request_region(0x3c0, 0x20, "cyblafb")) {
1468 output("region 0x3c0/0x20 already reserved\n");
1469 vesafb |= 1;
1253 1470
1471 }
1254 // 1472 //
1255 // Graphics Engine Registers 1473 // Graphics Engine Registers
1256 // 1474 //
1257 request_region(GEBase,0x100,"cyblafb"); 1475 if (!request_region(GEBase, 0x100, "cyblafb")) {
1476 output("region %#x/0x100 already reserved\n", GEBase);
1477 vesafb |= 2;
1478 }
1258 1479
1259 regdump(par); 1480 regdump(par);
1260 1481
1261 enable_mmio(); 1482 enable_mmio();
1262 1483
1263 // setup MMIO region 1484 // setup MMIO region
1264 info->fix.mmio_start = pci_resource_start(dev,1); 1485 info->fix.mmio_start = pci_resource_start(dev, 1);
1265 info->fix.mmio_len = 0x20000; 1486 info->fix.mmio_len = 0x20000;
1266 1487
1267 if (!request_mem_region(info->fix.mmio_start, 1488 if (!request_mem_region(info->fix.mmio_start,
1268 info->fix.mmio_len,"cyblafb")) { 1489 info->fix.mmio_len, "cyblafb")) {
1269 output("request_mem_region failed for mmio region!\n"); 1490 output("request_mem_region failed for mmio region!\n");
1270 goto errout_mmio_reqmem; 1491 goto errout_mmio_reqmem;
1271 } 1492 }
@@ -1276,18 +1497,17 @@ static int __devinit cybla_pci_probe(struct pci_dev * dev,
1276 output("ioremap failed for mmio region\n"); 1497 output("ioremap failed for mmio region\n");
1277 goto errout_mmio_remap; 1498 goto errout_mmio_remap;
1278 } 1499 }
1279
1280 // setup framebuffer memory ... might already be requested 1500 // setup framebuffer memory ... might already be requested
1281 // by vesafb. Not to fail in case of an unsuccessful request 1501 // by vesafb. Not to fail in case of an unsuccessful request
1282 // is useful for the development cycle 1502 // is useful if both are loaded.
1283 info->fix.smem_start = pci_resource_start(dev,0); 1503 info->fix.smem_start = pci_resource_start(dev, 0);
1284 info->fix.smem_len = get_memsize(); 1504 info->fix.smem_len = get_memsize();
1285 1505
1286 if (!request_mem_region(info->fix.smem_start, 1506 if (!request_mem_region(info->fix.smem_start,
1287 info->fix.smem_len,"cyblafb")) { 1507 info->fix.smem_len, "cyblafb")) {
1288 output("request_mem_region failed for smem region!\n"); 1508 output("region %#lx/%#x already reserved\n",
1289 if (!vesafb) 1509 info->fix.smem_start, info->fix.smem_len);
1290 goto errout_smem_req; 1510 vesafb |= 4;
1291 } 1511 }
1292 1512
1293 info->screen_base = ioremap_nocache(info->fix.smem_start, 1513 info->screen_base = ioremap_nocache(info->fix.smem_start,
@@ -1300,31 +1520,30 @@ static int __devinit cybla_pci_probe(struct pci_dev * dev,
1300 1520
1301 displaytype = get_displaytype(); 1521 displaytype = get_displaytype();
1302 1522
1303 if(displaytype == DISPLAY_FP) 1523 if (displaytype == DISPLAY_FP)
1304 nativex = get_nativex(); 1524 nativex = get_nativex();
1305 1525
1306 // 1526 info->flags = FBINFO_DEFAULT
1307 // FBINFO_HWACCEL_YWRAP .... does not work (could be made to work?) 1527 | FBINFO_HWACCEL_COPYAREA
1308 // FBINFO_PARTIAL_PAN_OK .... is not ok 1528 | FBINFO_HWACCEL_FILLRECT
1309 // FBINFO_READS_FAST .... is necessary for optimal scrolling 1529 | FBINFO_HWACCEL_IMAGEBLIT
1310 // 1530 | FBINFO_READS_FAST
1311 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN 1531// | FBINFO_PARTIAL_PAN_OK
1312 | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT 1532 | FBINFO_MISC_ALWAYS_SETPAR;
1313 | FBINFO_HWACCEL_IMAGEBLIT | FBINFO_READS_FAST;
1314 1533
1315 info->pseudo_palette = par->pseudo_pal; 1534 info->pseudo_palette = par->pseudo_pal;
1316 1535
1317 if(getstartupmode(info)) 1536 if (getstartupmode(info))
1318 goto errout_findmode; 1537 goto errout_findmode;
1319 1538
1320 fb_alloc_cmap(&info->cmap,256,0); 1539 fb_alloc_cmap(&info->cmap, 256, 0);
1321 1540
1322 if (register_framebuffer(info)) { 1541 if (register_framebuffer(info)) {
1323 output("Could not register CyBla framebuffer\n"); 1542 output("Could not register CyBla framebuffer\n");
1324 goto errout_register; 1543 goto errout_register;
1325 } 1544 }
1326 1545
1327 pci_set_drvdata(dev,info); 1546 pci_set_drvdata(dev, info);
1328 1547
1329 // 1548 //
1330 // normal exit and error paths 1549 // normal exit and error paths
@@ -1332,23 +1551,24 @@ static int __devinit cybla_pci_probe(struct pci_dev * dev,
1332 1551
1333 return 0; 1552 return 0;
1334 1553
1335 errout_register: 1554 errout_register:
1336 errout_findmode: 1555 errout_findmode:
1337 iounmap(info->screen_base); 1556 iounmap(info->screen_base);
1338 errout_smem_remap: 1557 errout_smem_remap:
1339 release_mem_region(info->fix.smem_start, 1558 if (!(vesafb & 4))
1340 info->fix.smem_len); 1559 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1341 errout_smem_req:
1342 iounmap(io_virt); 1560 iounmap(io_virt);
1343 errout_mmio_remap: 1561 errout_mmio_remap:
1344 release_mem_region(info->fix.mmio_start, 1562 release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
1345 info->fix.mmio_len); 1563 errout_mmio_reqmem:
1346 errout_mmio_reqmem: 1564 if (!(vesafb & 1))
1347// release_region(0x3c0,32); 1565 release_region(0x3c0, 32);
1348 errout_enable: 1566 errout_enable:
1567 kfree(info->pixmap.addr);
1568 errout_alloc_pixmap:
1349 framebuffer_release(info); 1569 framebuffer_release(info);
1350 errout_alloc: 1570 errout_alloc_info:
1351 output("CyblaFB version %s aborting init.\n",VERSION); 1571 output("CyblaFB version %s aborting init.\n", VERSION);
1352 return -ENODEV; 1572 return -ENODEV;
1353} 1573}
1354 1574
@@ -1359,35 +1579,41 @@ static void __devexit cybla_pci_remove(struct pci_dev *dev)
1359 unregister_framebuffer(info); 1579 unregister_framebuffer(info);
1360 iounmap(io_virt); 1580 iounmap(io_virt);
1361 iounmap(info->screen_base); 1581 iounmap(info->screen_base);
1362 release_mem_region(info->fix.smem_start,info->fix.smem_len); 1582 if (!(vesafb & 4))
1363 release_mem_region(info->fix.mmio_start,info->fix.mmio_len); 1583 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1584 release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
1364 fb_dealloc_cmap(&info->cmap); 1585 fb_dealloc_cmap(&info->cmap);
1586 if (!(vesafb & 2))
1587 release_region(GEBase, 0x100);
1588 if (!(vesafb & 1))
1589 release_region(0x3c0, 32);
1590 kfree(info->pixmap.addr);
1365 framebuffer_release(info); 1591 framebuffer_release(info);
1366 output("CyblaFB version %s normal exit.\n",VERSION); 1592 output("CyblaFB version %s normal exit.\n", VERSION);
1367} 1593}
1368 1594
1369// 1595//
1370// List of boards that we are trying to support 1596// List of boards that we are trying to support
1371// 1597//
1372static struct pci_device_id cybla_devices[] = { 1598static struct pci_device_id cybla_devices[] = {
1373 {PCI_VENDOR_ID_TRIDENT,CYBERBLADEi1,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1599 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1374 {0,} 1600 {0,}
1375}; 1601};
1376 1602
1377MODULE_DEVICE_TABLE(pci,cybla_devices); 1603MODULE_DEVICE_TABLE(pci, cybla_devices);
1378 1604
1379static struct pci_driver cyblafb_pci_driver = { 1605static struct pci_driver cyblafb_pci_driver = {
1380 .name = "cyblafb", 1606 .name = "cyblafb",
1381 .id_table = cybla_devices, 1607 .id_table = cybla_devices,
1382 .probe = cybla_pci_probe, 1608 .probe = cybla_pci_probe,
1383 .remove = __devexit_p(cybla_pci_remove) 1609 .remove = __devexit_p(cybla_pci_remove)
1384}; 1610};
1385 1611
1386//============================================================= 1612//=============================================================
1387// 1613//
1388// kernel command line example: 1614// kernel command line example:
1389// 1615//
1390// video=cyblafb:1280x1024,bpp=16,ref=50 ... 1616// video=cyblafb:1280x1024, bpp=16, ref=50 ...
1391// 1617//
1392// modprobe command line example: 1618// modprobe command line example:
1393// 1619//
@@ -1401,45 +1627,44 @@ static int __devinit cyblafb_init(void)
1401 char *options = NULL; 1627 char *options = NULL;
1402 char *opt; 1628 char *opt;
1403 1629
1404 if (fb_get_options("cyblafb",&options)) 1630 if (fb_get_options("cyblafb", &options))
1405 return -ENODEV; 1631 return -ENODEV;
1406 1632
1407 if (options && *options) 1633 if (options && *options)
1408 while((opt = strsep(&options,",")) != NULL ) { 1634 while ((opt = strsep(&options, ",")) != NULL) {
1409 if (!*opt) continue; 1635 if (!*opt)
1410 else if (!strncmp(opt,"bpp=",4)) 1636 continue;
1411 bpp = simple_strtoul(opt+4,NULL,0); 1637 else if (!strncmp(opt, "bpp=", 4))
1412 else if (!strncmp(opt,"ref=",4)) 1638 bpp = simple_strtoul(opt + 4, NULL, 0);
1413 ref = simple_strtoul(opt+4,NULL,0); 1639 else if (!strncmp(opt, "ref=", 4))
1414 else if (!strncmp(opt,"fp",2)) 1640 ref = simple_strtoul(opt + 4, NULL, 0);
1641 else if (!strncmp(opt, "fp", 2))
1415 displaytype = DISPLAY_FP; 1642 displaytype = DISPLAY_FP;
1416 else if (!strncmp(opt,"crt",3)) 1643 else if (!strncmp(opt, "crt", 3))
1417 displaytype = DISPLAY_CRT; 1644 displaytype = DISPLAY_CRT;
1418 else if (!strncmp(opt,"nativex=",8)) 1645 else if (!strncmp(opt, "nativex=", 8))
1419 nativex = simple_strtoul(opt+8,NULL,0); 1646 nativex = simple_strtoul(opt + 8, NULL, 0);
1420 else if (!strncmp(opt,"center",6)) 1647 else if (!strncmp(opt, "center", 6))
1421 center = 1; 1648 center = 1;
1422 else if (!strncmp(opt,"stretch",7)) 1649 else if (!strncmp(opt, "stretch", 7))
1423 stretch = 1; 1650 stretch = 1;
1424 else if (!strncmp(opt,"pciwb=",6)) 1651 else if (!strncmp(opt, "pciwb=", 6))
1425 pciwb = simple_strtoul(opt+6,NULL,0); 1652 pciwb = simple_strtoul(opt + 6, NULL, 0);
1426 else if (!strncmp(opt,"pcirb=",6)) 1653 else if (!strncmp(opt, "pcirb=", 6))
1427 pcirb = simple_strtoul(opt+6,NULL,0); 1654 pcirb = simple_strtoul(opt + 6, NULL, 0);
1428 else if (!strncmp(opt,"pciwr=",6)) 1655 else if (!strncmp(opt, "pciwr=", 6))
1429 pciwr = simple_strtoul(opt+6,NULL,0); 1656 pciwr = simple_strtoul(opt + 6, NULL, 0);
1430 else if (!strncmp(opt,"pcirr=",6)) 1657 else if (!strncmp(opt, "pcirr=", 6))
1431 pcirr = simple_strtoul(opt+6,NULL,0); 1658 pcirr = simple_strtoul(opt + 6, NULL, 0);
1432 else if (!strncmp(opt,"memsize=",8)) 1659 else if (!strncmp(opt, "memsize=", 8))
1433 memsize = simple_strtoul(opt+8,NULL,0); 1660 memsize = simple_strtoul(opt + 8, NULL, 0);
1434 else if (!strncmp(opt,"verbosity=",10)) 1661 else if (!strncmp(opt, "verbosity=", 10))
1435 verbosity = simple_strtoul(opt+10,NULL,0); 1662 verbosity = simple_strtoul(opt + 10, NULL, 0);
1436 else if (!strncmp(opt,"vesafb",6))
1437 vesafb = 1;
1438 else 1663 else
1439 mode = opt; 1664 mode = opt;
1440 } 1665 }
1441#endif 1666#endif
1442 output("CyblaFB version %s initializing\n",VERSION); 1667 output("CyblaFB version %s initializing\n", VERSION);
1443 return pci_module_init(&cyblafb_pci_driver); 1668 return pci_module_init(&cyblafb_pci_driver);
1444} 1669}
1445 1670
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 00d87f5bb7be..ad1434e3f227 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -223,6 +223,7 @@ static int offb_blank(int blank, struct fb_info *info)
223int __init offb_init(void) 223int __init offb_init(void)
224{ 224{
225 struct device_node *dp = NULL, *boot_disp = NULL; 225 struct device_node *dp = NULL, *boot_disp = NULL;
226
226#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) 227#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32)
227 struct device_node *macos_display = NULL; 228 struct device_node *macos_display = NULL;
228#endif 229#endif
@@ -234,60 +235,54 @@ int __init offb_init(void)
234 if (boot_infos != 0) { 235 if (boot_infos != 0) {
235 unsigned long addr = 236 unsigned long addr =
236 (unsigned long) boot_infos->dispDeviceBase; 237 (unsigned long) boot_infos->dispDeviceBase;
238 u32 *addrp;
239 u64 daddr, dsize;
240 unsigned int flags;
241
237 /* find the device node corresponding to the macos display */ 242 /* find the device node corresponding to the macos display */
238 while ((dp = of_find_node_by_type(dp, "display"))) { 243 while ((dp = of_find_node_by_type(dp, "display"))) {
239 int i; 244 int i;
240 /*
241 * Grrr... It looks like the MacOS ATI driver
242 * munges the assigned-addresses property (but
243 * the AAPL,address value is OK).
244 */
245 if (strncmp(dp->name, "ATY,", 4) == 0
246 && dp->n_addrs == 1) {
247 unsigned int *ap =
248 (unsigned int *) get_property(dp,
249 "AAPL,address",
250 NULL);
251 if (ap != NULL) {
252 dp->addrs[0].address = *ap;
253 dp->addrs[0].size = 0x01000000;
254 }
255 }
256 245
257 /* 246 /*
258 * The LTPro on the Lombard powerbook has no addresses 247 * Look for an AAPL,address property first.
259 * on the display nodes, they are on their parent.
260 */ 248 */
261 if (dp->n_addrs == 0 249 unsigned int na;
262 && device_is_compatible(dp, "ATY,264LTPro")) { 250 unsigned int *ap =
263 int na; 251 (unsigned int *)get_property(dp, "AAPL,address",
264 unsigned int *ap = (unsigned int *) 252 &na);
265 get_property(dp, "AAPL,address", &na); 253 if (ap != 0) {
266 if (ap != 0) 254 for (na /= sizeof(unsigned int); na > 0;
267 for (na /= sizeof(unsigned int); 255 --na, ++ap)
268 na > 0; --na, ++ap) 256 if (*ap <= addr &&
269 if (*ap <= addr 257 addr < *ap + 0x1000000) {
270 && addr < 258 macos_display = dp;
271 *ap + 0x1000000) 259 goto foundit;
272 goto foundit; 260 }
273 } 261 }
274 262
275 /* 263 /*
276 * See if the display address is in one of the address 264 * See if the display address is in one of the address
277 * ranges for this display. 265 * ranges for this display.
278 */ 266 */
279 for (i = 0; i < dp->n_addrs; ++i) { 267 i = 0;
280 if (dp->addrs[i].address <= addr 268 for (;;) {
281 && addr < 269 addrp = of_get_address(dp, i++, &dsize, &flags);
282 dp->addrs[i].address + 270 if (addrp == NULL)
283 dp->addrs[i].size)
284 break; 271 break;
272 if (!(flags & IORESOURCE_MEM))
273 continue;
274 daddr = of_translate_address(dp, addrp);
275 if (daddr == OF_BAD_ADDR)
276 continue;
277 if (daddr <= addr && addr < (daddr + dsize)) {
278 macos_display = dp;
279 goto foundit;
280 }
285 } 281 }
286 if (i < dp->n_addrs) { 282 foundit:
287 foundit: 283 if (macos_display) {
288 printk(KERN_INFO "MacOS display is %s\n", 284 printk(KERN_INFO "MacOS display is %s\n",
289 dp->full_name); 285 dp->full_name);
290 macos_display = dp;
291 break; 286 break;
292 } 287 }
293 } 288 }
@@ -326,8 +321,10 @@ static void __init offb_init_nodriver(struct device_node *dp)
326 int *pp, i; 321 int *pp, i;
327 unsigned int len; 322 unsigned int len;
328 int width = 640, height = 480, depth = 8, pitch; 323 int width = 640, height = 480, depth = 8, pitch;
329 unsigned int rsize, *up; 324 unsigned int flags, rsize, *up;
330 unsigned long address = 0; 325 u64 address = OF_BAD_ADDR;
326 u32 *addrp;
327 u64 asize;
331 328
332 if ((pp = (int *) get_property(dp, "depth", &len)) != NULL 329 if ((pp = (int *) get_property(dp, "depth", &len)) != NULL
333 && len == sizeof(int)) 330 && len == sizeof(int))
@@ -363,7 +360,7 @@ static void __init offb_init_nodriver(struct device_node *dp)
363 break; 360 break;
364 } 361 }
365 if (pdev) { 362 if (pdev) {
366 for (i = 0; i < 6 && address == 0; i++) { 363 for (i = 0; i < 6 && address == OF_BAD_ADDR; i++) {
367 if ((pci_resource_flags(pdev, i) & 364 if ((pci_resource_flags(pdev, i) &
368 IORESOURCE_MEM) && 365 IORESOURCE_MEM) &&
369 (pci_resource_len(pdev, i) >= rsize)) 366 (pci_resource_len(pdev, i) >= rsize))
@@ -374,27 +371,33 @@ static void __init offb_init_nodriver(struct device_node *dp)
374 } 371 }
375#endif /* CONFIG_PCI */ 372#endif /* CONFIG_PCI */
376 373
377 if (address == 0 && 374 /* This one is dodgy, we may drop it ... */
378 (up = (unsigned *) get_property(dp, "address", &len)) != NULL && 375 if (address == OF_BAD_ADDR &&
379 len == sizeof(unsigned)) 376 (up = (unsigned *) get_property(dp, "address", &len)) != NULL &&
380 address = (u_long) * up; 377 len == sizeof(unsigned int))
381 if (address == 0) { 378 address = (u64) * up;
382 for (i = 0; i < dp->n_addrs; ++i) 379
383 if (dp->addrs[i].size >= 380 if (address == OF_BAD_ADDR) {
384 pitch * height * depth / 8) 381 for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags))
385 break; 382 != NULL; i++) {
386 if (i >= dp->n_addrs) { 383 if (!(flags & IORESOURCE_MEM))
384 continue;
385 if (asize >= pitch * height * depth / 8)
386 break;
387 }
388 if (addrp == NULL) {
387 printk(KERN_ERR 389 printk(KERN_ERR
388 "no framebuffer address found for %s\n", 390 "no framebuffer address found for %s\n",
389 dp->full_name); 391 dp->full_name);
390 return; 392 return;
391 } 393 }
392 394 address = of_translate_address(dp, addrp);
393 address = (u_long) dp->addrs[i].address; 395 if (address == OF_BAD_ADDR) {
394 396 printk(KERN_ERR
395#ifdef CONFIG_PPC64 397 "can't translate framebuffer address for %s\n",
396 address += ((struct pci_dn *)dp->data)->phb->pci_mem_offset; 398 dp->full_name);
397#endif 399 return;
400 }
398 401
399 /* kludge for valkyrie */ 402 /* kludge for valkyrie */
400 if (strcmp(dp->name, "valkyrie") == 0) 403 if (strcmp(dp->name, "valkyrie") == 0)
@@ -459,7 +462,9 @@ static void __init offb_init_fb(const char *name, const char *full_name,
459 462
460 par->cmap_type = cmap_unknown; 463 par->cmap_type = cmap_unknown;
461 if (depth == 8) { 464 if (depth == 8) {
462 /* XXX kludge for ati */ 465
466 /* Palette hacks disabled for now */
467#if 0
463 if (dp && !strncmp(name, "ATY,Rage128", 11)) { 468 if (dp && !strncmp(name, "ATY,Rage128", 11)) {
464 unsigned long regbase = dp->addrs[2].address; 469 unsigned long regbase = dp->addrs[2].address;
465 par->cmap_adr = ioremap(regbase, 0x1FFF); 470 par->cmap_adr = ioremap(regbase, 0x1FFF);
@@ -490,6 +495,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,
490 par->cmap_adr = ioremap(regbase + 0x6000, 0x1000); 495 par->cmap_adr = ioremap(regbase + 0x6000, 0x1000);
491 par->cmap_type = cmap_gxt2000; 496 par->cmap_type = cmap_gxt2000;
492 } 497 }
498#endif
493 fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR 499 fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR
494 : FB_VISUAL_STATIC_PSEUDOCOLOR; 500 : FB_VISUAL_STATIC_PSEUDOCOLOR;
495 } else 501 } else
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index ca4082ae5a18..335e37465559 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -69,6 +69,8 @@ struct fb_info_platinum {
69 unsigned long total_vram; 69 unsigned long total_vram;
70 int clktype; 70 int clktype;
71 int dactype; 71 int dactype;
72
73 struct resource rsrc_fb, rsrc_reg;
72}; 74};
73 75
74/* 76/*
@@ -97,9 +99,6 @@ static int platinum_var_to_par(struct fb_var_screeninfo *var,
97 * Interface used by the world 99 * Interface used by the world
98 */ 100 */
99 101
100int platinumfb_init(void);
101int platinumfb_setup(char*);
102
103static struct fb_ops platinumfb_ops = { 102static struct fb_ops platinumfb_ops = {
104 .owner = THIS_MODULE, 103 .owner = THIS_MODULE,
105 .fb_check_var = platinumfb_check_var, 104 .fb_check_var = platinumfb_check_var,
@@ -138,13 +137,15 @@ static int platinumfb_set_par (struct fb_info *info)
138 137
139 init = platinum_reg_init[pinfo->vmode-1]; 138 init = platinum_reg_init[pinfo->vmode-1];
140 139
141 if (pinfo->vmode == 13 && pinfo->cmode > 0) 140 if ((pinfo->vmode == VMODE_832_624_75) && (pinfo->cmode > CMODE_8))
142 offset = 0x10; 141 offset = 0x10;
142
143 info->screen_base = pinfo->frame_buffer + init->fb_offset + offset; 143 info->screen_base = pinfo->frame_buffer + init->fb_offset + offset;
144 info->fix.smem_start = (pinfo->frame_buffer_phys) + init->fb_offset + offset; 144 info->fix.smem_start = (pinfo->frame_buffer_phys) + init->fb_offset + offset;
145 info->fix.visual = (pinfo->cmode == CMODE_8) ? 145 info->fix.visual = (pinfo->cmode == CMODE_8) ?
146 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; 146 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
147 info->fix.line_length = vmode_attrs[pinfo->vmode-1].hres * (1<<pinfo->cmode) + offset; 147 info->fix.line_length = vmode_attrs[pinfo->vmode-1].hres * (1<<pinfo->cmode)
148 + offset;
148 printk("line_length: %x\n", info->fix.line_length); 149 printk("line_length: %x\n", info->fix.line_length);
149 return 0; 150 return 0;
150} 151}
@@ -221,7 +222,9 @@ static int platinumfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
221static inline int platinum_vram_reqd(int video_mode, int color_mode) 222static inline int platinum_vram_reqd(int video_mode, int color_mode)
222{ 223{
223 return vmode_attrs[video_mode-1].vres * 224 return vmode_attrs[video_mode-1].vres *
224 (vmode_attrs[video_mode-1].hres * (1<<color_mode) + 0x20) +0x1000; 225 (vmode_attrs[video_mode-1].hres * (1<<color_mode) +
226 ((video_mode == VMODE_832_624_75) &&
227 (color_mode > CMODE_8)) ? 0x10 : 0x20) + 0x1000;
225} 228}
226 229
227#define STORE_D2(a, d) { \ 230#define STORE_D2(a, d) { \
@@ -481,7 +484,7 @@ static int platinum_var_to_par(struct fb_var_screeninfo *var,
481/* 484/*
482 * Parse user speficied options (`video=platinumfb:') 485 * Parse user speficied options (`video=platinumfb:')
483 */ 486 */
484int __init platinumfb_setup(char *options) 487static int __init platinumfb_setup(char *options)
485{ 488{
486 char *this_opt; 489 char *this_opt;
487 490
@@ -522,19 +525,15 @@ int __init platinumfb_setup(char *options)
522#define invalidate_cache(addr) 525#define invalidate_cache(addr)
523#endif 526#endif
524 527
525static int __devinit platinumfb_probe(struct of_device* odev, const struct of_device_id *match) 528static int __devinit platinumfb_probe(struct of_device* odev,
529 const struct of_device_id *match)
526{ 530{
527 struct device_node *dp = odev->node; 531 struct device_node *dp = odev->node;
528 struct fb_info *info; 532 struct fb_info *info;
529 struct fb_info_platinum *pinfo; 533 struct fb_info_platinum *pinfo;
530 unsigned long addr, size;
531 volatile __u8 *fbuffer; 534 volatile __u8 *fbuffer;
532 int i, bank0, bank1, bank2, bank3, rc; 535 int bank0, bank1, bank2, bank3, rc;
533 536
534 if (dp->n_addrs != 2) {
535 printk(KERN_ERR "expecting 2 address for platinum (got %d)", dp->n_addrs);
536 return -ENXIO;
537 }
538 printk(KERN_INFO "platinumfb: Found Apple Platinum video hardware\n"); 537 printk(KERN_INFO "platinumfb: Found Apple Platinum video hardware\n");
539 538
540 info = framebuffer_alloc(sizeof(*pinfo), &odev->dev); 539 info = framebuffer_alloc(sizeof(*pinfo), &odev->dev);
@@ -542,26 +541,39 @@ static int __devinit platinumfb_probe(struct of_device* odev, const struct of_de
542 return -ENOMEM; 541 return -ENOMEM;
543 pinfo = info->par; 542 pinfo = info->par;
544 543
545 /* Map in frame buffer and registers */ 544 if (of_address_to_resource(dp, 0, &pinfo->rsrc_reg) ||
546 for (i = 0; i < dp->n_addrs; ++i) { 545 of_address_to_resource(dp, 1, &pinfo->rsrc_fb)) {
547 addr = dp->addrs[i].address; 546 printk(KERN_ERR "platinumfb: Can't get resources\n");
548 size = dp->addrs[i].size; 547 framebuffer_release(info);
549 /* Let's assume we can request either all or nothing */ 548 return -ENXIO;
550 if (!request_mem_region(addr, size, "platinumfb")) {
551 framebuffer_release(info);
552 return -ENXIO;
553 }
554 if (size >= 0x400000) {
555 /* frame buffer - map only 4MB */
556 pinfo->frame_buffer_phys = addr;
557 pinfo->frame_buffer = __ioremap(addr, 0x400000, _PAGE_WRITETHRU);
558 pinfo->base_frame_buffer = pinfo->frame_buffer;
559 } else {
560 /* registers */
561 pinfo->platinum_regs_phys = addr;
562 pinfo->platinum_regs = ioremap(addr, size);
563 }
564 } 549 }
550 if (!request_mem_region(pinfo->rsrc_reg.start,
551 pinfo->rsrc_reg.start -
552 pinfo->rsrc_reg.end + 1,
553 "platinumfb registers")) {
554 framebuffer_release(info);
555 return -ENXIO;
556 }
557 if (!request_mem_region(pinfo->rsrc_fb.start,
558 pinfo->rsrc_fb.start
559 - pinfo->rsrc_fb.end + 1,
560 "platinumfb framebuffer")) {
561 release_mem_region(pinfo->rsrc_reg.start,
562 pinfo->rsrc_reg.end -
563 pinfo->rsrc_reg.start + 1);
564 framebuffer_release(info);
565 return -ENXIO;
566 }
567
568 /* frame buffer - map only 4MB */
569 pinfo->frame_buffer_phys = pinfo->rsrc_fb.start;
570 pinfo->frame_buffer = __ioremap(pinfo->rsrc_fb.start, 0x400000,
571 _PAGE_WRITETHRU);
572 pinfo->base_frame_buffer = pinfo->frame_buffer;
573
574 /* registers */
575 pinfo->platinum_regs_phys = pinfo->rsrc_reg.start;
576 pinfo->platinum_regs = ioremap(pinfo->rsrc_reg.start, 0x1000);
565 577
566 pinfo->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */ 578 pinfo->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */
567 request_mem_region(pinfo->cmap_regs_phys, 0x1000, "platinumfb cmap"); 579 request_mem_region(pinfo->cmap_regs_phys, 0x1000, "platinumfb cmap");
@@ -624,18 +636,16 @@ static int __devexit platinumfb_remove(struct of_device* odev)
624{ 636{
625 struct fb_info *info = dev_get_drvdata(&odev->dev); 637 struct fb_info *info = dev_get_drvdata(&odev->dev);
626 struct fb_info_platinum *pinfo = info->par; 638 struct fb_info_platinum *pinfo = info->par;
627 struct device_node *dp = odev->node;
628 unsigned long addr, size;
629 int i;
630 639
631 unregister_framebuffer (info); 640 unregister_framebuffer (info);
632 641
633 /* Unmap frame buffer and registers */ 642 /* Unmap frame buffer and registers */
634 for (i = 0; i < dp->n_addrs; ++i) { 643 release_mem_region(pinfo->rsrc_fb.start,
635 addr = dp->addrs[i].address; 644 pinfo->rsrc_fb.end -
636 size = dp->addrs[i].size; 645 pinfo->rsrc_fb.start + 1);
637 release_mem_region(addr, size); 646 release_mem_region(pinfo->rsrc_reg.start,
638 } 647 pinfo->rsrc_reg.end -
648 pinfo->rsrc_reg.start + 1);
639 iounmap(pinfo->frame_buffer); 649 iounmap(pinfo->frame_buffer);
640 iounmap(pinfo->platinum_regs); 650 iounmap(pinfo->platinum_regs);
641 release_mem_region(pinfo->cmap_regs_phys, 0x1000); 651 release_mem_region(pinfo->cmap_regs_phys, 0x1000);
@@ -662,7 +672,7 @@ static struct of_platform_driver platinum_driver =
662 .remove = platinumfb_remove, 672 .remove = platinumfb_remove,
663}; 673};
664 674
665int __init platinumfb_init(void) 675static int __init platinumfb_init(void)
666{ 676{
667#ifndef MODULE 677#ifndef MODULE
668 char *option = NULL; 678 char *option = NULL;
@@ -676,7 +686,7 @@ int __init platinumfb_init(void)
676 return 0; 686 return 0;
677} 687}
678 688
679void __exit platinumfb_exit(void) 689static void __exit platinumfb_exit(void)
680{ 690{
681 of_unregister_driver(&platinum_driver); 691 of_unregister_driver(&platinum_driver);
682} 692}
diff --git a/drivers/video/platinumfb.h b/drivers/video/platinumfb.h
index 2834fc1c344b..f6bd77cafd17 100644
--- a/drivers/video/platinumfb.h
+++ b/drivers/video/platinumfb.h
@@ -158,7 +158,9 @@ static struct platinum_regvals platinum_reg_init_14 = {
158/* 832x624, 75Hz (13) */ 158/* 832x624, 75Hz (13) */
159static struct platinum_regvals platinum_reg_init_13 = { 159static struct platinum_regvals platinum_reg_init_13 = {
160 0x70, 160 0x70,
161 { 864, 1680, 3360 }, /* MacOS does 1680 instead of 1696 to fit 16bpp in 1MB */ 161 { 864, 1680, 3344 }, /* MacOS does 1680 instead of 1696 to fit 16bpp in 1MB,
162 * and we use 3344 instead of 3360 to fit in 2Mb
163 */
162 { 0xff0, 4, 0, 0, 0, 0, 0x299, 0, 164 { 0xff0, 4, 0, 0, 0, 0, 0x299, 0,
163 0, 0x21e, 0x120, 0x10, 0x23f, 0x1f, 0x25, 0x37, 165 0, 0x21e, 0x120, 0x10, 0x23f, 0x1f, 0x25, 0x37,
164 0x8a, 0x22a, 0x23e, 0x536, 0x534, 4, 9, 0x52, 166 0x8a, 0x22a, 0x23e, 0x536, 0x534, 4, 9, 0x52,
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
index ce97ec8eae97..2bdeb4baa952 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/valkyriefb.c
@@ -342,19 +342,19 @@ int __init valkyriefb_init(void)
342#else /* ppc (!CONFIG_MAC) */ 342#else /* ppc (!CONFIG_MAC) */
343 { 343 {
344 struct device_node *dp; 344 struct device_node *dp;
345 struct resource r;
345 346
346 dp = find_devices("valkyrie"); 347 dp = of_find_node_by_name(NULL, "valkyrie");
347 if (dp == 0) 348 if (dp == 0)
348 return 0; 349 return 0;
349 350
350 if (dp->n_addrs != 1) { 351 if (of_address_to_resource(dp, 0, &r)) {
351 printk(KERN_ERR "expecting 1 address for valkyrie (got %d)\n", 352 printk(KERN_ERR "can't find address for valkyrie\n");
352 dp->n_addrs);
353 return 0; 353 return 0;
354 } 354 }
355 355
356 frame_buffer_phys = dp->addrs[0].address; 356 frame_buffer_phys = r.start;
357 cmap_regs_phys = dp->addrs[0].address+0x304000; 357 cmap_regs_phys = r.start + 0x304000;
358 flags = _PAGE_WRITETHRU; 358 flags = _PAGE_WRITETHRU;
359 } 359 }
360#endif /* ppc (!CONFIG_MAC) */ 360#endif /* ppc (!CONFIG_MAC) */
diff --git a/fs/9p/9p.c b/fs/9p/9p.c
index e847f504a47c..1a6d08761f39 100644
--- a/fs/9p/9p.c
+++ b/fs/9p/9p.c
@@ -1,8 +1,9 @@
1/* 1/*
2 * linux/fs/9p/9p.c 2 * linux/fs/9p/9p.c
3 * 3 *
4 * This file contains functions 9P2000 functions 4 * This file contains functions to perform synchronous 9P calls
5 * 5 *
6 * Copyright (C) 2004 by Latchesar Ionkov <lucho@ionkov.net>
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
8 * 9 *
@@ -33,6 +34,7 @@
33#include "debug.h" 34#include "debug.h"
34#include "v9fs.h" 35#include "v9fs.h"
35#include "9p.h" 36#include "9p.h"
37#include "conv.h"
36#include "mux.h" 38#include "mux.h"
37 39
38/** 40/**
@@ -46,16 +48,21 @@
46 48
47int 49int
48v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize, 50v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize,
49 char *version, struct v9fs_fcall **fcall) 51 char *version, struct v9fs_fcall **rcp)
50{ 52{
51 struct v9fs_fcall msg; 53 int ret;
54 struct v9fs_fcall *tc;
52 55
53 dprintk(DEBUG_9P, "msize: %d version: %s\n", msize, version); 56 dprintk(DEBUG_9P, "msize: %d version: %s\n", msize, version);
54 msg.id = TVERSION; 57 tc = v9fs_create_tversion(msize, version);
55 msg.params.tversion.msize = msize;
56 msg.params.tversion.version = version;
57 58
58 return v9fs_mux_rpc(v9ses, &msg, fcall); 59 if (!IS_ERR(tc)) {
60 ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
61 kfree(tc);
62 } else
63 ret = PTR_ERR(tc);
64
65 return ret;
59} 66}
60 67
61/** 68/**
@@ -71,19 +78,45 @@ v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize,
71 78
72int 79int
73v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname, 80v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname,
74 u32 fid, u32 afid, struct v9fs_fcall **fcall) 81 u32 fid, u32 afid, struct v9fs_fcall **rcp)
75{ 82{
76 struct v9fs_fcall msg; 83 int ret;
84 struct v9fs_fcall* tc;
77 85
78 dprintk(DEBUG_9P, "uname '%s' aname '%s' fid %d afid %d\n", uname, 86 dprintk(DEBUG_9P, "uname '%s' aname '%s' fid %d afid %d\n", uname,
79 aname, fid, afid); 87 aname, fid, afid);
80 msg.id = TATTACH;
81 msg.params.tattach.fid = fid;
82 msg.params.tattach.afid = afid;
83 msg.params.tattach.uname = uname;
84 msg.params.tattach.aname = aname;
85 88
86 return v9fs_mux_rpc(v9ses, &msg, fcall); 89 tc = v9fs_create_tattach(fid, afid, uname, aname);
90 if (!IS_ERR(tc)) {
91 ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
92 kfree(tc);
93 } else
94 ret = PTR_ERR(tc);
95
96 return ret;
97}
98
99static void v9fs_t_clunk_cb(void *a, struct v9fs_fcall *tc,
100 struct v9fs_fcall *rc, int err)
101{
102 int fid;
103 struct v9fs_session_info *v9ses;
104
105 if (err)
106 return;
107
108 fid = tc->params.tclunk.fid;
109 kfree(tc);
110
111 if (!rc)
112 return;
113
114 dprintk(DEBUG_9P, "tcall id %d rcall id %d\n", tc->id, rc->id);
115 v9ses = a;
116 if (rc->id == RCLUNK)
117 v9fs_put_idpool(fid, &v9ses->fidpool);
118
119 kfree(rc);
87} 120}
88 121
89/** 122/**
@@ -95,16 +128,25 @@ v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname,
95 */ 128 */
96 129
97int 130int
98v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid, 131v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid)
99 struct v9fs_fcall **fcall)
100{ 132{
101 struct v9fs_fcall msg; 133 int ret;
134 struct v9fs_fcall *tc, *rc;
102 135
103 dprintk(DEBUG_9P, "fid %d\n", fid); 136 dprintk(DEBUG_9P, "fid %d\n", fid);
104 msg.id = TCLUNK;
105 msg.params.tclunk.fid = fid;
106 137
107 return v9fs_mux_rpc(v9ses, &msg, fcall); 138 rc = NULL;
139 tc = v9fs_create_tclunk(fid);
140 if (!IS_ERR(tc))
141 ret = v9fs_mux_rpc(v9ses->mux, tc, &rc);
142 else
143 ret = PTR_ERR(tc);
144
145 if (ret)
146 dprintk(DEBUG_ERROR, "failed fid %d err %d\n", fid, ret);
147
148 v9fs_t_clunk_cb(v9ses, tc, rc, ret);
149 return ret;
108} 150}
109 151
110/** 152/**
@@ -114,14 +156,21 @@ v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid,
114 * 156 *
115 */ 157 */
116 158
117int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 tag) 159int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag)
118{ 160{
119 struct v9fs_fcall msg; 161 int ret;
162 struct v9fs_fcall *tc;
163
164 dprintk(DEBUG_9P, "oldtag %d\n", oldtag);
165
166 tc = v9fs_create_tflush(oldtag);
167 if (!IS_ERR(tc)) {
168 ret = v9fs_mux_rpc(v9ses->mux, tc, NULL);
169 kfree(tc);
170 } else
171 ret = PTR_ERR(tc);
120 172
121 dprintk(DEBUG_9P, "oldtag %d\n", tag); 173 return ret;
122 msg.id = TFLUSH;
123 msg.params.tflush.oldtag = tag;
124 return v9fs_mux_rpc(v9ses, &msg, NULL);
125} 174}
126 175
127/** 176/**
@@ -133,17 +182,22 @@ int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 tag)
133 */ 182 */
134 183
135int 184int
136v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, struct v9fs_fcall **fcall) 185v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, struct v9fs_fcall **rcp)
137{ 186{
138 struct v9fs_fcall msg; 187 int ret;
188 struct v9fs_fcall *tc;
139 189
140 dprintk(DEBUG_9P, "fid %d\n", fid); 190 dprintk(DEBUG_9P, "fid %d\n", fid);
141 if (fcall)
142 *fcall = NULL;
143 191
144 msg.id = TSTAT; 192 ret = -ENOMEM;
145 msg.params.tstat.fid = fid; 193 tc = v9fs_create_tstat(fid);
146 return v9fs_mux_rpc(v9ses, &msg, fcall); 194 if (!IS_ERR(tc)) {
195 ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
196 kfree(tc);
197 } else
198 ret = PTR_ERR(tc);
199
200 return ret;
147} 201}
148 202
149/** 203/**
@@ -157,16 +211,21 @@ v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, struct v9fs_fcall **fcall)
157 211
158int 212int
159v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid, 213v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid,
160 struct v9fs_stat *stat, struct v9fs_fcall **fcall) 214 struct v9fs_wstat *wstat, struct v9fs_fcall **rcp)
161{ 215{
162 struct v9fs_fcall msg; 216 int ret;
217 struct v9fs_fcall *tc;
218
219 dprintk(DEBUG_9P, "fid %d\n", fid);
163 220
164 dprintk(DEBUG_9P, "fid %d length %d\n", fid, (int)stat->length); 221 tc = v9fs_create_twstat(fid, wstat, v9ses->extended);
165 msg.id = TWSTAT; 222 if (!IS_ERR(tc)) {
166 msg.params.twstat.fid = fid; 223 ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
167 msg.params.twstat.stat = stat; 224 kfree(tc);
225 } else
226 ret = PTR_ERR(tc);
168 227
169 return v9fs_mux_rpc(v9ses, &msg, fcall); 228 return ret;
170} 229}
171 230
172/** 231/**
@@ -183,23 +242,27 @@ v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid,
183 242
184int 243int
185v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid, 244v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid,
186 char *name, struct v9fs_fcall **fcall) 245 char *name, struct v9fs_fcall **rcp)
187{ 246{
188 struct v9fs_fcall msg; 247 int ret;
248 struct v9fs_fcall *tc;
249 int nwname;
189 250
190 dprintk(DEBUG_9P, "fid %d newfid %d wname '%s'\n", fid, newfid, name); 251 dprintk(DEBUG_9P, "fid %d newfid %d wname '%s'\n", fid, newfid, name);
191 msg.id = TWALK; 252
192 msg.params.twalk.fid = fid; 253 if (name)
193 msg.params.twalk.newfid = newfid; 254 nwname = 1;
194 255 else
195 if (name) { 256 nwname = 0;
196 msg.params.twalk.nwname = 1; 257
197 msg.params.twalk.wnames = &name; 258 tc = v9fs_create_twalk(fid, newfid, nwname, &name);
198 } else { 259 if (!IS_ERR(tc)) {
199 msg.params.twalk.nwname = 0; 260 ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
200 } 261 kfree(tc);
201 262 } else
202 return v9fs_mux_rpc(v9ses, &msg, fcall); 263 ret = PTR_ERR(tc);
264
265 return ret;
203} 266}
204 267
205/** 268/**
@@ -214,19 +277,21 @@ v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid,
214 277
215int 278int
216v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode, 279v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode,
217 struct v9fs_fcall **fcall) 280 struct v9fs_fcall **rcp)
218{ 281{
219 struct v9fs_fcall msg; 282 int ret;
220 long errorno = -1; 283 struct v9fs_fcall *tc;
221 284
222 dprintk(DEBUG_9P, "fid %d mode %d\n", fid, mode); 285 dprintk(DEBUG_9P, "fid %d mode %d\n", fid, mode);
223 msg.id = TOPEN;
224 msg.params.topen.fid = fid;
225 msg.params.topen.mode = mode;
226 286
227 errorno = v9fs_mux_rpc(v9ses, &msg, fcall); 287 tc = v9fs_create_topen(fid, mode);
288 if (!IS_ERR(tc)) {
289 ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
290 kfree(tc);
291 } else
292 ret = PTR_ERR(tc);
228 293
229 return errorno; 294 return ret;
230} 295}
231 296
232/** 297/**
@@ -239,14 +304,21 @@ v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode,
239 304
240int 305int
241v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, 306v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid,
242 struct v9fs_fcall **fcall) 307 struct v9fs_fcall **rcp)
243{ 308{
244 struct v9fs_fcall msg; 309 int ret;
310 struct v9fs_fcall *tc;
245 311
246 dprintk(DEBUG_9P, "fid %d\n", fid); 312 dprintk(DEBUG_9P, "fid %d\n", fid);
247 msg.id = TREMOVE; 313
248 msg.params.tremove.fid = fid; 314 tc = v9fs_create_tremove(fid);
249 return v9fs_mux_rpc(v9ses, &msg, fcall); 315 if (!IS_ERR(tc)) {
316 ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
317 kfree(tc);
318 } else
319 ret = PTR_ERR(tc);
320
321 return ret;
250} 322}
251 323
252/** 324/**
@@ -262,20 +334,22 @@ v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid,
262 334
263int 335int
264v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, 336v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name,
265 u32 perm, u8 mode, struct v9fs_fcall **fcall) 337 u32 perm, u8 mode, struct v9fs_fcall **rcp)
266{ 338{
267 struct v9fs_fcall msg; 339 int ret;
340 struct v9fs_fcall *tc;
268 341
269 dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n", 342 dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n",
270 fid, name, perm, mode); 343 fid, name, perm, mode);
271 344
272 msg.id = TCREATE; 345 tc = v9fs_create_tcreate(fid, name, perm, mode);
273 msg.params.tcreate.fid = fid; 346 if (!IS_ERR(tc)) {
274 msg.params.tcreate.name = name; 347 ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
275 msg.params.tcreate.perm = perm; 348 kfree(tc);
276 msg.params.tcreate.mode = mode; 349 } else
350 ret = PTR_ERR(tc);
277 351
278 return v9fs_mux_rpc(v9ses, &msg, fcall); 352 return ret;
279} 353}
280 354
281/** 355/**
@@ -290,31 +364,29 @@ v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name,
290 364
291int 365int
292v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, u64 offset, 366v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, u64 offset,
293 u32 count, struct v9fs_fcall **fcall) 367 u32 count, struct v9fs_fcall **rcp)
294{ 368{
295 struct v9fs_fcall msg; 369 int ret;
296 struct v9fs_fcall *rc = NULL; 370 struct v9fs_fcall *tc, *rc;
297 long errorno = -1; 371
298 372 dprintk(DEBUG_9P, "fid %d offset 0x%llux count 0x%x\n", fid,
299 dprintk(DEBUG_9P, "fid %d offset 0x%lx count 0x%x\n", fid, 373 (long long unsigned) offset, count);
300 (long unsigned int)offset, count); 374
301 msg.id = TREAD; 375 tc = v9fs_create_tread(fid, offset, count);
302 msg.params.tread.fid = fid; 376 if (!IS_ERR(tc)) {
303 msg.params.tread.offset = offset; 377 ret = v9fs_mux_rpc(v9ses->mux, tc, &rc);
304 msg.params.tread.count = count; 378 if (!ret)
305 errorno = v9fs_mux_rpc(v9ses, &msg, &rc); 379 ret = rc->params.rread.count;
306 380 if (rcp)
307 if (!errorno) { 381 *rcp = rc;
308 errorno = rc->params.rread.count; 382 else
309 dump_data(rc->params.rread.data, rc->params.rread.count); 383 kfree(rc);
310 } 384
311 385 kfree(tc);
312 if (fcall) 386 } else
313 *fcall = rc; 387 ret = PTR_ERR(tc);
314 else 388
315 kfree(rc); 389 return ret;
316
317 return errorno;
318} 390}
319 391
320/** 392/**
@@ -328,32 +400,30 @@ v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, u64 offset,
328 */ 400 */
329 401
330int 402int
331v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, 403v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset, u32 count,
332 u64 offset, u32 count, void *data, struct v9fs_fcall **fcall) 404 const char __user *data, struct v9fs_fcall **rcp)
333{ 405{
334 struct v9fs_fcall msg; 406 int ret;
335 struct v9fs_fcall *rc = NULL; 407 struct v9fs_fcall *tc, *rc;
336 long errorno = -1;
337 408
338 dprintk(DEBUG_9P, "fid %d offset 0x%llx count 0x%x\n", fid, 409 dprintk(DEBUG_9P, "fid %d offset 0x%llux count 0x%x\n", fid,
339 (unsigned long long)offset, count); 410 (long long unsigned) offset, count);
340 dump_data(data, count);
341 411
342 msg.id = TWRITE; 412 tc = v9fs_create_twrite(fid, offset, count, data);
343 msg.params.twrite.fid = fid; 413 if (!IS_ERR(tc)) {
344 msg.params.twrite.offset = offset; 414 ret = v9fs_mux_rpc(v9ses->mux, tc, &rc);
345 msg.params.twrite.count = count;
346 msg.params.twrite.data = data;
347 415
348 errorno = v9fs_mux_rpc(v9ses, &msg, &rc); 416 if (!ret)
417 ret = rc->params.rwrite.count;
418 if (rcp)
419 *rcp = rc;
420 else
421 kfree(rc);
349 422
350 if (!errorno) 423 kfree(tc);
351 errorno = rc->params.rwrite.count; 424 } else
425 ret = PTR_ERR(tc);
352 426
353 if (fcall) 427 return ret;
354 *fcall = rc;
355 else
356 kfree(rc);
357
358 return errorno;
359} 428}
429
diff --git a/fs/9p/9p.h b/fs/9p/9p.h
index f55424216be2..0cd374d94717 100644
--- a/fs/9p/9p.h
+++ b/fs/9p/9p.h
@@ -3,6 +3,7 @@
3 * 3 *
4 * 9P protocol definitions. 4 * 9P protocol definitions.
5 * 5 *
6 * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
8 * 9 *
@@ -100,9 +101,18 @@ enum {
100 V9FS_QTFILE = 0x00, 101 V9FS_QTFILE = 0x00,
101}; 102};
102 103
104#define V9FS_NOTAG (u16)(~0)
105#define V9FS_NOFID (u32)(~0)
106#define V9FS_MAXWELEM 16
107
103/* ample room for Twrite/Rread header (iounit) */ 108/* ample room for Twrite/Rread header (iounit) */
104#define V9FS_IOHDRSZ 24 109#define V9FS_IOHDRSZ 24
105 110
111struct v9fs_str {
112 u16 len;
113 char *str;
114};
115
106/* qids are the unique ID for a file (like an inode */ 116/* qids are the unique ID for a file (like an inode */
107struct v9fs_qid { 117struct v9fs_qid {
108 u8 type; 118 u8 type;
@@ -120,6 +130,29 @@ struct v9fs_stat {
120 u32 atime; 130 u32 atime;
121 u32 mtime; 131 u32 mtime;
122 u64 length; 132 u64 length;
133 struct v9fs_str name;
134 struct v9fs_str uid;
135 struct v9fs_str gid;
136 struct v9fs_str muid;
137 struct v9fs_str extension; /* 9p2000.u extensions */
138 u32 n_uid; /* 9p2000.u extensions */
139 u32 n_gid; /* 9p2000.u extensions */
140 u32 n_muid; /* 9p2000.u extensions */
141};
142
143/* file metadata (stat) structure used to create Twstat message
144 The is similar to v9fs_stat, but the strings don't point to
145 the same memory block and should be freed separately
146*/
147struct v9fs_wstat {
148 u16 size;
149 u16 type;
150 u32 dev;
151 struct v9fs_qid qid;
152 u32 mode;
153 u32 atime;
154 u32 mtime;
155 u64 length;
123 char *name; 156 char *name;
124 char *uid; 157 char *uid;
125 char *gid; 158 char *gid;
@@ -128,25 +161,24 @@ struct v9fs_stat {
128 u32 n_uid; /* 9p2000.u extensions */ 161 u32 n_uid; /* 9p2000.u extensions */
129 u32 n_gid; /* 9p2000.u extensions */ 162 u32 n_gid; /* 9p2000.u extensions */
130 u32 n_muid; /* 9p2000.u extensions */ 163 u32 n_muid; /* 9p2000.u extensions */
131 char data[0];
132}; 164};
133 165
134/* Structures for Protocol Operations */ 166/* Structures for Protocol Operations */
135 167
136struct Tversion { 168struct Tversion {
137 u32 msize; 169 u32 msize;
138 char *version; 170 struct v9fs_str version;
139}; 171};
140 172
141struct Rversion { 173struct Rversion {
142 u32 msize; 174 u32 msize;
143 char *version; 175 struct v9fs_str version;
144}; 176};
145 177
146struct Tauth { 178struct Tauth {
147 u32 afid; 179 u32 afid;
148 char *uname; 180 struct v9fs_str uname;
149 char *aname; 181 struct v9fs_str aname;
150}; 182};
151 183
152struct Rauth { 184struct Rauth {
@@ -154,12 +186,12 @@ struct Rauth {
154}; 186};
155 187
156struct Rerror { 188struct Rerror {
157 char *error; 189 struct v9fs_str error;
158 u32 errno; /* 9p2000.u extension */ 190 u32 errno; /* 9p2000.u extension */
159}; 191};
160 192
161struct Tflush { 193struct Tflush {
162 u32 oldtag; 194 u16 oldtag;
163}; 195};
164 196
165struct Rflush { 197struct Rflush {
@@ -168,8 +200,8 @@ struct Rflush {
168struct Tattach { 200struct Tattach {
169 u32 fid; 201 u32 fid;
170 u32 afid; 202 u32 afid;
171 char *uname; 203 struct v9fs_str uname;
172 char *aname; 204 struct v9fs_str aname;
173}; 205};
174 206
175struct Rattach { 207struct Rattach {
@@ -179,13 +211,13 @@ struct Rattach {
179struct Twalk { 211struct Twalk {
180 u32 fid; 212 u32 fid;
181 u32 newfid; 213 u32 newfid;
182 u32 nwname; 214 u16 nwname;
183 char **wnames; 215 struct v9fs_str wnames[16];
184}; 216};
185 217
186struct Rwalk { 218struct Rwalk {
187 u32 nwqid; 219 u16 nwqid;
188 struct v9fs_qid *wqids; 220 struct v9fs_qid wqids[16];
189}; 221};
190 222
191struct Topen { 223struct Topen {
@@ -200,7 +232,7 @@ struct Ropen {
200 232
201struct Tcreate { 233struct Tcreate {
202 u32 fid; 234 u32 fid;
203 char *name; 235 struct v9fs_str name;
204 u32 perm; 236 u32 perm;
205 u8 mode; 237 u8 mode;
206}; 238};
@@ -251,12 +283,12 @@ struct Tstat {
251}; 283};
252 284
253struct Rstat { 285struct Rstat {
254 struct v9fs_stat *stat; 286 struct v9fs_stat stat;
255}; 287};
256 288
257struct Twstat { 289struct Twstat {
258 u32 fid; 290 u32 fid;
259 struct v9fs_stat *stat; 291 struct v9fs_stat stat;
260}; 292};
261 293
262struct Rwstat { 294struct Rwstat {
@@ -271,6 +303,7 @@ struct v9fs_fcall {
271 u32 size; 303 u32 size;
272 u8 id; 304 u8 id;
273 u16 tag; 305 u16 tag;
306 void *sdata;
274 307
275 union { 308 union {
276 struct Tversion tversion; 309 struct Tversion tversion;
@@ -303,7 +336,9 @@ struct v9fs_fcall {
303 } params; 336 } params;
304}; 337};
305 338
306#define FCALL_ERROR(fcall) (fcall ? fcall->params.rerror.error : "") 339#define PRINT_FCALL_ERROR(s, fcall) dprintk(DEBUG_ERROR, "%s: %.*s\n", s, \
340 fcall?fcall->params.rerror.error.len:0, \
341 fcall?fcall->params.rerror.error.str:"");
307 342
308int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize, 343int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize,
309 char *version, struct v9fs_fcall **rcall); 344 char *version, struct v9fs_fcall **rcall);
@@ -311,8 +346,7 @@ int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize,
311int v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname, 346int v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname,
312 u32 fid, u32 afid, struct v9fs_fcall **rcall); 347 u32 fid, u32 afid, struct v9fs_fcall **rcall);
313 348
314int v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid, 349int v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid);
315 struct v9fs_fcall **rcall);
316 350
317int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag); 351int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag);
318 352
@@ -320,7 +354,7 @@ int v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid,
320 struct v9fs_fcall **rcall); 354 struct v9fs_fcall **rcall);
321 355
322int v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid, 356int v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid,
323 struct v9fs_stat *stat, struct v9fs_fcall **rcall); 357 struct v9fs_wstat *wstat, struct v9fs_fcall **rcall);
324 358
325int v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid, 359int v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid,
326 char *name, struct v9fs_fcall **rcall); 360 char *name, struct v9fs_fcall **rcall);
@@ -338,4 +372,5 @@ int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid,
338 u64 offset, u32 count, struct v9fs_fcall **rcall); 372 u64 offset, u32 count, struct v9fs_fcall **rcall);
339 373
340int v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset, 374int v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset,
341 u32 count, void *data, struct v9fs_fcall **rcall); 375 u32 count, const char __user * data,
376 struct v9fs_fcall **rcall);
diff --git a/fs/9p/Makefile b/fs/9p/Makefile
index e4e4ffe5a7dc..3d023089707e 100644
--- a/fs/9p/Makefile
+++ b/fs/9p/Makefile
@@ -1,17 +1,17 @@
1obj-$(CONFIG_9P_FS) := 9p2000.o 1obj-$(CONFIG_9P_FS) := 9p2000.o
2 2
39p2000-objs := \ 39p2000-objs := \
4 trans_fd.o \
5 trans_sock.o \
6 mux.o \
7 9p.o \
8 conv.o \
4 vfs_super.o \ 9 vfs_super.o \
5 vfs_inode.o \ 10 vfs_inode.o \
6 vfs_file.o \ 11 vfs_file.o \
7 vfs_dir.o \ 12 vfs_dir.o \
8 vfs_dentry.o \ 13 vfs_dentry.o \
9 error.o \ 14 error.o \
10 mux.o \
11 trans_fd.o \
12 trans_sock.o \
13 9p.o \
14 conv.o \
15 v9fs.o \ 15 v9fs.o \
16 fid.o 16 fid.o
17 17
diff --git a/fs/9p/conv.c b/fs/9p/conv.c
index 18121af99d3e..55ccfa10ee9e 100644
--- a/fs/9p/conv.c
+++ b/fs/9p/conv.c
@@ -30,7 +30,7 @@
30#include <linux/errno.h> 30#include <linux/errno.h>
31#include <linux/fs.h> 31#include <linux/fs.h>
32#include <linux/idr.h> 32#include <linux/idr.h>
33 33#include <asm/uaccess.h>
34#include "debug.h" 34#include "debug.h"
35#include "v9fs.h" 35#include "v9fs.h"
36#include "9p.h" 36#include "9p.h"
@@ -58,12 +58,15 @@ static inline int buf_check_overflow(struct cbuf *buf)
58 58
59static inline int buf_check_size(struct cbuf *buf, int len) 59static inline int buf_check_size(struct cbuf *buf, int len)
60{ 60{
61 if (buf->p+len > buf->ep) { 61 if (buf->p + len > buf->ep) {
62 if (buf->p < buf->ep) { 62 if (buf->p < buf->ep) {
63 eprintk(KERN_ERR, "buffer overflow\n"); 63 eprintk(KERN_ERR, "buffer overflow: want %d has %d\n",
64 len, (int)(buf->ep - buf->p));
65 dump_stack();
64 buf->p = buf->ep + 1; 66 buf->p = buf->ep + 1;
65 return 0;
66 } 67 }
68
69 return 0;
67 } 70 }
68 71
69 return 1; 72 return 1;
@@ -127,14 +130,6 @@ static inline void buf_put_string(struct cbuf *buf, const char *s)
127 buf_put_stringn(buf, s, strlen(s)); 130 buf_put_stringn(buf, s, strlen(s));
128} 131}
129 132
130static inline void buf_put_data(struct cbuf *buf, void *data, u32 datalen)
131{
132 if (buf_check_size(buf, datalen)) {
133 memcpy(buf->p, data, datalen);
134 buf->p += datalen;
135 }
136}
137
138static inline u8 buf_get_int8(struct cbuf *buf) 133static inline u8 buf_get_int8(struct cbuf *buf)
139{ 134{
140 u8 ret = 0; 135 u8 ret = 0;
@@ -183,86 +178,37 @@ static inline u64 buf_get_int64(struct cbuf *buf)
183 return ret; 178 return ret;
184} 179}
185 180
186static inline int 181static inline void buf_get_str(struct cbuf *buf, struct v9fs_str *vstr)
187buf_get_string(struct cbuf *buf, char *data, unsigned int datalen)
188{
189 u16 len = 0;
190
191 len = buf_get_int16(buf);
192 if (!buf_check_overflow(buf) && buf_check_size(buf, len) && len+1>datalen) {
193 memcpy(data, buf->p, len);
194 data[len] = 0;
195 buf->p += len;
196 len++;
197 }
198
199 return len;
200}
201
202static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf)
203{
204 char *ret;
205 u16 len;
206
207 ret = NULL;
208 len = buf_get_int16(buf);
209
210 if (!buf_check_overflow(buf) && buf_check_size(buf, len) &&
211 buf_check_size(sbuf, len+1)) {
212
213 memcpy(sbuf->p, buf->p, len);
214 sbuf->p[len] = 0;
215 ret = sbuf->p;
216 buf->p += len;
217 sbuf->p += len + 1;
218 }
219
220 return ret;
221}
222
223static inline int buf_get_data(struct cbuf *buf, void *data, int datalen)
224{ 182{
225 int ret = 0; 183 vstr->len = buf_get_int16(buf);
226 184 if (!buf_check_overflow(buf) && buf_check_size(buf, vstr->len)) {
227 if (buf_check_size(buf, datalen)) { 185 vstr->str = buf->p;
228 memcpy(data, buf->p, datalen); 186 buf->p += vstr->len;
229 buf->p += datalen; 187 } else {
230 ret = datalen; 188 vstr->len = 0;
189 vstr->str = NULL;
231 } 190 }
232
233 return ret;
234} 191}
235 192
236static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf, 193static inline void buf_get_qid(struct cbuf *bufp, struct v9fs_qid *qid)
237 int datalen)
238{ 194{
239 char *ret = NULL; 195 qid->type = buf_get_int8(bufp);
240 int n = 0; 196 qid->version = buf_get_int32(bufp);
241 197 qid->path = buf_get_int64(bufp);
242 if (buf_check_size(dbuf, datalen)) {
243 n = buf_get_data(buf, dbuf->p, datalen);
244 if (n > 0) {
245 ret = dbuf->p;
246 dbuf->p += n;
247 }
248 }
249
250 return ret;
251} 198}
252 199
253/** 200/**
254 * v9fs_size_stat - calculate the size of a variable length stat struct 201 * v9fs_size_wstat - calculate the size of a variable length stat struct
255 * @v9ses: session information
256 * @stat: metadata (stat) structure 202 * @stat: metadata (stat) structure
203 * @extended: non-zero if 9P2000.u
257 * 204 *
258 */ 205 */
259 206
260static int v9fs_size_stat(struct v9fs_session_info *v9ses, 207static int v9fs_size_wstat(struct v9fs_wstat *wstat, int extended)
261 struct v9fs_stat *stat)
262{ 208{
263 int size = 0; 209 int size = 0;
264 210
265 if (stat == NULL) { 211 if (wstat == NULL) {
266 eprintk(KERN_ERR, "v9fs_size_stat: got a NULL stat pointer\n"); 212 eprintk(KERN_ERR, "v9fs_size_stat: got a NULL stat pointer\n");
267 return 0; 213 return 0;
268 } 214 }
@@ -279,82 +225,38 @@ static int v9fs_size_stat(struct v9fs_session_info *v9ses,
279 8 + /* length[8] */ 225 8 + /* length[8] */
280 8; /* minimum sum of string lengths */ 226 8; /* minimum sum of string lengths */
281 227
282 if (stat->name) 228 if (wstat->name)
283 size += strlen(stat->name); 229 size += strlen(wstat->name);
284 if (stat->uid) 230 if (wstat->uid)
285 size += strlen(stat->uid); 231 size += strlen(wstat->uid);
286 if (stat->gid) 232 if (wstat->gid)
287 size += strlen(stat->gid); 233 size += strlen(wstat->gid);
288 if (stat->muid) 234 if (wstat->muid)
289 size += strlen(stat->muid); 235 size += strlen(wstat->muid);
290 236
291 if (v9ses->extended) { 237 if (extended) {
292 size += 4 + /* n_uid[4] */ 238 size += 4 + /* n_uid[4] */
293 4 + /* n_gid[4] */ 239 4 + /* n_gid[4] */
294 4 + /* n_muid[4] */ 240 4 + /* n_muid[4] */
295 2; /* string length of extension[4] */ 241 2; /* string length of extension[4] */
296 if (stat->extension) 242 if (wstat->extension)
297 size += strlen(stat->extension); 243 size += strlen(wstat->extension);
298 } 244 }
299 245
300 return size; 246 return size;
301} 247}
302 248
303/** 249/**
304 * serialize_stat - safely format a stat structure for transmission 250 * buf_get_stat - safely decode a recieved metadata (stat) structure
305 * @v9ses: session info
306 * @stat: metadata (stat) structure
307 * @bufp: buffer to serialize structure into
308 *
309 */
310
311static int
312serialize_stat(struct v9fs_session_info *v9ses, struct v9fs_stat *stat,
313 struct cbuf *bufp)
314{
315 buf_put_int16(bufp, stat->size);
316 buf_put_int16(bufp, stat->type);
317 buf_put_int32(bufp, stat->dev);
318 buf_put_int8(bufp, stat->qid.type);
319 buf_put_int32(bufp, stat->qid.version);
320 buf_put_int64(bufp, stat->qid.path);
321 buf_put_int32(bufp, stat->mode);
322 buf_put_int32(bufp, stat->atime);
323 buf_put_int32(bufp, stat->mtime);
324 buf_put_int64(bufp, stat->length);
325
326 buf_put_string(bufp, stat->name);
327 buf_put_string(bufp, stat->uid);
328 buf_put_string(bufp, stat->gid);
329 buf_put_string(bufp, stat->muid);
330
331 if (v9ses->extended) {
332 buf_put_string(bufp, stat->extension);
333 buf_put_int32(bufp, stat->n_uid);
334 buf_put_int32(bufp, stat->n_gid);
335 buf_put_int32(bufp, stat->n_muid);
336 }
337
338 if (buf_check_overflow(bufp))
339 return 0;
340
341 return stat->size;
342}
343
344/**
345 * deserialize_stat - safely decode a recieved metadata (stat) structure
346 * @v9ses: session info
347 * @bufp: buffer to deserialize 251 * @bufp: buffer to deserialize
348 * @stat: metadata (stat) structure 252 * @stat: metadata (stat) structure
349 * @dbufp: buffer to deserialize variable strings into 253 * @extended: non-zero if 9P2000.u
350 * 254 *
351 */ 255 */
352 256
353static inline int 257static inline void
354deserialize_stat(struct v9fs_session_info *v9ses, struct cbuf *bufp, 258buf_get_stat(struct cbuf *bufp, struct v9fs_stat *stat, int extended)
355 struct v9fs_stat *stat, struct cbuf *dbufp)
356{ 259{
357
358 stat->size = buf_get_int16(bufp); 260 stat->size = buf_get_int16(bufp);
359 stat->type = buf_get_int16(bufp); 261 stat->type = buf_get_int16(bufp);
360 stat->dev = buf_get_int32(bufp); 262 stat->dev = buf_get_int32(bufp);
@@ -365,282 +267,82 @@ deserialize_stat(struct v9fs_session_info *v9ses, struct cbuf *bufp,
365 stat->atime = buf_get_int32(bufp); 267 stat->atime = buf_get_int32(bufp);
366 stat->mtime = buf_get_int32(bufp); 268 stat->mtime = buf_get_int32(bufp);
367 stat->length = buf_get_int64(bufp); 269 stat->length = buf_get_int64(bufp);
368 stat->name = buf_get_stringb(bufp, dbufp); 270 buf_get_str(bufp, &stat->name);
369 stat->uid = buf_get_stringb(bufp, dbufp); 271 buf_get_str(bufp, &stat->uid);
370 stat->gid = buf_get_stringb(bufp, dbufp); 272 buf_get_str(bufp, &stat->gid);
371 stat->muid = buf_get_stringb(bufp, dbufp); 273 buf_get_str(bufp, &stat->muid);
372 274
373 if (v9ses->extended) { 275 if (extended) {
374 stat->extension = buf_get_stringb(bufp, dbufp); 276 buf_get_str(bufp, &stat->extension);
375 stat->n_uid = buf_get_int32(bufp); 277 stat->n_uid = buf_get_int32(bufp);
376 stat->n_gid = buf_get_int32(bufp); 278 stat->n_gid = buf_get_int32(bufp);
377 stat->n_muid = buf_get_int32(bufp); 279 stat->n_muid = buf_get_int32(bufp);
378 } 280 }
379
380 if (buf_check_overflow(bufp) || buf_check_overflow(dbufp))
381 return 0;
382
383 return stat->size + 2;
384}
385
386/**
387 * deserialize_statb - wrapper for decoding a received metadata structure
388 * @v9ses: session info
389 * @bufp: buffer to deserialize
390 * @dbufp: buffer to deserialize variable strings into
391 *
392 */
393
394static inline struct v9fs_stat *deserialize_statb(struct v9fs_session_info
395 *v9ses, struct cbuf *bufp,
396 struct cbuf *dbufp)
397{
398 struct v9fs_stat *ret = buf_alloc(dbufp, sizeof(struct v9fs_stat));
399
400 if (ret) {
401 int n = deserialize_stat(v9ses, bufp, ret, dbufp);
402 if (n <= 0)
403 return NULL;
404 }
405
406 return ret;
407} 281}
408 282
409/** 283/**
410 * v9fs_deserialize_stat - decode a received metadata structure 284 * v9fs_deserialize_stat - decode a received metadata structure
411 * @v9ses: session info
412 * @buf: buffer to deserialize 285 * @buf: buffer to deserialize
413 * @buflen: length of received buffer 286 * @buflen: length of received buffer
414 * @stat: metadata structure to decode into 287 * @stat: metadata structure to decode into
415 * @statlen: length of destination metadata structure 288 * @extended: non-zero if 9P2000.u
416 * 289 *
290 * Note: stat will point to the buf region.
417 */ 291 */
418 292
419int 293int
420v9fs_deserialize_stat(struct v9fs_session_info *v9ses, void *buf, 294v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat,
421 u32 buflen, struct v9fs_stat *stat, u32 statlen) 295 int extended)
422{ 296{
423 struct cbuf buffer; 297 struct cbuf buffer;
424 struct cbuf *bufp = &buffer; 298 struct cbuf *bufp = &buffer;
425 struct cbuf dbuffer; 299 unsigned char *p;
426 struct cbuf *dbufp = &dbuffer;
427 300
428 buf_init(bufp, buf, buflen); 301 buf_init(bufp, buf, buflen);
429 buf_init(dbufp, (char *)stat + sizeof(struct v9fs_stat), 302 p = bufp->p;
430 statlen - sizeof(struct v9fs_stat)); 303 buf_get_stat(bufp, stat, extended);
431
432 return deserialize_stat(v9ses, bufp, stat, dbufp);
433}
434
435static inline int
436v9fs_size_fcall(struct v9fs_session_info *v9ses, struct v9fs_fcall *fcall)
437{
438 int size = 4 + 1 + 2; /* size[4] msg[1] tag[2] */
439 int i = 0;
440
441 switch (fcall->id) {
442 default:
443 eprintk(KERN_ERR, "bad msg type %d\n", fcall->id);
444 return 0;
445 case TVERSION: /* msize[4] version[s] */
446 size += 4 + 2 + strlen(fcall->params.tversion.version);
447 break;
448 case TAUTH: /* afid[4] uname[s] aname[s] */
449 size += 4 + 2 + strlen(fcall->params.tauth.uname) +
450 2 + strlen(fcall->params.tauth.aname);
451 break;
452 case TFLUSH: /* oldtag[2] */
453 size += 2;
454 break;
455 case TATTACH: /* fid[4] afid[4] uname[s] aname[s] */
456 size += 4 + 4 + 2 + strlen(fcall->params.tattach.uname) +
457 2 + strlen(fcall->params.tattach.aname);
458 break;
459 case TWALK: /* fid[4] newfid[4] nwname[2] nwname*(wname[s]) */
460 size += 4 + 4 + 2;
461 /* now compute total for the array of names */
462 for (i = 0; i < fcall->params.twalk.nwname; i++)
463 size += 2 + strlen(fcall->params.twalk.wnames[i]);
464 break;
465 case TOPEN: /* fid[4] mode[1] */
466 size += 4 + 1;
467 break;
468 case TCREATE: /* fid[4] name[s] perm[4] mode[1] */
469 size += 4 + 2 + strlen(fcall->params.tcreate.name) + 4 + 1;
470 break;
471 case TREAD: /* fid[4] offset[8] count[4] */
472 size += 4 + 8 + 4;
473 break;
474 case TWRITE: /* fid[4] offset[8] count[4] data[count] */
475 size += 4 + 8 + 4 + fcall->params.twrite.count;
476 break;
477 case TCLUNK: /* fid[4] */
478 size += 4;
479 break;
480 case TREMOVE: /* fid[4] */
481 size += 4;
482 break;
483 case TSTAT: /* fid[4] */
484 size += 4;
485 break;
486 case TWSTAT: /* fid[4] stat[n] */
487 fcall->params.twstat.stat->size =
488 v9fs_size_stat(v9ses, fcall->params.twstat.stat);
489 size += 4 + 2 + 2 + fcall->params.twstat.stat->size;
490 }
491 return size;
492}
493
494/*
495 * v9fs_serialize_fcall - marshall fcall struct into a packet
496 * @v9ses: session information
497 * @fcall: structure to convert
498 * @data: buffer to serialize fcall into
499 * @datalen: length of buffer to serialize fcall into
500 *
501 */
502
503int
504v9fs_serialize_fcall(struct v9fs_session_info *v9ses, struct v9fs_fcall *fcall,
505 void *data, u32 datalen)
506{
507 int i = 0;
508 struct v9fs_stat *stat = NULL;
509 struct cbuf buffer;
510 struct cbuf *bufp = &buffer;
511
512 buf_init(bufp, data, datalen);
513
514 if (!fcall) {
515 eprintk(KERN_ERR, "no fcall\n");
516 return -EINVAL;
517 }
518
519 fcall->size = v9fs_size_fcall(v9ses, fcall);
520
521 buf_put_int32(bufp, fcall->size);
522 buf_put_int8(bufp, fcall->id);
523 buf_put_int16(bufp, fcall->tag);
524
525 dprintk(DEBUG_CONV, "size %d id %d tag %d\n", fcall->size, fcall->id,
526 fcall->tag);
527
528 /* now encode it */
529 switch (fcall->id) {
530 default:
531 eprintk(KERN_ERR, "bad msg type: %d\n", fcall->id);
532 return -EPROTO;
533 case TVERSION:
534 buf_put_int32(bufp, fcall->params.tversion.msize);
535 buf_put_string(bufp, fcall->params.tversion.version);
536 break;
537 case TAUTH:
538 buf_put_int32(bufp, fcall->params.tauth.afid);
539 buf_put_string(bufp, fcall->params.tauth.uname);
540 buf_put_string(bufp, fcall->params.tauth.aname);
541 break;
542 case TFLUSH:
543 buf_put_int16(bufp, fcall->params.tflush.oldtag);
544 break;
545 case TATTACH:
546 buf_put_int32(bufp, fcall->params.tattach.fid);
547 buf_put_int32(bufp, fcall->params.tattach.afid);
548 buf_put_string(bufp, fcall->params.tattach.uname);
549 buf_put_string(bufp, fcall->params.tattach.aname);
550 break;
551 case TWALK:
552 buf_put_int32(bufp, fcall->params.twalk.fid);
553 buf_put_int32(bufp, fcall->params.twalk.newfid);
554 buf_put_int16(bufp, fcall->params.twalk.nwname);
555 for (i = 0; i < fcall->params.twalk.nwname; i++)
556 buf_put_string(bufp, fcall->params.twalk.wnames[i]);
557 break;
558 case TOPEN:
559 buf_put_int32(bufp, fcall->params.topen.fid);
560 buf_put_int8(bufp, fcall->params.topen.mode);
561 break;
562 case TCREATE:
563 buf_put_int32(bufp, fcall->params.tcreate.fid);
564 buf_put_string(bufp, fcall->params.tcreate.name);
565 buf_put_int32(bufp, fcall->params.tcreate.perm);
566 buf_put_int8(bufp, fcall->params.tcreate.mode);
567 break;
568 case TREAD:
569 buf_put_int32(bufp, fcall->params.tread.fid);
570 buf_put_int64(bufp, fcall->params.tread.offset);
571 buf_put_int32(bufp, fcall->params.tread.count);
572 break;
573 case TWRITE:
574 buf_put_int32(bufp, fcall->params.twrite.fid);
575 buf_put_int64(bufp, fcall->params.twrite.offset);
576 buf_put_int32(bufp, fcall->params.twrite.count);
577 buf_put_data(bufp, fcall->params.twrite.data,
578 fcall->params.twrite.count);
579 break;
580 case TCLUNK:
581 buf_put_int32(bufp, fcall->params.tclunk.fid);
582 break;
583 case TREMOVE:
584 buf_put_int32(bufp, fcall->params.tremove.fid);
585 break;
586 case TSTAT:
587 buf_put_int32(bufp, fcall->params.tstat.fid);
588 break;
589 case TWSTAT:
590 buf_put_int32(bufp, fcall->params.twstat.fid);
591 stat = fcall->params.twstat.stat;
592
593 buf_put_int16(bufp, stat->size + 2);
594 serialize_stat(v9ses, stat, bufp);
595 break;
596 }
597 304
598 if (buf_check_overflow(bufp)) 305 if (buf_check_overflow(bufp))
599 return -EIO; 306 return 0;
600 307 else
601 return fcall->size; 308 return bufp->p - p;
602} 309}
603 310
604/** 311/**
605 * deserialize_fcall - unmarshal a response 312 * deserialize_fcall - unmarshal a response
606 * @v9ses: session information
607 * @msgsize: size of rcall message
608 * @buf: recieved buffer 313 * @buf: recieved buffer
609 * @buflen: length of received buffer 314 * @buflen: length of received buffer
610 * @rcall: fcall structure to populate 315 * @rcall: fcall structure to populate
611 * @rcalllen: length of fcall structure to populate 316 * @rcalllen: length of fcall structure to populate
317 * @extended: non-zero if 9P2000.u
612 * 318 *
613 */ 319 */
614 320
615int 321int
616v9fs_deserialize_fcall(struct v9fs_session_info *v9ses, u32 msgsize, 322v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall,
617 void *buf, u32 buflen, struct v9fs_fcall *rcall, 323 int extended)
618 int rcalllen)
619{ 324{
620 325
621 struct cbuf buffer; 326 struct cbuf buffer;
622 struct cbuf *bufp = &buffer; 327 struct cbuf *bufp = &buffer;
623 struct cbuf dbuffer;
624 struct cbuf *dbufp = &dbuffer;
625 int i = 0; 328 int i = 0;
626 329
627 buf_init(bufp, buf, buflen); 330 buf_init(bufp, buf, buflen);
628 buf_init(dbufp, (char *)rcall + sizeof(struct v9fs_fcall),
629 rcalllen - sizeof(struct v9fs_fcall));
630 331
631 rcall->size = msgsize; 332 rcall->size = buf_get_int32(bufp);
632 rcall->id = buf_get_int8(bufp); 333 rcall->id = buf_get_int8(bufp);
633 rcall->tag = buf_get_int16(bufp); 334 rcall->tag = buf_get_int16(bufp);
634 335
635 dprintk(DEBUG_CONV, "size %d id %d tag %d\n", rcall->size, rcall->id, 336 dprintk(DEBUG_CONV, "size %d id %d tag %d\n", rcall->size, rcall->id,
636 rcall->tag); 337 rcall->tag);
338
637 switch (rcall->id) { 339 switch (rcall->id) {
638 default: 340 default:
639 eprintk(KERN_ERR, "unknown message type: %d\n", rcall->id); 341 eprintk(KERN_ERR, "unknown message type: %d\n", rcall->id);
640 return -EPROTO; 342 return -EPROTO;
641 case RVERSION: 343 case RVERSION:
642 rcall->params.rversion.msize = buf_get_int32(bufp); 344 rcall->params.rversion.msize = buf_get_int32(bufp);
643 rcall->params.rversion.version = buf_get_stringb(bufp, dbufp); 345 buf_get_str(bufp, &rcall->params.rversion.version);
644 break; 346 break;
645 case RFLUSH: 347 case RFLUSH:
646 break; 348 break;
@@ -651,34 +353,27 @@ v9fs_deserialize_fcall(struct v9fs_session_info *v9ses, u32 msgsize,
651 break; 353 break;
652 case RWALK: 354 case RWALK:
653 rcall->params.rwalk.nwqid = buf_get_int16(bufp); 355 rcall->params.rwalk.nwqid = buf_get_int16(bufp);
654 rcall->params.rwalk.wqids = buf_alloc(dbufp, 356 if (rcall->params.rwalk.nwqid > V9FS_MAXWELEM) {
655 rcall->params.rwalk.nwqid * sizeof(struct v9fs_qid)); 357 eprintk(KERN_ERR, "Rwalk with more than %d qids: %d\n",
656 if (rcall->params.rwalk.wqids) 358 V9FS_MAXWELEM, rcall->params.rwalk.nwqid);
657 for (i = 0; i < rcall->params.rwalk.nwqid; i++) { 359 return -EPROTO;
658 rcall->params.rwalk.wqids[i].type = 360 }
659 buf_get_int8(bufp); 361
660 rcall->params.rwalk.wqids[i].version = 362 for (i = 0; i < rcall->params.rwalk.nwqid; i++)
661 buf_get_int16(bufp); 363 buf_get_qid(bufp, &rcall->params.rwalk.wqids[i]);
662 rcall->params.rwalk.wqids[i].path =
663 buf_get_int64(bufp);
664 }
665 break; 364 break;
666 case ROPEN: 365 case ROPEN:
667 rcall->params.ropen.qid.type = buf_get_int8(bufp); 366 buf_get_qid(bufp, &rcall->params.ropen.qid);
668 rcall->params.ropen.qid.version = buf_get_int32(bufp);
669 rcall->params.ropen.qid.path = buf_get_int64(bufp);
670 rcall->params.ropen.iounit = buf_get_int32(bufp); 367 rcall->params.ropen.iounit = buf_get_int32(bufp);
671 break; 368 break;
672 case RCREATE: 369 case RCREATE:
673 rcall->params.rcreate.qid.type = buf_get_int8(bufp); 370 buf_get_qid(bufp, &rcall->params.rcreate.qid);
674 rcall->params.rcreate.qid.version = buf_get_int32(bufp);
675 rcall->params.rcreate.qid.path = buf_get_int64(bufp);
676 rcall->params.rcreate.iounit = buf_get_int32(bufp); 371 rcall->params.rcreate.iounit = buf_get_int32(bufp);
677 break; 372 break;
678 case RREAD: 373 case RREAD:
679 rcall->params.rread.count = buf_get_int32(bufp); 374 rcall->params.rread.count = buf_get_int32(bufp);
680 rcall->params.rread.data = buf_get_datab(bufp, dbufp, 375 rcall->params.rread.data = bufp->p;
681 rcall->params.rread.count); 376 buf_check_size(bufp, rcall->params.rread.count);
682 break; 377 break;
683 case RWRITE: 378 case RWRITE:
684 rcall->params.rwrite.count = buf_get_int32(bufp); 379 rcall->params.rwrite.count = buf_get_int32(bufp);
@@ -689,20 +384,443 @@ v9fs_deserialize_fcall(struct v9fs_session_info *v9ses, u32 msgsize,
689 break; 384 break;
690 case RSTAT: 385 case RSTAT:
691 buf_get_int16(bufp); 386 buf_get_int16(bufp);
692 rcall->params.rstat.stat = 387 buf_get_stat(bufp, &rcall->params.rstat.stat, extended);
693 deserialize_statb(v9ses, bufp, dbufp);
694 break; 388 break;
695 case RWSTAT: 389 case RWSTAT:
696 break; 390 break;
697 case RERROR: 391 case RERROR:
698 rcall->params.rerror.error = buf_get_stringb(bufp, dbufp); 392 buf_get_str(bufp, &rcall->params.rerror.error);
699 if (v9ses->extended) 393 if (extended)
700 rcall->params.rerror.errno = buf_get_int16(bufp); 394 rcall->params.rerror.errno = buf_get_int16(bufp);
701 break; 395 break;
702 } 396 }
703 397
704 if (buf_check_overflow(bufp) || buf_check_overflow(dbufp)) 398 if (buf_check_overflow(bufp)) {
399 dprintk(DEBUG_ERROR, "buffer overflow\n");
705 return -EIO; 400 return -EIO;
401 }
402
403 return bufp->p - bufp->sp;
404}
405
406static inline void v9fs_put_int8(struct cbuf *bufp, u8 val, u8 * p)
407{
408 *p = val;
409 buf_put_int8(bufp, val);
410}
411
412static inline void v9fs_put_int16(struct cbuf *bufp, u16 val, u16 * p)
413{
414 *p = val;
415 buf_put_int16(bufp, val);
416}
417
418static inline void v9fs_put_int32(struct cbuf *bufp, u32 val, u32 * p)
419{
420 *p = val;
421 buf_put_int32(bufp, val);
422}
423
424static inline void v9fs_put_int64(struct cbuf *bufp, u64 val, u64 * p)
425{
426 *p = val;
427 buf_put_int64(bufp, val);
428}
706 429
707 return rcall->size; 430static inline void
431v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str)
432{
433 if (data) {
434 str->len = strlen(data);
435 str->str = bufp->p;
436 } else {
437 str->len = 0;
438 str->str = NULL;
439 }
440
441 buf_put_stringn(bufp, data, str->len);
442}
443
444static inline int
445v9fs_put_user_data(struct cbuf *bufp, const char __user * data, int count,
446 unsigned char **pdata)
447{
448 *pdata = buf_alloc(bufp, count);
449 return copy_from_user(*pdata, data, count);
450}
451
452static void
453v9fs_put_wstat(struct cbuf *bufp, struct v9fs_wstat *wstat,
454 struct v9fs_stat *stat, int statsz, int extended)
455{
456 v9fs_put_int16(bufp, statsz, &stat->size);
457 v9fs_put_int16(bufp, wstat->type, &stat->type);
458 v9fs_put_int32(bufp, wstat->dev, &stat->dev);
459 v9fs_put_int8(bufp, wstat->qid.type, &stat->qid.type);
460 v9fs_put_int32(bufp, wstat->qid.version, &stat->qid.version);
461 v9fs_put_int64(bufp, wstat->qid.path, &stat->qid.path);
462 v9fs_put_int32(bufp, wstat->mode, &stat->mode);
463 v9fs_put_int32(bufp, wstat->atime, &stat->atime);
464 v9fs_put_int32(bufp, wstat->mtime, &stat->mtime);
465 v9fs_put_int64(bufp, wstat->length, &stat->length);
466
467 v9fs_put_str(bufp, wstat->name, &stat->name);
468 v9fs_put_str(bufp, wstat->uid, &stat->uid);
469 v9fs_put_str(bufp, wstat->gid, &stat->gid);
470 v9fs_put_str(bufp, wstat->muid, &stat->muid);
471
472 if (extended) {
473 v9fs_put_str(bufp, wstat->extension, &stat->extension);
474 v9fs_put_int32(bufp, wstat->n_uid, &stat->n_uid);
475 v9fs_put_int32(bufp, wstat->n_gid, &stat->n_gid);
476 v9fs_put_int32(bufp, wstat->n_muid, &stat->n_muid);
477 }
478}
479
480static struct v9fs_fcall *
481v9fs_create_common(struct cbuf *bufp, u32 size, u8 id)
482{
483 struct v9fs_fcall *fc;
484
485 size += 4 + 1 + 2; /* size[4] id[1] tag[2] */
486 fc = kmalloc(sizeof(struct v9fs_fcall) + size, GFP_KERNEL);
487 if (!fc)
488 return ERR_PTR(-ENOMEM);
489
490 fc->sdata = (char *)fc + sizeof(*fc);
491
492 buf_init(bufp, (char *)fc->sdata, size);
493 v9fs_put_int32(bufp, size, &fc->size);
494 v9fs_put_int8(bufp, id, &fc->id);
495 v9fs_put_int16(bufp, V9FS_NOTAG, &fc->tag);
496
497 return fc;
498}
499
500void v9fs_set_tag(struct v9fs_fcall *fc, u16 tag)
501{
502 fc->tag = tag;
503 *(__le16 *) (fc->sdata + 5) = cpu_to_le16(tag);
504}
505
506struct v9fs_fcall *v9fs_create_tversion(u32 msize, char *version)
507{
508 int size;
509 struct v9fs_fcall *fc;
510 struct cbuf buffer;
511 struct cbuf *bufp = &buffer;
512
513 size = 4 + 2 + strlen(version); /* msize[4] version[s] */
514 fc = v9fs_create_common(bufp, size, TVERSION);
515 if (IS_ERR(fc))
516 goto error;
517
518 v9fs_put_int32(bufp, msize, &fc->params.tversion.msize);
519 v9fs_put_str(bufp, version, &fc->params.tversion.version);
520
521 if (buf_check_overflow(bufp)) {
522 kfree(fc);
523 fc = ERR_PTR(-ENOMEM);
524 }
525 error:
526 return fc;
527}
528
529struct v9fs_fcall *v9fs_create_tauth(u32 afid, char *uname, char *aname)
530{
531 int size;
532 struct v9fs_fcall *fc;
533 struct cbuf buffer;
534 struct cbuf *bufp = &buffer;
535
536 size = 4 + 2 + strlen(uname) + 2 + strlen(aname); /* afid[4] uname[s] aname[s] */
537 fc = v9fs_create_common(bufp, size, TAUTH);
538 if (IS_ERR(fc))
539 goto error;
540
541 v9fs_put_int32(bufp, afid, &fc->params.tauth.afid);
542 v9fs_put_str(bufp, uname, &fc->params.tauth.uname);
543 v9fs_put_str(bufp, aname, &fc->params.tauth.aname);
544
545 if (buf_check_overflow(bufp)) {
546 kfree(fc);
547 fc = ERR_PTR(-ENOMEM);
548 }
549 error:
550 return fc;
551}
552
553struct v9fs_fcall *
554v9fs_create_tattach(u32 fid, u32 afid, char *uname, char *aname)
555{
556 int size;
557 struct v9fs_fcall *fc;
558 struct cbuf buffer;
559 struct cbuf *bufp = &buffer;
560
561 size = 4 + 4 + 2 + strlen(uname) + 2 + strlen(aname); /* fid[4] afid[4] uname[s] aname[s] */
562 fc = v9fs_create_common(bufp, size, TATTACH);
563 if (IS_ERR(fc))
564 goto error;
565
566 v9fs_put_int32(bufp, fid, &fc->params.tattach.fid);
567 v9fs_put_int32(bufp, afid, &fc->params.tattach.afid);
568 v9fs_put_str(bufp, uname, &fc->params.tattach.uname);
569 v9fs_put_str(bufp, aname, &fc->params.tattach.aname);
570
571 error:
572 return fc;
573}
574
575struct v9fs_fcall *v9fs_create_tflush(u16 oldtag)
576{
577 int size;
578 struct v9fs_fcall *fc;
579 struct cbuf buffer;
580 struct cbuf *bufp = &buffer;
581
582 size = 2; /* oldtag[2] */
583 fc = v9fs_create_common(bufp, size, TFLUSH);
584 if (IS_ERR(fc))
585 goto error;
586
587 v9fs_put_int16(bufp, oldtag, &fc->params.tflush.oldtag);
588
589 if (buf_check_overflow(bufp)) {
590 kfree(fc);
591 fc = ERR_PTR(-ENOMEM);
592 }
593 error:
594 return fc;
595}
596
597struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname,
598 char **wnames)
599{
600 int i, size;
601 struct v9fs_fcall *fc;
602 struct cbuf buffer;
603 struct cbuf *bufp = &buffer;
604
605 if (nwname > V9FS_MAXWELEM) {
606 dprintk(DEBUG_ERROR, "nwname > %d\n", V9FS_MAXWELEM);
607 return NULL;
608 }
609
610 size = 4 + 4 + 2; /* fid[4] newfid[4] nwname[2] ... */
611 for (i = 0; i < nwname; i++) {
612 size += 2 + strlen(wnames[i]); /* wname[s] */
613 }
614
615 fc = v9fs_create_common(bufp, size, TWALK);
616 if (IS_ERR(fc))
617 goto error;
618
619 v9fs_put_int32(bufp, fid, &fc->params.twalk.fid);
620 v9fs_put_int32(bufp, newfid, &fc->params.twalk.newfid);
621 v9fs_put_int16(bufp, nwname, &fc->params.twalk.nwname);
622 for (i = 0; i < nwname; i++) {
623 v9fs_put_str(bufp, wnames[i], &fc->params.twalk.wnames[i]);
624 }
625
626 if (buf_check_overflow(bufp)) {
627 kfree(fc);
628 fc = ERR_PTR(-ENOMEM);
629 }
630 error:
631 return fc;
632}
633
634struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode)
635{
636 int size;
637 struct v9fs_fcall *fc;
638 struct cbuf buffer;
639 struct cbuf *bufp = &buffer;
640
641 size = 4 + 1; /* fid[4] mode[1] */
642 fc = v9fs_create_common(bufp, size, TOPEN);
643 if (IS_ERR(fc))
644 goto error;
645
646 v9fs_put_int32(bufp, fid, &fc->params.topen.fid);
647 v9fs_put_int8(bufp, mode, &fc->params.topen.mode);
648
649 if (buf_check_overflow(bufp)) {
650 kfree(fc);
651 fc = ERR_PTR(-ENOMEM);
652 }
653 error:
654 return fc;
655}
656
657struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode)
658{
659 int size;
660 struct v9fs_fcall *fc;
661 struct cbuf buffer;
662 struct cbuf *bufp = &buffer;
663
664 size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */
665 fc = v9fs_create_common(bufp, size, TCREATE);
666 if (IS_ERR(fc))
667 goto error;
668
669 v9fs_put_int32(bufp, fid, &fc->params.tcreate.fid);
670 v9fs_put_str(bufp, name, &fc->params.tcreate.name);
671 v9fs_put_int32(bufp, perm, &fc->params.tcreate.perm);
672 v9fs_put_int8(bufp, mode, &fc->params.tcreate.mode);
673
674 if (buf_check_overflow(bufp)) {
675 kfree(fc);
676 fc = ERR_PTR(-ENOMEM);
677 }
678 error:
679 return fc;
680}
681
682struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count)
683{
684 int size;
685 struct v9fs_fcall *fc;
686 struct cbuf buffer;
687 struct cbuf *bufp = &buffer;
688
689 size = 4 + 8 + 4; /* fid[4] offset[8] count[4] */
690 fc = v9fs_create_common(bufp, size, TREAD);
691 if (IS_ERR(fc))
692 goto error;
693
694 v9fs_put_int32(bufp, fid, &fc->params.tread.fid);
695 v9fs_put_int64(bufp, offset, &fc->params.tread.offset);
696 v9fs_put_int32(bufp, count, &fc->params.tread.count);
697
698 if (buf_check_overflow(bufp)) {
699 kfree(fc);
700 fc = ERR_PTR(-ENOMEM);
701 }
702 error:
703 return fc;
704}
705
706struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count,
707 const char __user * data)
708{
709 int size, err;
710 struct v9fs_fcall *fc;
711 struct cbuf buffer;
712 struct cbuf *bufp = &buffer;
713
714 size = 4 + 8 + 4 + count; /* fid[4] offset[8] count[4] data[count] */
715 fc = v9fs_create_common(bufp, size, TWRITE);
716 if (IS_ERR(fc))
717 goto error;
718
719 v9fs_put_int32(bufp, fid, &fc->params.twrite.fid);
720 v9fs_put_int64(bufp, offset, &fc->params.twrite.offset);
721 v9fs_put_int32(bufp, count, &fc->params.twrite.count);
722 err = v9fs_put_user_data(bufp, data, count, &fc->params.twrite.data);
723 if (err) {
724 kfree(fc);
725 fc = ERR_PTR(err);
726 }
727
728 if (buf_check_overflow(bufp)) {
729 kfree(fc);
730 fc = ERR_PTR(-ENOMEM);
731 }
732 error:
733 return fc;
734}
735
736struct v9fs_fcall *v9fs_create_tclunk(u32 fid)
737{
738 int size;
739 struct v9fs_fcall *fc;
740 struct cbuf buffer;
741 struct cbuf *bufp = &buffer;
742
743 size = 4; /* fid[4] */
744 fc = v9fs_create_common(bufp, size, TCLUNK);
745 if (IS_ERR(fc))
746 goto error;
747
748 v9fs_put_int32(bufp, fid, &fc->params.tclunk.fid);
749
750 if (buf_check_overflow(bufp)) {
751 kfree(fc);
752 fc = ERR_PTR(-ENOMEM);
753 }
754 error:
755 return fc;
756}
757
758struct v9fs_fcall *v9fs_create_tremove(u32 fid)
759{
760 int size;
761 struct v9fs_fcall *fc;
762 struct cbuf buffer;
763 struct cbuf *bufp = &buffer;
764
765 size = 4; /* fid[4] */
766 fc = v9fs_create_common(bufp, size, TREMOVE);
767 if (IS_ERR(fc))
768 goto error;
769
770 v9fs_put_int32(bufp, fid, &fc->params.tremove.fid);
771
772 if (buf_check_overflow(bufp)) {
773 kfree(fc);
774 fc = ERR_PTR(-ENOMEM);
775 }
776 error:
777 return fc;
778}
779
780struct v9fs_fcall *v9fs_create_tstat(u32 fid)
781{
782 int size;
783 struct v9fs_fcall *fc;
784 struct cbuf buffer;
785 struct cbuf *bufp = &buffer;
786
787 size = 4; /* fid[4] */
788 fc = v9fs_create_common(bufp, size, TSTAT);
789 if (IS_ERR(fc))
790 goto error;
791
792 v9fs_put_int32(bufp, fid, &fc->params.tstat.fid);
793
794 if (buf_check_overflow(bufp)) {
795 kfree(fc);
796 fc = ERR_PTR(-ENOMEM);
797 }
798 error:
799 return fc;
800}
801
802struct v9fs_fcall *v9fs_create_twstat(u32 fid, struct v9fs_wstat *wstat,
803 int extended)
804{
805 int size, statsz;
806 struct v9fs_fcall *fc;
807 struct cbuf buffer;
808 struct cbuf *bufp = &buffer;
809
810 statsz = v9fs_size_wstat(wstat, extended);
811 size = 4 + 2 + 2 + statsz; /* fid[4] stat[n] */
812 fc = v9fs_create_common(bufp, size, TWSTAT);
813 if (IS_ERR(fc))
814 goto error;
815
816 v9fs_put_int32(bufp, fid, &fc->params.twstat.fid);
817 buf_put_int16(bufp, statsz + 2);
818 v9fs_put_wstat(bufp, wstat, &fc->params.twstat.stat, statsz, extended);
819
820 if (buf_check_overflow(bufp)) {
821 kfree(fc);
822 fc = ERR_PTR(-ENOMEM);
823 }
824 error:
825 return fc;
708} 826}
diff --git a/fs/9p/conv.h b/fs/9p/conv.h
index ee849613c61a..26a736e4a2e7 100644
--- a/fs/9p/conv.h
+++ b/fs/9p/conv.h
@@ -1,8 +1,9 @@
1/* 1/*
2 * linux/fs/9p/conv.h 2 * linux/fs/9p/conv.h
3 * 3 *
4 * 9P protocol conversion definitions 4 * 9P protocol conversion definitions.
5 * 5 *
6 * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
8 * 9 *
@@ -24,13 +25,27 @@
24 * 25 *
25 */ 26 */
26 27
27int v9fs_deserialize_stat(struct v9fs_session_info *, void *buf, 28int v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat,
28 u32 buflen, struct v9fs_stat *stat, u32 statlen); 29 int extended);
29int v9fs_serialize_fcall(struct v9fs_session_info *, struct v9fs_fcall *tcall, 30int v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall,
30 void *buf, u32 buflen); 31 int extended);
31int v9fs_deserialize_fcall(struct v9fs_session_info *, u32 msglen,
32 void *buf, u32 buflen, struct v9fs_fcall *rcall,
33 int rcalllen);
34 32
35/* this one is actually in error.c right now */ 33void v9fs_set_tag(struct v9fs_fcall *fc, u16 tag);
36int v9fs_errstr2errno(char *errstr); 34
35struct v9fs_fcall *v9fs_create_tversion(u32 msize, char *version);
36struct v9fs_fcall *v9fs_create_tauth(u32 afid, char *uname, char *aname);
37struct v9fs_fcall *v9fs_create_tattach(u32 fid, u32 afid, char *uname,
38 char *aname);
39struct v9fs_fcall *v9fs_create_tflush(u16 oldtag);
40struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname,
41 char **wnames);
42struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode);
43struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode);
44struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count);
45struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count,
46 const char __user *data);
47struct v9fs_fcall *v9fs_create_tclunk(u32 fid);
48struct v9fs_fcall *v9fs_create_tremove(u32 fid);
49struct v9fs_fcall *v9fs_create_tstat(u32 fid);
50struct v9fs_fcall *v9fs_create_twstat(u32 fid, struct v9fs_wstat *wstat,
51 int extended);
diff --git a/fs/9p/debug.h b/fs/9p/debug.h
index 4445f06919d9..fe551032788b 100644
--- a/fs/9p/debug.h
+++ b/fs/9p/debug.h
@@ -51,16 +51,23 @@ do { \
51#if DEBUG_DUMP_PKT 51#if DEBUG_DUMP_PKT
52static inline void dump_data(const unsigned char *data, unsigned int datalen) 52static inline void dump_data(const unsigned char *data, unsigned int datalen)
53{ 53{
54 int i, j; 54 int i, n;
55 int len = datalen; 55 char buf[5*8];
56 56
57 printk(KERN_DEBUG "data "); 57 n = 0;
58 for (i = 0; i < len; i += 4) { 58 i = 0;
59 for (j = 0; (j < 4) && (i + j < len); j++) 59 while (i < datalen) {
60 printk(KERN_DEBUG "%02x", data[i + j]); 60 n += snprintf(buf+n, sizeof(buf)-n, "%02x", data[i++]);
61 printk(KERN_DEBUG " "); 61 if (i%4 == 0)
62 n += snprintf(buf+n, sizeof(buf)-n, " ");
63
64 if (i%16 == 0) {
65 dprintk(DEBUG_ERROR, "%s\n", buf);
66 n = 0;
67 }
62 } 68 }
63 printk(KERN_DEBUG "\n"); 69
70 dprintk(DEBUG_ERROR, "%s\n", buf);
64} 71}
65#else /* DEBUG_DUMP_PKT */ 72#else /* DEBUG_DUMP_PKT */
66static inline void dump_data(const unsigned char *data, unsigned int datalen) 73static inline void dump_data(const unsigned char *data, unsigned int datalen)
diff --git a/fs/9p/error.c b/fs/9p/error.c
index 834cb179e388..e4b6f8f38b6f 100644
--- a/fs/9p/error.c
+++ b/fs/9p/error.c
@@ -33,7 +33,6 @@
33 33
34#include <linux/list.h> 34#include <linux/list.h>
35#include <linux/jhash.h> 35#include <linux/jhash.h>
36#include <linux/string.h>
37 36
38#include "debug.h" 37#include "debug.h"
39#include "error.h" 38#include "error.h"
@@ -55,7 +54,8 @@ int v9fs_error_init(void)
55 54
56 /* load initial error map into hash table */ 55 /* load initial error map into hash table */
57 for (c = errmap; c->name != NULL; c++) { 56 for (c = errmap; c->name != NULL; c++) {
58 bucket = jhash(c->name, strlen(c->name), 0) % ERRHASHSZ; 57 c->namelen = strlen(c->name);
58 bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ;
59 INIT_HLIST_NODE(&c->list); 59 INIT_HLIST_NODE(&c->list);
60 hlist_add_head(&c->list, &hash_errmap[bucket]); 60 hlist_add_head(&c->list, &hash_errmap[bucket]);
61 } 61 }
@@ -69,15 +69,15 @@ int v9fs_error_init(void)
69 * 69 *
70 */ 70 */
71 71
72int v9fs_errstr2errno(char *errstr) 72int v9fs_errstr2errno(char *errstr, int len)
73{ 73{
74 int errno = 0; 74 int errno = 0;
75 struct hlist_node *p = NULL; 75 struct hlist_node *p = NULL;
76 struct errormap *c = NULL; 76 struct errormap *c = NULL;
77 int bucket = jhash(errstr, strlen(errstr), 0) % ERRHASHSZ; 77 int bucket = jhash(errstr, len, 0) % ERRHASHSZ;
78 78
79 hlist_for_each_entry(c, p, &hash_errmap[bucket], list) { 79 hlist_for_each_entry(c, p, &hash_errmap[bucket], list) {
80 if (!strcmp(c->name, errstr)) { 80 if (c->namelen==len && !memcmp(c->name, errstr, len)) {
81 errno = c->val; 81 errno = c->val;
82 break; 82 break;
83 } 83 }
diff --git a/fs/9p/error.h b/fs/9p/error.h
index 78f89acf7c9a..a9794e85fe51 100644
--- a/fs/9p/error.h
+++ b/fs/9p/error.h
@@ -36,6 +36,7 @@ struct errormap {
36 char *name; 36 char *name;
37 int val; 37 int val;
38 38
39 int namelen;
39 struct hlist_node list; 40 struct hlist_node list;
40}; 41};
41 42
@@ -175,4 +176,3 @@ static struct errormap errmap[] = {
175}; 176};
176 177
177extern int v9fs_error_init(void); 178extern int v9fs_error_init(void);
178extern int v9fs_errstr2errno(char *errstr);
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index d95f8626d170..eda449778fa5 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -31,9 +31,6 @@
31#include "v9fs.h" 31#include "v9fs.h"
32#include "9p.h" 32#include "9p.h"
33#include "v9fs_vfs.h" 33#include "v9fs_vfs.h"
34#include "transport.h"
35#include "mux.h"
36#include "conv.h"
37#include "fid.h" 34#include "fid.h"
38 35
39/** 36/**
@@ -164,7 +161,7 @@ static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry)
164 return v9fs_fid_create(dentry, v9ses, fidnum, 0); 161 return v9fs_fid_create(dentry, v9ses, fidnum, 0);
165 162
166clunk_fid: 163clunk_fid:
167 v9fs_t_clunk(v9ses, fidnum, NULL); 164 v9fs_t_clunk(v9ses, fidnum);
168 return ERR_PTR(err); 165 return ERR_PTR(err);
169} 166}
170 167
diff --git a/fs/9p/mux.c b/fs/9p/mux.c
index 8835b576f744..945cb368d451 100644
--- a/fs/9p/mux.c
+++ b/fs/9p/mux.c
@@ -4,7 +4,7 @@
4 * Protocol Multiplexer 4 * Protocol Multiplexer
5 * 5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2004 by Latchesar Ionkov <lucho@ionkov.net> 7 * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -28,448 +28,943 @@
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/errno.h> 29#include <linux/errno.h>
30#include <linux/fs.h> 30#include <linux/fs.h>
31#include <linux/poll.h>
31#include <linux/kthread.h> 32#include <linux/kthread.h>
32#include <linux/idr.h> 33#include <linux/idr.h>
33 34
34#include "debug.h" 35#include "debug.h"
35#include "v9fs.h" 36#include "v9fs.h"
36#include "9p.h" 37#include "9p.h"
37#include "transport.h"
38#include "conv.h" 38#include "conv.h"
39#include "transport.h"
39#include "mux.h" 40#include "mux.h"
40 41
42#define ERREQFLUSH 1
43#define SCHED_TIMEOUT 10
44#define MAXPOLLWADDR 2
45
46enum {
47 Rworksched = 1, /* read work scheduled or running */
48 Rpending = 2, /* can read */
49 Wworksched = 4, /* write work scheduled or running */
50 Wpending = 8, /* can write */
51};
52
53struct v9fs_mux_poll_task;
54
55struct v9fs_req {
56 int tag;
57 struct v9fs_fcall *tcall;
58 struct v9fs_fcall *rcall;
59 int err;
60 v9fs_mux_req_callback cb;
61 void *cba;
62 struct list_head req_list;
63};
64
65struct v9fs_mux_data {
66 spinlock_t lock;
67 struct list_head mux_list;
68 struct v9fs_mux_poll_task *poll_task;
69 int msize;
70 unsigned char *extended;
71 struct v9fs_transport *trans;
72 struct v9fs_idpool tidpool;
73 int err;
74 wait_queue_head_t equeue;
75 struct list_head req_list;
76 struct list_head unsent_req_list;
77 struct v9fs_fcall *rcall;
78 int rpos;
79 char *rbuf;
80 int wpos;
81 int wsize;
82 char *wbuf;
83 wait_queue_t poll_wait[MAXPOLLWADDR];
84 wait_queue_head_t *poll_waddr[MAXPOLLWADDR];
85 poll_table pt;
86 struct work_struct rq;
87 struct work_struct wq;
88 unsigned long wsched;
89};
90
91struct v9fs_mux_poll_task {
92 struct task_struct *task;
93 struct list_head mux_list;
94 int muxnum;
95};
96
97struct v9fs_mux_rpc {
98 struct v9fs_mux_data *m;
99 struct v9fs_req *req;
100 int err;
101 struct v9fs_fcall *rcall;
102 wait_queue_head_t wqueue;
103};
104
105static int v9fs_poll_proc(void *);
106static void v9fs_read_work(void *);
107static void v9fs_write_work(void *);
108static void v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address,
109 poll_table * p);
110static u16 v9fs_mux_get_tag(struct v9fs_mux_data *);
111static void v9fs_mux_put_tag(struct v9fs_mux_data *, u16);
112
113static DECLARE_MUTEX(v9fs_mux_task_lock);
114static struct workqueue_struct *v9fs_mux_wq;
115
116static int v9fs_mux_num;
117static int v9fs_mux_poll_task_num;
118static struct v9fs_mux_poll_task v9fs_mux_poll_tasks[100];
119
120int v9fs_mux_global_init(void)
121{
122 int i;
123
124 for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++)
125 v9fs_mux_poll_tasks[i].task = NULL;
126
127 v9fs_mux_wq = create_workqueue("v9fs");
128 if (!v9fs_mux_wq)
129 return -ENOMEM;
130
131 return 0;
132}
133
134void v9fs_mux_global_exit(void)
135{
136 destroy_workqueue(v9fs_mux_wq);
137}
138
41/** 139/**
42 * dprintcond - print condition of session info 140 * v9fs_mux_calc_poll_procs - calculates the number of polling procs
43 * @v9ses: session info structure 141 * based on the number of mounted v9fs filesystems.
44 * @req: RPC request structure
45 * 142 *
143 * The current implementation returns sqrt of the number of mounts.
46 */ 144 */
145inline int v9fs_mux_calc_poll_procs(int muxnum)
146{
147 int n;
148
149 if (v9fs_mux_poll_task_num)
150 n = muxnum / v9fs_mux_poll_task_num +
151 (muxnum % v9fs_mux_poll_task_num ? 1 : 0);
152 else
153 n = 1;
154
155 if (n > ARRAY_SIZE(v9fs_mux_poll_tasks))
156 n = ARRAY_SIZE(v9fs_mux_poll_tasks);
157
158 return n;
159}
47 160
48static inline int 161static int v9fs_mux_poll_start(struct v9fs_mux_data *m)
49dprintcond(struct v9fs_session_info *v9ses, struct v9fs_rpcreq *req)
50{ 162{
51 dprintk(DEBUG_MUX, "condition: %d, %p\n", v9ses->transport->status, 163 int i, n;
52 req->rcall); 164 struct v9fs_mux_poll_task *vpt, *vptlast;
165 struct task_struct *pproc;
166
167 dprintk(DEBUG_MUX, "mux %p muxnum %d procnum %d\n", m, v9fs_mux_num,
168 v9fs_mux_poll_task_num);
169 up(&v9fs_mux_task_lock);
170
171 n = v9fs_mux_calc_poll_procs(v9fs_mux_num + 1);
172 if (n > v9fs_mux_poll_task_num) {
173 for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) {
174 if (v9fs_mux_poll_tasks[i].task == NULL) {
175 vpt = &v9fs_mux_poll_tasks[i];
176 dprintk(DEBUG_MUX, "create proc %p\n", vpt);
177 pproc = kthread_create(v9fs_poll_proc, vpt,
178 "v9fs-poll");
179
180 if (!IS_ERR(pproc)) {
181 vpt->task = pproc;
182 INIT_LIST_HEAD(&vpt->mux_list);
183 vpt->muxnum = 0;
184 v9fs_mux_poll_task_num++;
185 wake_up_process(vpt->task);
186 }
187 break;
188 }
189 }
190
191 if (i >= ARRAY_SIZE(v9fs_mux_poll_tasks))
192 dprintk(DEBUG_ERROR, "warning: no free poll slots\n");
193 }
194
195 n = (v9fs_mux_num + 1) / v9fs_mux_poll_task_num +
196 ((v9fs_mux_num + 1) % v9fs_mux_poll_task_num ? 1 : 0);
197
198 vptlast = NULL;
199 for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) {
200 vpt = &v9fs_mux_poll_tasks[i];
201 if (vpt->task != NULL) {
202 vptlast = vpt;
203 if (vpt->muxnum < n) {
204 dprintk(DEBUG_MUX, "put in proc %d\n", i);
205 list_add(&m->mux_list, &vpt->mux_list);
206 vpt->muxnum++;
207 m->poll_task = vpt;
208 memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
209 init_poll_funcptr(&m->pt, v9fs_pollwait);
210 break;
211 }
212 }
213 }
214
215 if (i >= ARRAY_SIZE(v9fs_mux_poll_tasks)) {
216 if (vptlast == NULL)
217 return -ENOMEM;
218
219 dprintk(DEBUG_MUX, "put in proc %d\n", i);
220 list_add(&m->mux_list, &vptlast->mux_list);
221 vptlast->muxnum++;
222 m->poll_task = vptlast;
223 memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
224 init_poll_funcptr(&m->pt, v9fs_pollwait);
225 }
226
227 v9fs_mux_num++;
228 down(&v9fs_mux_task_lock);
229
53 return 0; 230 return 0;
54} 231}
55 232
233static void v9fs_mux_poll_stop(struct v9fs_mux_data *m)
234{
235 int i;
236 struct v9fs_mux_poll_task *vpt;
237
238 up(&v9fs_mux_task_lock);
239 vpt = m->poll_task;
240 list_del(&m->mux_list);
241 for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) {
242 if (m->poll_waddr[i] != NULL) {
243 remove_wait_queue(m->poll_waddr[i], &m->poll_wait[i]);
244 m->poll_waddr[i] = NULL;
245 }
246 }
247 vpt->muxnum--;
248 if (!vpt->muxnum) {
249 dprintk(DEBUG_MUX, "destroy proc %p\n", vpt);
250 send_sig(SIGKILL, vpt->task, 1);
251 vpt->task = NULL;
252 v9fs_mux_poll_task_num--;
253 }
254 v9fs_mux_num--;
255 down(&v9fs_mux_task_lock);
256}
257
56/** 258/**
57 * xread - force read of a certain number of bytes 259 * v9fs_mux_init - allocate and initialize the per-session mux data
58 * @v9ses: session info structure 260 * Creates the polling task if this is the first session.
59 * @ptr: pointer to buffer
60 * @sz: number of bytes to read
61 * 261 *
62 * Chuck Cranor CS-533 project1 262 * @trans - transport structure
263 * @msize - maximum message size
264 * @extended - pointer to the extended flag
63 */ 265 */
64 266struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize,
65static int xread(struct v9fs_session_info *v9ses, void *ptr, unsigned long sz) 267 unsigned char *extended)
66{ 268{
67 int rd = 0; 269 int i, n;
68 int ret = 0; 270 struct v9fs_mux_data *m, *mtmp;
69 while (rd < sz) { 271
70 ret = v9ses->transport->read(v9ses->transport, ptr, sz - rd); 272 dprintk(DEBUG_MUX, "transport %p msize %d\n", trans, msize);
71 if (ret <= 0) { 273 m = kmalloc(sizeof(struct v9fs_mux_data), GFP_KERNEL);
72 dprintk(DEBUG_ERROR, "xread errno %d\n", ret); 274 if (!m)
73 return ret; 275 return ERR_PTR(-ENOMEM);
276
277 spin_lock_init(&m->lock);
278 INIT_LIST_HEAD(&m->mux_list);
279 m->msize = msize;
280 m->extended = extended;
281 m->trans = trans;
282 idr_init(&m->tidpool.pool);
283 init_MUTEX(&m->tidpool.lock);
284 m->err = 0;
285 init_waitqueue_head(&m->equeue);
286 INIT_LIST_HEAD(&m->req_list);
287 INIT_LIST_HEAD(&m->unsent_req_list);
288 m->rcall = NULL;
289 m->rpos = 0;
290 m->rbuf = NULL;
291 m->wpos = m->wsize = 0;
292 m->wbuf = NULL;
293 INIT_WORK(&m->rq, v9fs_read_work, m);
294 INIT_WORK(&m->wq, v9fs_write_work, m);
295 m->wsched = 0;
296 memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
297 m->poll_task = NULL;
298 n = v9fs_mux_poll_start(m);
299 if (n)
300 return ERR_PTR(n);
301
302 n = trans->poll(trans, &m->pt);
303 if (n & POLLIN) {
304 dprintk(DEBUG_MUX, "mux %p can read\n", m);
305 set_bit(Rpending, &m->wsched);
306 }
307
308 if (n & POLLOUT) {
309 dprintk(DEBUG_MUX, "mux %p can write\n", m);
310 set_bit(Wpending, &m->wsched);
311 }
312
313 for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) {
314 if (IS_ERR(m->poll_waddr[i])) {
315 v9fs_mux_poll_stop(m);
316 mtmp = (void *)m->poll_waddr; /* the error code */
317 kfree(m);
318 m = mtmp;
319 break;
74 } 320 }
75 rd += ret;
76 ptr += ret;
77 } 321 }
78 return (rd); 322
323 return m;
79} 324}
80 325
81/** 326/**
82 * read_message - read a full 9P2000 fcall packet 327 * v9fs_mux_destroy - cancels all pending requests and frees mux resources
83 * @v9ses: session info structure
84 * @rcall: fcall structure to read into
85 * @rcalllen: size of fcall buffer
86 *
87 */ 328 */
329void v9fs_mux_destroy(struct v9fs_mux_data *m)
330{
331 dprintk(DEBUG_MUX, "mux %p prev %p next %p\n", m,
332 m->mux_list.prev, m->mux_list.next);
333 v9fs_mux_cancel(m, -ECONNRESET);
334
335 if (!list_empty(&m->req_list)) {
336 /* wait until all processes waiting on this session exit */
337 dprintk(DEBUG_MUX, "mux %p waiting for empty request queue\n",
338 m);
339 wait_event_timeout(m->equeue, (list_empty(&m->req_list)), 5000);
340 dprintk(DEBUG_MUX, "mux %p request queue empty: %d\n", m,
341 list_empty(&m->req_list));
342 }
343
344 v9fs_mux_poll_stop(m);
345 m->trans = NULL;
346
347 kfree(m);
348}
88 349
89static int 350/**
90read_message(struct v9fs_session_info *v9ses, 351 * v9fs_pollwait - called by files poll operation to add v9fs-poll task
91 struct v9fs_fcall *rcall, int rcalllen) 352 * to files wait queue
353 */
354static void
355v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address,
356 poll_table * p)
92{ 357{
93 unsigned char buf[4]; 358 int i;
94 void *data; 359 struct v9fs_mux_data *m;
95 int size = 0; 360
96 int res = 0; 361 m = container_of(p, struct v9fs_mux_data, pt);
97 362 for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++)
98 res = xread(v9ses, buf, sizeof(buf)); 363 if (m->poll_waddr[i] == NULL)
99 if (res < 0) { 364 break;
100 dprintk(DEBUG_ERROR, 365
101 "Reading of count field failed returned: %d\n", res); 366 if (i >= ARRAY_SIZE(m->poll_waddr)) {
102 return res; 367 dprintk(DEBUG_ERROR, "not enough wait_address slots\n");
368 return;
103 } 369 }
104 370
105 if (res < 4) { 371 m->poll_waddr[i] = wait_address;
106 dprintk(DEBUG_ERROR, 372
107 "Reading of count field failed returned: %d\n", res); 373 if (!wait_address) {
108 return -EIO; 374 dprintk(DEBUG_ERROR, "no wait_address\n");
375 m->poll_waddr[i] = ERR_PTR(-EIO);
376 return;
109 } 377 }
110 378
111 size = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); 379 init_waitqueue_entry(&m->poll_wait[i], m->poll_task->task);
112 dprintk(DEBUG_MUX, "got a packet count: %d\n", size); 380 add_wait_queue(wait_address, &m->poll_wait[i]);
381}
382
383/**
384 * v9fs_poll_mux - polls a mux and schedules read or write works if necessary
385 */
386static inline void v9fs_poll_mux(struct v9fs_mux_data *m)
387{
388 int n;
113 389
114 /* adjust for the four bytes of size */ 390 if (m->err < 0)
115 size -= 4; 391 return;
116 392
117 if (size > v9ses->maxdata) { 393 n = m->trans->poll(m->trans, NULL);
118 dprintk(DEBUG_ERROR, "packet too big: %d\n", size); 394 if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) {
119 return -E2BIG; 395 dprintk(DEBUG_MUX, "error mux %p err %d\n", m, n);
396 if (n >= 0)
397 n = -ECONNRESET;
398 v9fs_mux_cancel(m, n);
120 } 399 }
121 400
122 data = kmalloc(size, GFP_KERNEL); 401 if (n & POLLIN) {
123 if (!data) { 402 set_bit(Rpending, &m->wsched);
124 eprintk(KERN_WARNING, "out of memory\n"); 403 dprintk(DEBUG_MUX, "mux %p can read\n", m);
125 return -ENOMEM; 404 if (!test_and_set_bit(Rworksched, &m->wsched)) {
405 dprintk(DEBUG_MUX, "schedule read work mux %p\n", m);
406 queue_work(v9fs_mux_wq, &m->rq);
407 }
126 } 408 }
127 409
128 res = xread(v9ses, data, size); 410 if (n & POLLOUT) {
129 if (res < size) { 411 set_bit(Wpending, &m->wsched);
130 dprintk(DEBUG_ERROR, "Reading of fcall failed returned: %d\n", 412 dprintk(DEBUG_MUX, "mux %p can write\n", m);
131 res); 413 if ((m->wsize || !list_empty(&m->unsent_req_list))
132 kfree(data); 414 && !test_and_set_bit(Wworksched, &m->wsched)) {
133 return res; 415 dprintk(DEBUG_MUX, "schedule write work mux %p\n", m);
416 queue_work(v9fs_mux_wq, &m->wq);
417 }
134 } 418 }
419}
420
421/**
422 * v9fs_poll_proc - polls all v9fs transports for new events and queues
423 * the appropriate work to the work queue
424 */
425static int v9fs_poll_proc(void *a)
426{
427 struct v9fs_mux_data *m, *mtmp;
428 struct v9fs_mux_poll_task *vpt;
135 429
136 /* we now have an in-memory string that is the reply. 430 vpt = a;
137 * deserialize it. There is very little to go wrong at this point 431 dprintk(DEBUG_MUX, "start %p %p\n", current, vpt);
138 * save for v9fs_alloc errors. 432 allow_signal(SIGKILL);
139 */ 433 while (!kthread_should_stop()) {
140 res = v9fs_deserialize_fcall(v9ses, size, data, v9ses->maxdata, 434 set_current_state(TASK_INTERRUPTIBLE);
141 rcall, rcalllen); 435 if (signal_pending(current))
436 break;
142 437
143 kfree(data); 438 list_for_each_entry_safe(m, mtmp, &vpt->mux_list, mux_list) {
439 v9fs_poll_mux(m);
440 }
144 441
145 if (res < 0) 442 dprintk(DEBUG_MUX, "sleeping...\n");
146 return res; 443 schedule_timeout(SCHED_TIMEOUT * HZ);
444 }
147 445
446 __set_current_state(TASK_RUNNING);
447 dprintk(DEBUG_MUX, "finish\n");
148 return 0; 448 return 0;
149} 449}
150 450
151/** 451/**
152 * v9fs_recv - receive an RPC response for a particular tag 452 * v9fs_write_work - called when a transport can send some data
153 * @v9ses: session info structure
154 * @req: RPC request structure
155 *
156 */ 453 */
157 454static void v9fs_write_work(void *a)
158static int v9fs_recv(struct v9fs_session_info *v9ses, struct v9fs_rpcreq *req)
159{ 455{
160 int ret = 0; 456 int n, err;
457 struct v9fs_mux_data *m;
458 struct v9fs_req *req;
161 459
162 dprintk(DEBUG_MUX, "waiting for response: %d\n", req->tcall->tag); 460 m = a;
163 ret = wait_event_interruptible(v9ses->read_wait,
164 ((v9ses->transport->status != Connected) ||
165 (req->rcall != 0) || (req->err < 0) ||
166 dprintcond(v9ses, req)));
167 461
168 dprintk(DEBUG_MUX, "got it: rcall %p\n", req->rcall); 462 if (m->err < 0) {
463 clear_bit(Wworksched, &m->wsched);
464 return;
465 }
169 466
170 spin_lock(&v9ses->muxlock); 467 if (!m->wsize) {
171 list_del(&req->next); 468 if (list_empty(&m->unsent_req_list)) {
172 spin_unlock(&v9ses->muxlock); 469 clear_bit(Wworksched, &m->wsched);
470 return;
471 }
173 472
174 if (req->err < 0) 473 spin_lock(&m->lock);
175 return req->err; 474 req =
475 list_entry(m->unsent_req_list.next, struct v9fs_req,
476 req_list);
477 list_move_tail(&req->req_list, &m->req_list);
478 m->wbuf = req->tcall->sdata;
479 m->wsize = req->tcall->size;
480 m->wpos = 0;
481 dump_data(m->wbuf, m->wsize);
482 spin_unlock(&m->lock);
483 }
176 484
177 if (v9ses->transport->status == Disconnected) 485 dprintk(DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos, m->wsize);
178 return -ECONNRESET; 486 clear_bit(Wpending, &m->wsched);
487 err = m->trans->write(m->trans, m->wbuf + m->wpos, m->wsize - m->wpos);
488 dprintk(DEBUG_MUX, "mux %p sent %d bytes\n", m, err);
489 if (err == -EAGAIN) {
490 clear_bit(Wworksched, &m->wsched);
491 return;
492 }
179 493
180 return ret; 494 if (err <= 0)
181} 495 goto error;
182 496
183/** 497 m->wpos += err;
184 * v9fs_send - send a 9P request 498 if (m->wpos == m->wsize)
185 * @v9ses: session info structure 499 m->wpos = m->wsize = 0;
186 * @req: RPC request to send 500
187 * 501 if (m->wsize == 0 && !list_empty(&m->unsent_req_list)) {
188 */ 502 if (test_and_clear_bit(Wpending, &m->wsched))
503 n = POLLOUT;
504 else
505 n = m->trans->poll(m->trans, NULL);
506
507 if (n & POLLOUT) {
508 dprintk(DEBUG_MUX, "schedule write work mux %p\n", m);
509 queue_work(v9fs_mux_wq, &m->wq);
510 } else
511 clear_bit(Wworksched, &m->wsched);
512 } else
513 clear_bit(Wworksched, &m->wsched);
514
515 return;
189 516
190static int v9fs_send(struct v9fs_session_info *v9ses, struct v9fs_rpcreq *req) 517 error:
518 v9fs_mux_cancel(m, err);
519 clear_bit(Wworksched, &m->wsched);
520}
521
522static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req)
191{ 523{
192 int ret = -1; 524 int ecode, tag;
193 void *data = NULL; 525 struct v9fs_str *ename;
194 struct v9fs_fcall *tcall = req->tcall;
195 526
196 data = kmalloc(v9ses->maxdata + V9FS_IOHDRSZ, GFP_KERNEL); 527 tag = req->tag;
197 if (!data) 528 if (req->rcall->id == RERROR && !req->err) {
198 return -ENOMEM; 529 ecode = req->rcall->params.rerror.errno;
530 ename = &req->rcall->params.rerror.error;
199 531
200 tcall->size = 0; /* enforce size recalculation */ 532 dprintk(DEBUG_MUX, "Rerror %.*s\n", ename->len, ename->str);
201 ret =
202 v9fs_serialize_fcall(v9ses, tcall, data,
203 v9ses->maxdata + V9FS_IOHDRSZ);
204 if (ret < 0)
205 goto free_data;
206 533
207 spin_lock(&v9ses->muxlock); 534 if (*m->extended)
208 list_add(&req->next, &v9ses->mux_fcalls); 535 req->err = -ecode;
209 spin_unlock(&v9ses->muxlock);
210 536
211 dprintk(DEBUG_MUX, "sending message: tag %d size %d\n", tcall->tag, 537 if (!req->err) {
212 tcall->size); 538 req->err = v9fs_errstr2errno(ename->str, ename->len);
213 ret = v9ses->transport->write(v9ses->transport, data, tcall->size);
214 539
215 if (ret != tcall->size) { 540 if (!req->err) { /* string match failed */
216 spin_lock(&v9ses->muxlock); 541 PRINT_FCALL_ERROR("unknown error", req->rcall);
217 list_del(&req->next); 542 }
218 kfree(req->rcall); 543
544 if (!req->err)
545 req->err = -ESERVERFAULT;
546 }
547 } else if (req->tcall && req->rcall->id != req->tcall->id + 1) {
548 dprintk(DEBUG_ERROR, "fcall mismatch: expected %d, got %d\n",
549 req->tcall->id + 1, req->rcall->id);
550 if (!req->err)
551 req->err = -EIO;
552 }
219 553
220 spin_unlock(&v9ses->muxlock); 554 if (req->cb && req->err != ERREQFLUSH) {
221 if (ret >= 0) 555 dprintk(DEBUG_MUX, "calling callback tcall %p rcall %p\n",
222 ret = -EREMOTEIO; 556 req->tcall, req->rcall);
557
558 (*req->cb) (req->cba, req->tcall, req->rcall, req->err);
559 req->cb = NULL;
223 } else 560 } else
224 ret = 0; 561 kfree(req->rcall);
225 562
226 free_data: 563 v9fs_mux_put_tag(m, tag);
227 kfree(data); 564
228 return ret; 565 wake_up(&m->equeue);
566 kfree(req);
229} 567}
230 568
231/** 569/**
232 * v9fs_mux_rpc - send a request, receive a response 570 * v9fs_read_work - called when there is some data to be read from a transport
233 * @v9ses: session info structure
234 * @tcall: fcall to send
235 * @rcall: buffer to place response into
236 *
237 */ 571 */
238 572static void v9fs_read_work(void *a)
239long
240v9fs_mux_rpc(struct v9fs_session_info *v9ses, struct v9fs_fcall *tcall,
241 struct v9fs_fcall **rcall)
242{ 573{
243 int tid = -1; 574 int n, err;
244 struct v9fs_fcall *fcall = NULL; 575 struct v9fs_mux_data *m;
245 struct v9fs_rpcreq req; 576 struct v9fs_req *req, *rptr, *rreq;
246 int ret = -1; 577 struct v9fs_fcall *rcall;
247 578 char *rbuf;
248 if (!v9ses) 579
249 return -EINVAL; 580 m = a;
250 581
251 if (!v9ses->transport || v9ses->transport->status != Connected) 582 if (m->err < 0)
252 return -EIO; 583 return;
584
585 rcall = NULL;
586 dprintk(DEBUG_MUX, "start mux %p pos %d\n", m, m->rpos);
587
588 if (!m->rcall) {
589 m->rcall =
590 kmalloc(sizeof(struct v9fs_fcall) + m->msize, GFP_KERNEL);
591 if (!m->rcall) {
592 err = -ENOMEM;
593 goto error;
594 }
253 595
254 if (rcall) 596 m->rbuf = (char *)m->rcall + sizeof(struct v9fs_fcall);
255 *rcall = NULL; 597 m->rpos = 0;
598 }
256 599
257 if (tcall->id != TVERSION) { 600 clear_bit(Rpending, &m->wsched);
258 tid = v9fs_get_idpool(&v9ses->tidpool); 601 err = m->trans->read(m->trans, m->rbuf + m->rpos, m->msize - m->rpos);
259 if (tid < 0) 602 dprintk(DEBUG_MUX, "mux %p got %d bytes\n", m, err);
260 return -ENOMEM; 603 if (err == -EAGAIN) {
604 clear_bit(Rworksched, &m->wsched);
605 return;
261 } 606 }
262 607
263 tcall->tag = tid; 608 if (err <= 0)
609 goto error;
264 610
265 req.tcall = tcall; 611 m->rpos += err;
266 req.err = 0; 612 while (m->rpos > 4) {
267 req.rcall = NULL; 613 n = le32_to_cpu(*(__le32 *) m->rbuf);
614 if (n >= m->msize) {
615 dprintk(DEBUG_ERROR,
616 "requested packet size too big: %d\n", n);
617 err = -EIO;
618 goto error;
619 }
268 620
269 ret = v9fs_send(v9ses, &req); 621 if (m->rpos < n)
622 break;
270 623
271 if (ret < 0) { 624 dump_data(m->rbuf, n);
272 if (tcall->id != TVERSION) 625 err =
273 v9fs_put_idpool(tid, &v9ses->tidpool); 626 v9fs_deserialize_fcall(m->rbuf, n, m->rcall, *m->extended);
274 dprintk(DEBUG_MUX, "error %d\n", ret); 627 if (err < 0) {
275 return ret; 628 goto error;
276 } 629 }
630
631 rcall = m->rcall;
632 rbuf = m->rbuf;
633 if (m->rpos > n) {
634 m->rcall = kmalloc(sizeof(struct v9fs_fcall) + m->msize,
635 GFP_KERNEL);
636 if (!m->rcall) {
637 err = -ENOMEM;
638 goto error;
639 }
277 640
278 ret = v9fs_recv(v9ses, &req); 641 m->rbuf = (char *)m->rcall + sizeof(struct v9fs_fcall);
279 642 memmove(m->rbuf, rbuf + n, m->rpos - n);
280 fcall = req.rcall; 643 m->rpos -= n;
281 644 } else {
282 dprintk(DEBUG_MUX, "received: tag=%x, ret=%d\n", tcall->tag, ret); 645 m->rcall = NULL;
283 if (ret == -ERESTARTSYS) { 646 m->rbuf = NULL;
284 if (v9ses->transport->status != Disconnected 647 m->rpos = 0;
285 && tcall->id != TFLUSH) {
286 unsigned long flags;
287
288 dprintk(DEBUG_MUX, "flushing the tag: %d\n",
289 tcall->tag);
290 clear_thread_flag(TIF_SIGPENDING);
291 v9fs_t_flush(v9ses, tcall->tag);
292 spin_lock_irqsave(&current->sighand->siglock, flags);
293 recalc_sigpending();
294 spin_unlock_irqrestore(&current->sighand->siglock,
295 flags);
296 dprintk(DEBUG_MUX, "flushing done\n");
297 } 648 }
298 649
299 goto release_req; 650 dprintk(DEBUG_MUX, "mux %p fcall id %d tag %d\n", m, rcall->id,
300 } else if (ret < 0) 651 rcall->tag);
301 goto release_req; 652
302 653 req = NULL;
303 if (!fcall) 654 spin_lock(&m->lock);
304 ret = -EIO; 655 list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) {
305 else { 656 if (rreq->tag == rcall->tag) {
306 if (fcall->id == RERROR) { 657 req = rreq;
307 ret = v9fs_errstr2errno(fcall->params.rerror.error); 658 req->rcall = rcall;
308 if (ret == 0) { /* string match failed */ 659 list_del(&req->req_list);
309 if (fcall->params.rerror.errno) 660 spin_unlock(&m->lock);
310 ret = -(fcall->params.rerror.errno); 661 process_request(m, req);
311 else 662 break;
312 ret = -ESERVERFAULT;
313 } 663 }
314 } else if (fcall->id != tcall->id + 1) { 664
315 dprintk(DEBUG_ERROR, 665 }
316 "fcall mismatch: expected %d, got %d\n", 666
317 tcall->id + 1, fcall->id); 667 if (!req) {
318 ret = -EIO; 668 spin_unlock(&m->lock);
669 if (err >= 0 && rcall->id != RFLUSH)
670 dprintk(DEBUG_ERROR,
671 "unexpected response mux %p id %d tag %d\n",
672 m, rcall->id, rcall->tag);
673 kfree(rcall);
319 } 674 }
320 } 675 }
321 676
322 release_req: 677 if (!list_empty(&m->req_list)) {
323 if (tcall->id != TVERSION) 678 if (test_and_clear_bit(Rpending, &m->wsched))
324 v9fs_put_idpool(tid, &v9ses->tidpool); 679 n = POLLIN;
325 if (rcall) 680 else
326 *rcall = fcall; 681 n = m->trans->poll(m->trans, NULL);
327 else 682
328 kfree(fcall); 683 if (n & POLLIN) {
684 dprintk(DEBUG_MUX, "schedule read work mux %p\n", m);
685 queue_work(v9fs_mux_wq, &m->rq);
686 } else
687 clear_bit(Rworksched, &m->wsched);
688 } else
689 clear_bit(Rworksched, &m->wsched);
690
691 return;
329 692
330 return ret; 693 error:
694 v9fs_mux_cancel(m, err);
695 clear_bit(Rworksched, &m->wsched);
331} 696}
332 697
333/** 698/**
334 * v9fs_mux_cancel_requests - cancels all pending requests 699 * v9fs_send_request - send 9P request
700 * The function can sleep until the request is scheduled for sending.
701 * The function can be interrupted. Return from the function is not
702 * a guarantee that the request is sent succesfully. Can return errors
703 * that can be retrieved by PTR_ERR macros.
335 * 704 *
336 * @v9ses: session info structure 705 * @m: mux data
337 * @err: error code to return to the requests 706 * @tc: request to be sent
707 * @cb: callback function to call when response is received
708 * @cba: parameter to pass to the callback function
338 */ 709 */
339void v9fs_mux_cancel_requests(struct v9fs_session_info *v9ses, int err) 710static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m,
711 struct v9fs_fcall *tc,
712 v9fs_mux_req_callback cb, void *cba)
340{ 713{
341 struct v9fs_rpcreq *rptr; 714 int n;
342 struct v9fs_rpcreq *rreq; 715 struct v9fs_req *req;
343 716
344 dprintk(DEBUG_MUX, " %d\n", err); 717 dprintk(DEBUG_MUX, "mux %p task %p tcall %p id %d\n", m, current,
345 spin_lock(&v9ses->muxlock); 718 tc, tc->id);
346 list_for_each_entry_safe(rreq, rptr, &v9ses->mux_fcalls, next) { 719 if (m->err < 0)
347 rreq->err = err; 720 return ERR_PTR(m->err);
348 }
349 spin_unlock(&v9ses->muxlock);
350 wake_up_all(&v9ses->read_wait);
351}
352 721
353/** 722 req = kmalloc(sizeof(struct v9fs_req), GFP_KERNEL);
354 * v9fs_recvproc - kproc to handle demultiplexing responses 723 if (!req)
355 * @data: session info structure 724 return ERR_PTR(-ENOMEM);
356 *
357 */
358 725
359static int v9fs_recvproc(void *data) 726 if (tc->id == TVERSION)
360{ 727 n = V9FS_NOTAG;
361 struct v9fs_session_info *v9ses = (struct v9fs_session_info *)data; 728 else
362 struct v9fs_fcall *rcall = NULL; 729 n = v9fs_mux_get_tag(m);
363 struct v9fs_rpcreq *rptr;
364 struct v9fs_rpcreq *req;
365 struct v9fs_rpcreq *rreq;
366 int err = 0;
367 730
368 allow_signal(SIGKILL); 731 if (n < 0)
369 set_current_state(TASK_INTERRUPTIBLE); 732 return ERR_PTR(-ENOMEM);
370 complete(&v9ses->proccmpl);
371 while (!kthread_should_stop() && err >= 0) {
372 req = rptr = rreq = NULL;
373
374 rcall = kmalloc(v9ses->maxdata + V9FS_IOHDRSZ, GFP_KERNEL);
375 if (!rcall) {
376 eprintk(KERN_ERR, "no memory for buffers\n");
377 break;
378 }
379 733
380 err = read_message(v9ses, rcall, v9ses->maxdata + V9FS_IOHDRSZ); 734 v9fs_set_tag(tc, n);
381 spin_lock(&v9ses->muxlock);
382 if (err < 0) {
383 list_for_each_entry_safe(rreq, rptr, &v9ses->mux_fcalls, next) {
384 rreq->err = err;
385 }
386 if(err != -ERESTARTSYS)
387 eprintk(KERN_ERR,
388 "Transport error while reading message %d\n", err);
389 } else {
390 list_for_each_entry_safe(rreq, rptr, &v9ses->mux_fcalls, next) {
391 if (rreq->tcall->tag == rcall->tag) {
392 req = rreq;
393 req->rcall = rcall;
394 break;
395 }
396 }
397 }
398 735
399 if (req && (req->tcall->id == TFLUSH)) { 736 req->tag = n;
400 struct v9fs_rpcreq *treq = NULL; 737 req->tcall = tc;
401 list_for_each_entry_safe(treq, rptr, &v9ses->mux_fcalls, next) { 738 req->rcall = NULL;
402 if (treq->tcall->tag == 739 req->err = 0;
403 req->tcall->params.tflush.oldtag) { 740 req->cb = cb;
404 list_del(&rptr->next); 741 req->cba = cba;
405 kfree(treq->rcall); 742
406 break; 743 spin_lock(&m->lock);
407 } 744 list_add_tail(&req->req_list, &m->unsent_req_list);
745 spin_unlock(&m->lock);
746
747 if (test_and_clear_bit(Wpending, &m->wsched))
748 n = POLLOUT;
749 else
750 n = m->trans->poll(m->trans, NULL);
751
752 if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
753 queue_work(v9fs_mux_wq, &m->wq);
754
755 return req;
756}
757
758static inline void
759v9fs_mux_flush_cb(void *a, struct v9fs_fcall *tc, struct v9fs_fcall *rc,
760 int err)
761{
762 v9fs_mux_req_callback cb;
763 int tag;
764 struct v9fs_mux_data *m;
765 struct v9fs_req *req, *rptr;
766
767 m = a;
768 dprintk(DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m, tc,
769 rc, err, tc->params.tflush.oldtag);
770
771 spin_lock(&m->lock);
772 cb = NULL;
773 tag = tc->params.tflush.oldtag;
774 list_for_each_entry_safe(req, rptr, &m->req_list, req_list) {
775 if (req->tag == tag) {
776 list_del(&req->req_list);
777 if (req->cb) {
778 cb = req->cb;
779 req->cb = NULL;
780 spin_unlock(&m->lock);
781 (*cb) (req->cba, req->tcall, req->rcall,
782 req->err);
408 } 783 }
784 kfree(req);
785 wake_up(&m->equeue);
786 break;
409 } 787 }
788 }
410 789
411 spin_unlock(&v9ses->muxlock); 790 if (!cb)
791 spin_unlock(&m->lock);
412 792
413 if (!req) { 793 v9fs_mux_put_tag(m, tag);
414 if (err >= 0) 794 kfree(tc);
415 dprintk(DEBUG_ERROR, 795 kfree(rc);
416 "unexpected response: id %d tag %d\n", 796}
417 rcall->id, rcall->tag);
418 797
419 kfree(rcall); 798static void
420 } 799v9fs_mux_flush_request(struct v9fs_mux_data *m, struct v9fs_req *req)
800{
801 struct v9fs_fcall *fc;
421 802
422 wake_up_all(&v9ses->read_wait); 803 dprintk(DEBUG_MUX, "mux %p req %p tag %d\n", m, req, req->tag);
423 set_current_state(TASK_INTERRUPTIBLE); 804
805 fc = v9fs_create_tflush(req->tag);
806 v9fs_send_request(m, fc, v9fs_mux_flush_cb, m);
807}
808
809static void
810v9fs_mux_rpc_cb(void *a, struct v9fs_fcall *tc, struct v9fs_fcall *rc, int err)
811{
812 struct v9fs_mux_rpc *r;
813
814 if (err == ERREQFLUSH) {
815 dprintk(DEBUG_MUX, "err req flush\n");
816 return;
424 } 817 }
425 818
426 v9ses->transport->close(v9ses->transport); 819 r = a;
820 dprintk(DEBUG_MUX, "mux %p req %p tc %p rc %p err %d\n", r->m, r->req,
821 tc, rc, err);
822 r->rcall = rc;
823 r->err = err;
824 wake_up(&r->wqueue);
825}
427 826
428 /* Inform all pending processes about the failure */ 827/**
429 wake_up_all(&v9ses->read_wait); 828 * v9fs_mux_rpc - sends 9P request and waits until a response is available.
829 * The function can be interrupted.
830 * @m: mux data
831 * @tc: request to be sent
832 * @rc: pointer where a pointer to the response is stored
833 */
834int
835v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc,
836 struct v9fs_fcall **rc)
837{
838 int err;
839 unsigned long flags;
840 struct v9fs_req *req;
841 struct v9fs_mux_rpc r;
842
843 r.err = 0;
844 r.rcall = NULL;
845 r.m = m;
846 init_waitqueue_head(&r.wqueue);
847
848 if (rc)
849 *rc = NULL;
850
851 req = v9fs_send_request(m, tc, v9fs_mux_rpc_cb, &r);
852 if (IS_ERR(req)) {
853 err = PTR_ERR(req);
854 dprintk(DEBUG_MUX, "error %d\n", err);
855 return PTR_ERR(req);
856 }
430 857
431 if (signal_pending(current)) 858 r.req = req;
432 complete(&v9ses->proccmpl); 859 dprintk(DEBUG_MUX, "mux %p tc %p tag %d rpc %p req %p\n", m, tc,
860 req->tag, &r, req);
861 err = wait_event_interruptible(r.wqueue, r.rcall != NULL || r.err < 0);
862 if (r.err < 0)
863 err = r.err;
864
865 if (err == -ERESTARTSYS && m->trans->status == Connected && m->err == 0) {
866 spin_lock(&m->lock);
867 req->tcall = NULL;
868 req->err = ERREQFLUSH;
869 spin_unlock(&m->lock);
870
871 clear_thread_flag(TIF_SIGPENDING);
872 v9fs_mux_flush_request(m, req);
873 spin_lock_irqsave(&current->sighand->siglock, flags);
874 recalc_sigpending();
875 spin_unlock_irqrestore(&current->sighand->siglock, flags);
876 }
433 877
434 dprintk(DEBUG_MUX, "recvproc: end\n"); 878 if (!err) {
435 v9ses->recvproc = NULL; 879 if (r.rcall)
880 dprintk(DEBUG_MUX, "got response id %d tag %d\n",
881 r.rcall->id, r.rcall->tag);
882
883 if (rc)
884 *rc = r.rcall;
885 else
886 kfree(r.rcall);
887 } else {
888 kfree(r.rcall);
889 dprintk(DEBUG_MUX, "got error %d\n", err);
890 if (err > 0)
891 err = -EIO;
892 }
436 893
437 return err >= 0; 894 return err;
438} 895}
439 896
440/** 897/**
441 * v9fs_mux_init - initialize multiplexer (spawn kproc) 898 * v9fs_mux_rpcnb - sends 9P request without waiting for response.
442 * @v9ses: session info structure 899 * @m: mux data
443 * @dev_name: mount device information (to create unique kproc) 900 * @tc: request to be sent
444 * 901 * @cb: callback function to be called when response arrives
902 * @cba: value to pass to the callback function
445 */ 903 */
904int v9fs_mux_rpcnb(struct v9fs_mux_data *m, struct v9fs_fcall *tc,
905 v9fs_mux_req_callback cb, void *a)
906{
907 int err;
908 struct v9fs_req *req;
909
910 req = v9fs_send_request(m, tc, cb, a);
911 if (IS_ERR(req)) {
912 err = PTR_ERR(req);
913 dprintk(DEBUG_MUX, "error %d\n", err);
914 return PTR_ERR(req);
915 }
916
917 dprintk(DEBUG_MUX, "mux %p tc %p tag %d\n", m, tc, req->tag);
918 return 0;
919}
446 920
447int v9fs_mux_init(struct v9fs_session_info *v9ses, const char *dev_name) 921/**
922 * v9fs_mux_cancel - cancel all pending requests with error
923 * @m: mux data
924 * @err: error code
925 */
926void v9fs_mux_cancel(struct v9fs_mux_data *m, int err)
448{ 927{
449 char procname[60]; 928 struct v9fs_req *req, *rtmp;
450 929 LIST_HEAD(cancel_list);
451 strncpy(procname, dev_name, sizeof(procname)); 930
452 procname[sizeof(procname) - 1] = 0; 931 dprintk(DEBUG_MUX, "mux %p err %d\n", m, err);
453 932 m->err = err;
454 init_waitqueue_head(&v9ses->read_wait); 933 spin_lock(&m->lock);
455 init_completion(&v9ses->fcread); 934 list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
456 init_completion(&v9ses->proccmpl); 935 list_move(&req->req_list, &cancel_list);
457 spin_lock_init(&v9ses->muxlock);
458 INIT_LIST_HEAD(&v9ses->mux_fcalls);
459 v9ses->recvproc = NULL;
460 v9ses->curfcall = NULL;
461
462 v9ses->recvproc = kthread_create(v9fs_recvproc, v9ses,
463 "v9fs_recvproc %s", procname);
464
465 if (IS_ERR(v9ses->recvproc)) {
466 eprintk(KERN_ERR, "cannot create receiving thread\n");
467 v9fs_session_close(v9ses);
468 return -ECONNABORTED;
469 } 936 }
937 spin_unlock(&m->lock);
470 938
471 wake_up_process(v9ses->recvproc); 939 list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
472 wait_for_completion(&v9ses->proccmpl); 940 list_del(&req->req_list);
941 if (!req->err)
942 req->err = err;
473 943
474 return 0; 944 if (req->cb)
945 (*req->cb) (req->cba, req->tcall, req->rcall, req->err);
946 else
947 kfree(req->rcall);
948
949 kfree(req);
950 }
951
952 wake_up(&m->equeue);
953}
954
955static u16 v9fs_mux_get_tag(struct v9fs_mux_data *m)
956{
957 int tag;
958
959 tag = v9fs_get_idpool(&m->tidpool);
960 if (tag < 0)
961 return V9FS_NOTAG;
962 else
963 return (u16) tag;
964}
965
966static void v9fs_mux_put_tag(struct v9fs_mux_data *m, u16 tag)
967{
968 if (tag != V9FS_NOTAG && v9fs_check_idpool(tag, &m->tidpool))
969 v9fs_put_idpool(tag, &m->tidpool);
475} 970}
diff --git a/fs/9p/mux.h b/fs/9p/mux.h
index 4994cb10badf..9473b84f24b2 100644
--- a/fs/9p/mux.h
+++ b/fs/9p/mux.h
@@ -3,6 +3,7 @@
3 * 3 *
4 * Multiplexer Definitions 4 * Multiplexer Definitions
5 * 5 *
6 * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
@@ -23,19 +24,35 @@
23 * 24 *
24 */ 25 */
25 26
26/* structure to manage each RPC transaction */ 27struct v9fs_mux_data;
27 28
28struct v9fs_rpcreq { 29/**
29 struct v9fs_fcall *tcall; 30 * v9fs_mux_req_callback - callback function that is called when the
30 struct v9fs_fcall *rcall; 31 * response of a request is received. The callback is called from
31 int err; /* error code if response failed */ 32 * a workqueue and shouldn't block.
33 *
34 * @a - the pointer that was specified when the request was send to be
35 * passed to the callback
36 * @tc - request call
37 * @rc - response call
38 * @err - error code (non-zero if error occured)
39 */
40typedef void (*v9fs_mux_req_callback)(void *a, struct v9fs_fcall *tc,
41 struct v9fs_fcall *rc, int err);
42
43int v9fs_mux_global_init(void);
44void v9fs_mux_global_exit(void);
32 45
33 /* XXX - could we put scatter/gather buffers here? */ 46struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize,
47 unsigned char *extended);
48void v9fs_mux_destroy(struct v9fs_mux_data *);
34 49
35 struct list_head next; 50int v9fs_mux_send(struct v9fs_mux_data *m, struct v9fs_fcall *tc);
36}; 51struct v9fs_fcall *v9fs_mux_recv(struct v9fs_mux_data *m);
52int v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, struct v9fs_fcall **rc);
53int v9fs_mux_rpcnb(struct v9fs_mux_data *m, struct v9fs_fcall *tc,
54 v9fs_mux_req_callback cb, void *a);
37 55
38int v9fs_mux_init(struct v9fs_session_info *v9ses, const char *dev_name); 56void v9fs_mux_flush(struct v9fs_mux_data *m, int sendflush);
39long v9fs_mux_rpc(struct v9fs_session_info *v9ses, 57void v9fs_mux_cancel(struct v9fs_mux_data *m, int err);
40 struct v9fs_fcall *tcall, struct v9fs_fcall **rcall); 58int v9fs_errstr2errno(char *errstr, int len);
41void v9fs_mux_cancel_requests(struct v9fs_session_info *v9ses, int err);
diff --git a/fs/9p/trans_fd.c b/fs/9p/trans_fd.c
index 63b58ce98ff4..1a28ef97a3d1 100644
--- a/fs/9p/trans_fd.c
+++ b/fs/9p/trans_fd.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * File Descriptor Transport Layer 4 * File Descriptor Transport Layer
5 * 5 *
6 * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
6 * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
@@ -106,9 +107,6 @@ v9fs_fd_init(struct v9fs_session_info *v9ses, const char *addr, char *data)
106 return -ENOPROTOOPT; 107 return -ENOPROTOOPT;
107 } 108 }
108 109
109 sema_init(&trans->writelock, 1);
110 sema_init(&trans->readlock, 1);
111
112 ts = kmalloc(sizeof(struct v9fs_trans_fd), GFP_KERNEL); 110 ts = kmalloc(sizeof(struct v9fs_trans_fd), GFP_KERNEL);
113 111
114 if (!ts) 112 if (!ts)
@@ -148,12 +146,12 @@ static void v9fs_fd_close(struct v9fs_transport *trans)
148 if (!trans) 146 if (!trans)
149 return; 147 return;
150 148
151 trans->status = Disconnected; 149 ts = xchg(&trans->priv, NULL);
152 ts = trans->priv;
153 150
154 if (!ts) 151 if (!ts)
155 return; 152 return;
156 153
154 trans->status = Disconnected;
157 if (ts->in_file) 155 if (ts->in_file)
158 fput(ts->in_file); 156 fput(ts->in_file);
159 157
@@ -163,10 +161,55 @@ static void v9fs_fd_close(struct v9fs_transport *trans)
163 kfree(ts); 161 kfree(ts);
164} 162}
165 163
164static unsigned int
165v9fs_fd_poll(struct v9fs_transport *trans, struct poll_table_struct *pt)
166{
167 int ret, n;
168 struct v9fs_trans_fd *ts;
169 mm_segment_t oldfs;
170
171 if (!trans)
172 return -EIO;
173
174 ts = trans->priv;
175 if (trans->status != Connected || !ts)
176 return -EIO;
177
178 oldfs = get_fs();
179 set_fs(get_ds());
180
181 if (!ts->in_file->f_op || !ts->in_file->f_op->poll) {
182 ret = -EIO;
183 goto end;
184 }
185
186 ret = ts->in_file->f_op->poll(ts->in_file, pt);
187
188 if (ts->out_file != ts->in_file) {
189 if (!ts->out_file->f_op || !ts->out_file->f_op->poll) {
190 ret = -EIO;
191 goto end;
192 }
193
194 n = ts->out_file->f_op->poll(ts->out_file, pt);
195
196 ret &= ~POLLOUT;
197 n &= ~POLLIN;
198
199 ret |= n;
200 }
201
202end:
203 set_fs(oldfs);
204 return ret;
205}
206
207
166struct v9fs_transport v9fs_trans_fd = { 208struct v9fs_transport v9fs_trans_fd = {
167 .init = v9fs_fd_init, 209 .init = v9fs_fd_init,
168 .write = v9fs_fd_send, 210 .write = v9fs_fd_send,
169 .read = v9fs_fd_recv, 211 .read = v9fs_fd_recv,
170 .close = v9fs_fd_close, 212 .close = v9fs_fd_close,
213 .poll = v9fs_fd_poll,
171}; 214};
172 215
diff --git a/fs/9p/trans_sock.c b/fs/9p/trans_sock.c
index 6a9a75d40f73..44e830697acb 100644
--- a/fs/9p/trans_sock.c
+++ b/fs/9p/trans_sock.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Socket Transport Layer 4 * Socket Transport Layer
5 * 5 *
6 * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com> 8 * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com>
8 * Copyright (C) 1995, 1996 by Olaf Kirch <okir@monad.swb.de> 9 * Copyright (C) 1995, 1996 by Olaf Kirch <okir@monad.swb.de>
@@ -36,6 +37,7 @@
36#include <asm/uaccess.h> 37#include <asm/uaccess.h>
37#include <linux/inet.h> 38#include <linux/inet.h>
38#include <linux/idr.h> 39#include <linux/idr.h>
40#include <linux/file.h>
39 41
40#include "debug.h" 42#include "debug.h"
41#include "v9fs.h" 43#include "v9fs.h"
@@ -45,6 +47,7 @@
45 47
46struct v9fs_trans_sock { 48struct v9fs_trans_sock {
47 struct socket *s; 49 struct socket *s;
50 struct file *filp;
48}; 51};
49 52
50/** 53/**
@@ -57,41 +60,26 @@ struct v9fs_trans_sock {
57 60
58static int v9fs_sock_recv(struct v9fs_transport *trans, void *v, int len) 61static int v9fs_sock_recv(struct v9fs_transport *trans, void *v, int len)
59{ 62{
60 struct msghdr msg; 63 int ret;
61 struct kvec iov; 64 struct v9fs_trans_sock *ts;
62 int result;
63 mm_segment_t oldfs;
64 struct v9fs_trans_sock *ts = trans ? trans->priv : NULL;
65 65
66 if (trans->status == Disconnected) 66 if (!trans || trans->status == Disconnected) {
67 dprintk(DEBUG_ERROR, "disconnected ...\n");
67 return -EREMOTEIO; 68 return -EREMOTEIO;
69 }
68 70
69 result = -EINVAL; 71 ts = trans->priv;
70
71 oldfs = get_fs();
72 set_fs(get_ds());
73
74 iov.iov_base = v;
75 iov.iov_len = len;
76 msg.msg_name = NULL;
77 msg.msg_namelen = 0;
78 msg.msg_iovlen = 1;
79 msg.msg_control = NULL;
80 msg.msg_controllen = 0;
81 msg.msg_namelen = 0;
82 msg.msg_flags = MSG_NOSIGNAL;
83 72
84 result = kernel_recvmsg(ts->s, &msg, &iov, 1, len, 0); 73 if (!(ts->filp->f_flags & O_NONBLOCK))
74 dprintk(DEBUG_ERROR, "blocking read ...\n");
85 75
86 dprintk(DEBUG_TRANS, "socket state %d\n", ts->s->state); 76 ret = kernel_read(ts->filp, ts->filp->f_pos, v, len);
87 set_fs(oldfs); 77 if (ret <= 0) {
88 78 if (ret != -ERESTARTSYS && ret != -EAGAIN)
89 if (result <= 0) {
90 if (result != -ERESTARTSYS)
91 trans->status = Disconnected; 79 trans->status = Disconnected;
92 } 80 }
93 81
94 return result; 82 return ret;
95} 83}
96 84
97/** 85/**
@@ -104,40 +92,72 @@ static int v9fs_sock_recv(struct v9fs_transport *trans, void *v, int len)
104 92
105static int v9fs_sock_send(struct v9fs_transport *trans, void *v, int len) 93static int v9fs_sock_send(struct v9fs_transport *trans, void *v, int len)
106{ 94{
107 struct kvec iov; 95 int ret;
108 struct msghdr msg;
109 int result = -1;
110 mm_segment_t oldfs; 96 mm_segment_t oldfs;
111 struct v9fs_trans_sock *ts = trans ? trans->priv : NULL; 97 struct v9fs_trans_sock *ts;
112 98
113 dprintk(DEBUG_TRANS, "Sending packet size %d (%x)\n", len, len); 99 if (!trans || trans->status == Disconnected) {
114 dump_data(v, len); 100 dprintk(DEBUG_ERROR, "disconnected ...\n");
101 return -EREMOTEIO;
102 }
103
104 ts = trans->priv;
105 if (!ts) {
106 dprintk(DEBUG_ERROR, "no transport ...\n");
107 return -EREMOTEIO;
108 }
115 109
116 down(&trans->writelock); 110 if (!(ts->filp->f_flags & O_NONBLOCK))
111 dprintk(DEBUG_ERROR, "blocking write ...\n");
117 112
118 oldfs = get_fs(); 113 oldfs = get_fs();
119 set_fs(get_ds()); 114 set_fs(get_ds());
120 iov.iov_base = v; 115 ret = vfs_write(ts->filp, (void __user *)v, len, &ts->filp->f_pos);
121 iov.iov_len = len;
122 msg.msg_name = NULL;
123 msg.msg_namelen = 0;
124 msg.msg_iovlen = 1;
125 msg.msg_control = NULL;
126 msg.msg_controllen = 0;
127 msg.msg_namelen = 0;
128 msg.msg_flags = MSG_NOSIGNAL;
129 result = kernel_sendmsg(ts->s, &msg, &iov, 1, len);
130 set_fs(oldfs); 116 set_fs(oldfs);
131 117
132 if (result < 0) { 118 if (ret < 0) {
133 if (result != -ERESTARTSYS) 119 if (ret != -ERESTARTSYS)
134 trans->status = Disconnected; 120 trans->status = Disconnected;
135 } 121 }
136 122
137 up(&trans->writelock); 123 return ret;
138 return result; 124}
125
126static unsigned int v9fs_sock_poll(struct v9fs_transport *trans,
127 struct poll_table_struct *pt) {
128
129 int ret;
130 struct v9fs_trans_sock *ts;
131 mm_segment_t oldfs;
132
133 if (!trans) {
134 dprintk(DEBUG_ERROR, "no transport\n");
135 return -EIO;
136 }
137
138 ts = trans->priv;
139 if (trans->status != Connected || !ts) {
140 dprintk(DEBUG_ERROR, "transport disconnected: %d\n", trans->status);
141 return -EIO;
142 }
143
144 oldfs = get_fs();
145 set_fs(get_ds());
146
147 if (!ts->filp->f_op || !ts->filp->f_op->poll) {
148 dprintk(DEBUG_ERROR, "no poll operation\n");
149 ret = -EIO;
150 goto end;
151 }
152
153 ret = ts->filp->f_op->poll(ts->filp, pt);
154
155end:
156 set_fs(oldfs);
157 return ret;
139} 158}
140 159
160
141/** 161/**
142 * v9fs_tcp_init - initialize TCP socket 162 * v9fs_tcp_init - initialize TCP socket
143 * @v9ses: session information 163 * @v9ses: session information
@@ -154,9 +174,9 @@ v9fs_tcp_init(struct v9fs_session_info *v9ses, const char *addr, char *data)
154 int rc = 0; 174 int rc = 0;
155 struct v9fs_trans_sock *ts = NULL; 175 struct v9fs_trans_sock *ts = NULL;
156 struct v9fs_transport *trans = v9ses->transport; 176 struct v9fs_transport *trans = v9ses->transport;
177 int fd;
157 178
158 sema_init(&trans->writelock, 1); 179 trans->status = Disconnected;
159 sema_init(&trans->readlock, 1);
160 180
161 ts = kmalloc(sizeof(struct v9fs_trans_sock), GFP_KERNEL); 181 ts = kmalloc(sizeof(struct v9fs_trans_sock), GFP_KERNEL);
162 182
@@ -165,6 +185,7 @@ v9fs_tcp_init(struct v9fs_session_info *v9ses, const char *addr, char *data)
165 185
166 trans->priv = ts; 186 trans->priv = ts;
167 ts->s = NULL; 187 ts->s = NULL;
188 ts->filp = NULL;
168 189
169 if (!addr) 190 if (!addr)
170 return -EINVAL; 191 return -EINVAL;
@@ -185,7 +206,18 @@ v9fs_tcp_init(struct v9fs_session_info *v9ses, const char *addr, char *data)
185 return rc; 206 return rc;
186 } 207 }
187 csocket->sk->sk_allocation = GFP_NOIO; 208 csocket->sk->sk_allocation = GFP_NOIO;
209
210 fd = sock_map_fd(csocket);
211 if (fd < 0) {
212 sock_release(csocket);
213 kfree(ts);
214 trans->priv = NULL;
215 return fd;
216 }
217
188 ts->s = csocket; 218 ts->s = csocket;
219 ts->filp = fget(fd);
220 ts->filp->f_flags |= O_NONBLOCK;
189 trans->status = Connected; 221 trans->status = Connected;
190 222
191 return 0; 223 return 0;
@@ -203,7 +235,7 @@ static int
203v9fs_unix_init(struct v9fs_session_info *v9ses, const char *dev_name, 235v9fs_unix_init(struct v9fs_session_info *v9ses, const char *dev_name,
204 char *data) 236 char *data)
205{ 237{
206 int rc; 238 int rc, fd;
207 struct socket *csocket; 239 struct socket *csocket;
208 struct sockaddr_un sun_server; 240 struct sockaddr_un sun_server;
209 struct v9fs_transport *trans; 241 struct v9fs_transport *trans;
@@ -213,6 +245,8 @@ v9fs_unix_init(struct v9fs_session_info *v9ses, const char *dev_name,
213 csocket = NULL; 245 csocket = NULL;
214 trans = v9ses->transport; 246 trans = v9ses->transport;
215 247
248 trans->status = Disconnected;
249
216 if (strlen(dev_name) > UNIX_PATH_MAX) { 250 if (strlen(dev_name) > UNIX_PATH_MAX) {
217 eprintk(KERN_ERR, "v9fs_trans_unix: address too long: %s\n", 251 eprintk(KERN_ERR, "v9fs_trans_unix: address too long: %s\n",
218 dev_name); 252 dev_name);
@@ -225,9 +259,7 @@ v9fs_unix_init(struct v9fs_session_info *v9ses, const char *dev_name,
225 259
226 trans->priv = ts; 260 trans->priv = ts;
227 ts->s = NULL; 261 ts->s = NULL;
228 262 ts->filp = NULL;
229 sema_init(&trans->writelock, 1);
230 sema_init(&trans->readlock, 1);
231 263
232 sun_server.sun_family = PF_UNIX; 264 sun_server.sun_family = PF_UNIX;
233 strcpy(sun_server.sun_path, dev_name); 265 strcpy(sun_server.sun_path, dev_name);
@@ -241,7 +273,18 @@ v9fs_unix_init(struct v9fs_session_info *v9ses, const char *dev_name,
241 return rc; 273 return rc;
242 } 274 }
243 csocket->sk->sk_allocation = GFP_NOIO; 275 csocket->sk->sk_allocation = GFP_NOIO;
276
277 fd = sock_map_fd(csocket);
278 if (fd < 0) {
279 sock_release(csocket);
280 kfree(ts);
281 trans->priv = NULL;
282 return fd;
283 }
284
244 ts->s = csocket; 285 ts->s = csocket;
286 ts->filp = fget(fd);
287 ts->filp->f_flags |= O_NONBLOCK;
245 trans->status = Connected; 288 trans->status = Connected;
246 289
247 return 0; 290 return 0;
@@ -262,12 +305,11 @@ static void v9fs_sock_close(struct v9fs_transport *trans)
262 305
263 ts = trans->priv; 306 ts = trans->priv;
264 307
265 if ((ts) && (ts->s)) { 308 if ((ts) && (ts->filp)) {
266 dprintk(DEBUG_TRANS, "closing the socket %p\n", ts->s); 309 fput(ts->filp);
267 sock_release(ts->s); 310 ts->filp = NULL;
268 ts->s = NULL; 311 ts->s = NULL;
269 trans->status = Disconnected; 312 trans->status = Disconnected;
270 dprintk(DEBUG_TRANS, "socket closed\n");
271 } 313 }
272 314
273 kfree(ts); 315 kfree(ts);
@@ -280,6 +322,7 @@ struct v9fs_transport v9fs_trans_tcp = {
280 .write = v9fs_sock_send, 322 .write = v9fs_sock_send,
281 .read = v9fs_sock_recv, 323 .read = v9fs_sock_recv,
282 .close = v9fs_sock_close, 324 .close = v9fs_sock_close,
325 .poll = v9fs_sock_poll,
283}; 326};
284 327
285struct v9fs_transport v9fs_trans_unix = { 328struct v9fs_transport v9fs_trans_unix = {
@@ -287,4 +330,5 @@ struct v9fs_transport v9fs_trans_unix = {
287 .write = v9fs_sock_send, 330 .write = v9fs_sock_send,
288 .read = v9fs_sock_recv, 331 .read = v9fs_sock_recv,
289 .close = v9fs_sock_close, 332 .close = v9fs_sock_close,
333 .poll = v9fs_sock_poll,
290}; 334};
diff --git a/fs/9p/transport.h b/fs/9p/transport.h
index 9e9cd418efd5..91fcdb94b361 100644
--- a/fs/9p/transport.h
+++ b/fs/9p/transport.h
@@ -3,6 +3,7 @@
3 * 3 *
4 * Transport Definition 4 * Transport Definition
5 * 5 *
6 * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
@@ -31,14 +32,13 @@ enum v9fs_transport_status {
31 32
32struct v9fs_transport { 33struct v9fs_transport {
33 enum v9fs_transport_status status; 34 enum v9fs_transport_status status;
34 struct semaphore writelock;
35 struct semaphore readlock;
36 void *priv; 35 void *priv;
37 36
38 int (*init) (struct v9fs_session_info *, const char *, char *); 37 int (*init) (struct v9fs_session_info *, const char *, char *);
39 int (*write) (struct v9fs_transport *, void *, int); 38 int (*write) (struct v9fs_transport *, void *, int);
40 int (*read) (struct v9fs_transport *, void *, int); 39 int (*read) (struct v9fs_transport *, void *, int);
41 void (*close) (struct v9fs_transport *); 40 void (*close) (struct v9fs_transport *);
41 unsigned int (*poll)(struct v9fs_transport *, struct poll_table_struct *);
42}; 42};
43 43
44extern struct v9fs_transport v9fs_trans_tcp; 44extern struct v9fs_transport v9fs_trans_tcp;
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 418c3743fdee..5250c428fc1f 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -37,7 +37,6 @@
37#include "v9fs_vfs.h" 37#include "v9fs_vfs.h"
38#include "transport.h" 38#include "transport.h"
39#include "mux.h" 39#include "mux.h"
40#include "conv.h"
41 40
42/* TODO: sysfs or debugfs interface */ 41/* TODO: sysfs or debugfs interface */
43int v9fs_debug_level = 0; /* feature-rific global debug level */ 42int v9fs_debug_level = 0; /* feature-rific global debug level */
@@ -213,7 +212,8 @@ retry:
213 return -1; 212 return -1;
214 } 213 }
215 214
216 error = idr_get_new(&p->pool, NULL, &i); 215 /* no need to store exactly p, we just need something non-null */
216 error = idr_get_new(&p->pool, p, &i);
217 up(&p->lock); 217 up(&p->lock);
218 218
219 if (error == -EAGAIN) 219 if (error == -EAGAIN)
@@ -243,6 +243,16 @@ void v9fs_put_idpool(int id, struct v9fs_idpool *p)
243} 243}
244 244
245/** 245/**
246 * v9fs_check_idpool - check if the specified id is available
247 * @id - id to check
248 * @p - pool
249 */
250int v9fs_check_idpool(int id, struct v9fs_idpool *p)
251{
252 return idr_find(&p->pool, id) != NULL;
253}
254
255/**
246 * v9fs_session_init - initialize session 256 * v9fs_session_init - initialize session
247 * @v9ses: session information structure 257 * @v9ses: session information structure
248 * @dev_name: device being mounted 258 * @dev_name: device being mounted
@@ -259,6 +269,7 @@ v9fs_session_init(struct v9fs_session_info *v9ses,
259 int n = 0; 269 int n = 0;
260 int newfid = -1; 270 int newfid = -1;
261 int retval = -EINVAL; 271 int retval = -EINVAL;
272 struct v9fs_str *version;
262 273
263 v9ses->name = __getname(); 274 v9ses->name = __getname();
264 if (!v9ses->name) 275 if (!v9ses->name)
@@ -281,9 +292,6 @@ v9fs_session_init(struct v9fs_session_info *v9ses,
281 /* id pools that are session-dependent: FIDs and TIDs */ 292 /* id pools that are session-dependent: FIDs and TIDs */
282 idr_init(&v9ses->fidpool.pool); 293 idr_init(&v9ses->fidpool.pool);
283 init_MUTEX(&v9ses->fidpool.lock); 294 init_MUTEX(&v9ses->fidpool.lock);
284 idr_init(&v9ses->tidpool.pool);
285 init_MUTEX(&v9ses->tidpool.lock);
286
287 295
288 switch (v9ses->proto) { 296 switch (v9ses->proto) {
289 case PROTO_TCP: 297 case PROTO_TCP:
@@ -320,7 +328,12 @@ v9fs_session_init(struct v9fs_session_info *v9ses,
320 v9ses->shutdown = 0; 328 v9ses->shutdown = 0;
321 v9ses->session_hung = 0; 329 v9ses->session_hung = 0;
322 330
323 if ((retval = v9fs_mux_init(v9ses, dev_name)) < 0) { 331 v9ses->mux = v9fs_mux_init(v9ses->transport, v9ses->maxdata + V9FS_IOHDRSZ,
332 &v9ses->extended);
333
334 if (IS_ERR(v9ses->mux)) {
335 retval = PTR_ERR(v9ses->mux);
336 v9ses->mux = NULL;
324 dprintk(DEBUG_ERROR, "problem initializing mux\n"); 337 dprintk(DEBUG_ERROR, "problem initializing mux\n");
325 goto SessCleanUp; 338 goto SessCleanUp;
326 } 339 }
@@ -339,13 +352,16 @@ v9fs_session_init(struct v9fs_session_info *v9ses,
339 goto FreeFcall; 352 goto FreeFcall;
340 } 353 }
341 354
342 /* Really should check for 9P1 and report error */ 355 version = &fcall->params.rversion.version;
343 if (!strcmp(fcall->params.rversion.version, "9P2000.u")) { 356 if (version->len==8 && !memcmp(version->str, "9P2000.u", 8)) {
344 dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n"); 357 dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n");
345 v9ses->extended = 1; 358 v9ses->extended = 1;
346 } else { 359 } else if (version->len==6 && !memcmp(version->str, "9P2000", 6)) {
347 dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n"); 360 dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n");
348 v9ses->extended = 0; 361 v9ses->extended = 0;
362 } else {
363 retval = -EREMOTEIO;
364 goto FreeFcall;
349 } 365 }
350 366
351 n = fcall->params.rversion.msize; 367 n = fcall->params.rversion.msize;
@@ -381,7 +397,7 @@ v9fs_session_init(struct v9fs_session_info *v9ses,
381 } 397 }
382 398
383 if (v9ses->afid != ~0) { 399 if (v9ses->afid != ~0) {
384 if (v9fs_t_clunk(v9ses, v9ses->afid, NULL)) 400 if (v9fs_t_clunk(v9ses, v9ses->afid))
385 dprintk(DEBUG_ERROR, "clunk failed\n"); 401 dprintk(DEBUG_ERROR, "clunk failed\n");
386 } 402 }
387 403
@@ -403,13 +419,16 @@ v9fs_session_init(struct v9fs_session_info *v9ses,
403 419
404void v9fs_session_close(struct v9fs_session_info *v9ses) 420void v9fs_session_close(struct v9fs_session_info *v9ses)
405{ 421{
406 if (v9ses->recvproc) { 422 if (v9ses->mux) {
407 send_sig(SIGKILL, v9ses->recvproc, 1); 423 v9fs_mux_destroy(v9ses->mux);
408 wait_for_completion(&v9ses->proccmpl); 424 v9ses->mux = NULL;
409 } 425 }
410 426
411 if (v9ses->transport) 427 if (v9ses->transport) {
412 v9ses->transport->close(v9ses->transport); 428 v9ses->transport->close(v9ses->transport);
429 kfree(v9ses->transport);
430 v9ses->transport = NULL;
431 }
413 432
414 __putname(v9ses->name); 433 __putname(v9ses->name);
415 __putname(v9ses->remotename); 434 __putname(v9ses->remotename);
@@ -420,8 +439,9 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
420 * and cancel all pending requests. 439 * and cancel all pending requests.
421 */ 440 */
422void v9fs_session_cancel(struct v9fs_session_info *v9ses) { 441void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
442 dprintk(DEBUG_ERROR, "cancel session %p\n", v9ses);
423 v9ses->transport->status = Disconnected; 443 v9ses->transport->status = Disconnected;
424 v9fs_mux_cancel_requests(v9ses, -EIO); 444 v9fs_mux_cancel(v9ses->mux, -EIO);
425} 445}
426 446
427extern int v9fs_error_init(void); 447extern int v9fs_error_init(void);
@@ -433,11 +453,17 @@ extern int v9fs_error_init(void);
433 453
434static int __init init_v9fs(void) 454static int __init init_v9fs(void)
435{ 455{
456 int ret;
457
436 v9fs_error_init(); 458 v9fs_error_init();
437 459
438 printk(KERN_INFO "Installing v9fs 9P2000 file system support\n"); 460 printk(KERN_INFO "Installing v9fs 9P2000 file system support\n");
439 461
440 return register_filesystem(&v9fs_fs_type); 462 ret = v9fs_mux_global_init();
463 if (!ret)
464 ret = register_filesystem(&v9fs_fs_type);
465
466 return ret;
441} 467}
442 468
443/** 469/**
@@ -447,6 +473,7 @@ static int __init init_v9fs(void)
447 473
448static void __exit exit_v9fs(void) 474static void __exit exit_v9fs(void)
449{ 475{
476 v9fs_mux_global_exit();
450 unregister_filesystem(&v9fs_fs_type); 477 unregister_filesystem(&v9fs_fs_type);
451} 478}
452 479
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index 45dcef42bdd6..f337da7a0eec 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -57,24 +57,14 @@ struct v9fs_session_info {
57 57
58 /* book keeping */ 58 /* book keeping */
59 struct v9fs_idpool fidpool; /* The FID pool for file descriptors */ 59 struct v9fs_idpool fidpool; /* The FID pool for file descriptors */
60 struct v9fs_idpool tidpool; /* The TID pool for transactions ids */
61 60
62 /* transport information */
63 struct v9fs_transport *transport; 61 struct v9fs_transport *transport;
62 struct v9fs_mux_data *mux;
64 63
65 int inprogress; /* session in progress => true */ 64 int inprogress; /* session in progress => true */
66 int shutdown; /* session shutting down. no more attaches. */ 65 int shutdown; /* session shutting down. no more attaches. */
67 unsigned char session_hung; 66 unsigned char session_hung;
68 67 struct dentry *debugfs_dir;
69 /* mux private data */
70 struct v9fs_fcall *curfcall;
71 wait_queue_head_t read_wait;
72 struct completion fcread;
73 struct completion proccmpl;
74 struct task_struct *recvproc;
75
76 spinlock_t muxlock;
77 struct list_head mux_fcalls;
78}; 68};
79 69
80/* possible values of ->proto */ 70/* possible values of ->proto */
@@ -84,11 +74,14 @@ enum {
84 PROTO_FD, 74 PROTO_FD,
85}; 75};
86 76
77extern struct dentry *v9fs_debugfs_root;
78
87int v9fs_session_init(struct v9fs_session_info *, const char *, char *); 79int v9fs_session_init(struct v9fs_session_info *, const char *, char *);
88struct v9fs_session_info *v9fs_inode2v9ses(struct inode *); 80struct v9fs_session_info *v9fs_inode2v9ses(struct inode *);
89void v9fs_session_close(struct v9fs_session_info *v9ses); 81void v9fs_session_close(struct v9fs_session_info *v9ses);
90int v9fs_get_idpool(struct v9fs_idpool *p); 82int v9fs_get_idpool(struct v9fs_idpool *p);
91void v9fs_put_idpool(int id, struct v9fs_idpool *p); 83void v9fs_put_idpool(int id, struct v9fs_idpool *p);
84int v9fs_check_idpool(int id, struct v9fs_idpool *p);
92void v9fs_session_cancel(struct v9fs_session_info *v9ses); 85void v9fs_session_cancel(struct v9fs_session_info *v9ses);
93 86
94#define V9FS_MAGIC 0x01021997 87#define V9FS_MAGIC 0x01021997
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index 2f2cea7ee3e7..c78502ad00ed 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -45,9 +45,8 @@ extern struct dentry_operations v9fs_dentry_operations;
45 45
46struct inode *v9fs_get_inode(struct super_block *sb, int mode); 46struct inode *v9fs_get_inode(struct super_block *sb, int mode);
47ino_t v9fs_qid2ino(struct v9fs_qid *qid); 47ino_t v9fs_qid2ino(struct v9fs_qid *qid);
48void v9fs_mistat2inode(struct v9fs_stat *, struct inode *, 48void v9fs_stat2inode(struct v9fs_stat *, struct inode *, struct super_block *);
49 struct super_block *);
50int v9fs_dir_release(struct inode *inode, struct file *filp); 49int v9fs_dir_release(struct inode *inode, struct file *filp);
51int v9fs_file_open(struct inode *inode, struct file *file); 50int v9fs_file_open(struct inode *inode, struct file *file);
52void v9fs_inode2mistat(struct inode *inode, struct v9fs_stat *mistat); 51void v9fs_inode2stat(struct inode *inode, struct v9fs_stat *stat);
53void v9fs_dentry_release(struct dentry *); 52void v9fs_dentry_release(struct dentry *);
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
index a6aa947de0f9..2dd806dac9f1 100644
--- a/fs/9p/vfs_dentry.c
+++ b/fs/9p/vfs_dentry.c
@@ -40,7 +40,6 @@
40#include "v9fs.h" 40#include "v9fs.h"
41#include "9p.h" 41#include "9p.h"
42#include "v9fs_vfs.h" 42#include "v9fs_vfs.h"
43#include "conv.h"
44#include "fid.h" 43#include "fid.h"
45 44
46/** 45/**
@@ -95,24 +94,22 @@ static int v9fs_dentry_validate(struct dentry *dentry, struct nameidata *nd)
95 94
96void v9fs_dentry_release(struct dentry *dentry) 95void v9fs_dentry_release(struct dentry *dentry)
97{ 96{
97 int err;
98
98 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); 99 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
99 100
100 if (dentry->d_fsdata != NULL) { 101 if (dentry->d_fsdata != NULL) {
101 struct list_head *fid_list = dentry->d_fsdata; 102 struct list_head *fid_list = dentry->d_fsdata;
102 struct v9fs_fid *temp = NULL; 103 struct v9fs_fid *temp = NULL;
103 struct v9fs_fid *current_fid = NULL; 104 struct v9fs_fid *current_fid = NULL;
104 struct v9fs_fcall *fcall = NULL;
105 105
106 list_for_each_entry_safe(current_fid, temp, fid_list, list) { 106 list_for_each_entry_safe(current_fid, temp, fid_list, list) {
107 if (v9fs_t_clunk 107 err = v9fs_t_clunk(current_fid->v9ses, current_fid->fid);
108 (current_fid->v9ses, current_fid->fid, &fcall))
109 dprintk(DEBUG_ERROR, "clunk failed: %s\n",
110 FCALL_ERROR(fcall));
111 108
112 v9fs_put_idpool(current_fid->fid, 109 if (err < 0)
113 &current_fid->v9ses->fidpool); 110 dprintk(DEBUG_ERROR, "clunk failed: %d name %s\n",
111 err, dentry->d_iname);
114 112
115 kfree(fcall);
116 v9fs_fid_destroy(current_fid); 113 v9fs_fid_destroy(current_fid);
117 } 114 }
118 115
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index 57a43b8feef5..ae6d032b9b59 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -37,8 +37,8 @@
37#include "debug.h" 37#include "debug.h"
38#include "v9fs.h" 38#include "v9fs.h"
39#include "9p.h" 39#include "9p.h"
40#include "v9fs_vfs.h"
41#include "conv.h" 40#include "conv.h"
41#include "v9fs_vfs.h"
42#include "fid.h" 42#include "fid.h"
43 43
44/** 44/**
@@ -74,20 +74,16 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
74 struct inode *inode = filp->f_dentry->d_inode; 74 struct inode *inode = filp->f_dentry->d_inode;
75 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); 75 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
76 struct v9fs_fid *file = filp->private_data; 76 struct v9fs_fid *file = filp->private_data;
77 unsigned int i, n; 77 unsigned int i, n, s;
78 int fid = -1; 78 int fid = -1;
79 int ret = 0; 79 int ret = 0;
80 struct v9fs_stat *mi = NULL; 80 struct v9fs_stat stat;
81 int over = 0; 81 int over = 0;
82 82
83 dprintk(DEBUG_VFS, "name %s\n", filp->f_dentry->d_name.name); 83 dprintk(DEBUG_VFS, "name %s\n", filp->f_dentry->d_name.name);
84 84
85 fid = file->fid; 85 fid = file->fid;
86 86
87 mi = kmalloc(v9ses->maxdata, GFP_KERNEL);
88 if (!mi)
89 return -ENOMEM;
90
91 if (file->rdir_fcall && (filp->f_pos != file->rdir_pos)) { 87 if (file->rdir_fcall && (filp->f_pos != file->rdir_pos)) {
92 kfree(file->rdir_fcall); 88 kfree(file->rdir_fcall);
93 file->rdir_fcall = NULL; 89 file->rdir_fcall = NULL;
@@ -97,20 +93,20 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
97 n = file->rdir_fcall->params.rread.count; 93 n = file->rdir_fcall->params.rread.count;
98 i = file->rdir_fpos; 94 i = file->rdir_fpos;
99 while (i < n) { 95 while (i < n) {
100 int s = v9fs_deserialize_stat(v9ses, 96 s = v9fs_deserialize_stat(
101 file->rdir_fcall->params.rread.data + i, 97 file->rdir_fcall->params.rread.data + i,
102 n - i, mi, v9ses->maxdata); 98 n - i, &stat, v9ses->extended);
103 99
104 if (s == 0) { 100 if (s == 0) {
105 dprintk(DEBUG_ERROR, 101 dprintk(DEBUG_ERROR,
106 "error while deserializing mistat\n"); 102 "error while deserializing stat\n");
107 ret = -EIO; 103 ret = -EIO;
108 goto FreeStructs; 104 goto FreeStructs;
109 } 105 }
110 106
111 over = filldir(dirent, mi->name, strlen(mi->name), 107 over = filldir(dirent, stat.name.str, stat.name.len,
112 filp->f_pos, v9fs_qid2ino(&mi->qid), 108 filp->f_pos, v9fs_qid2ino(&stat.qid),
113 dt_type(mi)); 109 dt_type(&stat));
114 110
115 if (over) { 111 if (over) {
116 file->rdir_fpos = i; 112 file->rdir_fpos = i;
@@ -130,7 +126,7 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
130 126
131 while (!over) { 127 while (!over) {
132 ret = v9fs_t_read(v9ses, fid, filp->f_pos, 128 ret = v9fs_t_read(v9ses, fid, filp->f_pos,
133 v9ses->maxdata-V9FS_IOHDRSZ, &fcall); 129 v9ses->maxdata-V9FS_IOHDRSZ, &fcall);
134 if (ret < 0) { 130 if (ret < 0) {
135 dprintk(DEBUG_ERROR, "error while reading: %d: %p\n", 131 dprintk(DEBUG_ERROR, "error while reading: %d: %p\n",
136 ret, fcall); 132 ret, fcall);
@@ -141,19 +137,18 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
141 n = ret; 137 n = ret;
142 i = 0; 138 i = 0;
143 while (i < n) { 139 while (i < n) {
144 int s = v9fs_deserialize_stat(v9ses, 140 s = v9fs_deserialize_stat(fcall->params.rread.data + i,
145 fcall->params.rread.data + i, n - i, mi, 141 n - i, &stat, v9ses->extended);
146 v9ses->maxdata);
147 142
148 if (s == 0) { 143 if (s == 0) {
149 dprintk(DEBUG_ERROR, 144 dprintk(DEBUG_ERROR,
150 "error while deserializing mistat\n"); 145 "error while deserializing stat\n");
151 return -EIO; 146 return -EIO;
152 } 147 }
153 148
154 over = filldir(dirent, mi->name, strlen(mi->name), 149 over = filldir(dirent, stat.name.str, stat.name.len,
155 filp->f_pos, v9fs_qid2ino(&mi->qid), 150 filp->f_pos, v9fs_qid2ino(&stat.qid),
156 dt_type(mi)); 151 dt_type(&stat));
157 152
158 if (over) { 153 if (over) {
159 file->rdir_fcall = fcall; 154 file->rdir_fcall = fcall;
@@ -172,7 +167,6 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
172 167
173 FreeStructs: 168 FreeStructs:
174 kfree(fcall); 169 kfree(fcall);
175 kfree(mi);
176 return ret; 170 return ret;
177} 171}
178 172
@@ -193,18 +187,15 @@ int v9fs_dir_release(struct inode *inode, struct file *filp)
193 fid->fid); 187 fid->fid);
194 fidnum = fid->fid; 188 fidnum = fid->fid;
195 189
196 filemap_fdatawrite(inode->i_mapping); 190 filemap_write_and_wait(inode->i_mapping);
197 filemap_fdatawait(inode->i_mapping);
198 191
199 if (fidnum >= 0) { 192 if (fidnum >= 0) {
200 dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen, 193 dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen,
201 fid->fid); 194 fid->fid);
202 195
203 if (v9fs_t_clunk(v9ses, fidnum, NULL)) 196 if (v9fs_t_clunk(v9ses, fidnum))
204 dprintk(DEBUG_ERROR, "clunk failed\n"); 197 dprintk(DEBUG_ERROR, "clunk failed\n");
205 198
206 v9fs_put_idpool(fid->fid, &v9ses->fidpool);
207
208 kfree(fid->rdir_fcall); 199 kfree(fid->rdir_fcall);
209 kfree(fid); 200 kfree(fid);
210 201
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 89c849da8504..6852f0eb96ed 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -32,6 +32,7 @@
32#include <linux/string.h> 32#include <linux/string.h>
33#include <linux/smp_lock.h> 33#include <linux/smp_lock.h>
34#include <linux/inet.h> 34#include <linux/inet.h>
35#include <linux/version.h>
35#include <linux/list.h> 36#include <linux/list.h>
36#include <asm/uaccess.h> 37#include <asm/uaccess.h>
37#include <linux/idr.h> 38#include <linux/idr.h>
@@ -117,9 +118,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
117 118
118 result = v9fs_t_open(v9ses, newfid, open_mode, &fcall); 119 result = v9fs_t_open(v9ses, newfid, open_mode, &fcall);
119 if (result < 0) { 120 if (result < 0) {
120 dprintk(DEBUG_ERROR, 121 PRINT_FCALL_ERROR("open failed", fcall);
121 "open failed, open_mode 0x%x: %s\n", open_mode,
122 FCALL_ERROR(fcall));
123 kfree(fcall); 122 kfree(fcall);
124 return result; 123 return result;
125 } 124 }
@@ -165,8 +164,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
165 return -ENOLCK; 164 return -ENOLCK;
166 165
167 if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { 166 if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
168 filemap_fdatawrite(inode->i_mapping); 167 filemap_write_and_wait(inode->i_mapping);
169 filemap_fdatawait(inode->i_mapping);
170 invalidate_inode_pages(&inode->i_data); 168 invalidate_inode_pages(&inode->i_data);
171 } 169 }
172 170
@@ -257,7 +255,6 @@ v9fs_file_write(struct file *filp, const char __user * data,
257 int result = -EIO; 255 int result = -EIO;
258 int rsize = 0; 256 int rsize = 0;
259 int total = 0; 257 int total = 0;
260 char *buf;
261 258
262 dprintk(DEBUG_VFS, "data %p count %d offset %x\n", data, (int)count, 259 dprintk(DEBUG_VFS, "data %p count %d offset %x\n", data, (int)count,
263 (int)*offset); 260 (int)*offset);
@@ -265,28 +262,14 @@ v9fs_file_write(struct file *filp, const char __user * data,
265 if (v9fid->iounit != 0 && rsize > v9fid->iounit) 262 if (v9fid->iounit != 0 && rsize > v9fid->iounit)
266 rsize = v9fid->iounit; 263 rsize = v9fid->iounit;
267 264
268 buf = kmalloc(v9ses->maxdata - V9FS_IOHDRSZ, GFP_KERNEL);
269 if (!buf)
270 return -ENOMEM;
271
272 do { 265 do {
273 if (count < rsize) 266 if (count < rsize)
274 rsize = count; 267 rsize = count;
275 268
276 result = copy_from_user(buf, data, rsize); 269 result = v9fs_t_write(v9ses, fid, *offset, rsize, data, &fcall);
277 if (result) {
278 dprintk(DEBUG_ERROR, "Problem copying from user\n");
279 kfree(buf);
280 return -EFAULT;
281 }
282
283 dump_data(buf, rsize);
284 result = v9fs_t_write(v9ses, fid, *offset, rsize, buf, &fcall);
285 if (result < 0) { 270 if (result < 0) {
286 eprintk(KERN_ERR, "error while writing: %s(%d)\n", 271 PRINT_FCALL_ERROR("error while writing", fcall);
287 FCALL_ERROR(fcall), result);
288 kfree(fcall); 272 kfree(fcall);
289 kfree(buf);
290 return result; 273 return result;
291 } else 274 } else
292 *offset += result; 275 *offset += result;
@@ -306,7 +289,6 @@ v9fs_file_write(struct file *filp, const char __user * data,
306 total += result; 289 total += result;
307 } while (count); 290 } while (count);
308 291
309 kfree(buf);
310 return total; 292 return total;
311} 293}
312 294
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 0ea965c3bb7d..d933ef1fbd8a 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -40,7 +40,6 @@
40#include "v9fs.h" 40#include "v9fs.h"
41#include "9p.h" 41#include "9p.h"
42#include "v9fs_vfs.h" 42#include "v9fs_vfs.h"
43#include "conv.h"
44#include "fid.h" 43#include "fid.h"
45 44
46static struct inode_operations v9fs_dir_inode_operations; 45static struct inode_operations v9fs_dir_inode_operations;
@@ -127,100 +126,32 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
127} 126}
128 127
129/** 128/**
130 * v9fs_blank_mistat - helper function to setup a 9P stat structure 129 * v9fs_blank_wstat - helper function to setup a 9P stat structure
131 * @v9ses: 9P session info (for determining extended mode) 130 * @v9ses: 9P session info (for determining extended mode)
132 * @mistat: structure to initialize 131 * @wstat: structure to initialize
133 * 132 *
134 */ 133 */
135 134
136static void 135static void
137v9fs_blank_mistat(struct v9fs_session_info *v9ses, struct v9fs_stat *mistat) 136v9fs_blank_wstat(struct v9fs_wstat *wstat)
138{ 137{
139 mistat->type = ~0; 138 wstat->type = ~0;
140 mistat->dev = ~0; 139 wstat->dev = ~0;
141 mistat->qid.type = ~0; 140 wstat->qid.type = ~0;
142 mistat->qid.version = ~0; 141 wstat->qid.version = ~0;
143 *((long long *)&mistat->qid.path) = ~0; 142 *((long long *)&wstat->qid.path) = ~0;
144 mistat->mode = ~0; 143 wstat->mode = ~0;
145 mistat->atime = ~0; 144 wstat->atime = ~0;
146 mistat->mtime = ~0; 145 wstat->mtime = ~0;
147 mistat->length = ~0; 146 wstat->length = ~0;
148 mistat->name = mistat->data; 147 wstat->name = NULL;
149 mistat->uid = mistat->data; 148 wstat->uid = NULL;
150 mistat->gid = mistat->data; 149 wstat->gid = NULL;
151 mistat->muid = mistat->data; 150 wstat->muid = NULL;
152 if (v9ses->extended) { 151 wstat->n_uid = ~0;
153 mistat->n_uid = ~0; 152 wstat->n_gid = ~0;
154 mistat->n_gid = ~0; 153 wstat->n_muid = ~0;
155 mistat->n_muid = ~0; 154 wstat->extension = NULL;
156 mistat->extension = mistat->data;
157 }
158 *mistat->data = 0;
159}
160
161/**
162 * v9fs_mistat2unix - convert mistat to unix stat
163 * @mistat: Plan 9 metadata (mistat) structure
164 * @buf: unix metadata (stat) structure to populate
165 * @sb: superblock
166 *
167 */
168
169static void
170v9fs_mistat2unix(struct v9fs_stat *mistat, struct stat *buf,
171 struct super_block *sb)
172{
173 struct v9fs_session_info *v9ses = sb ? sb->s_fs_info : NULL;
174
175 buf->st_nlink = 1;
176
177 buf->st_atime = mistat->atime;
178 buf->st_mtime = mistat->mtime;
179 buf->st_ctime = mistat->mtime;
180
181 buf->st_uid = (unsigned short)-1;
182 buf->st_gid = (unsigned short)-1;
183
184 if (v9ses && v9ses->extended) {
185 /* TODO: string to uid mapping via user-space daemon */
186 if (mistat->n_uid != -1)
187 sscanf(mistat->uid, "%x", (unsigned int *)&buf->st_uid);
188
189 if (mistat->n_gid != -1)
190 sscanf(mistat->gid, "%x", (unsigned int *)&buf->st_gid);
191 }
192
193 if (buf->st_uid == (unsigned short)-1)
194 buf->st_uid = v9ses->uid;
195 if (buf->st_gid == (unsigned short)-1)
196 buf->st_gid = v9ses->gid;
197
198 buf->st_mode = p9mode2unixmode(v9ses, mistat->mode);
199 if ((S_ISBLK(buf->st_mode)) || (S_ISCHR(buf->st_mode))) {
200 char type = 0;
201 int major = -1;
202 int minor = -1;
203 sscanf(mistat->extension, "%c %u %u", &type, &major, &minor);
204 switch (type) {
205 case 'c':
206 buf->st_mode &= ~S_IFBLK;
207 buf->st_mode |= S_IFCHR;
208 break;
209 case 'b':
210 break;
211 default:
212 dprintk(DEBUG_ERROR, "Unknown special type %c (%s)\n",
213 type, mistat->extension);
214 };
215 buf->st_rdev = MKDEV(major, minor);
216 } else
217 buf->st_rdev = 0;
218
219 buf->st_size = mistat->length;
220
221 buf->st_blksize = sb->s_blocksize;
222 buf->st_blocks =
223 (buf->st_size + buf->st_blksize - 1) >> sb->s_blocksize_bits;
224} 155}
225 156
226/** 157/**
@@ -312,12 +243,12 @@ v9fs_create(struct inode *dir,
312 struct inode *file_inode = NULL; 243 struct inode *file_inode = NULL;
313 struct v9fs_fcall *fcall = NULL; 244 struct v9fs_fcall *fcall = NULL;
314 struct v9fs_qid qid; 245 struct v9fs_qid qid;
315 struct stat newstat;
316 int dirfidnum = -1; 246 int dirfidnum = -1;
317 long newfid = -1; 247 long newfid = -1;
318 int result = 0; 248 int result = 0;
319 unsigned int iounit = 0; 249 unsigned int iounit = 0;
320 int wfidno = -1; 250 int wfidno = -1;
251 int err;
321 252
322 perm = unixmode2p9mode(v9ses, perm); 253 perm = unixmode2p9mode(v9ses, perm);
323 254
@@ -349,57 +280,64 @@ v9fs_create(struct inode *dir,
349 280
350 result = v9fs_t_walk(v9ses, dirfidnum, newfid, NULL, &fcall); 281 result = v9fs_t_walk(v9ses, dirfidnum, newfid, NULL, &fcall);
351 if (result < 0) { 282 if (result < 0) {
352 dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall)); 283 PRINT_FCALL_ERROR("clone error", fcall);
353 v9fs_put_idpool(newfid, &v9ses->fidpool); 284 v9fs_put_idpool(newfid, &v9ses->fidpool);
354 newfid = -1; 285 newfid = -1;
355 goto CleanUpFid; 286 goto CleanUpFid;
356 } 287 }
357 288
358 kfree(fcall); 289 kfree(fcall);
290 fcall = NULL;
359 291
360 result = v9fs_t_create(v9ses, newfid, (char *)file_dentry->d_name.name, 292 result = v9fs_t_create(v9ses, newfid, (char *)file_dentry->d_name.name,
361 perm, open_mode, &fcall); 293 perm, open_mode, &fcall);
362 if (result < 0) { 294 if (result < 0) {
363 dprintk(DEBUG_ERROR, "create fails: %s(%d)\n", 295 PRINT_FCALL_ERROR("create fails", fcall);
364 FCALL_ERROR(fcall), result);
365
366 goto CleanUpFid; 296 goto CleanUpFid;
367 } 297 }
368 298
369 iounit = fcall->params.rcreate.iounit; 299 iounit = fcall->params.rcreate.iounit;
370 qid = fcall->params.rcreate.qid; 300 qid = fcall->params.rcreate.qid;
371 kfree(fcall); 301 kfree(fcall);
302 fcall = NULL;
372 303
373 fid = v9fs_fid_create(file_dentry, v9ses, newfid, 1); 304 if (!(perm&V9FS_DMDIR)) {
374 dprintk(DEBUG_VFS, "fid %p %d\n", fid, fid->fidcreate); 305 fid = v9fs_fid_create(file_dentry, v9ses, newfid, 1);
375 if (!fid) { 306 dprintk(DEBUG_VFS, "fid %p %d\n", fid, fid->fidcreate);
376 result = -ENOMEM; 307 if (!fid) {
377 goto CleanUpFid; 308 result = -ENOMEM;
378 } 309 goto CleanUpFid;
310 }
379 311
380 fid->qid = qid; 312 fid->qid = qid;
381 fid->iounit = iounit; 313 fid->iounit = iounit;
314 } else {
315 err = v9fs_t_clunk(v9ses, newfid);
316 newfid = -1;
317 if (err < 0)
318 dprintk(DEBUG_ERROR, "clunk for mkdir failed: %d\n", err);
319 }
382 320
383 /* walk to the newly created file and put the fid in the dentry */ 321 /* walk to the newly created file and put the fid in the dentry */
384 wfidno = v9fs_get_idpool(&v9ses->fidpool); 322 wfidno = v9fs_get_idpool(&v9ses->fidpool);
385 if (newfid < 0) { 323 if (wfidno < 0) {
386 eprintk(KERN_WARNING, "no free fids available\n"); 324 eprintk(KERN_WARNING, "no free fids available\n");
387 return -ENOSPC; 325 return -ENOSPC;
388 } 326 }
389 327
390 result = v9fs_t_walk(v9ses, dirfidnum, wfidno, 328 result = v9fs_t_walk(v9ses, dirfidnum, wfidno,
391 (char *) file_dentry->d_name.name, NULL); 329 (char *) file_dentry->d_name.name, &fcall);
392 if (result < 0) { 330 if (result < 0) {
393 dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall)); 331 PRINT_FCALL_ERROR("clone error", fcall);
394 v9fs_put_idpool(wfidno, &v9ses->fidpool); 332 v9fs_put_idpool(wfidno, &v9ses->fidpool);
395 wfidno = -1; 333 wfidno = -1;
396 goto CleanUpFid; 334 goto CleanUpFid;
397 } 335 }
336 kfree(fcall);
337 fcall = NULL;
398 338
399 if (!v9fs_fid_create(file_dentry, v9ses, wfidno, 0)) { 339 if (!v9fs_fid_create(file_dentry, v9ses, wfidno, 0)) {
400 if (!v9fs_t_clunk(v9ses, newfid, &fcall)) { 340 v9fs_put_idpool(wfidno, &v9ses->fidpool);
401 v9fs_put_idpool(wfidno, &v9ses->fidpool);
402 }
403 341
404 goto CleanUpFid; 342 goto CleanUpFid;
405 } 343 }
@@ -409,62 +347,43 @@ v9fs_create(struct inode *dir,
409 (perm & V9FS_DMDEVICE)) 347 (perm & V9FS_DMDEVICE))
410 return 0; 348 return 0;
411 349
412 result = v9fs_t_stat(v9ses, newfid, &fcall); 350 result = v9fs_t_stat(v9ses, wfidno, &fcall);
413 if (result < 0) { 351 if (result < 0) {
414 dprintk(DEBUG_ERROR, "stat error: %s(%d)\n", FCALL_ERROR(fcall), 352 PRINT_FCALL_ERROR("stat error", fcall);
415 result);
416 goto CleanUpFid; 353 goto CleanUpFid;
417 } 354 }
418 355
419 v9fs_mistat2unix(fcall->params.rstat.stat, &newstat, sb);
420 356
421 file_inode = v9fs_get_inode(sb, newstat.st_mode); 357 file_inode = v9fs_get_inode(sb,
358 p9mode2unixmode(v9ses, fcall->params.rstat.stat.mode));
359
422 if ((!file_inode) || IS_ERR(file_inode)) { 360 if ((!file_inode) || IS_ERR(file_inode)) {
423 dprintk(DEBUG_ERROR, "create inode failed\n"); 361 dprintk(DEBUG_ERROR, "create inode failed\n");
424 result = -EBADF; 362 result = -EBADF;
425 goto CleanUpFid; 363 goto CleanUpFid;
426 } 364 }
427 365
428 v9fs_mistat2inode(fcall->params.rstat.stat, file_inode, sb); 366 v9fs_stat2inode(&fcall->params.rstat.stat, file_inode, sb);
429 kfree(fcall); 367 kfree(fcall);
430 fcall = NULL; 368 fcall = NULL;
431 file_dentry->d_op = &v9fs_dentry_operations; 369 file_dentry->d_op = &v9fs_dentry_operations;
432 d_instantiate(file_dentry, file_inode); 370 d_instantiate(file_dentry, file_inode);
433 371
434 if (perm & V9FS_DMDIR) {
435 if (!v9fs_t_clunk(v9ses, newfid, &fcall))
436 v9fs_put_idpool(newfid, &v9ses->fidpool);
437 else
438 dprintk(DEBUG_ERROR, "clunk for mkdir failed: %s\n",
439 FCALL_ERROR(fcall));
440 kfree(fcall);
441 fid->fidopen = 0;
442 fid->fidcreate = 0;
443 d_drop(file_dentry);
444 }
445
446 return 0; 372 return 0;
447 373
448 CleanUpFid: 374 CleanUpFid:
449 kfree(fcall); 375 kfree(fcall);
376 fcall = NULL;
450 377
451 if (newfid >= 0) { 378 if (newfid >= 0) {
452 if (!v9fs_t_clunk(v9ses, newfid, &fcall)) 379 err = v9fs_t_clunk(v9ses, newfid);
453 v9fs_put_idpool(newfid, &v9ses->fidpool); 380 if (err < 0)
454 else 381 dprintk(DEBUG_ERROR, "clunk failed: %d\n", err);
455 dprintk(DEBUG_ERROR, "clunk failed: %s\n",
456 FCALL_ERROR(fcall));
457
458 kfree(fcall);
459 } 382 }
460 if (wfidno >= 0) { 383 if (wfidno >= 0) {
461 if (!v9fs_t_clunk(v9ses, wfidno, &fcall)) 384 err = v9fs_t_clunk(v9ses, wfidno);
462 v9fs_put_idpool(wfidno, &v9ses->fidpool); 385 if (err < 0)
463 else 386 dprintk(DEBUG_ERROR, "clunk failed: %d\n", err);
464 dprintk(DEBUG_ERROR, "clunk failed: %s\n",
465 FCALL_ERROR(fcall));
466
467 kfree(fcall);
468 } 387 }
469 return result; 388 return result;
470} 389}
@@ -509,10 +428,9 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
509 } 428 }
510 429
511 result = v9fs_t_remove(v9ses, fid, &fcall); 430 result = v9fs_t_remove(v9ses, fid, &fcall);
512 if (result < 0) 431 if (result < 0) {
513 dprintk(DEBUG_ERROR, "remove of file fails: %s(%d)\n", 432 PRINT_FCALL_ERROR("remove fails", fcall);
514 FCALL_ERROR(fcall), result); 433 } else {
515 else {
516 v9fs_put_idpool(fid, &v9ses->fidpool); 434 v9fs_put_idpool(fid, &v9ses->fidpool);
517 v9fs_fid_destroy(v9fid); 435 v9fs_fid_destroy(v9fid);
518 } 436 }
@@ -567,7 +485,6 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
567 struct v9fs_fid *fid; 485 struct v9fs_fid *fid;
568 struct inode *inode; 486 struct inode *inode;
569 struct v9fs_fcall *fcall = NULL; 487 struct v9fs_fcall *fcall = NULL;
570 struct stat newstat;
571 int dirfidnum = -1; 488 int dirfidnum = -1;
572 int newfid = -1; 489 int newfid = -1;
573 int result = 0; 490 int result = 0;
@@ -620,8 +537,8 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
620 goto FreeFcall; 537 goto FreeFcall;
621 } 538 }
622 539
623 v9fs_mistat2unix(fcall->params.rstat.stat, &newstat, sb); 540 inode = v9fs_get_inode(sb, p9mode2unixmode(v9ses,
624 inode = v9fs_get_inode(sb, newstat.st_mode); 541 fcall->params.rstat.stat.mode));
625 542
626 if (IS_ERR(inode) && (PTR_ERR(inode) == -ENOSPC)) { 543 if (IS_ERR(inode) && (PTR_ERR(inode) == -ENOSPC)) {
627 eprintk(KERN_WARNING, "inode alloc failes, returns %ld\n", 544 eprintk(KERN_WARNING, "inode alloc failes, returns %ld\n",
@@ -631,7 +548,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
631 goto FreeFcall; 548 goto FreeFcall;
632 } 549 }
633 550
634 inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat->qid); 551 inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat.qid);
635 552
636 fid = v9fs_fid_create(dentry, v9ses, newfid, 0); 553 fid = v9fs_fid_create(dentry, v9ses, newfid, 0);
637 if (fid == NULL) { 554 if (fid == NULL) {
@@ -640,10 +557,10 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
640 goto FreeFcall; 557 goto FreeFcall;
641 } 558 }
642 559
643 fid->qid = fcall->params.rstat.stat->qid; 560 fid->qid = fcall->params.rstat.stat.qid;
644 561
645 dentry->d_op = &v9fs_dentry_operations; 562 dentry->d_op = &v9fs_dentry_operations;
646 v9fs_mistat2inode(fcall->params.rstat.stat, inode, inode->i_sb); 563 v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb);
647 564
648 d_add(dentry, inode); 565 d_add(dentry, inode);
649 kfree(fcall); 566 kfree(fcall);
@@ -699,7 +616,7 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
699 v9fs_fid_lookup(old_dentry->d_parent); 616 v9fs_fid_lookup(old_dentry->d_parent);
700 struct v9fs_fid *newdirfid = 617 struct v9fs_fid *newdirfid =
701 v9fs_fid_lookup(new_dentry->d_parent); 618 v9fs_fid_lookup(new_dentry->d_parent);
702 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); 619 struct v9fs_wstat wstat;
703 struct v9fs_fcall *fcall = NULL; 620 struct v9fs_fcall *fcall = NULL;
704 int fid = -1; 621 int fid = -1;
705 int olddirfidnum = -1; 622 int olddirfidnum = -1;
@@ -708,9 +625,6 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
708 625
709 dprintk(DEBUG_VFS, "\n"); 626 dprintk(DEBUG_VFS, "\n");
710 627
711 if (!mistat)
712 return -ENOMEM;
713
714 if ((!oldfid) || (!olddirfid) || (!newdirfid)) { 628 if ((!oldfid) || (!olddirfid) || (!newdirfid)) {
715 dprintk(DEBUG_ERROR, "problem with arguments\n"); 629 dprintk(DEBUG_ERROR, "problem with arguments\n");
716 return -EBADF; 630 return -EBADF;
@@ -734,26 +648,15 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
734 goto FreeFcallnBail; 648 goto FreeFcallnBail;
735 } 649 }
736 650
737 v9fs_blank_mistat(v9ses, mistat); 651 v9fs_blank_wstat(&wstat);
652 wstat.muid = v9ses->name;
653 wstat.name = (char *) new_dentry->d_name.name;
738 654
739 strcpy(mistat->data + 1, v9ses->name); 655 retval = v9fs_t_wstat(v9ses, fid, &wstat, &fcall);
740 mistat->name = mistat->data + 1 + strlen(v9ses->name);
741
742 if (new_dentry->d_name.len >
743 (v9ses->maxdata - strlen(v9ses->name) - sizeof(struct v9fs_stat))) {
744 dprintk(DEBUG_ERROR, "new name too long\n");
745 goto FreeFcallnBail;
746 }
747
748 strcpy(mistat->name, new_dentry->d_name.name);
749 retval = v9fs_t_wstat(v9ses, fid, mistat, &fcall);
750 656
751 FreeFcallnBail: 657 FreeFcallnBail:
752 kfree(mistat);
753
754 if (retval < 0) 658 if (retval < 0)
755 dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n", 659 PRINT_FCALL_ERROR("wstat error", fcall);
756 FCALL_ERROR(fcall));
757 660
758 kfree(fcall); 661 kfree(fcall);
759 return retval; 662 return retval;
@@ -788,7 +691,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
788 if (err < 0) 691 if (err < 0)
789 dprintk(DEBUG_ERROR, "stat error\n"); 692 dprintk(DEBUG_ERROR, "stat error\n");
790 else { 693 else {
791 v9fs_mistat2inode(fcall->params.rstat.stat, dentry->d_inode, 694 v9fs_stat2inode(&fcall->params.rstat.stat, dentry->d_inode,
792 dentry->d_inode->i_sb); 695 dentry->d_inode->i_sb);
793 generic_fillattr(dentry->d_inode, stat); 696 generic_fillattr(dentry->d_inode, stat);
794 } 697 }
@@ -809,57 +712,44 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
809 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); 712 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
810 struct v9fs_fid *fid = v9fs_fid_lookup(dentry); 713 struct v9fs_fid *fid = v9fs_fid_lookup(dentry);
811 struct v9fs_fcall *fcall = NULL; 714 struct v9fs_fcall *fcall = NULL;
812 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); 715 struct v9fs_wstat wstat;
813 int res = -EPERM; 716 int res = -EPERM;
814 717
815 dprintk(DEBUG_VFS, "\n"); 718 dprintk(DEBUG_VFS, "\n");
816 719
817 if (!mistat)
818 return -ENOMEM;
819
820 if (!fid) { 720 if (!fid) {
821 dprintk(DEBUG_ERROR, 721 dprintk(DEBUG_ERROR,
822 "Couldn't find fid associated with dentry\n"); 722 "Couldn't find fid associated with dentry\n");
823 return -EBADF; 723 return -EBADF;
824 } 724 }
825 725
826 v9fs_blank_mistat(v9ses, mistat); 726 v9fs_blank_wstat(&wstat);
827 if (iattr->ia_valid & ATTR_MODE) 727 if (iattr->ia_valid & ATTR_MODE)
828 mistat->mode = unixmode2p9mode(v9ses, iattr->ia_mode); 728 wstat.mode = unixmode2p9mode(v9ses, iattr->ia_mode);
829 729
830 if (iattr->ia_valid & ATTR_MTIME) 730 if (iattr->ia_valid & ATTR_MTIME)
831 mistat->mtime = iattr->ia_mtime.tv_sec; 731 wstat.mtime = iattr->ia_mtime.tv_sec;
832 732
833 if (iattr->ia_valid & ATTR_ATIME) 733 if (iattr->ia_valid & ATTR_ATIME)
834 mistat->atime = iattr->ia_atime.tv_sec; 734 wstat.atime = iattr->ia_atime.tv_sec;
835 735
836 if (iattr->ia_valid & ATTR_SIZE) 736 if (iattr->ia_valid & ATTR_SIZE)
837 mistat->length = iattr->ia_size; 737 wstat.length = iattr->ia_size;
838 738
839 if (v9ses->extended) { 739 if (v9ses->extended) {
840 char *ptr = mistat->data+1; 740 if (iattr->ia_valid & ATTR_UID)
841 741 wstat.n_uid = iattr->ia_uid;
842 if (iattr->ia_valid & ATTR_UID) {
843 mistat->uid = ptr;
844 ptr += 1+sprintf(ptr, "%08x", iattr->ia_uid);
845 mistat->n_uid = iattr->ia_uid;
846 }
847 742
848 if (iattr->ia_valid & ATTR_GID) { 743 if (iattr->ia_valid & ATTR_GID)
849 mistat->gid = ptr; 744 wstat.n_gid = iattr->ia_gid;
850 ptr += 1+sprintf(ptr, "%08x", iattr->ia_gid);
851 mistat->n_gid = iattr->ia_gid;
852 }
853 } 745 }
854 746
855 res = v9fs_t_wstat(v9ses, fid->fid, mistat, &fcall); 747 res = v9fs_t_wstat(v9ses, fid->fid, &wstat, &fcall);
856 748
857 if (res < 0) 749 if (res < 0)
858 dprintk(DEBUG_ERROR, "wstat error: %s\n", FCALL_ERROR(fcall)); 750 PRINT_FCALL_ERROR("wstat error", fcall);
859 751
860 kfree(mistat);
861 kfree(fcall); 752 kfree(fcall);
862
863 if (res >= 0) 753 if (res >= 0)
864 res = inode_setattr(dentry->d_inode, iattr); 754 res = inode_setattr(dentry->d_inode, iattr);
865 755
@@ -867,51 +757,47 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
867} 757}
868 758
869/** 759/**
870 * v9fs_mistat2inode - populate an inode structure with mistat info 760 * v9fs_stat2inode - populate an inode structure with mistat info
871 * @mistat: Plan 9 metadata (mistat) structure 761 * @stat: Plan 9 metadata (mistat) structure
872 * @inode: inode to populate 762 * @inode: inode to populate
873 * @sb: superblock of filesystem 763 * @sb: superblock of filesystem
874 * 764 *
875 */ 765 */
876 766
877void 767void
878v9fs_mistat2inode(struct v9fs_stat *mistat, struct inode *inode, 768v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode,
879 struct super_block *sb) 769 struct super_block *sb)
880{ 770{
771 int n;
772 char ext[32];
881 struct v9fs_session_info *v9ses = sb->s_fs_info; 773 struct v9fs_session_info *v9ses = sb->s_fs_info;
882 774
883 inode->i_nlink = 1; 775 inode->i_nlink = 1;
884 776
885 inode->i_atime.tv_sec = mistat->atime; 777 inode->i_atime.tv_sec = stat->atime;
886 inode->i_mtime.tv_sec = mistat->mtime; 778 inode->i_mtime.tv_sec = stat->mtime;
887 inode->i_ctime.tv_sec = mistat->mtime; 779 inode->i_ctime.tv_sec = stat->mtime;
888 780
889 inode->i_uid = -1; 781 inode->i_uid = v9ses->uid;
890 inode->i_gid = -1; 782 inode->i_gid = v9ses->gid;
891 783
892 if (v9ses->extended) { 784 if (v9ses->extended) {
893 /* TODO: string to uid mapping via user-space daemon */ 785 inode->i_uid = stat->n_uid;
894 inode->i_uid = mistat->n_uid; 786 inode->i_gid = stat->n_gid;
895 inode->i_gid = mistat->n_gid;
896
897 if (mistat->n_uid == -1)
898 sscanf(mistat->uid, "%x", &inode->i_uid);
899
900 if (mistat->n_gid == -1)
901 sscanf(mistat->gid, "%x", &inode->i_gid);
902 } 787 }
903 788
904 if (inode->i_uid == -1) 789 inode->i_mode = p9mode2unixmode(v9ses, stat->mode);
905 inode->i_uid = v9ses->uid;
906 if (inode->i_gid == -1)
907 inode->i_gid = v9ses->gid;
908
909 inode->i_mode = p9mode2unixmode(v9ses, mistat->mode);
910 if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) { 790 if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) {
911 char type = 0; 791 char type = 0;
912 int major = -1; 792 int major = -1;
913 int minor = -1; 793 int minor = -1;
914 sscanf(mistat->extension, "%c %u %u", &type, &major, &minor); 794
795 n = stat->extension.len;
796 if (n > sizeof(ext)-1)
797 n = sizeof(ext)-1;
798 memmove(ext, stat->extension.str, n);
799 ext[n] = 0;
800 sscanf(ext, "%c %u %u", &type, &major, &minor);
915 switch (type) { 801 switch (type) {
916 case 'c': 802 case 'c':
917 inode->i_mode &= ~S_IFBLK; 803 inode->i_mode &= ~S_IFBLK;
@@ -920,14 +806,14 @@ v9fs_mistat2inode(struct v9fs_stat *mistat, struct inode *inode,
920 case 'b': 806 case 'b':
921 break; 807 break;
922 default: 808 default:
923 dprintk(DEBUG_ERROR, "Unknown special type %c (%s)\n", 809 dprintk(DEBUG_ERROR, "Unknown special type %c (%.*s)\n",
924 type, mistat->extension); 810 type, stat->extension.len, stat->extension.str);
925 }; 811 };
926 inode->i_rdev = MKDEV(major, minor); 812 inode->i_rdev = MKDEV(major, minor);
927 } else 813 } else
928 inode->i_rdev = 0; 814 inode->i_rdev = 0;
929 815
930 inode->i_size = mistat->length; 816 inode->i_size = stat->length;
931 817
932 inode->i_blksize = sb->s_blocksize; 818 inode->i_blksize = sb->s_blocksize;
933 inode->i_blocks = 819 inode->i_blocks =
@@ -955,71 +841,6 @@ ino_t v9fs_qid2ino(struct v9fs_qid *qid)
955} 841}
956 842
957/** 843/**
958 * v9fs_vfs_symlink - helper function to create symlinks
959 * @dir: directory inode containing symlink
960 * @dentry: dentry for symlink
961 * @symname: symlink data
962 *
963 * See 9P2000.u RFC for more information
964 *
965 */
966
967static int
968v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
969{
970 int retval = -EPERM;
971 struct v9fs_fid *newfid;
972 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
973 struct v9fs_fcall *fcall = NULL;
974 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
975
976 dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
977 symname);
978
979 if (!mistat)
980 return -ENOMEM;
981
982 if (!v9ses->extended) {
983 dprintk(DEBUG_ERROR, "not extended\n");
984 goto FreeFcall;
985 }
986
987 /* issue a create */
988 retval = v9fs_create(dir, dentry, S_IFLNK, 0);
989 if (retval != 0)
990 goto FreeFcall;
991
992 newfid = v9fs_fid_lookup(dentry);
993
994 /* issue a twstat */
995 v9fs_blank_mistat(v9ses, mistat);
996 strcpy(mistat->data + 1, symname);
997 mistat->extension = mistat->data + 1;
998 retval = v9fs_t_wstat(v9ses, newfid->fid, mistat, &fcall);
999 if (retval < 0) {
1000 dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
1001 FCALL_ERROR(fcall));
1002 goto FreeFcall;
1003 }
1004
1005 kfree(fcall);
1006
1007 if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) {
1008 dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n",
1009 FCALL_ERROR(fcall));
1010 goto FreeFcall;
1011 }
1012
1013 d_drop(dentry); /* FID - will this also clunk? */
1014
1015 FreeFcall:
1016 kfree(mistat);
1017 kfree(fcall);
1018
1019 return retval;
1020}
1021
1022/**
1023 * v9fs_readlink - read a symlink's location (internal version) 844 * v9fs_readlink - read a symlink's location (internal version)
1024 * @dentry: dentry for symlink 845 * @dentry: dentry for symlink
1025 * @buffer: buffer to load symlink location into 846 * @buffer: buffer to load symlink location into
@@ -1058,16 +879,17 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
1058 if (!fcall) 879 if (!fcall)
1059 return -EIO; 880 return -EIO;
1060 881
1061 if (!(fcall->params.rstat.stat->mode & V9FS_DMSYMLINK)) { 882 if (!(fcall->params.rstat.stat.mode & V9FS_DMSYMLINK)) {
1062 retval = -EINVAL; 883 retval = -EINVAL;
1063 goto FreeFcall; 884 goto FreeFcall;
1064 } 885 }
1065 886
1066 /* copy extension buffer into buffer */ 887 /* copy extension buffer into buffer */
1067 if (strlen(fcall->params.rstat.stat->extension) < buflen) 888 if (fcall->params.rstat.stat.extension.len < buflen)
1068 buflen = strlen(fcall->params.rstat.stat->extension); 889 buflen = fcall->params.rstat.stat.extension.len;
1069 890
1070 memcpy(buffer, fcall->params.rstat.stat->extension, buflen + 1); 891 memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1);
892 buffer[buflen-1] = 0;
1071 893
1072 retval = buflen; 894 retval = buflen;
1073 895
@@ -1157,6 +979,77 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void
1157 __putname(s); 979 __putname(s);
1158} 980}
1159 981
982static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
983 int mode, const char *extension)
984{
985 int err, retval;
986 struct v9fs_session_info *v9ses;
987 struct v9fs_fcall *fcall;
988 struct v9fs_fid *fid;
989 struct v9fs_wstat wstat;
990
991 v9ses = v9fs_inode2v9ses(dir);
992 retval = -EPERM;
993 fcall = NULL;
994
995 if (!v9ses->extended) {
996 dprintk(DEBUG_ERROR, "not extended\n");
997 goto free_mem;
998 }
999
1000 /* issue a create */
1001 retval = v9fs_create(dir, dentry, mode, 0);
1002 if (retval != 0)
1003 goto free_mem;
1004
1005 fid = v9fs_fid_get_created(dentry);
1006 if (!fid) {
1007 dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n");
1008 goto free_mem;
1009 }
1010
1011 /* issue a Twstat */
1012 v9fs_blank_wstat(&wstat);
1013 wstat.muid = v9ses->name;
1014 wstat.extension = (char *) extension;
1015 retval = v9fs_t_wstat(v9ses, fid->fid, &wstat, &fcall);
1016 if (retval < 0) {
1017 PRINT_FCALL_ERROR("wstat error", fcall);
1018 goto free_mem;
1019 }
1020
1021 err = v9fs_t_clunk(v9ses, fid->fid);
1022 if (err < 0) {
1023 dprintk(DEBUG_ERROR, "clunk failed: %d\n", err);
1024 goto free_mem;
1025 }
1026
1027 d_drop(dentry); /* FID - will this also clunk? */
1028
1029free_mem:
1030 kfree(fcall);
1031 return retval;
1032}
1033
1034/**
1035 * v9fs_vfs_symlink - helper function to create symlinks
1036 * @dir: directory inode containing symlink
1037 * @dentry: dentry for symlink
1038 * @symname: symlink data
1039 *
1040 * See 9P2000.u RFC for more information
1041 *
1042 */
1043
1044static int
1045v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
1046{
1047 dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
1048 symname);
1049
1050 return v9fs_vfs_mkspecial(dir, dentry, S_IFLNK, symname);
1051}
1052
1160/** 1053/**
1161 * v9fs_vfs_link - create a hardlink 1054 * v9fs_vfs_link - create a hardlink
1162 * @old_dentry: dentry for file to link to 1055 * @old_dentry: dentry for file to link to
@@ -1173,64 +1066,24 @@ static int
1173v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, 1066v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
1174 struct dentry *dentry) 1067 struct dentry *dentry)
1175{ 1068{
1176 int retval = -EPERM; 1069 int retval;
1177 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); 1070 struct v9fs_fid *oldfid;
1178 struct v9fs_fcall *fcall = NULL; 1071 char *name;
1179 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
1180 struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry);
1181 struct v9fs_fid *newfid = NULL;
1182 char *symname = __getname();
1183 1072
1184 dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, 1073 dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
1185 old_dentry->d_name.name); 1074 old_dentry->d_name.name);
1186 1075
1187 if (!v9ses->extended) { 1076 oldfid = v9fs_fid_lookup(old_dentry);
1188 dprintk(DEBUG_ERROR, "not extended\n"); 1077 if (!oldfid) {
1189 goto FreeMem; 1078 dprintk(DEBUG_ERROR, "can't find oldfid\n");
1190 } 1079 return -EPERM;
1191
1192 /* get fid of old_dentry */
1193 sprintf(symname, "hardlink(%d)\n", oldfid->fid);
1194
1195 /* issue a create */
1196 retval = v9fs_create(dir, dentry, V9FS_DMLINK, 0);
1197 if (retval != 0)
1198 goto FreeMem;
1199
1200 newfid = v9fs_fid_lookup(dentry);
1201 if (!newfid) {
1202 dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n");
1203 goto FreeMem;
1204 }
1205
1206 /* issue a twstat */
1207 v9fs_blank_mistat(v9ses, mistat);
1208 strcpy(mistat->data + 1, symname);
1209 mistat->extension = mistat->data + 1;
1210 retval = v9fs_t_wstat(v9ses, newfid->fid, mistat, &fcall);
1211 if (retval < 0) {
1212 dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
1213 FCALL_ERROR(fcall));
1214 goto FreeMem;
1215 }
1216
1217 kfree(fcall);
1218
1219 if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) {
1220 dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n",
1221 FCALL_ERROR(fcall));
1222 goto FreeMem;
1223 } 1080 }
1224 1081
1225 d_drop(dentry); /* FID - will this also clunk? */ 1082 name = __getname();
1226 1083 sprintf(name, "hardlink(%d)\n", oldfid->fid);
1227 kfree(fcall); 1084 retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name);
1228 fcall = NULL; 1085 __putname(name);
1229 1086
1230 FreeMem:
1231 kfree(mistat);
1232 kfree(fcall);
1233 __putname(symname);
1234 return retval; 1087 return retval;
1235} 1088}
1236 1089
@@ -1246,82 +1099,30 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
1246static int 1099static int
1247v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) 1100v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
1248{ 1101{
1249 int retval = -EPERM; 1102 int retval;
1250 struct v9fs_fid *newfid; 1103 char *name;
1251 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
1252 struct v9fs_fcall *fcall = NULL;
1253 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
1254 char *symname = __getname();
1255 1104
1256 dprintk(DEBUG_VFS, " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, 1105 dprintk(DEBUG_VFS, " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
1257 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); 1106 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev));
1258 1107
1259 if (!mistat) 1108 if (!new_valid_dev(rdev))
1260 return -ENOMEM; 1109 return -EINVAL;
1261
1262 if (!new_valid_dev(rdev)) {
1263 retval = -EINVAL;
1264 goto FreeMem;
1265 }
1266
1267 if (!v9ses->extended) {
1268 dprintk(DEBUG_ERROR, "not extended\n");
1269 goto FreeMem;
1270 }
1271
1272 /* issue a create */
1273 retval = v9fs_create(dir, dentry, mode, 0);
1274
1275 if (retval != 0)
1276 goto FreeMem;
1277
1278 newfid = v9fs_fid_lookup(dentry);
1279 if (!newfid) {
1280 dprintk(DEBUG_ERROR, "coudn't resove fid from dentry\n");
1281 retval = -EINVAL;
1282 goto FreeMem;
1283 }
1284 1110
1111 name = __getname();
1285 /* build extension */ 1112 /* build extension */
1286 if (S_ISBLK(mode)) 1113 if (S_ISBLK(mode))
1287 sprintf(symname, "b %u %u", MAJOR(rdev), MINOR(rdev)); 1114 sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev));
1288 else if (S_ISCHR(mode)) 1115 else if (S_ISCHR(mode))
1289 sprintf(symname, "c %u %u", MAJOR(rdev), MINOR(rdev)); 1116 sprintf(name, "c %u %u", MAJOR(rdev), MINOR(rdev));
1290 else if (S_ISFIFO(mode)) 1117 else if (S_ISFIFO(mode))
1291 ; /* DO NOTHING */ 1118 *name = 0;
1292 else { 1119 else {
1293 retval = -EINVAL; 1120 __putname(name);
1294 goto FreeMem; 1121 return -EINVAL;
1295 }
1296
1297 if (!S_ISFIFO(mode)) {
1298 /* issue a twstat */
1299 v9fs_blank_mistat(v9ses, mistat);
1300 strcpy(mistat->data + 1, symname);
1301 mistat->extension = mistat->data + 1;
1302 retval = v9fs_t_wstat(v9ses, newfid->fid, mistat, &fcall);
1303 if (retval < 0) {
1304 dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
1305 FCALL_ERROR(fcall));
1306 goto FreeMem;
1307 }
1308 } 1122 }
1309 1123
1310 /* need to update dcache so we show up */ 1124 retval = v9fs_vfs_mkspecial(dir, dentry, mode, name);
1311 kfree(fcall); 1125 __putname(name);
1312
1313 if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) {
1314 dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n",
1315 FCALL_ERROR(fcall));
1316 goto FreeMem;
1317 }
1318
1319 d_drop(dentry); /* FID - will this also clunk? */
1320
1321 FreeMem:
1322 kfree(mistat);
1323 kfree(fcall);
1324 __putname(symname);
1325 1126
1326 return retval; 1127 return retval;
1327} 1128}
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 82c5b0084079..ae0f06b3c11a 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -44,7 +44,6 @@
44#include "v9fs.h" 44#include "v9fs.h"
45#include "9p.h" 45#include "9p.h"
46#include "v9fs_vfs.h" 46#include "v9fs_vfs.h"
47#include "conv.h"
48#include "fid.h" 47#include "fid.h"
49 48
50static void v9fs_clear_inode(struct inode *); 49static void v9fs_clear_inode(struct inode *);
@@ -123,12 +122,13 @@ static struct super_block *v9fs_get_sb(struct file_system_type
123 122
124 dprintk(DEBUG_VFS, " \n"); 123 dprintk(DEBUG_VFS, " \n");
125 124
126 v9ses = kcalloc(1, sizeof(struct v9fs_session_info), GFP_KERNEL); 125 v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL);
127 if (!v9ses) 126 if (!v9ses)
128 return ERR_PTR(-ENOMEM); 127 return ERR_PTR(-ENOMEM);
129 128
130 if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { 129 if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) {
131 dprintk(DEBUG_ERROR, "problem initiating session\n"); 130 dprintk(DEBUG_ERROR, "problem initiating session\n");
131 kfree(v9ses);
132 return ERR_PTR(newfid); 132 return ERR_PTR(newfid);
133 } 133 }
134 134
@@ -157,7 +157,7 @@ static struct super_block *v9fs_get_sb(struct file_system_type
157 stat_result = v9fs_t_stat(v9ses, newfid, &fcall); 157 stat_result = v9fs_t_stat(v9ses, newfid, &fcall);
158 if (stat_result < 0) { 158 if (stat_result < 0) {
159 dprintk(DEBUG_ERROR, "stat error\n"); 159 dprintk(DEBUG_ERROR, "stat error\n");
160 v9fs_t_clunk(v9ses, newfid, NULL); 160 v9fs_t_clunk(v9ses, newfid);
161 v9fs_put_idpool(newfid, &v9ses->fidpool); 161 v9fs_put_idpool(newfid, &v9ses->fidpool);
162 } else { 162 } else {
163 /* Setup the Root Inode */ 163 /* Setup the Root Inode */
@@ -167,10 +167,10 @@ static struct super_block *v9fs_get_sb(struct file_system_type
167 goto put_back_sb; 167 goto put_back_sb;
168 } 168 }
169 169
170 root_fid->qid = fcall->params.rstat.stat->qid; 170 root_fid->qid = fcall->params.rstat.stat.qid;
171 root->d_inode->i_ino = 171 root->d_inode->i_ino =
172 v9fs_qid2ino(&fcall->params.rstat.stat->qid); 172 v9fs_qid2ino(&fcall->params.rstat.stat.qid);
173 v9fs_mistat2inode(fcall->params.rstat.stat, root->d_inode, sb); 173 v9fs_stat2inode(&fcall->params.rstat.stat, root->d_inode, sb);
174 } 174 }
175 175
176 kfree(fcall); 176 kfree(fcall);
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 175b2e8177c1..f3d3d81eb7e9 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -1,6 +1,6 @@
1config BINFMT_ELF 1config BINFMT_ELF
2 bool "Kernel support for ELF binaries" 2 bool "Kernel support for ELF binaries"
3 depends on MMU 3 depends on MMU && (BROKEN || !FRV)
4 default y 4 default y
5 ---help--- 5 ---help---
6 ELF (Executable and Linkable Format) is a format for libraries and 6 ELF (Executable and Linkable Format) is a format for libraries and
diff --git a/fs/Makefile b/fs/Makefile
index 73676111ebbe..35e9aec608e4 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -10,7 +10,7 @@ obj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \
10 ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \ 10 ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \
11 attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \ 11 attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \
12 seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \ 12 seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \
13 ioprio.o pnode.o 13 ioprio.o pnode.o drop_caches.o
14 14
15obj-$(CONFIG_INOTIFY) += inotify.o 15obj-$(CONFIG_INOTIFY) += inotify.o
16obj-$(CONFIG_EPOLL) += eventpoll.o 16obj-$(CONFIG_EPOLL) += eventpoll.o
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 6682d6d7f294..5c61c24dab2a 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -137,7 +137,7 @@ static inline void afs_dir_check_page(struct inode *dir, struct page *page)
137#endif 137#endif
138 138
139 /* determine how many magic numbers there should be in this page */ 139 /* determine how many magic numbers there should be in this page */
140 latter = dir->i_size - (page->index << PAGE_CACHE_SHIFT); 140 latter = dir->i_size - page_offset(page);
141 if (latter >= PAGE_SIZE) 141 if (latter >= PAGE_SIZE)
142 qty = PAGE_SIZE; 142 qty = PAGE_SIZE;
143 else 143 else
diff --git a/fs/afs/volume.h b/fs/afs/volume.h
index 1e691889c4c9..bfdcf19ba3f3 100644
--- a/fs/afs/volume.h
+++ b/fs/afs/volume.h
@@ -18,8 +18,6 @@
18#include "kafsasyncd.h" 18#include "kafsasyncd.h"
19#include "cache.h" 19#include "cache.h"
20 20
21#define __packed __attribute__((packed))
22
23typedef enum { 21typedef enum {
24 AFS_VLUPD_SLEEP, /* sleeping waiting for update timer to fire */ 22 AFS_VLUPD_SLEEP, /* sleeping waiting for update timer to fire */
25 AFS_VLUPD_PENDING, /* on pending queue */ 23 AFS_VLUPD_PENDING, /* on pending queue */
@@ -115,7 +113,7 @@ struct afs_volume
115 struct cachefs_cookie *cache; /* caching cookie */ 113 struct cachefs_cookie *cache; /* caching cookie */
116#endif 114#endif
117 afs_volid_t vid; /* volume ID */ 115 afs_volid_t vid; /* volume ID */
118 afs_voltype_t __packed type; /* type of volume */ 116 afs_voltype_t type; /* type of volume */
119 char type_force; /* force volume type (suppress R/O -> R/W) */ 117 char type_force; /* force volume type (suppress R/O -> R/W) */
120 unsigned short nservers; /* number of server slots filled */ 118 unsigned short nservers; /* number of server slots filled */
121 unsigned short rjservers; /* number of servers discarded due to -ENOMEDIUM */ 119 unsigned short rjservers; /* number of servers discarded due to -ENOMEDIUM */
diff --git a/fs/aio.c b/fs/aio.c
index 5a28b69ad223..aec2b1916d1b 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -29,7 +29,6 @@
29#include <linux/highmem.h> 29#include <linux/highmem.h>
30#include <linux/workqueue.h> 30#include <linux/workqueue.h>
31#include <linux/security.h> 31#include <linux/security.h>
32#include <linux/rcuref.h>
33 32
34#include <asm/kmap_types.h> 33#include <asm/kmap_types.h>
35#include <asm/uaccess.h> 34#include <asm/uaccess.h>
@@ -514,7 +513,7 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req)
514 /* Must be done under the lock to serialise against cancellation. 513 /* Must be done under the lock to serialise against cancellation.
515 * Call this aio_fput as it duplicates fput via the fput_work. 514 * Call this aio_fput as it duplicates fput via the fput_work.
516 */ 515 */
517 if (unlikely(rcuref_dec_and_test(&req->ki_filp->f_count))) { 516 if (unlikely(atomic_dec_and_test(&req->ki_filp->f_count))) {
518 get_ioctx(ctx); 517 get_ioctx(ctx);
519 spin_lock(&fput_lock); 518 spin_lock(&fput_lock);
520 list_add(&req->ki_list, &fput_head); 519 list_add(&req->ki_list, &fput_head);
diff --git a/fs/attr.c b/fs/attr.c
index 67bcd9b14ea5..b34732506f1d 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -67,20 +67,12 @@ EXPORT_SYMBOL(inode_change_ok);
67int inode_setattr(struct inode * inode, struct iattr * attr) 67int inode_setattr(struct inode * inode, struct iattr * attr)
68{ 68{
69 unsigned int ia_valid = attr->ia_valid; 69 unsigned int ia_valid = attr->ia_valid;
70 int error = 0; 70
71 71 if (ia_valid & ATTR_SIZE &&
72 if (ia_valid & ATTR_SIZE) { 72 attr->ia_size != i_size_read(inode)) {
73 if (attr->ia_size != i_size_read(inode)) { 73 int error = vmtruncate(inode, attr->ia_size);
74 error = vmtruncate(inode, attr->ia_size); 74 if (error)
75 if (error || (ia_valid == ATTR_SIZE)) 75 return error;
76 goto out;
77 } else {
78 /*
79 * We skipped the truncate but must still update
80 * timestamps
81 */
82 ia_valid |= ATTR_MTIME|ATTR_CTIME;
83 }
84 } 76 }
85 77
86 if (ia_valid & ATTR_UID) 78 if (ia_valid & ATTR_UID)
@@ -104,8 +96,8 @@ int inode_setattr(struct inode * inode, struct iattr * attr)
104 inode->i_mode = mode; 96 inode->i_mode = mode;
105 } 97 }
106 mark_inode_dirty(inode); 98 mark_inode_dirty(inode);
107out: 99
108 return error; 100 return 0;
109} 101}
110EXPORT_SYMBOL(inode_setattr); 102EXPORT_SYMBOL(inode_setattr);
111 103
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index fca83e28edcf..385bed09b0d8 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -209,7 +209,7 @@ static inline int simple_empty_nolock(struct dentry *dentry)
209 struct dentry *child; 209 struct dentry *child;
210 int ret = 0; 210 int ret = 0;
211 211
212 list_for_each_entry(child, &dentry->d_subdirs, d_child) 212 list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child)
213 if (simple_positive(child)) 213 if (simple_positive(child))
214 goto out; 214 goto out;
215 ret = 1; 215 ret = 1;
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index feb6ac427d05..dc39589df165 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -105,7 +105,7 @@ repeat:
105 next = this_parent->d_subdirs.next; 105 next = this_parent->d_subdirs.next;
106resume: 106resume:
107 while (next != &this_parent->d_subdirs) { 107 while (next != &this_parent->d_subdirs) {
108 struct dentry *dentry = list_entry(next, struct dentry, d_child); 108 struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
109 109
110 /* Negative dentry - give up */ 110 /* Negative dentry - give up */
111 if (!simple_positive(dentry)) { 111 if (!simple_positive(dentry)) {
@@ -138,7 +138,7 @@ resume:
138 } 138 }
139 139
140 if (this_parent != top) { 140 if (this_parent != top) {
141 next = this_parent->d_child.next; 141 next = this_parent->d_u.d_child.next;
142 this_parent = this_parent->d_parent; 142 this_parent = this_parent->d_parent;
143 goto resume; 143 goto resume;
144 } 144 }
@@ -163,7 +163,7 @@ repeat:
163 next = this_parent->d_subdirs.next; 163 next = this_parent->d_subdirs.next;
164resume: 164resume:
165 while (next != &this_parent->d_subdirs) { 165 while (next != &this_parent->d_subdirs) {
166 struct dentry *dentry = list_entry(next, struct dentry, d_child); 166 struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
167 167
168 /* Negative dentry - give up */ 168 /* Negative dentry - give up */
169 if (!simple_positive(dentry)) { 169 if (!simple_positive(dentry)) {
@@ -199,7 +199,7 @@ cont:
199 } 199 }
200 200
201 if (this_parent != parent) { 201 if (this_parent != parent) {
202 next = this_parent->d_child.next; 202 next = this_parent->d_u.d_child.next;
203 this_parent = this_parent->d_parent; 203 this_parent = this_parent->d_parent;
204 goto resume; 204 goto resume;
205 } 205 }
@@ -238,7 +238,7 @@ static struct dentry *autofs4_expire(struct super_block *sb,
238 /* On exit from the loop expire is set to a dgot dentry 238 /* On exit from the loop expire is set to a dgot dentry
239 * to expire or it's NULL */ 239 * to expire or it's NULL */
240 while ( next != &root->d_subdirs ) { 240 while ( next != &root->d_subdirs ) {
241 struct dentry *dentry = list_entry(next, struct dentry, d_child); 241 struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
242 242
243 /* Negative dentry - give up */ 243 /* Negative dentry - give up */
244 if ( !simple_positive(dentry) ) { 244 if ( !simple_positive(dentry) ) {
@@ -302,7 +302,7 @@ next:
302 expired, (int)expired->d_name.len, expired->d_name.name); 302 expired, (int)expired->d_name.len, expired->d_name.name);
303 spin_lock(&dcache_lock); 303 spin_lock(&dcache_lock);
304 list_del(&expired->d_parent->d_subdirs); 304 list_del(&expired->d_parent->d_subdirs);
305 list_add(&expired->d_parent->d_subdirs, &expired->d_child); 305 list_add(&expired->d_parent->d_subdirs, &expired->d_u.d_child);
306 spin_unlock(&dcache_lock); 306 spin_unlock(&dcache_lock);
307 return expired; 307 return expired;
308 } 308 }
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 818b37be5153..2d3082854a29 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -91,7 +91,7 @@ repeat:
91 next = this_parent->d_subdirs.next; 91 next = this_parent->d_subdirs.next;
92resume: 92resume:
93 while (next != &this_parent->d_subdirs) { 93 while (next != &this_parent->d_subdirs) {
94 struct dentry *dentry = list_entry(next, struct dentry, d_child); 94 struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
95 95
96 /* Negative dentry - don`t care */ 96 /* Negative dentry - don`t care */
97 if (!simple_positive(dentry)) { 97 if (!simple_positive(dentry)) {
@@ -117,7 +117,7 @@ resume:
117 if (this_parent != sbi->root) { 117 if (this_parent != sbi->root) {
118 struct dentry *dentry = this_parent; 118 struct dentry *dentry = this_parent;
119 119
120 next = this_parent->d_child.next; 120 next = this_parent->d_u.d_child.next;
121 this_parent = this_parent->d_parent; 121 this_parent = this_parent->d_parent;
122 spin_unlock(&dcache_lock); 122 spin_unlock(&dcache_lock);
123 DPRINTK("parent dentry %p %.*s", 123 DPRINTK("parent dentry %p %.*s",
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 2a771ec66956..2241405ffc41 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -143,7 +143,8 @@ static int autofs4_dcache_readdir(struct file * filp, void * dirent, filldir_t f
143 } 143 }
144 144
145 while(1) { 145 while(1) {
146 struct dentry *de = list_entry(list, struct dentry, d_child); 146 struct dentry *de = list_entry(list,
147 struct dentry, d_u.d_child);
147 148
148 if (!d_unhashed(de) && de->d_inode) { 149 if (!d_unhashed(de) && de->d_inode) {
149 spin_unlock(&dcache_lock); 150 spin_unlock(&dcache_lock);
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index f36f2210204f..80ca932ba0bd 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -58,7 +58,7 @@ extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
58 * If we don't support core dumping, then supply a NULL so we 58 * If we don't support core dumping, then supply a NULL so we
59 * don't even try. 59 * don't even try.
60 */ 60 */
61#ifdef USE_ELF_CORE_DUMP 61#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
62static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file); 62static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file);
63#else 63#else
64#define elf_core_dump NULL 64#define elf_core_dump NULL
@@ -288,11 +288,17 @@ static unsigned long elf_map(struct file *filep, unsigned long addr,
288 struct elf_phdr *eppnt, int prot, int type) 288 struct elf_phdr *eppnt, int prot, int type)
289{ 289{
290 unsigned long map_addr; 290 unsigned long map_addr;
291 unsigned long pageoffset = ELF_PAGEOFFSET(eppnt->p_vaddr);
291 292
292 down_write(&current->mm->mmap_sem); 293 down_write(&current->mm->mmap_sem);
293 map_addr = do_mmap(filep, ELF_PAGESTART(addr), 294 /* mmap() will return -EINVAL if given a zero size, but a
294 eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type, 295 * segment with zero filesize is perfectly valid */
295 eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr)); 296 if (eppnt->p_filesz + pageoffset)
297 map_addr = do_mmap(filep, ELF_PAGESTART(addr),
298 eppnt->p_filesz + pageoffset, prot, type,
299 eppnt->p_offset - pageoffset);
300 else
301 map_addr = ELF_PAGESTART(addr);
296 up_write(&current->mm->mmap_sem); 302 up_write(&current->mm->mmap_sem);
297 return(map_addr); 303 return(map_addr);
298} 304}
@@ -1107,7 +1113,7 @@ out:
1107 * Note that some platforms still use traditional core dumps and not 1113 * Note that some platforms still use traditional core dumps and not
1108 * the ELF core dump. Each platform can select it as appropriate. 1114 * the ELF core dump. Each platform can select it as appropriate.
1109 */ 1115 */
1110#ifdef USE_ELF_CORE_DUMP 1116#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
1111 1117
1112/* 1118/*
1113 * ELF core dumper 1119 * ELF core dumper
diff --git a/fs/bio.c b/fs/bio.c
index dfe242a21eb4..7b3069589951 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -126,6 +126,7 @@ static void bio_fs_destructor(struct bio *bio)
126inline void bio_init(struct bio *bio) 126inline void bio_init(struct bio *bio)
127{ 127{
128 bio->bi_next = NULL; 128 bio->bi_next = NULL;
129 bio->bi_bdev = NULL;
129 bio->bi_flags = 1 << BIO_UPTODATE; 130 bio->bi_flags = 1 << BIO_UPTODATE;
130 bio->bi_rw = 0; 131 bio->bi_rw = 0;
131 bio->bi_vcnt = 0; 132 bio->bi_vcnt = 0;
diff --git a/fs/buffer.c b/fs/buffer.c
index 5287be18633b..55f0975a9b15 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -153,14 +153,8 @@ int sync_blockdev(struct block_device *bdev)
153{ 153{
154 int ret = 0; 154 int ret = 0;
155 155
156 if (bdev) { 156 if (bdev)
157 int err; 157 ret = filemap_write_and_wait(bdev->bd_inode->i_mapping);
158
159 ret = filemap_fdatawrite(bdev->bd_inode->i_mapping);
160 err = filemap_fdatawait(bdev->bd_inode->i_mapping);
161 if (!ret)
162 ret = err;
163 }
164 return ret; 158 return ret;
165} 159}
166EXPORT_SYMBOL(sync_blockdev); 160EXPORT_SYMBOL(sync_blockdev);
@@ -1768,7 +1762,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
1768 * handle that here by just cleaning them. 1762 * handle that here by just cleaning them.
1769 */ 1763 */
1770 1764
1771 block = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); 1765 block = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
1772 head = page_buffers(page); 1766 head = page_buffers(page);
1773 bh = head; 1767 bh = head;
1774 1768
@@ -2160,11 +2154,12 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
2160 * truncates. Uses prepare/commit_write to allow the filesystem to 2154 * truncates. Uses prepare/commit_write to allow the filesystem to
2161 * deal with the hole. 2155 * deal with the hole.
2162 */ 2156 */
2163int generic_cont_expand(struct inode *inode, loff_t size) 2157static int __generic_cont_expand(struct inode *inode, loff_t size,
2158 pgoff_t index, unsigned int offset)
2164{ 2159{
2165 struct address_space *mapping = inode->i_mapping; 2160 struct address_space *mapping = inode->i_mapping;
2166 struct page *page; 2161 struct page *page;
2167 unsigned long index, offset, limit; 2162 unsigned long limit;
2168 int err; 2163 int err;
2169 2164
2170 err = -EFBIG; 2165 err = -EFBIG;
@@ -2176,24 +2171,24 @@ int generic_cont_expand(struct inode *inode, loff_t size)
2176 if (size > inode->i_sb->s_maxbytes) 2171 if (size > inode->i_sb->s_maxbytes)
2177 goto out; 2172 goto out;
2178 2173
2179 offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */
2180
2181 /* ugh. in prepare/commit_write, if from==to==start of block, we
2182 ** skip the prepare. make sure we never send an offset for the start
2183 ** of a block
2184 */
2185 if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) {
2186 offset++;
2187 }
2188 index = size >> PAGE_CACHE_SHIFT;
2189 err = -ENOMEM; 2174 err = -ENOMEM;
2190 page = grab_cache_page(mapping, index); 2175 page = grab_cache_page(mapping, index);
2191 if (!page) 2176 if (!page)
2192 goto out; 2177 goto out;
2193 err = mapping->a_ops->prepare_write(NULL, page, offset, offset); 2178 err = mapping->a_ops->prepare_write(NULL, page, offset, offset);
2194 if (!err) { 2179 if (err) {
2195 err = mapping->a_ops->commit_write(NULL, page, offset, offset); 2180 /*
2181 * ->prepare_write() may have instantiated a few blocks
2182 * outside i_size. Trim these off again.
2183 */
2184 unlock_page(page);
2185 page_cache_release(page);
2186 vmtruncate(inode, inode->i_size);
2187 goto out;
2196 } 2188 }
2189
2190 err = mapping->a_ops->commit_write(NULL, page, offset, offset);
2191
2197 unlock_page(page); 2192 unlock_page(page);
2198 page_cache_release(page); 2193 page_cache_release(page);
2199 if (err > 0) 2194 if (err > 0)
@@ -2202,6 +2197,36 @@ out:
2202 return err; 2197 return err;
2203} 2198}
2204 2199
2200int generic_cont_expand(struct inode *inode, loff_t size)
2201{
2202 pgoff_t index;
2203 unsigned int offset;
2204
2205 offset = (size & (PAGE_CACHE_SIZE - 1)); /* Within page */
2206
2207 /* ugh. in prepare/commit_write, if from==to==start of block, we
2208 ** skip the prepare. make sure we never send an offset for the start
2209 ** of a block
2210 */
2211 if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) {
2212 /* caller must handle this extra byte. */
2213 offset++;
2214 }
2215 index = size >> PAGE_CACHE_SHIFT;
2216
2217 return __generic_cont_expand(inode, size, index, offset);
2218}
2219
2220int generic_cont_expand_simple(struct inode *inode, loff_t size)
2221{
2222 loff_t pos = size - 1;
2223 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
2224 unsigned int offset = (pos & (PAGE_CACHE_SIZE - 1)) + 1;
2225
2226 /* prepare/commit_write can handle even if from==to==start of block. */
2227 return __generic_cont_expand(inode, size, index, offset);
2228}
2229
2205/* 2230/*
2206 * For moronic filesystems that do not allow holes in file. 2231 * For moronic filesystems that do not allow holes in file.
2207 * We may have to extend the file. 2232 * We may have to extend the file.
@@ -2610,7 +2635,7 @@ int block_truncate_page(struct address_space *mapping,
2610 pgoff_t index = from >> PAGE_CACHE_SHIFT; 2635 pgoff_t index = from >> PAGE_CACHE_SHIFT;
2611 unsigned offset = from & (PAGE_CACHE_SIZE-1); 2636 unsigned offset = from & (PAGE_CACHE_SIZE-1);
2612 unsigned blocksize; 2637 unsigned blocksize;
2613 pgoff_t iblock; 2638 sector_t iblock;
2614 unsigned length, pos; 2639 unsigned length, pos;
2615 struct inode *inode = mapping->host; 2640 struct inode *inode = mapping->host;
2616 struct page *page; 2641 struct page *page;
@@ -2626,7 +2651,7 @@ int block_truncate_page(struct address_space *mapping,
2626 return 0; 2651 return 0;
2627 2652
2628 length = blocksize - length; 2653 length = blocksize - length;
2629 iblock = index << (PAGE_CACHE_SHIFT - inode->i_blkbits); 2654 iblock = (sector_t)index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
2630 2655
2631 page = grab_cache_page(mapping, index); 2656 page = grab_cache_page(mapping, index);
2632 err = -ENOMEM; 2657 err = -ENOMEM;
@@ -3145,6 +3170,7 @@ EXPORT_SYMBOL(fsync_bdev);
3145EXPORT_SYMBOL(generic_block_bmap); 3170EXPORT_SYMBOL(generic_block_bmap);
3146EXPORT_SYMBOL(generic_commit_write); 3171EXPORT_SYMBOL(generic_commit_write);
3147EXPORT_SYMBOL(generic_cont_expand); 3172EXPORT_SYMBOL(generic_cont_expand);
3173EXPORT_SYMBOL(generic_cont_expand_simple);
3148EXPORT_SYMBOL(init_buffer); 3174EXPORT_SYMBOL(init_buffer);
3149EXPORT_SYMBOL(invalidate_bdev); 3175EXPORT_SYMBOL(invalidate_bdev);
3150EXPORT_SYMBOL(ll_rw_block); 3176EXPORT_SYMBOL(ll_rw_block);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 14a1c72ced92..5ade53d7bca8 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -127,8 +127,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
127 if (file->f_dentry->d_inode->i_mapping) { 127 if (file->f_dentry->d_inode->i_mapping) {
128 /* BB no need to lock inode until after invalidate 128 /* BB no need to lock inode until after invalidate
129 since namei code should already have it locked? */ 129 since namei code should already have it locked? */
130 filemap_fdatawrite(file->f_dentry->d_inode->i_mapping); 130 filemap_write_and_wait(file->f_dentry->d_inode->i_mapping);
131 filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
132 } 131 }
133 cFYI(1, ("invalidating remote inode since open detected it " 132 cFYI(1, ("invalidating remote inode since open detected it "
134 "changed")); 133 "changed"));
@@ -419,8 +418,7 @@ static int cifs_reopen_file(struct inode *inode, struct file *file,
419 pCifsInode = CIFS_I(inode); 418 pCifsInode = CIFS_I(inode);
420 if (pCifsInode) { 419 if (pCifsInode) {
421 if (can_flush) { 420 if (can_flush) {
422 filemap_fdatawrite(inode->i_mapping); 421 filemap_write_and_wait(inode->i_mapping);
423 filemap_fdatawait(inode->i_mapping);
424 /* temporarily disable caching while we 422 /* temporarily disable caching while we
425 go to server to get inode info */ 423 go to server to get inode info */
426 pCifsInode->clientCanCacheAll = FALSE; 424 pCifsInode->clientCanCacheAll = FALSE;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 411c1f7f84da..9558f51bca55 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1148,8 +1148,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1148 /* BB check if we need to refresh inode from server now ? BB */ 1148 /* BB check if we need to refresh inode from server now ? BB */
1149 1149
1150 /* need to flush data before changing file size on server */ 1150 /* need to flush data before changing file size on server */
1151 filemap_fdatawrite(direntry->d_inode->i_mapping); 1151 filemap_write_and_wait(direntry->d_inode->i_mapping);
1152 filemap_fdatawait(direntry->d_inode->i_mapping);
1153 1152
1154 if (attrs->ia_valid & ATTR_SIZE) { 1153 if (attrs->ia_valid & ATTR_SIZE) {
1155 /* To avoid spurious oplock breaks from server, in the case of 1154 /* To avoid spurious oplock breaks from server, in the case of
diff --git a/fs/coda/cache.c b/fs/coda/cache.c
index 80072fd9b7fa..c607d923350a 100644
--- a/fs/coda/cache.c
+++ b/fs/coda/cache.c
@@ -93,7 +93,7 @@ static void coda_flag_children(struct dentry *parent, int flag)
93 spin_lock(&dcache_lock); 93 spin_lock(&dcache_lock);
94 list_for_each(child, &parent->d_subdirs) 94 list_for_each(child, &parent->d_subdirs)
95 { 95 {
96 de = list_entry(child, struct dentry, d_child); 96 de = list_entry(child, struct dentry, d_u.d_child);
97 /* don't know what to do with negative dentries */ 97 /* don't know what to do with negative dentries */
98 if ( ! de->d_inode ) 98 if ( ! de->d_inode )
99 continue; 99 continue;
diff --git a/fs/compat.c b/fs/compat.c
index 55ac0324aaf1..271b75d1597f 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -494,9 +494,21 @@ asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
494 ret = sys_fcntl(fd, cmd, (unsigned long)&f); 494 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
495 set_fs(old_fs); 495 set_fs(old_fs);
496 if (cmd == F_GETLK && ret == 0) { 496 if (cmd == F_GETLK && ret == 0) {
497 if ((f.l_start >= COMPAT_OFF_T_MAX) || 497 /* GETLK was successfule and we need to return the data...
498 ((f.l_start + f.l_len) > COMPAT_OFF_T_MAX)) 498 * but it needs to fit in the compat structure.
499 * l_start shouldn't be too big, unless the original
500 * start + end is greater than COMPAT_OFF_T_MAX, in which
501 * case the app was asking for trouble, so we return
502 * -EOVERFLOW in that case.
503 * l_len could be too big, in which case we just truncate it,
504 * and only allow the app to see that part of the conflicting
505 * lock that might make sense to it anyway
506 */
507
508 if (f.l_start > COMPAT_OFF_T_MAX)
499 ret = -EOVERFLOW; 509 ret = -EOVERFLOW;
510 if (f.l_len > COMPAT_OFF_T_MAX)
511 f.l_len = COMPAT_OFF_T_MAX;
500 if (ret == 0) 512 if (ret == 0)
501 ret = put_compat_flock(&f, compat_ptr(arg)); 513 ret = put_compat_flock(&f, compat_ptr(arg));
502 } 514 }
@@ -515,9 +527,11 @@ asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
515 (unsigned long)&f); 527 (unsigned long)&f);
516 set_fs(old_fs); 528 set_fs(old_fs);
517 if (cmd == F_GETLK64 && ret == 0) { 529 if (cmd == F_GETLK64 && ret == 0) {
518 if ((f.l_start >= COMPAT_LOFF_T_MAX) || 530 /* need to return lock information - see above for commentary */
519 ((f.l_start + f.l_len) > COMPAT_LOFF_T_MAX)) 531 if (f.l_start > COMPAT_LOFF_T_MAX)
520 ret = -EOVERFLOW; 532 ret = -EOVERFLOW;
533 if (f.l_len > COMPAT_LOFF_T_MAX)
534 f.l_len = COMPAT_LOFF_T_MAX;
521 if (ret == 0) 535 if (ret == 0)
522 ret = put_compat_flock64(&f, compat_ptr(arg)); 536 ret = put_compat_flock64(&f, compat_ptr(arg));
523 } 537 }
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 43a2508ac696..55d9a3a954cf 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -207,244 +207,6 @@ static int do_ext3_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
207 return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); 207 return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));
208} 208}
209 209
210struct video_tuner32 {
211 compat_int_t tuner;
212 char name[32];
213 compat_ulong_t rangelow, rangehigh;
214 u32 flags; /* It is really u32 in videodev.h */
215 u16 mode, signal;
216};
217
218static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
219{
220 int i;
221
222 if(get_user(kp->tuner, &up->tuner))
223 return -EFAULT;
224 for(i = 0; i < 32; i++)
225 __get_user(kp->name[i], &up->name[i]);
226 __get_user(kp->rangelow, &up->rangelow);
227 __get_user(kp->rangehigh, &up->rangehigh);
228 __get_user(kp->flags, &up->flags);
229 __get_user(kp->mode, &up->mode);
230 __get_user(kp->signal, &up->signal);
231 return 0;
232}
233
234static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
235{
236 int i;
237
238 if(put_user(kp->tuner, &up->tuner))
239 return -EFAULT;
240 for(i = 0; i < 32; i++)
241 __put_user(kp->name[i], &up->name[i]);
242 __put_user(kp->rangelow, &up->rangelow);
243 __put_user(kp->rangehigh, &up->rangehigh);
244 __put_user(kp->flags, &up->flags);
245 __put_user(kp->mode, &up->mode);
246 __put_user(kp->signal, &up->signal);
247 return 0;
248}
249
250struct video_buffer32 {
251 compat_caddr_t base;
252 compat_int_t height, width, depth, bytesperline;
253};
254
255static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
256{
257 u32 tmp;
258
259 if (get_user(tmp, &up->base))
260 return -EFAULT;
261
262 /* This is actually a physical address stored
263 * as a void pointer.
264 */
265 kp->base = (void *)(unsigned long) tmp;
266
267 __get_user(kp->height, &up->height);
268 __get_user(kp->width, &up->width);
269 __get_user(kp->depth, &up->depth);
270 __get_user(kp->bytesperline, &up->bytesperline);
271 return 0;
272}
273
274static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
275{
276 u32 tmp = (u32)((unsigned long)kp->base);
277
278 if(put_user(tmp, &up->base))
279 return -EFAULT;
280 __put_user(kp->height, &up->height);
281 __put_user(kp->width, &up->width);
282 __put_user(kp->depth, &up->depth);
283 __put_user(kp->bytesperline, &up->bytesperline);
284 return 0;
285}
286
287struct video_clip32 {
288 s32 x, y, width, height; /* Its really s32 in videodev.h */
289 compat_caddr_t next;
290};
291
292struct video_window32 {
293 u32 x, y, width, height, chromakey, flags;
294 compat_caddr_t clips;
295 compat_int_t clipcount;
296};
297
298/* You get back everything except the clips... */
299static int put_video_window32(struct video_window *kp, struct video_window32 __user *up)
300{
301 if(put_user(kp->x, &up->x))
302 return -EFAULT;
303 __put_user(kp->y, &up->y);
304 __put_user(kp->width, &up->width);
305 __put_user(kp->height, &up->height);
306 __put_user(kp->chromakey, &up->chromakey);
307 __put_user(kp->flags, &up->flags);
308 __put_user(kp->clipcount, &up->clipcount);
309 return 0;
310}
311
312#define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32)
313#define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32)
314#define VIDIOCGWIN32 _IOR('v',9, struct video_window32)
315#define VIDIOCSWIN32 _IOW('v',10, struct video_window32)
316#define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32)
317#define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32)
318#define VIDIOCGFREQ32 _IOR('v',14, u32)
319#define VIDIOCSFREQ32 _IOW('v',15, u32)
320
321enum {
322 MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip)
323};
324
325static int do_set_window(unsigned int fd, unsigned int cmd, unsigned long arg)
326{
327 struct video_window32 __user *up = compat_ptr(arg);
328 struct video_window __user *vw;
329 struct video_clip __user *p;
330 int nclips;
331 u32 n;
332
333 if (get_user(nclips, &up->clipcount))
334 return -EFAULT;
335
336 /* Peculiar interface... */
337 if (nclips < 0)
338 nclips = VIDEO_CLIPMAP_SIZE;
339
340 if (nclips > MaxClips)
341 return -ENOMEM;
342
343 vw = compat_alloc_user_space(sizeof(struct video_window) +
344 nclips * sizeof(struct video_clip));
345
346 p = nclips ? (struct video_clip __user *)(vw + 1) : NULL;
347
348 if (get_user(n, &up->x) || put_user(n, &vw->x) ||
349 get_user(n, &up->y) || put_user(n, &vw->y) ||
350 get_user(n, &up->width) || put_user(n, &vw->width) ||
351 get_user(n, &up->height) || put_user(n, &vw->height) ||
352 get_user(n, &up->chromakey) || put_user(n, &vw->chromakey) ||
353 get_user(n, &up->flags) || put_user(n, &vw->flags) ||
354 get_user(n, &up->clipcount) || put_user(n, &vw->clipcount) ||
355 get_user(n, &up->clips) || put_user(p, &vw->clips))
356 return -EFAULT;
357
358 if (nclips) {
359 struct video_clip32 __user *u = compat_ptr(n);
360 int i;
361 if (!u)
362 return -EINVAL;
363 for (i = 0; i < nclips; i++, u++, p++) {
364 s32 v;
365 if (get_user(v, &u->x) ||
366 put_user(v, &p->x) ||
367 get_user(v, &u->y) ||
368 put_user(v, &p->y) ||
369 get_user(v, &u->width) ||
370 put_user(v, &p->width) ||
371 get_user(v, &u->height) ||
372 put_user(v, &p->height) ||
373 put_user(NULL, &p->next))
374 return -EFAULT;
375 }
376 }
377
378 return sys_ioctl(fd, VIDIOCSWIN, (unsigned long)p);
379}
380
381static int do_video_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
382{
383 union {
384 struct video_tuner vt;
385 struct video_buffer vb;
386 struct video_window vw;
387 unsigned long vx;
388 } karg;
389 mm_segment_t old_fs = get_fs();
390 void __user *up = compat_ptr(arg);
391 int err = 0;
392
393 /* First, convert the command. */
394 switch(cmd) {
395 case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break;
396 case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break;
397 case VIDIOCGWIN32: cmd = VIDIOCGWIN; break;
398 case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break;
399 case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break;
400 case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break;
401 case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break;
402 };
403
404 switch(cmd) {
405 case VIDIOCSTUNER:
406 case VIDIOCGTUNER:
407 err = get_video_tuner32(&karg.vt, up);
408 break;
409
410 case VIDIOCSFBUF:
411 err = get_video_buffer32(&karg.vb, up);
412 break;
413
414 case VIDIOCSFREQ:
415 err = get_user(karg.vx, (u32 __user *)up);
416 break;
417 };
418 if(err)
419 goto out;
420
421 set_fs(KERNEL_DS);
422 err = sys_ioctl(fd, cmd, (unsigned long)&karg);
423 set_fs(old_fs);
424
425 if(err == 0) {
426 switch(cmd) {
427 case VIDIOCGTUNER:
428 err = put_video_tuner32(&karg.vt, up);
429 break;
430
431 case VIDIOCGWIN:
432 err = put_video_window32(&karg.vw, up);
433 break;
434
435 case VIDIOCGFBUF:
436 err = put_video_buffer32(&karg.vb, up);
437 break;
438
439 case VIDIOCGFREQ:
440 err = put_user(((u32)karg.vx), (u32 __user *)up);
441 break;
442 };
443 }
444out:
445 return err;
446}
447
448struct compat_dmx_event { 210struct compat_dmx_event {
449 dmx_event_t event; 211 dmx_event_t event;
450 compat_time_t timeStamp; 212 compat_time_t timeStamp;
@@ -3015,14 +2777,6 @@ COMPATIBLE_IOCTL(EXT3_IOC_GROUP_ADD)
3015#ifdef CONFIG_JBD_DEBUG 2777#ifdef CONFIG_JBD_DEBUG
3016HANDLE_IOCTL(EXT3_IOC32_WAIT_FOR_READONLY, do_ext3_ioctl) 2778HANDLE_IOCTL(EXT3_IOC32_WAIT_FOR_READONLY, do_ext3_ioctl)
3017#endif 2779#endif
3018HANDLE_IOCTL(VIDIOCGTUNER32, do_video_ioctl)
3019HANDLE_IOCTL(VIDIOCSTUNER32, do_video_ioctl)
3020HANDLE_IOCTL(VIDIOCGWIN32, do_video_ioctl)
3021HANDLE_IOCTL(VIDIOCSWIN32, do_set_window)
3022HANDLE_IOCTL(VIDIOCGFBUF32, do_video_ioctl)
3023HANDLE_IOCTL(VIDIOCSFBUF32, do_video_ioctl)
3024HANDLE_IOCTL(VIDIOCGFREQ32, do_video_ioctl)
3025HANDLE_IOCTL(VIDIOCSFREQ32, do_video_ioctl)
3026/* One SMB ioctl needs translations. */ 2780/* One SMB ioctl needs translations. */
3027#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) 2781#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
3028HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid) 2782HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
diff --git a/fs/dcache.c b/fs/dcache.c
index 17e439138681..1536f15c4d4c 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -71,7 +71,7 @@ struct dentry_stat_t dentry_stat = {
71 71
72static void d_callback(struct rcu_head *head) 72static void d_callback(struct rcu_head *head)
73{ 73{
74 struct dentry * dentry = container_of(head, struct dentry, d_rcu); 74 struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu);
75 75
76 if (dname_external(dentry)) 76 if (dname_external(dentry))
77 kfree(dentry->d_name.name); 77 kfree(dentry->d_name.name);
@@ -86,7 +86,7 @@ static void d_free(struct dentry *dentry)
86{ 86{
87 if (dentry->d_op && dentry->d_op->d_release) 87 if (dentry->d_op && dentry->d_op->d_release)
88 dentry->d_op->d_release(dentry); 88 dentry->d_op->d_release(dentry);
89 call_rcu(&dentry->d_rcu, d_callback); 89 call_rcu(&dentry->d_u.d_rcu, d_callback);
90} 90}
91 91
92/* 92/*
@@ -193,7 +193,7 @@ kill_it: {
193 list_del(&dentry->d_lru); 193 list_del(&dentry->d_lru);
194 dentry_stat.nr_unused--; 194 dentry_stat.nr_unused--;
195 } 195 }
196 list_del(&dentry->d_child); 196 list_del(&dentry->d_u.d_child);
197 dentry_stat.nr_dentry--; /* For d_free, below */ 197 dentry_stat.nr_dentry--; /* For d_free, below */
198 /*drops the locks, at that point nobody can reach this dentry */ 198 /*drops the locks, at that point nobody can reach this dentry */
199 dentry_iput(dentry); 199 dentry_iput(dentry);
@@ -367,7 +367,7 @@ static inline void prune_one_dentry(struct dentry * dentry)
367 struct dentry * parent; 367 struct dentry * parent;
368 368
369 __d_drop(dentry); 369 __d_drop(dentry);
370 list_del(&dentry->d_child); 370 list_del(&dentry->d_u.d_child);
371 dentry_stat.nr_dentry--; /* For d_free, below */ 371 dentry_stat.nr_dentry--; /* For d_free, below */
372 dentry_iput(dentry); 372 dentry_iput(dentry);
373 parent = dentry->d_parent; 373 parent = dentry->d_parent;
@@ -518,7 +518,7 @@ repeat:
518resume: 518resume:
519 while (next != &this_parent->d_subdirs) { 519 while (next != &this_parent->d_subdirs) {
520 struct list_head *tmp = next; 520 struct list_head *tmp = next;
521 struct dentry *dentry = list_entry(tmp, struct dentry, d_child); 521 struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
522 next = tmp->next; 522 next = tmp->next;
523 /* Have we found a mount point ? */ 523 /* Have we found a mount point ? */
524 if (d_mountpoint(dentry)) 524 if (d_mountpoint(dentry))
@@ -532,7 +532,7 @@ resume:
532 * All done at this level ... ascend and resume the search. 532 * All done at this level ... ascend and resume the search.
533 */ 533 */
534 if (this_parent != parent) { 534 if (this_parent != parent) {
535 next = this_parent->d_child.next; 535 next = this_parent->d_u.d_child.next;
536 this_parent = this_parent->d_parent; 536 this_parent = this_parent->d_parent;
537 goto resume; 537 goto resume;
538 } 538 }
@@ -569,7 +569,7 @@ repeat:
569resume: 569resume:
570 while (next != &this_parent->d_subdirs) { 570 while (next != &this_parent->d_subdirs) {
571 struct list_head *tmp = next; 571 struct list_head *tmp = next;
572 struct dentry *dentry = list_entry(tmp, struct dentry, d_child); 572 struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
573 next = tmp->next; 573 next = tmp->next;
574 574
575 if (!list_empty(&dentry->d_lru)) { 575 if (!list_empty(&dentry->d_lru)) {
@@ -610,7 +610,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, found);
610 * All done at this level ... ascend and resume the search. 610 * All done at this level ... ascend and resume the search.
611 */ 611 */
612 if (this_parent != parent) { 612 if (this_parent != parent) {
613 next = this_parent->d_child.next; 613 next = this_parent->d_u.d_child.next;
614 this_parent = this_parent->d_parent; 614 this_parent = this_parent->d_parent;
615#ifdef DCACHE_DEBUG 615#ifdef DCACHE_DEBUG
616printk(KERN_DEBUG "select_parent: ascending to %s/%s, found=%d\n", 616printk(KERN_DEBUG "select_parent: ascending to %s/%s, found=%d\n",
@@ -753,12 +753,12 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
753 dentry->d_parent = dget(parent); 753 dentry->d_parent = dget(parent);
754 dentry->d_sb = parent->d_sb; 754 dentry->d_sb = parent->d_sb;
755 } else { 755 } else {
756 INIT_LIST_HEAD(&dentry->d_child); 756 INIT_LIST_HEAD(&dentry->d_u.d_child);
757 } 757 }
758 758
759 spin_lock(&dcache_lock); 759 spin_lock(&dcache_lock);
760 if (parent) 760 if (parent)
761 list_add(&dentry->d_child, &parent->d_subdirs); 761 list_add(&dentry->d_u.d_child, &parent->d_subdirs);
762 dentry_stat.nr_dentry++; 762 dentry_stat.nr_dentry++;
763 spin_unlock(&dcache_lock); 763 spin_unlock(&dcache_lock);
764 764
@@ -1310,8 +1310,8 @@ already_unhashed:
1310 /* Unhash the target: dput() will then get rid of it */ 1310 /* Unhash the target: dput() will then get rid of it */
1311 __d_drop(target); 1311 __d_drop(target);
1312 1312
1313 list_del(&dentry->d_child); 1313 list_del(&dentry->d_u.d_child);
1314 list_del(&target->d_child); 1314 list_del(&target->d_u.d_child);
1315 1315
1316 /* Switch the names.. */ 1316 /* Switch the names.. */
1317 switch_names(dentry, target); 1317 switch_names(dentry, target);
@@ -1322,15 +1322,15 @@ already_unhashed:
1322 if (IS_ROOT(dentry)) { 1322 if (IS_ROOT(dentry)) {
1323 dentry->d_parent = target->d_parent; 1323 dentry->d_parent = target->d_parent;
1324 target->d_parent = target; 1324 target->d_parent = target;
1325 INIT_LIST_HEAD(&target->d_child); 1325 INIT_LIST_HEAD(&target->d_u.d_child);
1326 } else { 1326 } else {
1327 do_switch(dentry->d_parent, target->d_parent); 1327 do_switch(dentry->d_parent, target->d_parent);
1328 1328
1329 /* And add them back to the (new) parent lists */ 1329 /* And add them back to the (new) parent lists */
1330 list_add(&target->d_child, &target->d_parent->d_subdirs); 1330 list_add(&target->d_u.d_child, &target->d_parent->d_subdirs);
1331 } 1331 }
1332 1332
1333 list_add(&dentry->d_child, &dentry->d_parent->d_subdirs); 1333 list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
1334 spin_unlock(&target->d_lock); 1334 spin_unlock(&target->d_lock);
1335 spin_unlock(&dentry->d_lock); 1335 spin_unlock(&dentry->d_lock);
1336 write_sequnlock(&rename_lock); 1336 write_sequnlock(&rename_lock);
@@ -1568,7 +1568,7 @@ repeat:
1568resume: 1568resume:
1569 while (next != &this_parent->d_subdirs) { 1569 while (next != &this_parent->d_subdirs) {
1570 struct list_head *tmp = next; 1570 struct list_head *tmp = next;
1571 struct dentry *dentry = list_entry(tmp, struct dentry, d_child); 1571 struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
1572 next = tmp->next; 1572 next = tmp->next;
1573 if (d_unhashed(dentry)||!dentry->d_inode) 1573 if (d_unhashed(dentry)||!dentry->d_inode)
1574 continue; 1574 continue;
@@ -1579,7 +1579,7 @@ resume:
1579 atomic_dec(&dentry->d_count); 1579 atomic_dec(&dentry->d_count);
1580 } 1580 }
1581 if (this_parent != root) { 1581 if (this_parent != root) {
1582 next = this_parent->d_child.next; 1582 next = this_parent->d_u.d_child.next;
1583 atomic_dec(&this_parent->d_count); 1583 atomic_dec(&this_parent->d_count);
1584 this_parent = this_parent->d_parent; 1584 this_parent = this_parent->d_parent;
1585 goto resume; 1585 goto resume;
diff --git a/fs/drop_caches.c b/fs/drop_caches.c
new file mode 100644
index 000000000000..4e4762389bdc
--- /dev/null
+++ b/fs/drop_caches.c
@@ -0,0 +1,68 @@
1/*
2 * Implement the manual drop-all-pagecache function
3 */
4
5#include <linux/kernel.h>
6#include <linux/mm.h>
7#include <linux/fs.h>
8#include <linux/writeback.h>
9#include <linux/sysctl.h>
10#include <linux/gfp.h>
11
12/* A global variable is a bit ugly, but it keeps the code simple */
13int sysctl_drop_caches;
14
15static void drop_pagecache_sb(struct super_block *sb)
16{
17 struct inode *inode;
18
19 spin_lock(&inode_lock);
20 list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
21 if (inode->i_state & (I_FREEING|I_WILL_FREE))
22 continue;
23 invalidate_inode_pages(inode->i_mapping);
24 }
25 spin_unlock(&inode_lock);
26}
27
28void drop_pagecache(void)
29{
30 struct super_block *sb;
31
32 spin_lock(&sb_lock);
33restart:
34 list_for_each_entry(sb, &super_blocks, s_list) {
35 sb->s_count++;
36 spin_unlock(&sb_lock);
37 down_read(&sb->s_umount);
38 if (sb->s_root)
39 drop_pagecache_sb(sb);
40 up_read(&sb->s_umount);
41 spin_lock(&sb_lock);
42 if (__put_super_and_need_restart(sb))
43 goto restart;
44 }
45 spin_unlock(&sb_lock);
46}
47
48void drop_slab(void)
49{
50 int nr_objects;
51
52 do {
53 nr_objects = shrink_slab(1000, GFP_KERNEL, 1000);
54 } while (nr_objects > 10);
55}
56
57int drop_caches_sysctl_handler(ctl_table *table, int write,
58 struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
59{
60 proc_dointvec_minmax(table, write, file, buffer, length, ppos);
61 if (write) {
62 if (sysctl_drop_caches & 1)
63 drop_pagecache();
64 if (sysctl_drop_caches & 2)
65 drop_slab();
66 }
67 return 0;
68}
diff --git a/fs/exec.c b/fs/exec.c
index e75a9548da8e..fd02ea4a81e9 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -760,7 +760,7 @@ no_thread_group:
760 spin_lock(&oldsighand->siglock); 760 spin_lock(&oldsighand->siglock);
761 spin_lock(&newsighand->siglock); 761 spin_lock(&newsighand->siglock);
762 762
763 current->sighand = newsighand; 763 rcu_assign_pointer(current->sighand, newsighand);
764 recalc_sigpending(); 764 recalc_sigpending();
765 765
766 spin_unlock(&newsighand->siglock); 766 spin_unlock(&newsighand->siglock);
@@ -768,7 +768,7 @@ no_thread_group:
768 write_unlock_irq(&tasklist_lock); 768 write_unlock_irq(&tasklist_lock);
769 769
770 if (atomic_dec_and_test(&oldsighand->count)) 770 if (atomic_dec_and_test(&oldsighand->count))
771 kmem_cache_free(sighand_cachep, oldsighand); 771 sighand_free(oldsighand);
772 } 772 }
773 773
774 BUG_ON(!thread_group_leader(current)); 774 BUG_ON(!thread_group_leader(current));
@@ -1462,6 +1462,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1462 if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) { 1462 if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
1463 current->signal->flags = SIGNAL_GROUP_EXIT; 1463 current->signal->flags = SIGNAL_GROUP_EXIT;
1464 current->signal->group_exit_code = exit_code; 1464 current->signal->group_exit_code = exit_code;
1465 current->signal->group_stop_count = 0;
1465 retval = 0; 1466 retval = 0;
1466 } 1467 }
1467 spin_unlock_irq(&current->sighand->siglock); 1468 spin_unlock_irq(&current->sighand->siglock);
@@ -1477,7 +1478,6 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1477 * Clear any false indication of pending signals that might 1478 * Clear any false indication of pending signals that might
1478 * be seen by the filesystem code called to write the core file. 1479 * be seen by the filesystem code called to write the core file.
1479 */ 1480 */
1480 current->signal->group_stop_count = 0;
1481 clear_thread_flag(TIF_SIGPENDING); 1481 clear_thread_flag(TIF_SIGPENDING);
1482 1482
1483 if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump) 1483 if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
@@ -1505,7 +1505,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1505 goto close_fail; 1505 goto close_fail;
1506 if (!file->f_op->write) 1506 if (!file->f_op->write)
1507 goto close_fail; 1507 goto close_fail;
1508 if (do_truncate(file->f_dentry, 0, file) != 0) 1508 if (do_truncate(file->f_dentry, 0, 0, file) != 0)
1509 goto close_fail; 1509 goto close_fail;
1510 1510
1511 retval = binfmt->core_dump(signr, regs, file); 1511 retval = binfmt->core_dump(signr, regs, file);
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index 9e4a24376210..69078079b19c 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -651,7 +651,7 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
651 /* Error cases - e2fsck has already cleaned up for us */ 651 /* Error cases - e2fsck has already cleaned up for us */
652 if (ino > max_ino) { 652 if (ino > max_ino) {
653 ext3_warning(sb, __FUNCTION__, 653 ext3_warning(sb, __FUNCTION__,
654 "bad orphan ino %lu! e2fsck was run?\n", ino); 654 "bad orphan ino %lu! e2fsck was run?", ino);
655 goto out; 655 goto out;
656 } 656 }
657 657
@@ -660,7 +660,7 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
660 bitmap_bh = read_inode_bitmap(sb, block_group); 660 bitmap_bh = read_inode_bitmap(sb, block_group);
661 if (!bitmap_bh) { 661 if (!bitmap_bh) {
662 ext3_warning(sb, __FUNCTION__, 662 ext3_warning(sb, __FUNCTION__,
663 "inode bitmap error for orphan %lu\n", ino); 663 "inode bitmap error for orphan %lu", ino);
664 goto out; 664 goto out;
665 } 665 }
666 666
@@ -672,7 +672,7 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
672 !(inode = iget(sb, ino)) || is_bad_inode(inode) || 672 !(inode = iget(sb, ino)) || is_bad_inode(inode) ||
673 NEXT_ORPHAN(inode) > max_ino) { 673 NEXT_ORPHAN(inode) > max_ino) {
674 ext3_warning(sb, __FUNCTION__, 674 ext3_warning(sb, __FUNCTION__,
675 "bad orphan inode %lu! e2fsck was run?\n", ino); 675 "bad orphan inode %lu! e2fsck was run?", ino);
676 printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n", 676 printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n",
677 bit, (unsigned long long)bitmap_bh->b_blocknr, 677 bit, (unsigned long long)bitmap_bh->b_blocknr,
678 ext3_test_bit(bit, bitmap_bh->b_data)); 678 ext3_test_bit(bit, bitmap_bh->b_data));
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index b3c690a3b54a..af193a304ee5 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1476,7 +1476,7 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
1476 if (levels && (dx_get_count(frames->entries) == 1476 if (levels && (dx_get_count(frames->entries) ==
1477 dx_get_limit(frames->entries))) { 1477 dx_get_limit(frames->entries))) {
1478 ext3_warning(sb, __FUNCTION__, 1478 ext3_warning(sb, __FUNCTION__,
1479 "Directory index full!\n"); 1479 "Directory index full!");
1480 err = -ENOSPC; 1480 err = -ENOSPC;
1481 goto cleanup; 1481 goto cleanup;
1482 } 1482 }
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 6104ad310507..1041dab6de2f 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -31,7 +31,7 @@ static int verify_group_input(struct super_block *sb,
31 unsigned start = le32_to_cpu(es->s_blocks_count); 31 unsigned start = le32_to_cpu(es->s_blocks_count);
32 unsigned end = start + input->blocks_count; 32 unsigned end = start + input->blocks_count;
33 unsigned group = input->group; 33 unsigned group = input->group;
34 unsigned itend = input->inode_table + EXT3_SB(sb)->s_itb_per_group; 34 unsigned itend = input->inode_table + sbi->s_itb_per_group;
35 unsigned overhead = ext3_bg_has_super(sb, group) ? 35 unsigned overhead = ext3_bg_has_super(sb, group) ?
36 (1 + ext3_bg_num_gdb(sb, group) + 36 (1 + ext3_bg_num_gdb(sb, group) +
37 le16_to_cpu(es->s_reserved_gdt_blocks)) : 0; 37 le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
@@ -340,7 +340,7 @@ static int verify_reserved_gdb(struct super_block *sb,
340 while ((grp = ext3_list_backups(sb, &three, &five, &seven)) < end) { 340 while ((grp = ext3_list_backups(sb, &three, &five, &seven)) < end) {
341 if (le32_to_cpu(*p++) != grp * EXT3_BLOCKS_PER_GROUP(sb) + blk){ 341 if (le32_to_cpu(*p++) != grp * EXT3_BLOCKS_PER_GROUP(sb) + blk){
342 ext3_warning(sb, __FUNCTION__, 342 ext3_warning(sb, __FUNCTION__,
343 "reserved GDT %ld missing grp %d (%ld)\n", 343 "reserved GDT %ld missing grp %d (%ld)",
344 blk, grp, 344 blk, grp,
345 grp * EXT3_BLOCKS_PER_GROUP(sb) + blk); 345 grp * EXT3_BLOCKS_PER_GROUP(sb) + blk);
346 return -EINVAL; 346 return -EINVAL;
@@ -393,7 +393,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
393 if (EXT3_SB(sb)->s_sbh->b_blocknr != 393 if (EXT3_SB(sb)->s_sbh->b_blocknr !=
394 le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) { 394 le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) {
395 ext3_warning(sb, __FUNCTION__, 395 ext3_warning(sb, __FUNCTION__,
396 "won't resize using backup superblock at %llu\n", 396 "won't resize using backup superblock at %llu",
397 (unsigned long long)EXT3_SB(sb)->s_sbh->b_blocknr); 397 (unsigned long long)EXT3_SB(sb)->s_sbh->b_blocknr);
398 return -EPERM; 398 return -EPERM;
399 } 399 }
@@ -417,7 +417,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
417 data = (__u32 *)dind->b_data; 417 data = (__u32 *)dind->b_data;
418 if (le32_to_cpu(data[gdb_num % EXT3_ADDR_PER_BLOCK(sb)]) != gdblock) { 418 if (le32_to_cpu(data[gdb_num % EXT3_ADDR_PER_BLOCK(sb)]) != gdblock) {
419 ext3_warning(sb, __FUNCTION__, 419 ext3_warning(sb, __FUNCTION__,
420 "new group %u GDT block %lu not reserved\n", 420 "new group %u GDT block %lu not reserved",
421 input->group, gdblock); 421 input->group, gdblock);
422 err = -EINVAL; 422 err = -EINVAL;
423 goto exit_dind; 423 goto exit_dind;
@@ -540,7 +540,7 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode,
540 for (res = 0; res < reserved_gdb; res++, blk++) { 540 for (res = 0; res < reserved_gdb; res++, blk++) {
541 if (le32_to_cpu(*data) != blk) { 541 if (le32_to_cpu(*data) != blk) {
542 ext3_warning(sb, __FUNCTION__, 542 ext3_warning(sb, __FUNCTION__,
543 "reserved block %lu not at offset %ld\n", 543 "reserved block %lu not at offset %ld",
544 blk, (long)(data - (__u32 *)dind->b_data)); 544 blk, (long)(data - (__u32 *)dind->b_data));
545 err = -EINVAL; 545 err = -EINVAL;
546 goto exit_bh; 546 goto exit_bh;
@@ -683,7 +683,7 @@ exit_err:
683 if (err) { 683 if (err) {
684 ext3_warning(sb, __FUNCTION__, 684 ext3_warning(sb, __FUNCTION__,
685 "can't update backup for group %d (err %d), " 685 "can't update backup for group %d (err %d), "
686 "forcing fsck on next reboot\n", group, err); 686 "forcing fsck on next reboot", group, err);
687 sbi->s_mount_state &= ~EXT3_VALID_FS; 687 sbi->s_mount_state &= ~EXT3_VALID_FS;
688 sbi->s_es->s_state &= ~cpu_to_le16(EXT3_VALID_FS); 688 sbi->s_es->s_state &= ~cpu_to_le16(EXT3_VALID_FS);
689 mark_buffer_dirty(sbi->s_sbh); 689 mark_buffer_dirty(sbi->s_sbh);
@@ -722,7 +722,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
722 if (gdb_off == 0 && !EXT3_HAS_RO_COMPAT_FEATURE(sb, 722 if (gdb_off == 0 && !EXT3_HAS_RO_COMPAT_FEATURE(sb,
723 EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER)) { 723 EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
724 ext3_warning(sb, __FUNCTION__, 724 ext3_warning(sb, __FUNCTION__,
725 "Can't resize non-sparse filesystem further\n"); 725 "Can't resize non-sparse filesystem further");
726 return -EPERM; 726 return -EPERM;
727 } 727 }
728 728
@@ -730,13 +730,13 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
730 if (!EXT3_HAS_COMPAT_FEATURE(sb, 730 if (!EXT3_HAS_COMPAT_FEATURE(sb,
731 EXT3_FEATURE_COMPAT_RESIZE_INODE)){ 731 EXT3_FEATURE_COMPAT_RESIZE_INODE)){
732 ext3_warning(sb, __FUNCTION__, 732 ext3_warning(sb, __FUNCTION__,
733 "No reserved GDT blocks, can't resize\n"); 733 "No reserved GDT blocks, can't resize");
734 return -EPERM; 734 return -EPERM;
735 } 735 }
736 inode = iget(sb, EXT3_RESIZE_INO); 736 inode = iget(sb, EXT3_RESIZE_INO);
737 if (!inode || is_bad_inode(inode)) { 737 if (!inode || is_bad_inode(inode)) {
738 ext3_warning(sb, __FUNCTION__, 738 ext3_warning(sb, __FUNCTION__,
739 "Error opening resize inode\n"); 739 "Error opening resize inode");
740 iput(inode); 740 iput(inode);
741 return -ENOENT; 741 return -ENOENT;
742 } 742 }
@@ -764,9 +764,9 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
764 } 764 }
765 765
766 lock_super(sb); 766 lock_super(sb);
767 if (input->group != EXT3_SB(sb)->s_groups_count) { 767 if (input->group != sbi->s_groups_count) {
768 ext3_warning(sb, __FUNCTION__, 768 ext3_warning(sb, __FUNCTION__,
769 "multiple resizers run on filesystem!\n"); 769 "multiple resizers run on filesystem!");
770 err = -EBUSY; 770 err = -EBUSY;
771 goto exit_journal; 771 goto exit_journal;
772 } 772 }
@@ -799,7 +799,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
799 * data. So we need to be careful to set all of the relevant 799 * data. So we need to be careful to set all of the relevant
800 * group descriptor data etc. *before* we enable the group. 800 * group descriptor data etc. *before* we enable the group.
801 * 801 *
802 * The key field here is EXT3_SB(sb)->s_groups_count: as long as 802 * The key field here is sbi->s_groups_count: as long as
803 * that retains its old value, nobody is going to access the new 803 * that retains its old value, nobody is going to access the new
804 * group. 804 * group.
805 * 805 *
@@ -859,7 +859,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
859 smp_wmb(); 859 smp_wmb();
860 860
861 /* Update the global fs size fields */ 861 /* Update the global fs size fields */
862 EXT3_SB(sb)->s_groups_count++; 862 sbi->s_groups_count++;
863 863
864 ext3_journal_dirty_metadata(handle, primary); 864 ext3_journal_dirty_metadata(handle, primary);
865 865
@@ -874,7 +874,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
874 percpu_counter_mod(&sbi->s_freeinodes_counter, 874 percpu_counter_mod(&sbi->s_freeinodes_counter,
875 EXT3_INODES_PER_GROUP(sb)); 875 EXT3_INODES_PER_GROUP(sb));
876 876
877 ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); 877 ext3_journal_dirty_metadata(handle, sbi->s_sbh);
878 sb->s_dirt = 1; 878 sb->s_dirt = 1;
879 879
880exit_journal: 880exit_journal:
@@ -937,7 +937,7 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
937 937
938 if (last == 0) { 938 if (last == 0) {
939 ext3_warning(sb, __FUNCTION__, 939 ext3_warning(sb, __FUNCTION__,
940 "need to use ext2online to resize further\n"); 940 "need to use ext2online to resize further");
941 return -EPERM; 941 return -EPERM;
942 } 942 }
943 943
@@ -973,7 +973,7 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
973 lock_super(sb); 973 lock_super(sb);
974 if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) { 974 if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) {
975 ext3_warning(sb, __FUNCTION__, 975 ext3_warning(sb, __FUNCTION__,
976 "multiple resizers run on filesystem!\n"); 976 "multiple resizers run on filesystem!");
977 err = -EBUSY; 977 err = -EBUSY;
978 goto exit_put; 978 goto exit_put;
979 } 979 }
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 4e6730622d90..7c45acf94589 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -43,7 +43,8 @@
43#include "acl.h" 43#include "acl.h"
44#include "namei.h" 44#include "namei.h"
45 45
46static int ext3_load_journal(struct super_block *, struct ext3_super_block *); 46static int ext3_load_journal(struct super_block *, struct ext3_super_block *,
47 unsigned long journal_devnum);
47static int ext3_create_journal(struct super_block *, struct ext3_super_block *, 48static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
48 int); 49 int);
49static void ext3_commit_super (struct super_block * sb, 50static void ext3_commit_super (struct super_block * sb,
@@ -628,7 +629,7 @@ enum {
628 Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, 629 Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
629 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, 630 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
630 Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, 631 Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh,
631 Opt_commit, Opt_journal_update, Opt_journal_inum, 632 Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,
632 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, 633 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
633 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, 634 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
634 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, 635 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
@@ -666,6 +667,7 @@ static match_table_t tokens = {
666 {Opt_commit, "commit=%u"}, 667 {Opt_commit, "commit=%u"},
667 {Opt_journal_update, "journal=update"}, 668 {Opt_journal_update, "journal=update"},
668 {Opt_journal_inum, "journal=%u"}, 669 {Opt_journal_inum, "journal=%u"},
670 {Opt_journal_dev, "journal_dev=%u"},
669 {Opt_abort, "abort"}, 671 {Opt_abort, "abort"},
670 {Opt_data_journal, "data=journal"}, 672 {Opt_data_journal, "data=journal"},
671 {Opt_data_ordered, "data=ordered"}, 673 {Opt_data_ordered, "data=ordered"},
@@ -705,8 +707,9 @@ static unsigned long get_sb_block(void **data)
705 return sb_block; 707 return sb_block;
706} 708}
707 709
708static int parse_options (char * options, struct super_block *sb, 710static int parse_options (char *options, struct super_block *sb,
709 unsigned long * inum, unsigned long *n_blocks_count, int is_remount) 711 unsigned long *inum, unsigned long *journal_devnum,
712 unsigned long *n_blocks_count, int is_remount)
710{ 713{
711 struct ext3_sb_info *sbi = EXT3_SB(sb); 714 struct ext3_sb_info *sbi = EXT3_SB(sb);
712 char * p; 715 char * p;
@@ -839,6 +842,16 @@ static int parse_options (char * options, struct super_block *sb,
839 return 0; 842 return 0;
840 *inum = option; 843 *inum = option;
841 break; 844 break;
845 case Opt_journal_dev:
846 if (is_remount) {
847 printk(KERN_ERR "EXT3-fs: cannot specify "
848 "journal on remount\n");
849 return 0;
850 }
851 if (match_int(&args[0], &option))
852 return 0;
853 *journal_devnum = option;
854 break;
842 case Opt_noload: 855 case Opt_noload:
843 set_opt (sbi->s_mount_opt, NOLOAD); 856 set_opt (sbi->s_mount_opt, NOLOAD);
844 break; 857 break;
@@ -1331,6 +1344,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1331 unsigned long logic_sb_block; 1344 unsigned long logic_sb_block;
1332 unsigned long offset = 0; 1345 unsigned long offset = 0;
1333 unsigned long journal_inum = 0; 1346 unsigned long journal_inum = 0;
1347 unsigned long journal_devnum = 0;
1334 unsigned long def_mount_opts; 1348 unsigned long def_mount_opts;
1335 struct inode *root; 1349 struct inode *root;
1336 int blocksize; 1350 int blocksize;
@@ -1411,7 +1425,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1411 1425
1412 set_opt(sbi->s_mount_opt, RESERVATION); 1426 set_opt(sbi->s_mount_opt, RESERVATION);
1413 1427
1414 if (!parse_options ((char *) data, sb, &journal_inum, NULL, 0)) 1428 if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum,
1429 NULL, 0))
1415 goto failed_mount; 1430 goto failed_mount;
1416 1431
1417 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | 1432 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
@@ -1622,7 +1637,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1622 */ 1637 */
1623 if (!test_opt(sb, NOLOAD) && 1638 if (!test_opt(sb, NOLOAD) &&
1624 EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) { 1639 EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
1625 if (ext3_load_journal(sb, es)) 1640 if (ext3_load_journal(sb, es, journal_devnum))
1626 goto failed_mount2; 1641 goto failed_mount2;
1627 } else if (journal_inum) { 1642 } else if (journal_inum) {
1628 if (ext3_create_journal(sb, es, journal_inum)) 1643 if (ext3_create_journal(sb, es, journal_inum))
@@ -1902,15 +1917,24 @@ out_bdev:
1902 return NULL; 1917 return NULL;
1903} 1918}
1904 1919
1905static int ext3_load_journal(struct super_block * sb, 1920static int ext3_load_journal(struct super_block *sb,
1906 struct ext3_super_block * es) 1921 struct ext3_super_block *es,
1922 unsigned long journal_devnum)
1907{ 1923{
1908 journal_t *journal; 1924 journal_t *journal;
1909 int journal_inum = le32_to_cpu(es->s_journal_inum); 1925 int journal_inum = le32_to_cpu(es->s_journal_inum);
1910 dev_t journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev)); 1926 dev_t journal_dev;
1911 int err = 0; 1927 int err = 0;
1912 int really_read_only; 1928 int really_read_only;
1913 1929
1930 if (journal_devnum &&
1931 journal_devnum != le32_to_cpu(es->s_journal_dev)) {
1932 printk(KERN_INFO "EXT3-fs: external journal device major/minor "
1933 "numbers have changed\n");
1934 journal_dev = new_decode_dev(journal_devnum);
1935 } else
1936 journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
1937
1914 really_read_only = bdev_read_only(sb->s_bdev); 1938 really_read_only = bdev_read_only(sb->s_bdev);
1915 1939
1916 /* 1940 /*
@@ -1969,6 +1993,16 @@ static int ext3_load_journal(struct super_block * sb,
1969 1993
1970 EXT3_SB(sb)->s_journal = journal; 1994 EXT3_SB(sb)->s_journal = journal;
1971 ext3_clear_journal_err(sb, es); 1995 ext3_clear_journal_err(sb, es);
1996
1997 if (journal_devnum &&
1998 journal_devnum != le32_to_cpu(es->s_journal_dev)) {
1999 es->s_journal_dev = cpu_to_le32(journal_devnum);
2000 sb->s_dirt = 1;
2001
2002 /* Make sure we flush the recovery flag to disk. */
2003 ext3_commit_super(sb, es, 1);
2004 }
2005
1972 return 0; 2006 return 0;
1973} 2007}
1974 2008
@@ -2197,7 +2231,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
2197 /* 2231 /*
2198 * Allow the "check" option to be passed as a remount option. 2232 * Allow the "check" option to be passed as a remount option.
2199 */ 2233 */
2200 if (!parse_options(data, sb, NULL, &n_blocks_count, 1)) { 2234 if (!parse_options(data, sb, NULL, NULL, &n_blocks_count, 1)) {
2201 err = -EINVAL; 2235 err = -EINVAL;
2202 goto restore_opts; 2236 goto restore_opts;
2203 } 2237 }
diff --git a/fs/fat/cache.c b/fs/fat/cache.c
index 77c24fcf712a..1acc941245fb 100644
--- a/fs/fat/cache.c
+++ b/fs/fat/cache.c
@@ -295,7 +295,8 @@ static int fat_bmap_cluster(struct inode *inode, int cluster)
295 return dclus; 295 return dclus;
296} 296}
297 297
298int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys) 298int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
299 unsigned long *mapped_blocks)
299{ 300{
300 struct super_block *sb = inode->i_sb; 301 struct super_block *sb = inode->i_sb;
301 struct msdos_sb_info *sbi = MSDOS_SB(sb); 302 struct msdos_sb_info *sbi = MSDOS_SB(sb);
@@ -303,9 +304,12 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys)
303 int cluster, offset; 304 int cluster, offset;
304 305
305 *phys = 0; 306 *phys = 0;
307 *mapped_blocks = 0;
306 if ((sbi->fat_bits != 32) && (inode->i_ino == MSDOS_ROOT_INO)) { 308 if ((sbi->fat_bits != 32) && (inode->i_ino == MSDOS_ROOT_INO)) {
307 if (sector < (sbi->dir_entries >> sbi->dir_per_block_bits)) 309 if (sector < (sbi->dir_entries >> sbi->dir_per_block_bits)) {
308 *phys = sector + sbi->dir_start; 310 *phys = sector + sbi->dir_start;
311 *mapped_blocks = 1;
312 }
309 return 0; 313 return 0;
310 } 314 }
311 last_block = (MSDOS_I(inode)->mmu_private + (sb->s_blocksize - 1)) 315 last_block = (MSDOS_I(inode)->mmu_private + (sb->s_blocksize - 1))
@@ -318,7 +322,11 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys)
318 cluster = fat_bmap_cluster(inode, cluster); 322 cluster = fat_bmap_cluster(inode, cluster);
319 if (cluster < 0) 323 if (cluster < 0)
320 return cluster; 324 return cluster;
321 else if (cluster) 325 else if (cluster) {
322 *phys = fat_clus_to_blknr(sbi, cluster) + offset; 326 *phys = fat_clus_to_blknr(sbi, cluster) + offset;
327 *mapped_blocks = sbi->sec_per_clus - offset;
328 if (*mapped_blocks > last_block - sector)
329 *mapped_blocks = last_block - sector;
330 }
323 return 0; 331 return 0;
324} 332}
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index ba824964b9bb..eef1b81aa294 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -45,8 +45,8 @@ static inline void fat_dir_readahead(struct inode *dir, sector_t iblock,
45 if ((sbi->fat_bits != 32) && (dir->i_ino == MSDOS_ROOT_INO)) 45 if ((sbi->fat_bits != 32) && (dir->i_ino == MSDOS_ROOT_INO))
46 return; 46 return;
47 47
48 bh = sb_getblk(sb, phys); 48 bh = sb_find_get_block(sb, phys);
49 if (bh && !buffer_uptodate(bh)) { 49 if (bh == NULL || !buffer_uptodate(bh)) {
50 for (sec = 0; sec < sbi->sec_per_clus; sec++) 50 for (sec = 0; sec < sbi->sec_per_clus; sec++)
51 sb_breadahead(sb, phys + sec); 51 sb_breadahead(sb, phys + sec);
52 } 52 }
@@ -68,8 +68,8 @@ static int fat__get_entry(struct inode *dir, loff_t *pos,
68{ 68{
69 struct super_block *sb = dir->i_sb; 69 struct super_block *sb = dir->i_sb;
70 sector_t phys, iblock; 70 sector_t phys, iblock;
71 int offset; 71 unsigned long mapped_blocks;
72 int err; 72 int err, offset;
73 73
74next: 74next:
75 if (*bh) 75 if (*bh)
@@ -77,7 +77,7 @@ next:
77 77
78 *bh = NULL; 78 *bh = NULL;
79 iblock = *pos >> sb->s_blocksize_bits; 79 iblock = *pos >> sb->s_blocksize_bits;
80 err = fat_bmap(dir, iblock, &phys); 80 err = fat_bmap(dir, iblock, &phys, &mapped_blocks);
81 if (err || !phys) 81 if (err || !phys)
82 return -1; /* beyond EOF or error */ 82 return -1; /* beyond EOF or error */
83 83
@@ -418,7 +418,7 @@ EODir:
418 return err; 418 return err;
419} 419}
420 420
421EXPORT_SYMBOL(fat_search_long); 421EXPORT_SYMBOL_GPL(fat_search_long);
422 422
423struct fat_ioctl_filldir_callback { 423struct fat_ioctl_filldir_callback {
424 struct dirent __user *dirent; 424 struct dirent __user *dirent;
@@ -780,7 +780,7 @@ int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh,
780 return -ENOENT; 780 return -ENOENT;
781} 781}
782 782
783EXPORT_SYMBOL(fat_get_dotdot_entry); 783EXPORT_SYMBOL_GPL(fat_get_dotdot_entry);
784 784
785/* See if directory is empty */ 785/* See if directory is empty */
786int fat_dir_empty(struct inode *dir) 786int fat_dir_empty(struct inode *dir)
@@ -803,7 +803,7 @@ int fat_dir_empty(struct inode *dir)
803 return result; 803 return result;
804} 804}
805 805
806EXPORT_SYMBOL(fat_dir_empty); 806EXPORT_SYMBOL_GPL(fat_dir_empty);
807 807
808/* 808/*
809 * fat_subdirs counts the number of sub-directories of dir. It can be run 809 * fat_subdirs counts the number of sub-directories of dir. It can be run
@@ -849,7 +849,7 @@ int fat_scan(struct inode *dir, const unsigned char *name,
849 return -ENOENT; 849 return -ENOENT;
850} 850}
851 851
852EXPORT_SYMBOL(fat_scan); 852EXPORT_SYMBOL_GPL(fat_scan);
853 853
854static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots) 854static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots)
855{ 855{
@@ -936,7 +936,7 @@ int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo)
936 return 0; 936 return 0;
937} 937}
938 938
939EXPORT_SYMBOL(fat_remove_entries); 939EXPORT_SYMBOL_GPL(fat_remove_entries);
940 940
941static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used, 941static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used,
942 struct buffer_head **bhs, int nr_bhs) 942 struct buffer_head **bhs, int nr_bhs)
@@ -1048,7 +1048,7 @@ error:
1048 return err; 1048 return err;
1049} 1049}
1050 1050
1051EXPORT_SYMBOL(fat_alloc_new_dir); 1051EXPORT_SYMBOL_GPL(fat_alloc_new_dir);
1052 1052
1053static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots, 1053static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots,
1054 int *nr_cluster, struct msdos_dir_entry **de, 1054 int *nr_cluster, struct msdos_dir_entry **de,
@@ -1264,4 +1264,4 @@ error_remove:
1264 return err; 1264 return err;
1265} 1265}
1266 1266
1267EXPORT_SYMBOL(fat_add_entries); 1267EXPORT_SYMBOL_GPL(fat_add_entries);
diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c
index 4164cd54c4d1..a1a9e0451217 100644
--- a/fs/fat/fatent.c
+++ b/fs/fat/fatent.c
@@ -476,6 +476,7 @@ int fat_alloc_clusters(struct inode *inode, int *cluster, int nr_cluster)
476 sbi->prev_free = entry; 476 sbi->prev_free = entry;
477 if (sbi->free_clusters != -1) 477 if (sbi->free_clusters != -1)
478 sbi->free_clusters--; 478 sbi->free_clusters--;
479 sb->s_dirt = 1;
479 480
480 cluster[idx_clus] = entry; 481 cluster[idx_clus] = entry;
481 idx_clus++; 482 idx_clus++;
@@ -496,6 +497,7 @@ int fat_alloc_clusters(struct inode *inode, int *cluster, int nr_cluster)
496 497
497 /* Couldn't allocate the free entries */ 498 /* Couldn't allocate the free entries */
498 sbi->free_clusters = 0; 499 sbi->free_clusters = 0;
500 sb->s_dirt = 1;
499 err = -ENOSPC; 501 err = -ENOSPC;
500 502
501out: 503out:
@@ -509,7 +511,6 @@ out:
509 } 511 }
510 for (i = 0; i < nr_bhs; i++) 512 for (i = 0; i < nr_bhs; i++)
511 brelse(bhs[i]); 513 brelse(bhs[i]);
512 fat_clusters_flush(sb);
513 514
514 if (err && idx_clus) 515 if (err && idx_clus)
515 fat_free_clusters(inode, cluster[0]); 516 fat_free_clusters(inode, cluster[0]);
@@ -542,8 +543,10 @@ int fat_free_clusters(struct inode *inode, int cluster)
542 } 543 }
543 544
544 ops->ent_put(&fatent, FAT_ENT_FREE); 545 ops->ent_put(&fatent, FAT_ENT_FREE);
545 if (sbi->free_clusters != -1) 546 if (sbi->free_clusters != -1) {
546 sbi->free_clusters++; 547 sbi->free_clusters++;
548 sb->s_dirt = 1;
549 }
547 550
548 if (nr_bhs + fatent.nr_bhs > MAX_BUF_PER_PAGE) { 551 if (nr_bhs + fatent.nr_bhs > MAX_BUF_PER_PAGE) {
549 if (sb->s_flags & MS_SYNCHRONOUS) { 552 if (sb->s_flags & MS_SYNCHRONOUS) {
@@ -578,7 +581,7 @@ error:
578 return err; 581 return err;
579} 582}
580 583
581EXPORT_SYMBOL(fat_free_clusters); 584EXPORT_SYMBOL_GPL(fat_free_clusters);
582 585
583int fat_count_free_clusters(struct super_block *sb) 586int fat_count_free_clusters(struct super_block *sb)
584{ 587{
@@ -605,6 +608,7 @@ int fat_count_free_clusters(struct super_block *sb)
605 } while (fat_ent_next(sbi, &fatent)); 608 } while (fat_ent_next(sbi, &fatent));
606 } 609 }
607 sbi->free_clusters = free; 610 sbi->free_clusters = free;
611 sb->s_dirt = 1;
608 fatent_brelse(&fatent); 612 fatent_brelse(&fatent);
609out: 613out:
610 unlock_fat(sbi); 614 unlock_fat(sbi);
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 7134403d5be2..9b07c328a6fc 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -11,6 +11,7 @@
11#include <linux/msdos_fs.h> 11#include <linux/msdos_fs.h>
12#include <linux/smp_lock.h> 12#include <linux/smp_lock.h>
13#include <linux/buffer_head.h> 13#include <linux/buffer_head.h>
14#include <linux/writeback.h>
14 15
15int fat_generic_ioctl(struct inode *inode, struct file *filp, 16int fat_generic_ioctl(struct inode *inode, struct file *filp,
16 unsigned int cmd, unsigned long arg) 17 unsigned int cmd, unsigned long arg)
@@ -124,6 +125,24 @@ struct file_operations fat_file_operations = {
124 .sendfile = generic_file_sendfile, 125 .sendfile = generic_file_sendfile,
125}; 126};
126 127
128static int fat_cont_expand(struct inode *inode, loff_t size)
129{
130 struct address_space *mapping = inode->i_mapping;
131 loff_t start = inode->i_size, count = size - inode->i_size;
132 int err;
133
134 err = generic_cont_expand_simple(inode, size);
135 if (err)
136 goto out;
137
138 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
139 mark_inode_dirty(inode);
140 if (IS_SYNC(inode))
141 err = sync_page_range_nolock(inode, mapping, start, count);
142out:
143 return err;
144}
145
127int fat_notify_change(struct dentry *dentry, struct iattr *attr) 146int fat_notify_change(struct dentry *dentry, struct iattr *attr)
128{ 147{
129 struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); 148 struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
@@ -132,11 +151,17 @@ int fat_notify_change(struct dentry *dentry, struct iattr *attr)
132 151
133 lock_kernel(); 152 lock_kernel();
134 153
135 /* FAT cannot truncate to a longer file */ 154 /*
155 * Expand the file. Since inode_setattr() updates ->i_size
156 * before calling the ->truncate(), but FAT needs to fill the
157 * hole before it.
158 */
136 if (attr->ia_valid & ATTR_SIZE) { 159 if (attr->ia_valid & ATTR_SIZE) {
137 if (attr->ia_size > inode->i_size) { 160 if (attr->ia_size > inode->i_size) {
138 error = -EPERM; 161 error = fat_cont_expand(inode, attr->ia_size);
139 goto out; 162 if (error || attr->ia_valid == ATTR_SIZE)
163 goto out;
164 attr->ia_valid &= ~ATTR_SIZE;
140 } 165 }
141 } 166 }
142 167
@@ -173,7 +198,7 @@ out:
173 return error; 198 return error;
174} 199}
175 200
176EXPORT_SYMBOL(fat_notify_change); 201EXPORT_SYMBOL_GPL(fat_notify_change);
177 202
178/* Free all clusters after the skip'th cluster. */ 203/* Free all clusters after the skip'th cluster. */
179static int fat_free(struct inode *inode, int skip) 204static int fat_free(struct inode *inode, int skip)
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index a0f9b9fe1307..e7f4aa7fc686 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -18,10 +18,12 @@
18#include <linux/seq_file.h> 18#include <linux/seq_file.h>
19#include <linux/msdos_fs.h> 19#include <linux/msdos_fs.h>
20#include <linux/pagemap.h> 20#include <linux/pagemap.h>
21#include <linux/mpage.h>
21#include <linux/buffer_head.h> 22#include <linux/buffer_head.h>
22#include <linux/mount.h> 23#include <linux/mount.h>
23#include <linux/vfs.h> 24#include <linux/vfs.h>
24#include <linux/parser.h> 25#include <linux/parser.h>
26#include <linux/uio.h>
25#include <asm/unaligned.h> 27#include <asm/unaligned.h>
26 28
27#ifndef CONFIG_FAT_DEFAULT_IOCHARSET 29#ifndef CONFIG_FAT_DEFAULT_IOCHARSET
@@ -48,51 +50,97 @@ static int fat_add_cluster(struct inode *inode)
48 return err; 50 return err;
49} 51}
50 52
51static int fat_get_block(struct inode *inode, sector_t iblock, 53static int __fat_get_blocks(struct inode *inode, sector_t iblock,
52 struct buffer_head *bh_result, int create) 54 unsigned long *max_blocks,
55 struct buffer_head *bh_result, int create)
53{ 56{
54 struct super_block *sb = inode->i_sb; 57 struct super_block *sb = inode->i_sb;
58 struct msdos_sb_info *sbi = MSDOS_SB(sb);
55 sector_t phys; 59 sector_t phys;
56 int err; 60 unsigned long mapped_blocks;
61 int err, offset;
57 62
58 err = fat_bmap(inode, iblock, &phys); 63 err = fat_bmap(inode, iblock, &phys, &mapped_blocks);
59 if (err) 64 if (err)
60 return err; 65 return err;
61 if (phys) { 66 if (phys) {
62 map_bh(bh_result, sb, phys); 67 map_bh(bh_result, sb, phys);
68 *max_blocks = min(mapped_blocks, *max_blocks);
63 return 0; 69 return 0;
64 } 70 }
65 if (!create) 71 if (!create)
66 return 0; 72 return 0;
73
67 if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) { 74 if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
68 fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)", 75 fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)",
69 MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private); 76 MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
70 return -EIO; 77 return -EIO;
71 } 78 }
72 if (!((unsigned long)iblock & (MSDOS_SB(sb)->sec_per_clus - 1))) { 79
80 offset = (unsigned long)iblock & (sbi->sec_per_clus - 1);
81 if (!offset) {
82 /* TODO: multiple cluster allocation would be desirable. */
73 err = fat_add_cluster(inode); 83 err = fat_add_cluster(inode);
74 if (err) 84 if (err)
75 return err; 85 return err;
76 } 86 }
77 MSDOS_I(inode)->mmu_private += sb->s_blocksize; 87 /* available blocks on this cluster */
78 err = fat_bmap(inode, iblock, &phys); 88 mapped_blocks = sbi->sec_per_clus - offset;
89
90 *max_blocks = min(mapped_blocks, *max_blocks);
91 MSDOS_I(inode)->mmu_private += *max_blocks << sb->s_blocksize_bits;
92
93 err = fat_bmap(inode, iblock, &phys, &mapped_blocks);
79 if (err) 94 if (err)
80 return err; 95 return err;
81 if (!phys) 96 BUG_ON(!phys);
82 BUG(); 97 BUG_ON(*max_blocks != mapped_blocks);
83 set_buffer_new(bh_result); 98 set_buffer_new(bh_result);
84 map_bh(bh_result, sb, phys); 99 map_bh(bh_result, sb, phys);
85 return 0; 100 return 0;
86} 101}
87 102
103static int fat_get_blocks(struct inode *inode, sector_t iblock,
104 unsigned long max_blocks,
105 struct buffer_head *bh_result, int create)
106{
107 struct super_block *sb = inode->i_sb;
108 int err;
109
110 err = __fat_get_blocks(inode, iblock, &max_blocks, bh_result, create);
111 if (err)
112 return err;
113 bh_result->b_size = max_blocks << sb->s_blocksize_bits;
114 return 0;
115}
116
117static int fat_get_block(struct inode *inode, sector_t iblock,
118 struct buffer_head *bh_result, int create)
119{
120 unsigned long max_blocks = 1;
121 return __fat_get_blocks(inode, iblock, &max_blocks, bh_result, create);
122}
123
88static int fat_writepage(struct page *page, struct writeback_control *wbc) 124static int fat_writepage(struct page *page, struct writeback_control *wbc)
89{ 125{
90 return block_write_full_page(page, fat_get_block, wbc); 126 return block_write_full_page(page, fat_get_block, wbc);
91} 127}
92 128
129static int fat_writepages(struct address_space *mapping,
130 struct writeback_control *wbc)
131{
132 return mpage_writepages(mapping, wbc, fat_get_block);
133}
134
93static int fat_readpage(struct file *file, struct page *page) 135static int fat_readpage(struct file *file, struct page *page)
94{ 136{
95 return block_read_full_page(page, fat_get_block); 137 return mpage_readpage(page, fat_get_block);
138}
139
140static int fat_readpages(struct file *file, struct address_space *mapping,
141 struct list_head *pages, unsigned nr_pages)
142{
143 return mpage_readpages(mapping, pages, nr_pages, fat_get_block);
96} 144}
97 145
98static int fat_prepare_write(struct file *file, struct page *page, 146static int fat_prepare_write(struct file *file, struct page *page,
@@ -115,6 +163,34 @@ static int fat_commit_write(struct file *file, struct page *page,
115 return err; 163 return err;
116} 164}
117 165
166static ssize_t fat_direct_IO(int rw, struct kiocb *iocb,
167 const struct iovec *iov,
168 loff_t offset, unsigned long nr_segs)
169{
170 struct file *file = iocb->ki_filp;
171 struct inode *inode = file->f_mapping->host;
172
173 if (rw == WRITE) {
174 /*
175 * FIXME: blockdev_direct_IO() doesn't use ->prepare_write(),
176 * so we need to update the ->mmu_private to block boundary.
177 *
178 * But we must fill the remaining area or hole by nul for
179 * updating ->mmu_private.
180 */
181 loff_t size = offset + iov_length(iov, nr_segs);
182 if (MSDOS_I(inode)->mmu_private < size)
183 return -EINVAL;
184 }
185
186 /*
187 * FAT need to use the DIO_LOCKING for avoiding the race
188 * condition of fat_get_block() and ->truncate().
189 */
190 return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
191 offset, nr_segs, fat_get_blocks, NULL);
192}
193
118static sector_t _fat_bmap(struct address_space *mapping, sector_t block) 194static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
119{ 195{
120 return generic_block_bmap(mapping, block, fat_get_block); 196 return generic_block_bmap(mapping, block, fat_get_block);
@@ -122,10 +198,13 @@ static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
122 198
123static struct address_space_operations fat_aops = { 199static struct address_space_operations fat_aops = {
124 .readpage = fat_readpage, 200 .readpage = fat_readpage,
201 .readpages = fat_readpages,
125 .writepage = fat_writepage, 202 .writepage = fat_writepage,
203 .writepages = fat_writepages,
126 .sync_page = block_sync_page, 204 .sync_page = block_sync_page,
127 .prepare_write = fat_prepare_write, 205 .prepare_write = fat_prepare_write,
128 .commit_write = fat_commit_write, 206 .commit_write = fat_commit_write,
207 .direct_IO = fat_direct_IO,
129 .bmap = _fat_bmap 208 .bmap = _fat_bmap
130}; 209};
131 210
@@ -182,7 +261,7 @@ void fat_attach(struct inode *inode, loff_t i_pos)
182 spin_unlock(&sbi->inode_hash_lock); 261 spin_unlock(&sbi->inode_hash_lock);
183} 262}
184 263
185EXPORT_SYMBOL(fat_attach); 264EXPORT_SYMBOL_GPL(fat_attach);
186 265
187void fat_detach(struct inode *inode) 266void fat_detach(struct inode *inode)
188{ 267{
@@ -193,7 +272,7 @@ void fat_detach(struct inode *inode)
193 spin_unlock(&sbi->inode_hash_lock); 272 spin_unlock(&sbi->inode_hash_lock);
194} 273}
195 274
196EXPORT_SYMBOL(fat_detach); 275EXPORT_SYMBOL_GPL(fat_detach);
197 276
198struct inode *fat_iget(struct super_block *sb, loff_t i_pos) 277struct inode *fat_iget(struct super_block *sb, loff_t i_pos)
199{ 278{
@@ -347,7 +426,7 @@ out:
347 return inode; 426 return inode;
348} 427}
349 428
350EXPORT_SYMBOL(fat_build_inode); 429EXPORT_SYMBOL_GPL(fat_build_inode);
351 430
352static void fat_delete_inode(struct inode *inode) 431static void fat_delete_inode(struct inode *inode)
353{ 432{
@@ -374,12 +453,17 @@ static void fat_clear_inode(struct inode *inode)
374 unlock_kernel(); 453 unlock_kernel();
375} 454}
376 455
377static void fat_put_super(struct super_block *sb) 456static void fat_write_super(struct super_block *sb)
378{ 457{
379 struct msdos_sb_info *sbi = MSDOS_SB(sb); 458 sb->s_dirt = 0;
380 459
381 if (!(sb->s_flags & MS_RDONLY)) 460 if (!(sb->s_flags & MS_RDONLY))
382 fat_clusters_flush(sb); 461 fat_clusters_flush(sb);
462}
463
464static void fat_put_super(struct super_block *sb)
465{
466 struct msdos_sb_info *sbi = MSDOS_SB(sb);
383 467
384 if (sbi->nls_disk) { 468 if (sbi->nls_disk) {
385 unload_nls(sbi->nls_disk); 469 unload_nls(sbi->nls_disk);
@@ -537,7 +621,7 @@ int fat_sync_inode(struct inode *inode)
537 return fat_write_inode(inode, 1); 621 return fat_write_inode(inode, 1);
538} 622}
539 623
540EXPORT_SYMBOL(fat_sync_inode); 624EXPORT_SYMBOL_GPL(fat_sync_inode);
541 625
542static int fat_show_options(struct seq_file *m, struct vfsmount *mnt); 626static int fat_show_options(struct seq_file *m, struct vfsmount *mnt);
543static struct super_operations fat_sops = { 627static struct super_operations fat_sops = {
@@ -546,6 +630,7 @@ static struct super_operations fat_sops = {
546 .write_inode = fat_write_inode, 630 .write_inode = fat_write_inode,
547 .delete_inode = fat_delete_inode, 631 .delete_inode = fat_delete_inode,
548 .put_super = fat_put_super, 632 .put_super = fat_put_super,
633 .write_super = fat_write_super,
549 .statfs = fat_statfs, 634 .statfs = fat_statfs,
550 .clear_inode = fat_clear_inode, 635 .clear_inode = fat_clear_inode,
551 .remount_fs = fat_remount, 636 .remount_fs = fat_remount,
@@ -1347,7 +1432,7 @@ out_fail:
1347 return error; 1432 return error;
1348} 1433}
1349 1434
1350EXPORT_SYMBOL(fat_fill_super); 1435EXPORT_SYMBOL_GPL(fat_fill_super);
1351 1436
1352int __init fat_cache_init(void); 1437int __init fat_cache_init(void);
1353void fat_cache_destroy(void); 1438void fat_cache_destroy(void);
diff --git a/fs/fat/misc.c b/fs/fat/misc.c
index 2a0df2122f5d..32fb0a3f1da4 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -33,7 +33,7 @@ void fat_fs_panic(struct super_block *s, const char *fmt, ...)
33 } 33 }
34} 34}
35 35
36EXPORT_SYMBOL(fat_fs_panic); 36EXPORT_SYMBOL_GPL(fat_fs_panic);
37 37
38/* Flushes the number of free clusters on FAT32 */ 38/* Flushes the number of free clusters on FAT32 */
39/* XXX: Need to write one per FSINFO block. Currently only writes 1 */ 39/* XXX: Need to write one per FSINFO block. Currently only writes 1 */
@@ -67,8 +67,6 @@ void fat_clusters_flush(struct super_block *sb)
67 if (sbi->prev_free != -1) 67 if (sbi->prev_free != -1)
68 fsinfo->next_cluster = cpu_to_le32(sbi->prev_free); 68 fsinfo->next_cluster = cpu_to_le32(sbi->prev_free);
69 mark_buffer_dirty(bh); 69 mark_buffer_dirty(bh);
70 if (sb->s_flags & MS_SYNCHRONOUS)
71 sync_dirty_buffer(bh);
72 } 70 }
73 brelse(bh); 71 brelse(bh);
74} 72}
@@ -194,7 +192,7 @@ void fat_date_unix2dos(int unix_date, __le16 *time, __le16 *date)
194 *date = cpu_to_le16(nl_day-day_n[month-1]+1+(month << 5)+(year << 9)); 192 *date = cpu_to_le16(nl_day-day_n[month-1]+1+(month << 5)+(year << 9));
195} 193}
196 194
197EXPORT_SYMBOL(fat_date_unix2dos); 195EXPORT_SYMBOL_GPL(fat_date_unix2dos);
198 196
199int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs) 197int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
200{ 198{
@@ -222,4 +220,4 @@ int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
222 return err; 220 return err;
223} 221}
224 222
225EXPORT_SYMBOL(fat_sync_bhs); 223EXPORT_SYMBOL_GPL(fat_sync_bhs);
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 863b46e0d78a..9903bde475f2 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -457,11 +457,11 @@ static void send_sigio_to_task(struct task_struct *p,
457 else 457 else
458 si.si_band = band_table[reason - POLL_IN]; 458 si.si_band = band_table[reason - POLL_IN];
459 si.si_fd = fd; 459 si.si_fd = fd;
460 if (!send_group_sig_info(fown->signum, &si, p)) 460 if (!group_send_sig_info(fown->signum, &si, p))
461 break; 461 break;
462 /* fall-through: fall back on the old plain SIGIO signal */ 462 /* fall-through: fall back on the old plain SIGIO signal */
463 case 0: 463 case 0:
464 send_group_sig_info(SIGIO, SEND_SIG_PRIV, p); 464 group_send_sig_info(SIGIO, SEND_SIG_PRIV, p);
465 } 465 }
466} 466}
467 467
@@ -495,7 +495,7 @@ static void send_sigurg_to_task(struct task_struct *p,
495 struct fown_struct *fown) 495 struct fown_struct *fown)
496{ 496{
497 if (sigio_perm(p, fown, SIGURG)) 497 if (sigio_perm(p, fown, SIGURG))
498 send_group_sig_info(SIGURG, SEND_SIG_PRIV, p); 498 group_send_sig_info(SIGURG, SEND_SIG_PRIV, p);
499} 499}
500 500
501int send_sigurg(struct fown_struct *fown) 501int send_sigurg(struct fown_struct *fown)
diff --git a/fs/file_table.c b/fs/file_table.c
index c3a5e2fd663b..6142250104a6 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -117,7 +117,7 @@ EXPORT_SYMBOL(get_empty_filp);
117 117
118void fastcall fput(struct file *file) 118void fastcall fput(struct file *file)
119{ 119{
120 if (rcuref_dec_and_test(&file->f_count)) 120 if (atomic_dec_and_test(&file->f_count))
121 __fput(file); 121 __fput(file);
122} 122}
123 123
@@ -166,7 +166,7 @@ struct file fastcall *fget(unsigned int fd)
166 rcu_read_lock(); 166 rcu_read_lock();
167 file = fcheck_files(files, fd); 167 file = fcheck_files(files, fd);
168 if (file) { 168 if (file) {
169 if (!rcuref_inc_lf(&file->f_count)) { 169 if (!atomic_inc_not_zero(&file->f_count)) {
170 /* File object ref couldn't be taken */ 170 /* File object ref couldn't be taken */
171 rcu_read_unlock(); 171 rcu_read_unlock();
172 return NULL; 172 return NULL;
@@ -198,7 +198,7 @@ struct file fastcall *fget_light(unsigned int fd, int *fput_needed)
198 rcu_read_lock(); 198 rcu_read_lock();
199 file = fcheck_files(files, fd); 199 file = fcheck_files(files, fd);
200 if (file) { 200 if (file) {
201 if (rcuref_inc_lf(&file->f_count)) 201 if (atomic_inc_not_zero(&file->f_count))
202 *fput_needed = 1; 202 *fput_needed = 1;
203 else 203 else
204 /* Didn't get the reference, someone's freed */ 204 /* Didn't get the reference, someone's freed */
@@ -213,7 +213,7 @@ struct file fastcall *fget_light(unsigned int fd, int *fput_needed)
213 213
214void put_filp(struct file *file) 214void put_filp(struct file *file)
215{ 215{
216 if (rcuref_dec_and_test(&file->f_count)) { 216 if (atomic_dec_and_test(&file->f_count)) {
217 security_file_free(file); 217 security_file_free(file);
218 file_kill(file); 218 file_kill(file);
219 file_free(file); 219 file_free(file);
diff --git a/fs/freevxfs/vxfs_immed.c b/fs/freevxfs/vxfs_immed.c
index d0401dc68d41..6f5df1700e95 100644
--- a/fs/freevxfs/vxfs_immed.c
+++ b/fs/freevxfs/vxfs_immed.c
@@ -99,8 +99,8 @@ static int
99vxfs_immed_readpage(struct file *fp, struct page *pp) 99vxfs_immed_readpage(struct file *fp, struct page *pp)
100{ 100{
101 struct vxfs_inode_info *vip = VXFS_INO(pp->mapping->host); 101 struct vxfs_inode_info *vip = VXFS_INO(pp->mapping->host);
102 u_int64_t offset = pp->index << PAGE_CACHE_SHIFT; 102 u_int64_t offset = (u_int64_t)pp->index << PAGE_CACHE_SHIFT;
103 caddr_t kaddr; 103 caddr_t kaddr;
104 104
105 kaddr = kmap(pp); 105 kaddr = kmap(pp);
106 memcpy(kaddr, vip->vii_immed.vi_immed + offset, PAGE_CACHE_SIZE); 106 memcpy(kaddr, vip->vii_immed.vi_immed + offset, PAGE_CACHE_SIZE);
diff --git a/fs/inode.c b/fs/inode.c
index d8d04bd72b59..fd568caf7f74 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -770,7 +770,7 @@ EXPORT_SYMBOL(igrab);
770 * 770 *
771 * Note, @test is called with the inode_lock held, so can't sleep. 771 * Note, @test is called with the inode_lock held, so can't sleep.
772 */ 772 */
773static inline struct inode *ifind(struct super_block *sb, 773static struct inode *ifind(struct super_block *sb,
774 struct hlist_head *head, int (*test)(struct inode *, void *), 774 struct hlist_head *head, int (*test)(struct inode *, void *),
775 void *data, const int wait) 775 void *data, const int wait)
776{ 776{
@@ -804,7 +804,7 @@ static inline struct inode *ifind(struct super_block *sb,
804 * 804 *
805 * Otherwise NULL is returned. 805 * Otherwise NULL is returned.
806 */ 806 */
807static inline struct inode *ifind_fast(struct super_block *sb, 807static struct inode *ifind_fast(struct super_block *sb,
808 struct hlist_head *head, unsigned long ino) 808 struct hlist_head *head, unsigned long ino)
809{ 809{
810 struct inode *inode; 810 struct inode *inode;
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index 3dcc6d2162cb..2559ee10beda 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -757,7 +757,7 @@ jffs_do_readpage_nolock(struct file *file, struct page *page)
757 757
758 read_len = 0; 758 read_len = 0;
759 result = 0; 759 result = 0;
760 offset = page->index << PAGE_CACHE_SHIFT; 760 offset = page_offset(page);
761 761
762 kmap(page); 762 kmap(page);
763 buf = page_address(page); 763 buf = page_address(page);
@@ -1545,7 +1545,7 @@ jffs_commit_write(struct file *filp, struct page *page,
1545{ 1545{
1546 void *addr = page_address(page) + from; 1546 void *addr = page_address(page) + from;
1547 /* XXX: PAGE_CACHE_SHIFT or PAGE_SHIFT */ 1547 /* XXX: PAGE_CACHE_SHIFT or PAGE_SHIFT */
1548 loff_t pos = (page->index<<PAGE_CACHE_SHIFT) + from; 1548 loff_t pos = page_offset(page) + from;
1549 1549
1550 return jffs_file_write(filp, addr, to-from, &pos); 1550 return jffs_file_write(filp, addr, to-from, &pos);
1551} /* jffs_commit_write() */ 1551} /* jffs_commit_write() */
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index 68000a50ceb6..2967b7393415 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -302,8 +302,7 @@ int dbSync(struct inode *ipbmap)
302 /* 302 /*
303 * write out dirty pages of bmap 303 * write out dirty pages of bmap
304 */ 304 */
305 filemap_fdatawrite(ipbmap->i_mapping); 305 filemap_write_and_wait(ipbmap->i_mapping);
306 filemap_fdatawait(ipbmap->i_mapping);
307 306
308 diWriteSpecial(ipbmap, 0); 307 diWriteSpecial(ipbmap, 0);
309 308
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index 28201b194f53..31b4aa13dd4b 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -265,8 +265,7 @@ int diSync(struct inode *ipimap)
265 /* 265 /*
266 * write out dirty pages of imap 266 * write out dirty pages of imap
267 */ 267 */
268 filemap_fdatawrite(ipimap->i_mapping); 268 filemap_write_and_wait(ipimap->i_mapping);
269 filemap_fdatawait(ipimap->i_mapping);
270 269
271 diWriteSpecial(ipimap, 0); 270 diWriteSpecial(ipimap, 0);
272 271
@@ -565,8 +564,7 @@ void diFreeSpecial(struct inode *ip)
565 jfs_err("diFreeSpecial called with NULL ip!"); 564 jfs_err("diFreeSpecial called with NULL ip!");
566 return; 565 return;
567 } 566 }
568 filemap_fdatawrite(ip->i_mapping); 567 filemap_write_and_wait(ip->i_mapping);
569 filemap_fdatawait(ip->i_mapping);
570 truncate_inode_pages(ip->i_mapping, 0); 568 truncate_inode_pages(ip->i_mapping, 0);
571 iput(ip); 569 iput(ip);
572} 570}
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index b660c93c92de..2ddb6b892bcf 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -1231,10 +1231,8 @@ int txCommit(tid_t tid, /* transaction identifier */
1231 * when we don't need to worry about it at all. 1231 * when we don't need to worry about it at all.
1232 * 1232 *
1233 * if ((!S_ISDIR(ip->i_mode)) 1233 * if ((!S_ISDIR(ip->i_mode))
1234 * && (tblk->flag & COMMIT_DELETE) == 0) { 1234 * && (tblk->flag & COMMIT_DELETE) == 0)
1235 * filemap_fdatawrite(ip->i_mapping); 1235 * filemap_write_and_wait(ip->i_mapping);
1236 * filemap_fdatawait(ip->i_mapping);
1237 * }
1238 */ 1236 */
1239 1237
1240 /* 1238 /*
diff --git a/fs/jfs/jfs_umount.c b/fs/jfs/jfs_umount.c
index 5cf91785b541..21eaf7ac0fcb 100644
--- a/fs/jfs/jfs_umount.c
+++ b/fs/jfs/jfs_umount.c
@@ -108,8 +108,7 @@ int jfs_umount(struct super_block *sb)
108 * Make sure all metadata makes it to disk before we mark 108 * Make sure all metadata makes it to disk before we mark
109 * the superblock as clean 109 * the superblock as clean
110 */ 110 */
111 filemap_fdatawrite(sbi->direct_inode->i_mapping); 111 filemap_write_and_wait(sbi->direct_inode->i_mapping);
112 filemap_fdatawait(sbi->direct_inode->i_mapping);
113 112
114 /* 113 /*
115 * ensure all file system file pages are propagated to their 114 * ensure all file system file pages are propagated to their
@@ -161,8 +160,7 @@ int jfs_umount_rw(struct super_block *sb)
161 * mark the superblock clean before everything is flushed to 160 * mark the superblock clean before everything is flushed to
162 * disk. 161 * disk.
163 */ 162 */
164 filemap_fdatawrite(sbi->direct_inode->i_mapping); 163 filemap_write_and_wait(sbi->direct_inode->i_mapping);
165 filemap_fdatawait(sbi->direct_inode->i_mapping);
166 164
167 updateSuper(sb, FM_CLEAN); 165 updateSuper(sb, FM_CLEAN);
168 166
diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c
index c6dc254d3253..45180361871c 100644
--- a/fs/jfs/resize.c
+++ b/fs/jfs/resize.c
@@ -376,8 +376,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
376 * by txCommit(); 376 * by txCommit();
377 */ 377 */
378 filemap_fdatawait(ipbmap->i_mapping); 378 filemap_fdatawait(ipbmap->i_mapping);
379 filemap_fdatawrite(ipbmap->i_mapping); 379 filemap_write_and_wait(ipbmap->i_mapping);
380 filemap_fdatawait(ipbmap->i_mapping);
381 diWriteSpecial(ipbmap, 0); 380 diWriteSpecial(ipbmap, 0);
382 381
383 newPage = nPages; /* first new page number */ 382 newPage = nPages; /* first new page number */
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 4226af3ea91b..8d31f1336431 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -502,8 +502,7 @@ out_no_rw:
502 jfs_err("jfs_umount failed with return code %d", rc); 502 jfs_err("jfs_umount failed with return code %d", rc);
503 } 503 }
504out_mount_failed: 504out_mount_failed:
505 filemap_fdatawrite(sbi->direct_inode->i_mapping); 505 filemap_write_and_wait(sbi->direct_inode->i_mapping);
506 filemap_fdatawait(sbi->direct_inode->i_mapping);
507 truncate_inode_pages(sbi->direct_inode->i_mapping, 0); 506 truncate_inode_pages(sbi->direct_inode->i_mapping, 0);
508 make_bad_inode(sbi->direct_inode); 507 make_bad_inode(sbi->direct_inode);
509 iput(sbi->direct_inode); 508 iput(sbi->direct_inode);
diff --git a/fs/libfs.c b/fs/libfs.c
index 58101dff2c66..9c50523382e7 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -93,16 +93,16 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
93 loff_t n = file->f_pos - 2; 93 loff_t n = file->f_pos - 2;
94 94
95 spin_lock(&dcache_lock); 95 spin_lock(&dcache_lock);
96 list_del(&cursor->d_child); 96 list_del(&cursor->d_u.d_child);
97 p = file->f_dentry->d_subdirs.next; 97 p = file->f_dentry->d_subdirs.next;
98 while (n && p != &file->f_dentry->d_subdirs) { 98 while (n && p != &file->f_dentry->d_subdirs) {
99 struct dentry *next; 99 struct dentry *next;
100 next = list_entry(p, struct dentry, d_child); 100 next = list_entry(p, struct dentry, d_u.d_child);
101 if (!d_unhashed(next) && next->d_inode) 101 if (!d_unhashed(next) && next->d_inode)
102 n--; 102 n--;
103 p = p->next; 103 p = p->next;
104 } 104 }
105 list_add_tail(&cursor->d_child, p); 105 list_add_tail(&cursor->d_u.d_child, p);
106 spin_unlock(&dcache_lock); 106 spin_unlock(&dcache_lock);
107 } 107 }
108 } 108 }
@@ -126,7 +126,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
126{ 126{
127 struct dentry *dentry = filp->f_dentry; 127 struct dentry *dentry = filp->f_dentry;
128 struct dentry *cursor = filp->private_data; 128 struct dentry *cursor = filp->private_data;
129 struct list_head *p, *q = &cursor->d_child; 129 struct list_head *p, *q = &cursor->d_u.d_child;
130 ino_t ino; 130 ino_t ino;
131 int i = filp->f_pos; 131 int i = filp->f_pos;
132 132
@@ -153,7 +153,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
153 } 153 }
154 for (p=q->next; p != &dentry->d_subdirs; p=p->next) { 154 for (p=q->next; p != &dentry->d_subdirs; p=p->next) {
155 struct dentry *next; 155 struct dentry *next;
156 next = list_entry(p, struct dentry, d_child); 156 next = list_entry(p, struct dentry, d_u.d_child);
157 if (d_unhashed(next) || !next->d_inode) 157 if (d_unhashed(next) || !next->d_inode)
158 continue; 158 continue;
159 159
@@ -261,7 +261,7 @@ int simple_empty(struct dentry *dentry)
261 int ret = 0; 261 int ret = 0;
262 262
263 spin_lock(&dcache_lock); 263 spin_lock(&dcache_lock);
264 list_for_each_entry(child, &dentry->d_subdirs, d_child) 264 list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child)
265 if (simple_positive(child)) 265 if (simple_positive(child))
266 goto out; 266 goto out;
267 ret = 1; 267 ret = 1;
diff --git a/fs/locks.c b/fs/locks.c
index fb32d6218e21..909eab8fb1d0 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -154,7 +154,7 @@ static struct file_lock *locks_alloc_lock(void)
154} 154}
155 155
156/* Free a lock which is not in use. */ 156/* Free a lock which is not in use. */
157static inline void locks_free_lock(struct file_lock *fl) 157static void locks_free_lock(struct file_lock *fl)
158{ 158{
159 if (fl == NULL) { 159 if (fl == NULL) {
160 BUG(); 160 BUG();
@@ -475,8 +475,7 @@ static inline int locks_overlap(struct file_lock *fl1, struct file_lock *fl2)
475/* 475/*
476 * Check whether two locks have the same owner. 476 * Check whether two locks have the same owner.
477 */ 477 */
478static inline int 478static int posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
479posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
480{ 479{
481 if (fl1->fl_lmops && fl1->fl_lmops->fl_compare_owner) 480 if (fl1->fl_lmops && fl1->fl_lmops->fl_compare_owner)
482 return fl2->fl_lmops == fl1->fl_lmops && 481 return fl2->fl_lmops == fl1->fl_lmops &&
@@ -487,7 +486,7 @@ posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
487/* Remove waiter from blocker's block list. 486/* Remove waiter from blocker's block list.
488 * When blocker ends up pointing to itself then the list is empty. 487 * When blocker ends up pointing to itself then the list is empty.
489 */ 488 */
490static inline void __locks_delete_block(struct file_lock *waiter) 489static void __locks_delete_block(struct file_lock *waiter)
491{ 490{
492 list_del_init(&waiter->fl_block); 491 list_del_init(&waiter->fl_block);
493 list_del_init(&waiter->fl_link); 492 list_del_init(&waiter->fl_link);
diff --git a/fs/mpage.c b/fs/mpage.c
index f1d2d02bd4c8..e431cb3878d6 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -184,7 +184,7 @@ do_mpage_readpage(struct bio *bio, struct page *page, unsigned nr_pages,
184 if (page_has_buffers(page)) 184 if (page_has_buffers(page))
185 goto confused; 185 goto confused;
186 186
187 block_in_file = page->index << (PAGE_CACHE_SHIFT - blkbits); 187 block_in_file = (sector_t)page->index << (PAGE_CACHE_SHIFT - blkbits);
188 last_block = (i_size_read(inode) + blocksize - 1) >> blkbits; 188 last_block = (i_size_read(inode) + blocksize - 1) >> blkbits;
189 189
190 bh.b_page = page; 190 bh.b_page = page;
@@ -466,7 +466,7 @@ __mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
466 * The page has no buffers: map it to disk 466 * The page has no buffers: map it to disk
467 */ 467 */
468 BUG_ON(!PageUptodate(page)); 468 BUG_ON(!PageUptodate(page));
469 block_in_file = page->index << (PAGE_CACHE_SHIFT - blkbits); 469 block_in_file = (sector_t)page->index << (PAGE_CACHE_SHIFT - blkbits);
470 last_block = (i_size - 1) >> blkbits; 470 last_block = (i_size - 1) >> blkbits;
471 map_bh.b_page = page; 471 map_bh.b_page = page;
472 for (page_block = 0; page_block < blocks_per_page; ) { 472 for (page_block = 0; page_block < blocks_per_page; ) {
diff --git a/fs/namei.c b/fs/namei.c
index 6dbbd42d8b95..300eae088d5f 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1491,7 +1491,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1491 if (!error) { 1491 if (!error) {
1492 DQUOT_INIT(inode); 1492 DQUOT_INIT(inode);
1493 1493
1494 error = do_truncate(dentry, 0, NULL); 1494 error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL);
1495 } 1495 }
1496 put_write_access(inode); 1496 put_write_access(inode);
1497 if (error) 1497 if (error)
diff --git a/fs/namespace.c b/fs/namespace.c
index 2019899f2ab8..3e8fb61ad597 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -451,7 +451,7 @@ EXPORT_SYMBOL(may_umount);
451void release_mounts(struct list_head *head) 451void release_mounts(struct list_head *head)
452{ 452{
453 struct vfsmount *mnt; 453 struct vfsmount *mnt;
454 while(!list_empty(head)) { 454 while (!list_empty(head)) {
455 mnt = list_entry(head->next, struct vfsmount, mnt_hash); 455 mnt = list_entry(head->next, struct vfsmount, mnt_hash);
456 list_del_init(&mnt->mnt_hash); 456 list_del_init(&mnt->mnt_hash);
457 if (mnt->mnt_parent != mnt) { 457 if (mnt->mnt_parent != mnt) {
@@ -1526,6 +1526,10 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
1526 * pointed to by put_old must yield the same directory as new_root. No other 1526 * pointed to by put_old must yield the same directory as new_root. No other
1527 * file system may be mounted on put_old. After all, new_root is a mountpoint. 1527 * file system may be mounted on put_old. After all, new_root is a mountpoint.
1528 * 1528 *
1529 * Also, the current root cannot be on the 'rootfs' (initial ramfs) filesystem.
1530 * See Documentation/filesystems/ramfs-rootfs-initramfs.txt for alternatives
1531 * in this situation.
1532 *
1529 * Notes: 1533 * Notes:
1530 * - we don't move root/cwd if they are not at the root (reason: if something 1534 * - we don't move root/cwd if they are not at the root (reason: if something
1531 * cared enough to change them, it's probably wrong to force them elsewhere) 1535 * cared enough to change them, it's probably wrong to force them elsewhere)
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index a9f7a8ab1d59..cfd76f431dc0 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -365,7 +365,7 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
365 spin_lock(&dcache_lock); 365 spin_lock(&dcache_lock);
366 next = parent->d_subdirs.next; 366 next = parent->d_subdirs.next;
367 while (next != &parent->d_subdirs) { 367 while (next != &parent->d_subdirs) {
368 dent = list_entry(next, struct dentry, d_child); 368 dent = list_entry(next, struct dentry, d_u.d_child);
369 if ((unsigned long)dent->d_fsdata == fpos) { 369 if ((unsigned long)dent->d_fsdata == fpos) {
370 if (dent->d_inode) 370 if (dent->d_inode)
371 dget_locked(dent); 371 dget_locked(dent);
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h
index 9e4dc30c2435..799e5c2bec55 100644
--- a/fs/ncpfs/ncplib_kernel.h
+++ b/fs/ncpfs/ncplib_kernel.h
@@ -196,7 +196,7 @@ ncp_renew_dentries(struct dentry *parent)
196 spin_lock(&dcache_lock); 196 spin_lock(&dcache_lock);
197 next = parent->d_subdirs.next; 197 next = parent->d_subdirs.next;
198 while (next != &parent->d_subdirs) { 198 while (next != &parent->d_subdirs) {
199 dentry = list_entry(next, struct dentry, d_child); 199 dentry = list_entry(next, struct dentry, d_u.d_child);
200 200
201 if (dentry->d_fsdata == NULL) 201 if (dentry->d_fsdata == NULL)
202 ncp_age_dentry(server, dentry); 202 ncp_age_dentry(server, dentry);
@@ -218,7 +218,7 @@ ncp_invalidate_dircache_entries(struct dentry *parent)
218 spin_lock(&dcache_lock); 218 spin_lock(&dcache_lock);
219 next = parent->d_subdirs.next; 219 next = parent->d_subdirs.next;
220 while (next != &parent->d_subdirs) { 220 while (next != &parent->d_subdirs) {
221 dentry = list_entry(next, struct dentry, d_child); 221 dentry = list_entry(next, struct dentry, d_u.d_child);
222 dentry->d_fsdata = NULL; 222 dentry->d_fsdata = NULL;
223 ncp_age_dentry(server, dentry); 223 ncp_age_dentry(server, dentry);
224 next = next->next; 224 next = next->next;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index e7bd0d92600f..3e4ba9cb7f80 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -644,10 +644,7 @@ int nfs_sync_mapping(struct address_space *mapping)
644 if (mapping->nrpages == 0) 644 if (mapping->nrpages == 0)
645 return 0; 645 return 0;
646 unmap_mapping_range(mapping, 0, 0, 0); 646 unmap_mapping_range(mapping, 0, 0, 0);
647 ret = filemap_fdatawrite(mapping); 647 ret = filemap_write_and_wait(mapping);
648 if (ret != 0)
649 goto out;
650 ret = filemap_fdatawait(mapping);
651 if (ret != 0) 648 if (ret != 0)
652 goto out; 649 goto out;
653 ret = nfs_wb_all(mapping->host); 650 ret = nfs_wb_all(mapping->host);
@@ -864,8 +861,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
864 nfs_begin_data_update(inode); 861 nfs_begin_data_update(inode);
865 /* Write all dirty data if we're changing file permissions or size */ 862 /* Write all dirty data if we're changing file permissions or size */
866 if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE)) != 0) { 863 if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE)) != 0) {
867 if (filemap_fdatawrite(inode->i_mapping) == 0) 864 filemap_write_and_wait(inode->i_mapping);
868 filemap_fdatawait(inode->i_mapping);
869 nfs_wb_all(inode); 865 nfs_wb_all(inode);
870 } 866 }
871 /* 867 /*
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index 985cc53b8dd5..e897e00c2c9d 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -275,7 +275,9 @@ static int __init root_nfs_parse(char *name, char *buf)
275 case Opt_noacl: 275 case Opt_noacl:
276 nfs_data.flags |= NFS_MOUNT_NOACL; 276 nfs_data.flags |= NFS_MOUNT_NOACL;
277 break; 277 break;
278 default : 278 default:
279 printk(KERN_WARNING "Root-NFS: unknown "
280 "option: %s\n", p);
279 return 0; 281 return 0;
280 } 282 }
281 } 283 }
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
index f5ef5ea61a05..e8c56a3d9c64 100644
--- a/fs/ocfs2/cluster/masklog.h
+++ b/fs/ocfs2/cluster/masklog.h
@@ -212,11 +212,10 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits;
212 mlog(ML_ENTRY, "ENTRY:\n"); \ 212 mlog(ML_ENTRY, "ENTRY:\n"); \
213} while (0) 213} while (0)
214 214
215/* We disable this for old compilers since they don't have support for 215/*
216 * __builtin_types_compatible_p. 216 * We disable this for sparse.
217 */ 217 */
218#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) && \ 218#if !defined(__CHECKER__)
219 !defined(__CHECKER__)
220#define mlog_exit(st) do { \ 219#define mlog_exit(st) do { \
221 if (__builtin_types_compatible_p(typeof(st), unsigned long)) \ 220 if (__builtin_types_compatible_p(typeof(st), unsigned long)) \
222 mlog(ML_EXIT, "EXIT: %lu\n", (unsigned long) (st)); \ 221 mlog(ML_EXIT, "EXIT: %lu\n", (unsigned long) (st)); \
diff --git a/fs/open.c b/fs/open.c
index f53a5b9ffb7d..75f3329e8a67 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -194,7 +194,8 @@ out:
194 return error; 194 return error;
195} 195}
196 196
197int do_truncate(struct dentry *dentry, loff_t length, struct file *filp) 197int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
198 struct file *filp)
198{ 199{
199 int err; 200 int err;
200 struct iattr newattrs; 201 struct iattr newattrs;
@@ -204,7 +205,7 @@ int do_truncate(struct dentry *dentry, loff_t length, struct file *filp)
204 return -EINVAL; 205 return -EINVAL;
205 206
206 newattrs.ia_size = length; 207 newattrs.ia_size = length;
207 newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; 208 newattrs.ia_valid = ATTR_SIZE | time_attrs;
208 if (filp) { 209 if (filp) {
209 newattrs.ia_file = filp; 210 newattrs.ia_file = filp;
210 newattrs.ia_valid |= ATTR_FILE; 211 newattrs.ia_valid |= ATTR_FILE;
@@ -216,7 +217,7 @@ int do_truncate(struct dentry *dentry, loff_t length, struct file *filp)
216 return err; 217 return err;
217} 218}
218 219
219static inline long do_sys_truncate(const char __user * path, loff_t length) 220static long do_sys_truncate(const char __user * path, loff_t length)
220{ 221{
221 struct nameidata nd; 222 struct nameidata nd;
222 struct inode * inode; 223 struct inode * inode;
@@ -266,7 +267,7 @@ static inline long do_sys_truncate(const char __user * path, loff_t length)
266 error = locks_verify_truncate(inode, NULL, length); 267 error = locks_verify_truncate(inode, NULL, length);
267 if (!error) { 268 if (!error) {
268 DQUOT_INIT(inode); 269 DQUOT_INIT(inode);
269 error = do_truncate(nd.dentry, length, NULL); 270 error = do_truncate(nd.dentry, length, 0, NULL);
270 } 271 }
271 put_write_access(inode); 272 put_write_access(inode);
272 273
@@ -282,7 +283,7 @@ asmlinkage long sys_truncate(const char __user * path, unsigned long length)
282 return do_sys_truncate(path, (long)length); 283 return do_sys_truncate(path, (long)length);
283} 284}
284 285
285static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small) 286static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
286{ 287{
287 struct inode * inode; 288 struct inode * inode;
288 struct dentry *dentry; 289 struct dentry *dentry;
@@ -318,7 +319,7 @@ static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
318 319
319 error = locks_verify_truncate(inode, file, length); 320 error = locks_verify_truncate(inode, file, length);
320 if (!error) 321 if (!error)
321 error = do_truncate(dentry, length, file); 322 error = do_truncate(dentry, length, 0, file);
322out_putf: 323out_putf:
323 fput(file); 324 fput(file);
324out: 325out:
@@ -970,7 +971,7 @@ out:
970 971
971EXPORT_SYMBOL(get_unused_fd); 972EXPORT_SYMBOL(get_unused_fd);
972 973
973static inline void __put_unused_fd(struct files_struct *files, unsigned int fd) 974static void __put_unused_fd(struct files_struct *files, unsigned int fd)
974{ 975{
975 struct fdtable *fdt = files_fdtable(files); 976 struct fdtable *fdt = files_fdtable(files);
976 __FD_CLR(fd, fdt->open_fds); 977 __FD_CLR(fd, fdt->open_fds);
diff --git a/fs/pnode.c b/fs/pnode.c
index aeeec8ba8dd2..f1871f773f64 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -103,7 +103,7 @@ static struct vfsmount *propagation_next(struct vfsmount *m,
103 struct vfsmount *next; 103 struct vfsmount *next;
104 struct vfsmount *master = m->mnt_master; 104 struct vfsmount *master = m->mnt_master;
105 105
106 if ( master == origin->mnt_master ) { 106 if (master == origin->mnt_master) {
107 next = next_peer(m); 107 next = next_peer(m);
108 return ((next == origin) ? NULL : next); 108 return ((next == origin) ? NULL : next);
109 } else if (m->mnt_slave.next != &master->mnt_slave_list) 109 } else if (m->mnt_slave.next != &master->mnt_slave_list)
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 72b431d0a0a4..20e5c4509a43 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -21,6 +21,8 @@
21#include <linux/bitops.h> 21#include <linux/bitops.h>
22#include <asm/uaccess.h> 22#include <asm/uaccess.h>
23 23
24#include "internal.h"
25
24static ssize_t proc_file_read(struct file *file, char __user *buf, 26static ssize_t proc_file_read(struct file *file, char __user *buf,
25 size_t nbytes, loff_t *ppos); 27 size_t nbytes, loff_t *ppos);
26static ssize_t proc_file_write(struct file *file, const char __user *buffer, 28static ssize_t proc_file_write(struct file *file, const char __user *buffer,
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index e6a818a93f3d..6573f31f1fd9 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -19,7 +19,7 @@
19#include <asm/system.h> 19#include <asm/system.h>
20#include <asm/uaccess.h> 20#include <asm/uaccess.h>
21 21
22extern void free_proc_entry(struct proc_dir_entry *); 22#include "internal.h"
23 23
24static inline struct proc_dir_entry * de_get(struct proc_dir_entry *de) 24static inline struct proc_dir_entry * de_get(struct proc_dir_entry *de)
25{ 25{
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 3e55198f9806..95a1cf32b838 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -37,6 +37,10 @@ extern int proc_tgid_stat(struct task_struct *, char *);
37extern int proc_pid_status(struct task_struct *, char *); 37extern int proc_pid_status(struct task_struct *, char *);
38extern int proc_pid_statm(struct task_struct *, char *); 38extern int proc_pid_statm(struct task_struct *, char *);
39 39
40void free_proc_entry(struct proc_dir_entry *de);
41
42int proc_init_inodecache(void);
43
40static inline struct task_struct *proc_task(struct inode *inode) 44static inline struct task_struct *proc_task(struct inode *inode)
41{ 45{
42 return PROC_I(inode)->task; 46 return PROC_I(inode)->task;
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 5b6b0b6038a7..63bf6c00fa0c 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -323,6 +323,7 @@ static struct file_operations proc_modules_operations = {
323}; 323};
324#endif 324#endif
325 325
326#ifdef CONFIG_SLAB
326extern struct seq_operations slabinfo_op; 327extern struct seq_operations slabinfo_op;
327extern ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *); 328extern ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *);
328static int slabinfo_open(struct inode *inode, struct file *file) 329static int slabinfo_open(struct inode *inode, struct file *file)
@@ -336,6 +337,7 @@ static struct file_operations proc_slabinfo_operations = {
336 .llseek = seq_lseek, 337 .llseek = seq_lseek,
337 .release = seq_release, 338 .release = seq_release,
338}; 339};
340#endif
339 341
340static int show_stat(struct seq_file *p, void *v) 342static int show_stat(struct seq_file *p, void *v)
341{ 343{
@@ -600,7 +602,9 @@ void __init proc_misc_init(void)
600 create_seq_entry("partitions", 0, &proc_partitions_operations); 602 create_seq_entry("partitions", 0, &proc_partitions_operations);
601 create_seq_entry("stat", 0, &proc_stat_operations); 603 create_seq_entry("stat", 0, &proc_stat_operations);
602 create_seq_entry("interrupts", 0, &proc_interrupts_operations); 604 create_seq_entry("interrupts", 0, &proc_interrupts_operations);
605#ifdef CONFIG_SLAB
603 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); 606 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
607#endif
604 create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); 608 create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
605 create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); 609 create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
606 create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations); 610 create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
diff --git a/fs/proc/root.c b/fs/proc/root.c
index aef148f099a2..68896283c8ae 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -18,6 +18,8 @@
18#include <linux/bitops.h> 18#include <linux/bitops.h>
19#include <linux/smp_lock.h> 19#include <linux/smp_lock.h>
20 20
21#include "internal.h"
22
21struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver; 23struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver;
22 24
23#ifdef CONFIG_SYSCTL 25#ifdef CONFIG_SYSCTL
@@ -36,7 +38,6 @@ static struct file_system_type proc_fs_type = {
36 .kill_sb = kill_anon_super, 38 .kill_sb = kill_anon_super,
37}; 39};
38 40
39extern int __init proc_init_inodecache(void);
40void __init proc_root_init(void) 41void __init proc_root_init(void)
41{ 42{
42 int err = proc_init_inodecache(); 43 int err = proc_init_inodecache();
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 50bd5a8f0446..0eaad41f4658 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -390,129 +390,12 @@ struct seq_operations proc_pid_smaps_op = {
390}; 390};
391 391
392#ifdef CONFIG_NUMA 392#ifdef CONFIG_NUMA
393 393extern int show_numa_map(struct seq_file *m, void *v);
394struct numa_maps {
395 unsigned long pages;
396 unsigned long anon;
397 unsigned long mapped;
398 unsigned long mapcount_max;
399 unsigned long node[MAX_NUMNODES];
400};
401
402/*
403 * Calculate numa node maps for a vma
404 */
405static struct numa_maps *get_numa_maps(struct vm_area_struct *vma)
406{
407 int i;
408 struct page *page;
409 unsigned long vaddr;
410 struct numa_maps *md = kmalloc(sizeof(struct numa_maps), GFP_KERNEL);
411
412 if (!md)
413 return NULL;
414 md->pages = 0;
415 md->anon = 0;
416 md->mapped = 0;
417 md->mapcount_max = 0;
418 for_each_node(i)
419 md->node[i] =0;
420
421 for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) {
422 page = follow_page(vma, vaddr, 0);
423 if (page) {
424 int count = page_mapcount(page);
425
426 if (count)
427 md->mapped++;
428 if (count > md->mapcount_max)
429 md->mapcount_max = count;
430 md->pages++;
431 if (PageAnon(page))
432 md->anon++;
433 md->node[page_to_nid(page)]++;
434 }
435 cond_resched();
436 }
437 return md;
438}
439
440static int show_numa_map(struct seq_file *m, void *v)
441{
442 struct task_struct *task = m->private;
443 struct vm_area_struct *vma = v;
444 struct mempolicy *pol;
445 struct numa_maps *md;
446 struct zone **z;
447 int n;
448 int first;
449
450 if (!vma->vm_mm)
451 return 0;
452
453 md = get_numa_maps(vma);
454 if (!md)
455 return 0;
456
457 seq_printf(m, "%08lx", vma->vm_start);
458 pol = get_vma_policy(task, vma, vma->vm_start);
459 /* Print policy */
460 switch (pol->policy) {
461 case MPOL_PREFERRED:
462 seq_printf(m, " prefer=%d", pol->v.preferred_node);
463 break;
464 case MPOL_BIND:
465 seq_printf(m, " bind={");
466 first = 1;
467 for (z = pol->v.zonelist->zones; *z; z++) {
468
469 if (!first)
470 seq_putc(m, ',');
471 else
472 first = 0;
473 seq_printf(m, "%d/%s", (*z)->zone_pgdat->node_id,
474 (*z)->name);
475 }
476 seq_putc(m, '}');
477 break;
478 case MPOL_INTERLEAVE:
479 seq_printf(m, " interleave={");
480 first = 1;
481 for_each_node(n) {
482 if (node_isset(n, pol->v.nodes)) {
483 if (!first)
484 seq_putc(m,',');
485 else
486 first = 0;
487 seq_printf(m, "%d",n);
488 }
489 }
490 seq_putc(m, '}');
491 break;
492 default:
493 seq_printf(m," default");
494 break;
495 }
496 seq_printf(m, " MaxRef=%lu Pages=%lu Mapped=%lu",
497 md->mapcount_max, md->pages, md->mapped);
498 if (md->anon)
499 seq_printf(m," Anon=%lu",md->anon);
500
501 for_each_online_node(n) {
502 if (md->node[n])
503 seq_printf(m, " N%d=%lu", n, md->node[n]);
504 }
505 seq_putc(m, '\n');
506 kfree(md);
507 if (m->count < m->size) /* vma is copied successfully */
508 m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0;
509 return 0;
510}
511 394
512struct seq_operations proc_pid_numa_maps_op = { 395struct seq_operations proc_pid_numa_maps_op = {
513 .start = m_start, 396 .start = m_start,
514 .next = m_next, 397 .next = m_next,
515 .stop = m_stop, 398 .stop = m_stop,
516 .show = show_numa_map 399 .show = show_numa_map
517}; 400};
518#endif 401#endif
diff --git a/fs/relayfs/buffers.c b/fs/relayfs/buffers.c
index 84e21ffa5ca8..10187812771e 100644
--- a/fs/relayfs/buffers.c
+++ b/fs/relayfs/buffers.c
@@ -185,5 +185,6 @@ void relay_destroy_buf(struct rchan_buf *buf)
185void relay_remove_buf(struct kref *kref) 185void relay_remove_buf(struct kref *kref)
186{ 186{
187 struct rchan_buf *buf = container_of(kref, struct rchan_buf, kref); 187 struct rchan_buf *buf = container_of(kref, struct rchan_buf, kref);
188 relayfs_remove(buf->dentry); 188 buf->chan->cb->remove_buf_file(buf->dentry);
189 relay_destroy_buf(buf);
189} 190}
diff --git a/fs/relayfs/inode.c b/fs/relayfs/inode.c
index 0f7f88d067ad..7b7f2cb5f0e1 100644
--- a/fs/relayfs/inode.c
+++ b/fs/relayfs/inode.c
@@ -26,31 +26,22 @@
26 26
27static struct vfsmount * relayfs_mount; 27static struct vfsmount * relayfs_mount;
28static int relayfs_mount_count; 28static int relayfs_mount_count;
29static kmem_cache_t * relayfs_inode_cachep;
30 29
31static struct backing_dev_info relayfs_backing_dev_info = { 30static struct backing_dev_info relayfs_backing_dev_info = {
32 .ra_pages = 0, /* No readahead */ 31 .ra_pages = 0, /* No readahead */
33 .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, 32 .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
34}; 33};
35 34
36static struct inode *relayfs_get_inode(struct super_block *sb, int mode, 35static struct inode *relayfs_get_inode(struct super_block *sb,
37 struct rchan *chan) 36 int mode,
37 struct file_operations *fops,
38 void *data)
38{ 39{
39 struct rchan_buf *buf = NULL;
40 struct inode *inode; 40 struct inode *inode;
41 41
42 if (S_ISREG(mode)) {
43 BUG_ON(!chan);
44 buf = relay_create_buf(chan);
45 if (!buf)
46 return NULL;
47 }
48
49 inode = new_inode(sb); 42 inode = new_inode(sb);
50 if (!inode) { 43 if (!inode)
51 relay_destroy_buf(buf);
52 return NULL; 44 return NULL;
53 }
54 45
55 inode->i_mode = mode; 46 inode->i_mode = mode;
56 inode->i_uid = 0; 47 inode->i_uid = 0;
@@ -61,8 +52,9 @@ static struct inode *relayfs_get_inode(struct super_block *sb, int mode,
61 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 52 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
62 switch (mode & S_IFMT) { 53 switch (mode & S_IFMT) {
63 case S_IFREG: 54 case S_IFREG:
64 inode->i_fop = &relayfs_file_operations; 55 inode->i_fop = fops;
65 RELAYFS_I(inode)->buf = buf; 56 if (data)
57 inode->u.generic_ip = data;
66 break; 58 break;
67 case S_IFDIR: 59 case S_IFDIR:
68 inode->i_op = &simple_dir_inode_operations; 60 inode->i_op = &simple_dir_inode_operations;
@@ -83,7 +75,8 @@ static struct inode *relayfs_get_inode(struct super_block *sb, int mode,
83 * @name: the name of the file to create 75 * @name: the name of the file to create
84 * @parent: parent directory 76 * @parent: parent directory
85 * @mode: mode 77 * @mode: mode
86 * @chan: relay channel associated with the file 78 * @fops: file operations to use for the file
79 * @data: user-associated data for this file
87 * 80 *
88 * Returns the new dentry, NULL on failure 81 * Returns the new dentry, NULL on failure
89 * 82 *
@@ -92,7 +85,8 @@ static struct inode *relayfs_get_inode(struct super_block *sb, int mode,
92static struct dentry *relayfs_create_entry(const char *name, 85static struct dentry *relayfs_create_entry(const char *name,
93 struct dentry *parent, 86 struct dentry *parent,
94 int mode, 87 int mode,
95 struct rchan *chan) 88 struct file_operations *fops,
89 void *data)
96{ 90{
97 struct dentry *d; 91 struct dentry *d;
98 struct inode *inode; 92 struct inode *inode;
@@ -127,7 +121,7 @@ static struct dentry *relayfs_create_entry(const char *name,
127 goto release_mount; 121 goto release_mount;
128 } 122 }
129 123
130 inode = relayfs_get_inode(parent->d_inode->i_sb, mode, chan); 124 inode = relayfs_get_inode(parent->d_inode->i_sb, mode, fops, data);
131 if (!inode) { 125 if (!inode) {
132 d = NULL; 126 d = NULL;
133 goto release_mount; 127 goto release_mount;
@@ -155,20 +149,26 @@ exit:
155 * @name: the name of the file to create 149 * @name: the name of the file to create
156 * @parent: parent directory 150 * @parent: parent directory
157 * @mode: mode, if not specied the default perms are used 151 * @mode: mode, if not specied the default perms are used
158 * @chan: channel associated with the file 152 * @fops: file operations to use for the file
153 * @data: user-associated data for this file
159 * 154 *
160 * Returns file dentry if successful, NULL otherwise. 155 * Returns file dentry if successful, NULL otherwise.
161 * 156 *
162 * The file will be created user r on behalf of current user. 157 * The file will be created user r on behalf of current user.
163 */ 158 */
164struct dentry *relayfs_create_file(const char *name, struct dentry *parent, 159struct dentry *relayfs_create_file(const char *name,
165 int mode, struct rchan *chan) 160 struct dentry *parent,
161 int mode,
162 struct file_operations *fops,
163 void *data)
166{ 164{
165 BUG_ON(!fops);
166
167 if (!mode) 167 if (!mode)
168 mode = S_IRUSR; 168 mode = S_IRUSR;
169 mode = (mode & S_IALLUGO) | S_IFREG; 169 mode = (mode & S_IALLUGO) | S_IFREG;
170 170
171 return relayfs_create_entry(name, parent, mode, chan); 171 return relayfs_create_entry(name, parent, mode, fops, data);
172} 172}
173 173
174/** 174/**
@@ -183,7 +183,7 @@ struct dentry *relayfs_create_file(const char *name, struct dentry *parent,
183struct dentry *relayfs_create_dir(const char *name, struct dentry *parent) 183struct dentry *relayfs_create_dir(const char *name, struct dentry *parent)
184{ 184{
185 int mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; 185 int mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
186 return relayfs_create_entry(name, parent, mode, NULL); 186 return relayfs_create_entry(name, parent, mode, NULL, NULL);
187} 187}
188 188
189/** 189/**
@@ -225,6 +225,17 @@ int relayfs_remove(struct dentry *dentry)
225} 225}
226 226
227/** 227/**
228 * relayfs_remove_file - remove a file from relay filesystem
229 * @dentry: directory dentry
230 *
231 * Returns 0 if successful, negative otherwise.
232 */
233int relayfs_remove_file(struct dentry *dentry)
234{
235 return relayfs_remove(dentry);
236}
237
238/**
228 * relayfs_remove_dir - remove a directory in the relay filesystem 239 * relayfs_remove_dir - remove a directory in the relay filesystem
229 * @dentry: directory dentry 240 * @dentry: directory dentry
230 * 241 *
@@ -236,45 +247,45 @@ int relayfs_remove_dir(struct dentry *dentry)
236} 247}
237 248
238/** 249/**
239 * relayfs_open - open file op for relayfs files 250 * relay_file_open - open file op for relay files
240 * @inode: the inode 251 * @inode: the inode
241 * @filp: the file 252 * @filp: the file
242 * 253 *
243 * Increments the channel buffer refcount. 254 * Increments the channel buffer refcount.
244 */ 255 */
245static int relayfs_open(struct inode *inode, struct file *filp) 256static int relay_file_open(struct inode *inode, struct file *filp)
246{ 257{
247 struct rchan_buf *buf = RELAYFS_I(inode)->buf; 258 struct rchan_buf *buf = inode->u.generic_ip;
248 kref_get(&buf->kref); 259 kref_get(&buf->kref);
260 filp->private_data = buf;
249 261
250 return 0; 262 return 0;
251} 263}
252 264
253/** 265/**
254 * relayfs_mmap - mmap file op for relayfs files 266 * relay_file_mmap - mmap file op for relay files
255 * @filp: the file 267 * @filp: the file
256 * @vma: the vma describing what to map 268 * @vma: the vma describing what to map
257 * 269 *
258 * Calls upon relay_mmap_buf to map the file into user space. 270 * Calls upon relay_mmap_buf to map the file into user space.
259 */ 271 */
260static int relayfs_mmap(struct file *filp, struct vm_area_struct *vma) 272static int relay_file_mmap(struct file *filp, struct vm_area_struct *vma)
261{ 273{
262 struct inode *inode = filp->f_dentry->d_inode; 274 struct rchan_buf *buf = filp->private_data;
263 return relay_mmap_buf(RELAYFS_I(inode)->buf, vma); 275 return relay_mmap_buf(buf, vma);
264} 276}
265 277
266/** 278/**
267 * relayfs_poll - poll file op for relayfs files 279 * relay_file_poll - poll file op for relay files
268 * @filp: the file 280 * @filp: the file
269 * @wait: poll table 281 * @wait: poll table
270 * 282 *
271 * Poll implemention. 283 * Poll implemention.
272 */ 284 */
273static unsigned int relayfs_poll(struct file *filp, poll_table *wait) 285static unsigned int relay_file_poll(struct file *filp, poll_table *wait)
274{ 286{
275 unsigned int mask = 0; 287 unsigned int mask = 0;
276 struct inode *inode = filp->f_dentry->d_inode; 288 struct rchan_buf *buf = filp->private_data;
277 struct rchan_buf *buf = RELAYFS_I(inode)->buf;
278 289
279 if (buf->finalized) 290 if (buf->finalized)
280 return POLLERR; 291 return POLLERR;
@@ -289,27 +300,27 @@ static unsigned int relayfs_poll(struct file *filp, poll_table *wait)
289} 300}
290 301
291/** 302/**
292 * relayfs_release - release file op for relayfs files 303 * relay_file_release - release file op for relay files
293 * @inode: the inode 304 * @inode: the inode
294 * @filp: the file 305 * @filp: the file
295 * 306 *
296 * Decrements the channel refcount, as the filesystem is 307 * Decrements the channel refcount, as the filesystem is
297 * no longer using it. 308 * no longer using it.
298 */ 309 */
299static int relayfs_release(struct inode *inode, struct file *filp) 310static int relay_file_release(struct inode *inode, struct file *filp)
300{ 311{
301 struct rchan_buf *buf = RELAYFS_I(inode)->buf; 312 struct rchan_buf *buf = filp->private_data;
302 kref_put(&buf->kref, relay_remove_buf); 313 kref_put(&buf->kref, relay_remove_buf);
303 314
304 return 0; 315 return 0;
305} 316}
306 317
307/** 318/**
308 * relayfs_read_consume - update the consumed count for the buffer 319 * relay_file_read_consume - update the consumed count for the buffer
309 */ 320 */
310static void relayfs_read_consume(struct rchan_buf *buf, 321static void relay_file_read_consume(struct rchan_buf *buf,
311 size_t read_pos, 322 size_t read_pos,
312 size_t bytes_consumed) 323 size_t bytes_consumed)
313{ 324{
314 size_t subbuf_size = buf->chan->subbuf_size; 325 size_t subbuf_size = buf->chan->subbuf_size;
315 size_t n_subbufs = buf->chan->n_subbufs; 326 size_t n_subbufs = buf->chan->n_subbufs;
@@ -332,9 +343,9 @@ static void relayfs_read_consume(struct rchan_buf *buf,
332} 343}
333 344
334/** 345/**
335 * relayfs_read_avail - boolean, are there unconsumed bytes available? 346 * relay_file_read_avail - boolean, are there unconsumed bytes available?
336 */ 347 */
337static int relayfs_read_avail(struct rchan_buf *buf, size_t read_pos) 348static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos)
338{ 349{
339 size_t bytes_produced, bytes_consumed, write_offset; 350 size_t bytes_produced, bytes_consumed, write_offset;
340 size_t subbuf_size = buf->chan->subbuf_size; 351 size_t subbuf_size = buf->chan->subbuf_size;
@@ -365,16 +376,16 @@ static int relayfs_read_avail(struct rchan_buf *buf, size_t read_pos)
365 if (bytes_produced == bytes_consumed) 376 if (bytes_produced == bytes_consumed)
366 return 0; 377 return 0;
367 378
368 relayfs_read_consume(buf, read_pos, 0); 379 relay_file_read_consume(buf, read_pos, 0);
369 380
370 return 1; 381 return 1;
371} 382}
372 383
373/** 384/**
374 * relayfs_read_subbuf_avail - return bytes available in sub-buffer 385 * relay_file_read_subbuf_avail - return bytes available in sub-buffer
375 */ 386 */
376static size_t relayfs_read_subbuf_avail(size_t read_pos, 387static size_t relay_file_read_subbuf_avail(size_t read_pos,
377 struct rchan_buf *buf) 388 struct rchan_buf *buf)
378{ 389{
379 size_t padding, avail = 0; 390 size_t padding, avail = 0;
380 size_t read_subbuf, read_offset, write_subbuf, write_offset; 391 size_t read_subbuf, read_offset, write_subbuf, write_offset;
@@ -396,14 +407,14 @@ static size_t relayfs_read_subbuf_avail(size_t read_pos,
396} 407}
397 408
398/** 409/**
399 * relayfs_read_start_pos - find the first available byte to read 410 * relay_file_read_start_pos - find the first available byte to read
400 * 411 *
401 * If the read_pos is in the middle of padding, return the 412 * If the read_pos is in the middle of padding, return the
402 * position of the first actually available byte, otherwise 413 * position of the first actually available byte, otherwise
403 * return the original value. 414 * return the original value.
404 */ 415 */
405static size_t relayfs_read_start_pos(size_t read_pos, 416static size_t relay_file_read_start_pos(size_t read_pos,
406 struct rchan_buf *buf) 417 struct rchan_buf *buf)
407{ 418{
408 size_t read_subbuf, padding, padding_start, padding_end; 419 size_t read_subbuf, padding, padding_start, padding_end;
409 size_t subbuf_size = buf->chan->subbuf_size; 420 size_t subbuf_size = buf->chan->subbuf_size;
@@ -422,11 +433,11 @@ static size_t relayfs_read_start_pos(size_t read_pos,
422} 433}
423 434
424/** 435/**
425 * relayfs_read_end_pos - return the new read position 436 * relay_file_read_end_pos - return the new read position
426 */ 437 */
427static size_t relayfs_read_end_pos(struct rchan_buf *buf, 438static size_t relay_file_read_end_pos(struct rchan_buf *buf,
428 size_t read_pos, 439 size_t read_pos,
429 size_t count) 440 size_t count)
430{ 441{
431 size_t read_subbuf, padding, end_pos; 442 size_t read_subbuf, padding, end_pos;
432 size_t subbuf_size = buf->chan->subbuf_size; 443 size_t subbuf_size = buf->chan->subbuf_size;
@@ -445,7 +456,7 @@ static size_t relayfs_read_end_pos(struct rchan_buf *buf,
445} 456}
446 457
447/** 458/**
448 * relayfs_read - read file op for relayfs files 459 * relay_file_read - read file op for relay files
449 * @filp: the file 460 * @filp: the file
450 * @buffer: the userspace buffer 461 * @buffer: the userspace buffer
451 * @count: number of bytes to read 462 * @count: number of bytes to read
@@ -454,23 +465,23 @@ static size_t relayfs_read_end_pos(struct rchan_buf *buf,
454 * Reads count bytes or the number of bytes available in the 465 * Reads count bytes or the number of bytes available in the
455 * current sub-buffer being read, whichever is smaller. 466 * current sub-buffer being read, whichever is smaller.
456 */ 467 */
457static ssize_t relayfs_read(struct file *filp, 468static ssize_t relay_file_read(struct file *filp,
458 char __user *buffer, 469 char __user *buffer,
459 size_t count, 470 size_t count,
460 loff_t *ppos) 471 loff_t *ppos)
461{ 472{
473 struct rchan_buf *buf = filp->private_data;
462 struct inode *inode = filp->f_dentry->d_inode; 474 struct inode *inode = filp->f_dentry->d_inode;
463 struct rchan_buf *buf = RELAYFS_I(inode)->buf;
464 size_t read_start, avail; 475 size_t read_start, avail;
465 ssize_t ret = 0; 476 ssize_t ret = 0;
466 void *from; 477 void *from;
467 478
468 down(&inode->i_sem); 479 down(&inode->i_sem);
469 if(!relayfs_read_avail(buf, *ppos)) 480 if(!relay_file_read_avail(buf, *ppos))
470 goto out; 481 goto out;
471 482
472 read_start = relayfs_read_start_pos(*ppos, buf); 483 read_start = relay_file_read_start_pos(*ppos, buf);
473 avail = relayfs_read_subbuf_avail(read_start, buf); 484 avail = relay_file_read_subbuf_avail(read_start, buf);
474 if (!avail) 485 if (!avail)
475 goto out; 486 goto out;
476 487
@@ -480,58 +491,25 @@ static ssize_t relayfs_read(struct file *filp,
480 ret = -EFAULT; 491 ret = -EFAULT;
481 goto out; 492 goto out;
482 } 493 }
483 relayfs_read_consume(buf, read_start, count); 494 relay_file_read_consume(buf, read_start, count);
484 *ppos = relayfs_read_end_pos(buf, read_start, count); 495 *ppos = relay_file_read_end_pos(buf, read_start, count);
485out: 496out:
486 up(&inode->i_sem); 497 up(&inode->i_sem);
487 return ret; 498 return ret;
488} 499}
489 500
490/** 501struct file_operations relay_file_operations = {
491 * relayfs alloc_inode() implementation 502 .open = relay_file_open,
492 */ 503 .poll = relay_file_poll,
493static struct inode *relayfs_alloc_inode(struct super_block *sb) 504 .mmap = relay_file_mmap,
494{ 505 .read = relay_file_read,
495 struct relayfs_inode_info *p = kmem_cache_alloc(relayfs_inode_cachep, SLAB_KERNEL);
496 if (!p)
497 return NULL;
498 p->buf = NULL;
499
500 return &p->vfs_inode;
501}
502
503/**
504 * relayfs destroy_inode() implementation
505 */
506static void relayfs_destroy_inode(struct inode *inode)
507{
508 if (RELAYFS_I(inode)->buf)
509 relay_destroy_buf(RELAYFS_I(inode)->buf);
510
511 kmem_cache_free(relayfs_inode_cachep, RELAYFS_I(inode));
512}
513
514static void init_once(void *p, kmem_cache_t *cachep, unsigned long flags)
515{
516 struct relayfs_inode_info *i = p;
517 if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR)
518 inode_init_once(&i->vfs_inode);
519}
520
521struct file_operations relayfs_file_operations = {
522 .open = relayfs_open,
523 .poll = relayfs_poll,
524 .mmap = relayfs_mmap,
525 .read = relayfs_read,
526 .llseek = no_llseek, 506 .llseek = no_llseek,
527 .release = relayfs_release, 507 .release = relay_file_release,
528}; 508};
529 509
530static struct super_operations relayfs_ops = { 510static struct super_operations relayfs_ops = {
531 .statfs = simple_statfs, 511 .statfs = simple_statfs,
532 .drop_inode = generic_delete_inode, 512 .drop_inode = generic_delete_inode,
533 .alloc_inode = relayfs_alloc_inode,
534 .destroy_inode = relayfs_destroy_inode,
535}; 513};
536 514
537static int relayfs_fill_super(struct super_block * sb, void * data, int silent) 515static int relayfs_fill_super(struct super_block * sb, void * data, int silent)
@@ -544,7 +522,7 @@ static int relayfs_fill_super(struct super_block * sb, void * data, int silent)
544 sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 522 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
545 sb->s_magic = RELAYFS_MAGIC; 523 sb->s_magic = RELAYFS_MAGIC;
546 sb->s_op = &relayfs_ops; 524 sb->s_op = &relayfs_ops;
547 inode = relayfs_get_inode(sb, mode, NULL); 525 inode = relayfs_get_inode(sb, mode, NULL, NULL);
548 526
549 if (!inode) 527 if (!inode)
550 return -ENOMEM; 528 return -ENOMEM;
@@ -575,33 +553,27 @@ static struct file_system_type relayfs_fs_type = {
575 553
576static int __init init_relayfs_fs(void) 554static int __init init_relayfs_fs(void)
577{ 555{
578 int err; 556 return register_filesystem(&relayfs_fs_type);
579
580 relayfs_inode_cachep = kmem_cache_create("relayfs_inode_cache",
581 sizeof(struct relayfs_inode_info), 0,
582 0, init_once, NULL);
583 if (!relayfs_inode_cachep)
584 return -ENOMEM;
585
586 err = register_filesystem(&relayfs_fs_type);
587 if (err)
588 kmem_cache_destroy(relayfs_inode_cachep);
589
590 return err;
591} 557}
592 558
593static void __exit exit_relayfs_fs(void) 559static void __exit exit_relayfs_fs(void)
594{ 560{
561
562
563
564
565
595 unregister_filesystem(&relayfs_fs_type); 566 unregister_filesystem(&relayfs_fs_type);
596 kmem_cache_destroy(relayfs_inode_cachep);
597} 567}
598 568
599module_init(init_relayfs_fs) 569module_init(init_relayfs_fs)
600module_exit(exit_relayfs_fs) 570module_exit(exit_relayfs_fs)
601 571
602EXPORT_SYMBOL_GPL(relayfs_file_operations); 572EXPORT_SYMBOL_GPL(relay_file_operations);
603EXPORT_SYMBOL_GPL(relayfs_create_dir); 573EXPORT_SYMBOL_GPL(relayfs_create_dir);
604EXPORT_SYMBOL_GPL(relayfs_remove_dir); 574EXPORT_SYMBOL_GPL(relayfs_remove_dir);
575EXPORT_SYMBOL_GPL(relayfs_create_file);
576EXPORT_SYMBOL_GPL(relayfs_remove_file);
605 577
606MODULE_AUTHOR("Tom Zanussi <zanussi@us.ibm.com> and Karim Yaghmour <karim@opersys.com>"); 578MODULE_AUTHOR("Tom Zanussi <zanussi@us.ibm.com> and Karim Yaghmour <karim@opersys.com>");
607MODULE_DESCRIPTION("Relay Filesystem"); 579MODULE_DESCRIPTION("Relay Filesystem");
diff --git a/fs/relayfs/relay.c b/fs/relayfs/relay.c
index 2a6f7f12b7f9..abf3ceaace49 100644
--- a/fs/relayfs/relay.c
+++ b/fs/relayfs/relay.c
@@ -80,11 +80,34 @@ static void buf_unmapped_default_callback(struct rchan_buf *buf,
80{ 80{
81} 81}
82 82
83/*
84 * create_buf_file_create() default callback. Creates file to represent buf.
85 */
86static struct dentry *create_buf_file_default_callback(const char *filename,
87 struct dentry *parent,
88 int mode,
89 struct rchan_buf *buf,
90 int *is_global)
91{
92 return relayfs_create_file(filename, parent, mode,
93 &relay_file_operations, buf);
94}
95
96/*
97 * remove_buf_file() default callback. Removes file representing relay buffer.
98 */
99static int remove_buf_file_default_callback(struct dentry *dentry)
100{
101 return relayfs_remove(dentry);
102}
103
83/* relay channel default callbacks */ 104/* relay channel default callbacks */
84static struct rchan_callbacks default_channel_callbacks = { 105static struct rchan_callbacks default_channel_callbacks = {
85 .subbuf_start = subbuf_start_default_callback, 106 .subbuf_start = subbuf_start_default_callback,
86 .buf_mapped = buf_mapped_default_callback, 107 .buf_mapped = buf_mapped_default_callback,
87 .buf_unmapped = buf_unmapped_default_callback, 108 .buf_unmapped = buf_unmapped_default_callback,
109 .create_buf_file = create_buf_file_default_callback,
110 .remove_buf_file = remove_buf_file_default_callback,
88}; 111};
89 112
90/** 113/**
@@ -148,14 +171,16 @@ static inline void __relay_reset(struct rchan_buf *buf, unsigned int init)
148void relay_reset(struct rchan *chan) 171void relay_reset(struct rchan *chan)
149{ 172{
150 unsigned int i; 173 unsigned int i;
174 struct rchan_buf *prev = NULL;
151 175
152 if (!chan) 176 if (!chan)
153 return; 177 return;
154 178
155 for (i = 0; i < NR_CPUS; i++) { 179 for (i = 0; i < NR_CPUS; i++) {
156 if (!chan->buf[i]) 180 if (!chan->buf[i] || chan->buf[i] == prev)
157 continue; 181 break;
158 __relay_reset(chan->buf[i], 0); 182 __relay_reset(chan->buf[i], 0);
183 prev = chan->buf[i];
159 } 184 }
160} 185}
161 186
@@ -166,17 +191,27 @@ void relay_reset(struct rchan *chan)
166 */ 191 */
167static struct rchan_buf *relay_open_buf(struct rchan *chan, 192static struct rchan_buf *relay_open_buf(struct rchan *chan,
168 const char *filename, 193 const char *filename,
169 struct dentry *parent) 194 struct dentry *parent,
195 int *is_global)
170{ 196{
171 struct rchan_buf *buf; 197 struct rchan_buf *buf;
172 struct dentry *dentry; 198 struct dentry *dentry;
173 199
200 if (*is_global)
201 return chan->buf[0];
202
203 buf = relay_create_buf(chan);
204 if (!buf)
205 return NULL;
206
174 /* Create file in fs */ 207 /* Create file in fs */
175 dentry = relayfs_create_file(filename, parent, S_IRUSR, chan); 208 dentry = chan->cb->create_buf_file(filename, parent, S_IRUSR,
176 if (!dentry) 209 buf, is_global);
210 if (!dentry) {
211 relay_destroy_buf(buf);
177 return NULL; 212 return NULL;
213 }
178 214
179 buf = RELAYFS_I(dentry->d_inode)->buf;
180 buf->dentry = dentry; 215 buf->dentry = dentry;
181 __relay_reset(buf, 1); 216 __relay_reset(buf, 1);
182 217
@@ -214,6 +249,10 @@ static inline void setup_callbacks(struct rchan *chan,
214 cb->buf_mapped = buf_mapped_default_callback; 249 cb->buf_mapped = buf_mapped_default_callback;
215 if (!cb->buf_unmapped) 250 if (!cb->buf_unmapped)
216 cb->buf_unmapped = buf_unmapped_default_callback; 251 cb->buf_unmapped = buf_unmapped_default_callback;
252 if (!cb->create_buf_file)
253 cb->create_buf_file = create_buf_file_default_callback;
254 if (!cb->remove_buf_file)
255 cb->remove_buf_file = remove_buf_file_default_callback;
217 chan->cb = cb; 256 chan->cb = cb;
218} 257}
219 258
@@ -241,6 +280,7 @@ struct rchan *relay_open(const char *base_filename,
241 unsigned int i; 280 unsigned int i;
242 struct rchan *chan; 281 struct rchan *chan;
243 char *tmpname; 282 char *tmpname;
283 int is_global = 0;
244 284
245 if (!base_filename) 285 if (!base_filename)
246 return NULL; 286 return NULL;
@@ -265,7 +305,8 @@ struct rchan *relay_open(const char *base_filename,
265 305
266 for_each_online_cpu(i) { 306 for_each_online_cpu(i) {
267 sprintf(tmpname, "%s%d", base_filename, i); 307 sprintf(tmpname, "%s%d", base_filename, i);
268 chan->buf[i] = relay_open_buf(chan, tmpname, parent); 308 chan->buf[i] = relay_open_buf(chan, tmpname, parent,
309 &is_global);
269 chan->buf[i]->cpu = i; 310 chan->buf[i]->cpu = i;
270 if (!chan->buf[i]) 311 if (!chan->buf[i])
271 goto free_bufs; 312 goto free_bufs;
@@ -279,6 +320,8 @@ free_bufs:
279 if (!chan->buf[i]) 320 if (!chan->buf[i])
280 break; 321 break;
281 relay_close_buf(chan->buf[i]); 322 relay_close_buf(chan->buf[i]);
323 if (is_global)
324 break;
282 } 325 }
283 kfree(tmpname); 326 kfree(tmpname);
284 327
@@ -388,14 +431,16 @@ void relay_destroy_channel(struct kref *kref)
388void relay_close(struct rchan *chan) 431void relay_close(struct rchan *chan)
389{ 432{
390 unsigned int i; 433 unsigned int i;
434 struct rchan_buf *prev = NULL;
391 435
392 if (!chan) 436 if (!chan)
393 return; 437 return;
394 438
395 for (i = 0; i < NR_CPUS; i++) { 439 for (i = 0; i < NR_CPUS; i++) {
396 if (!chan->buf[i]) 440 if (!chan->buf[i] || chan->buf[i] == prev)
397 continue; 441 break;
398 relay_close_buf(chan->buf[i]); 442 relay_close_buf(chan->buf[i]);
443 prev = chan->buf[i];
399 } 444 }
400 445
401 if (chan->last_toobig) 446 if (chan->last_toobig)
@@ -415,14 +460,16 @@ void relay_close(struct rchan *chan)
415void relay_flush(struct rchan *chan) 460void relay_flush(struct rchan *chan)
416{ 461{
417 unsigned int i; 462 unsigned int i;
463 struct rchan_buf *prev = NULL;
418 464
419 if (!chan) 465 if (!chan)
420 return; 466 return;
421 467
422 for (i = 0; i < NR_CPUS; i++) { 468 for (i = 0; i < NR_CPUS; i++) {
423 if (!chan->buf[i]) 469 if (!chan->buf[i] || chan->buf[i] == prev)
424 continue; 470 break;
425 relay_switch_subbuf(chan->buf[i], 0); 471 relay_switch_subbuf(chan->buf[i], 0);
472 prev = chan->buf[i];
426 } 473 }
427} 474}
428 475
diff --git a/fs/relayfs/relay.h b/fs/relayfs/relay.h
index 703503fa22b6..0993d3e5753b 100644
--- a/fs/relayfs/relay.h
+++ b/fs/relayfs/relay.h
@@ -1,10 +1,6 @@
1#ifndef _RELAY_H 1#ifndef _RELAY_H
2#define _RELAY_H 2#define _RELAY_H
3 3
4struct dentry *relayfs_create_file(const char *name,
5 struct dentry *parent,
6 int mode,
7 struct rchan *chan);
8extern int relayfs_remove(struct dentry *dentry); 4extern int relayfs_remove(struct dentry *dentry);
9extern int relay_buf_empty(struct rchan_buf *buf); 5extern int relay_buf_empty(struct rchan_buf *buf);
10extern void relay_destroy_channel(struct kref *kref); 6extern void relay_destroy_channel(struct kref *kref);
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index c74f382dabba..0a13859fd57b 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -418,7 +418,7 @@ static int
418romfs_readpage(struct file *file, struct page * page) 418romfs_readpage(struct file *file, struct page * page)
419{ 419{
420 struct inode *inode = page->mapping->host; 420 struct inode *inode = page->mapping->host;
421 unsigned long offset, avail, readlen; 421 loff_t offset, avail, readlen;
422 void *buf; 422 void *buf;
423 int result = -EIO; 423 int result = -EIO;
424 424
@@ -429,8 +429,8 @@ romfs_readpage(struct file *file, struct page * page)
429 goto err_out; 429 goto err_out;
430 430
431 /* 32 bit warning -- but not for us :) */ 431 /* 32 bit warning -- but not for us :) */
432 offset = page->index << PAGE_CACHE_SHIFT; 432 offset = page_offset(page);
433 if (offset < inode->i_size) { 433 if (offset < i_size_read(inode)) {
434 avail = inode->i_size-offset; 434 avail = inode->i_size-offset;
435 readlen = min_t(unsigned long, avail, PAGE_SIZE); 435 readlen = min_t(unsigned long, avail, PAGE_SIZE);
436 if (romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen) == readlen) { 436 if (romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen) == readlen) {
diff --git a/fs/smbfs/cache.c b/fs/smbfs/cache.c
index f3e6b81288ab..74b86d9725a6 100644
--- a/fs/smbfs/cache.c
+++ b/fs/smbfs/cache.c
@@ -66,7 +66,7 @@ smb_invalidate_dircache_entries(struct dentry *parent)
66 spin_lock(&dcache_lock); 66 spin_lock(&dcache_lock);
67 next = parent->d_subdirs.next; 67 next = parent->d_subdirs.next;
68 while (next != &parent->d_subdirs) { 68 while (next != &parent->d_subdirs) {
69 dentry = list_entry(next, struct dentry, d_child); 69 dentry = list_entry(next, struct dentry, d_u.d_child);
70 dentry->d_fsdata = NULL; 70 dentry->d_fsdata = NULL;
71 smb_age_dentry(server, dentry); 71 smb_age_dentry(server, dentry);
72 next = next->next; 72 next = next->next;
@@ -100,7 +100,7 @@ smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
100 spin_lock(&dcache_lock); 100 spin_lock(&dcache_lock);
101 next = parent->d_subdirs.next; 101 next = parent->d_subdirs.next;
102 while (next != &parent->d_subdirs) { 102 while (next != &parent->d_subdirs) {
103 dent = list_entry(next, struct dentry, d_child); 103 dent = list_entry(next, struct dentry, d_u.d_child);
104 if ((unsigned long)dent->d_fsdata == fpos) { 104 if ((unsigned long)dent->d_fsdata == fpos) {
105 if (dent->d_inode) 105 if (dent->d_inode)
106 dget_locked(dent); 106 dget_locked(dent);
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index b4fcfa8b55a1..7042e62726a4 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -209,8 +209,8 @@ smb_updatepage(struct file *file, struct page *page, unsigned long offset,
209{ 209{
210 struct dentry *dentry = file->f_dentry; 210 struct dentry *dentry = file->f_dentry;
211 211
212 DEBUG1("(%s/%s %d@%ld)\n", DENTRY_PATH(dentry), 212 DEBUG1("(%s/%s %d@%lld)\n", DENTRY_PATH(dentry), count,
213 count, (page->index << PAGE_CACHE_SHIFT)+offset); 213 ((unsigned long long)page->index << PAGE_CACHE_SHIFT) + offset);
214 214
215 return smb_writepage_sync(dentry->d_inode, page, offset, count); 215 return smb_writepage_sync(dentry->d_inode, page, offset, count);
216} 216}
@@ -374,8 +374,7 @@ smb_file_release(struct inode *inode, struct file * file)
374 /* We must flush any dirty pages now as we won't be able to 374 /* We must flush any dirty pages now as we won't be able to
375 write anything after close. mmap can trigger this. 375 write anything after close. mmap can trigger this.
376 "openers" should perhaps include mmap'ers ... */ 376 "openers" should perhaps include mmap'ers ... */
377 filemap_fdatawrite(inode->i_mapping); 377 filemap_write_and_wait(inode->i_mapping);
378 filemap_fdatawait(inode->i_mapping);
379 smb_close(inode); 378 smb_close(inode);
380 } 379 }
381 unlock_kernel(); 380 unlock_kernel();
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 10b994428fef..6ec88bf59b2d 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -697,8 +697,7 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr)
697 DENTRY_PATH(dentry), 697 DENTRY_PATH(dentry),
698 (long) inode->i_size, (long) attr->ia_size); 698 (long) inode->i_size, (long) attr->ia_size);
699 699
700 filemap_fdatawrite(inode->i_mapping); 700 filemap_write_and_wait(inode->i_mapping);
701 filemap_fdatawait(inode->i_mapping);
702 701
703 error = smb_open(dentry, O_WRONLY); 702 error = smb_open(dentry, O_WRONLY);
704 if (error) 703 if (error)
diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c
index 38ab558835c4..d6baec0f24ad 100644
--- a/fs/smbfs/proc.c
+++ b/fs/smbfs/proc.c
@@ -3113,7 +3113,7 @@ smb_proc_setattr_unix(struct dentry *d, struct iattr *attr,
3113 LSET(data, 32, SMB_TIME_NO_CHANGE); 3113 LSET(data, 32, SMB_TIME_NO_CHANGE);
3114 LSET(data, 40, SMB_UID_NO_CHANGE); 3114 LSET(data, 40, SMB_UID_NO_CHANGE);
3115 LSET(data, 48, SMB_GID_NO_CHANGE); 3115 LSET(data, 48, SMB_GID_NO_CHANGE);
3116 LSET(data, 56, smb_filetype_from_mode(attr->ia_mode)); 3116 DSET(data, 56, smb_filetype_from_mode(attr->ia_mode));
3117 LSET(data, 60, major); 3117 LSET(data, 60, major);
3118 LSET(data, 68, minor); 3118 LSET(data, 68, minor);
3119 LSET(data, 76, 0); 3119 LSET(data, 76, 0);
diff --git a/fs/super.c b/fs/super.c
index 5a347a4f673a..0a30e51692cf 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -700,8 +700,7 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
700 700
701 s->s_flags = flags; 701 s->s_flags = flags;
702 strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); 702 strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
703 s->s_old_blocksize = block_size(bdev); 703 sb_set_blocksize(s, block_size(bdev));
704 sb_set_blocksize(s, s->s_old_blocksize);
705 error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); 704 error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
706 if (error) { 705 if (error) {
707 up_write(&s->s_umount); 706 up_write(&s->s_umount);
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index 69a085abad6f..cce8b05cba5a 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -103,7 +103,7 @@ static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir)
103 offset = (char *)de - kaddr; 103 offset = (char *)de - kaddr;
104 104
105 over = filldir(dirent, name, strnlen(name,SYSV_NAMELEN), 105 over = filldir(dirent, name, strnlen(name,SYSV_NAMELEN),
106 (n<<PAGE_CACHE_SHIFT) | offset, 106 ((loff_t)n<<PAGE_CACHE_SHIFT) | offset,
107 fs16_to_cpu(SYSV_SB(sb), de->inode), 107 fs16_to_cpu(SYSV_SB(sb), de->inode),
108 DT_UNKNOWN); 108 DT_UNKNOWN);
109 if (over) { 109 if (over) {
@@ -115,7 +115,7 @@ static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir)
115 } 115 }
116 116
117done: 117done:
118 filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; 118 filp->f_pos = ((loff_t)n << PAGE_CACHE_SHIFT) | offset;
119 unlock_kernel(); 119 unlock_kernel();
120 return 0; 120 return 0;
121} 121}
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index 6598a5037ac8..4fae57d9d115 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -41,7 +41,7 @@
41#define uint(x) xuint(x) 41#define uint(x) xuint(x)
42#define xuint(x) __le ## x 42#define xuint(x) __le ## x
43 43
44extern inline int find_next_one_bit (void * addr, int size, int offset) 44static inline int find_next_one_bit (void * addr, int size, int offset)
45{ 45{
46 uintBPL_t * p = ((uintBPL_t *) addr) + (offset / BITS_PER_LONG); 46 uintBPL_t * p = ((uintBPL_t *) addr) + (offset / BITS_PER_LONG);
47 int result = offset & ~(BITS_PER_LONG-1); 47 int result = offset & ~(BITS_PER_LONG-1);
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 4014f17d382e..395e582ee542 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1957,11 +1957,6 @@ int8_t inode_bmap(struct inode *inode, int block, kernel_lb_addr *bloc, uint32_t
1957 printk(KERN_ERR "udf: inode_bmap: block < 0\n"); 1957 printk(KERN_ERR "udf: inode_bmap: block < 0\n");
1958 return -1; 1958 return -1;
1959 } 1959 }
1960 if (!inode)
1961 {
1962 printk(KERN_ERR "udf: inode_bmap: NULL inode\n");
1963 return -1;
1964 }
1965 1960
1966 *extoffset = 0; 1961 *extoffset = 0;
1967 *elen = 0; 1962 *elen = 0;
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 54828ebcf1ba..2ba11a9aa995 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -1296,8 +1296,10 @@ static ssize_t ufs_quota_write(struct super_block *sb, int type,
1296 blk++; 1296 blk++;
1297 } 1297 }
1298out: 1298out:
1299 if (len == towrite) 1299 if (len == towrite) {
1300 up(&inode->i_sem);
1300 return err; 1301 return err;
1302 }
1301 if (inode->i_size < off+len-towrite) 1303 if (inode->i_size < off+len-towrite)
1302 i_size_write(inode, off+len-towrite); 1304 i_size_write(inode, off+len-towrite);
1303 inode->i_version++; 1305 inode->i_version++;
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c
index f89340c61bf2..4fa4b1a5187e 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.c
@@ -79,8 +79,7 @@ fs_flushinval_pages(
79 struct inode *ip = LINVFS_GET_IP(vp); 79 struct inode *ip = LINVFS_GET_IP(vp);
80 80
81 if (VN_CACHED(vp)) { 81 if (VN_CACHED(vp)) {
82 filemap_fdatawrite(ip->i_mapping); 82 filemap_write_and_wait(ip->i_mapping);
83 filemap_fdatawait(ip->i_mapping);
84 83
85 truncate_inode_pages(ip->i_mapping, first); 84 truncate_inode_pages(ip->i_mapping, first);
86 } 85 }
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index 158829ca56f6..f40d4391fcfc 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -30,13 +30,7 @@
30 * By comparing each compnent, we don't have to worry about extra 30 * By comparing each compnent, we don't have to worry about extra
31 * endian issues in treating two 32 bit numbers as one 64 bit number 31 * endian issues in treating two 32 bit numbers as one 64 bit number
32 */ 32 */
33static 33static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
34#if defined(__GNUC__) && (__GNUC__ == 2) && ( (__GNUC_MINOR__ == 95) || (__GNUC_MINOR__ == 96))
35__attribute__((unused)) /* gcc 2.95, 2.96 miscompile this when inlined */
36#else
37__inline__
38#endif
39xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
40{ 34{
41 if (CYCLE_LSN(lsn1) != CYCLE_LSN(lsn2)) 35 if (CYCLE_LSN(lsn1) != CYCLE_LSN(lsn2))
42 return (CYCLE_LSN(lsn1)<CYCLE_LSN(lsn2))? -999 : 999; 36 return (CYCLE_LSN(lsn1)<CYCLE_LSN(lsn2))? -999 : 999;
diff --git a/include/asm-alpha/cache.h b/include/asm-alpha/cache.h
index e69b29501a5f..e6d4d1695e25 100644
--- a/include/asm-alpha/cache.h
+++ b/include/asm-alpha/cache.h
@@ -20,6 +20,5 @@
20 20
21#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) 21#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
22#define SMP_CACHE_BYTES L1_CACHE_BYTES 22#define SMP_CACHE_BYTES L1_CACHE_BYTES
23#define L1_CACHE_SHIFT_MAX L1_CACHE_SHIFT
24 23
25#endif 24#endif
diff --git a/include/asm-alpha/compiler.h b/include/asm-alpha/compiler.h
index 0a4a8b40dfcd..00c6f57ad9a7 100644
--- a/include/asm-alpha/compiler.h
+++ b/include/asm-alpha/compiler.h
@@ -98,9 +98,7 @@
98#undef inline 98#undef inline
99#undef __inline__ 99#undef __inline__
100#undef __inline 100#undef __inline
101#if __GNUC__ == 3 && __GNUC_MINOR__ >= 1 || __GNUC__ > 3
102#undef __always_inline 101#undef __always_inline
103#define __always_inline inline __attribute__((always_inline)) 102#define __always_inline inline __attribute__((always_inline))
104#endif
105 103
106#endif /* __ALPHA_COMPILER_H */ 104#endif /* __ALPHA_COMPILER_H */
diff --git a/include/asm-alpha/futex.h b/include/asm-alpha/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-alpha/futex.h
+++ b/include/asm-alpha/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-alpha/processor.h b/include/asm-alpha/processor.h
index 059780a7d3d7..bb1a7a3abb8b 100644
--- a/include/asm-alpha/processor.h
+++ b/include/asm-alpha/processor.h
@@ -77,7 +77,6 @@ unsigned long get_wchan(struct task_struct *p);
77#define spin_lock_prefetch(lock) do { } while (0) 77#define spin_lock_prefetch(lock) do { } while (0)
78#endif 78#endif
79 79
80#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
81extern inline void prefetch(const void *ptr) 80extern inline void prefetch(const void *ptr)
82{ 81{
83 __builtin_prefetch(ptr, 0, 3); 82 __builtin_prefetch(ptr, 0, 3);
@@ -95,24 +94,4 @@ extern inline void spin_lock_prefetch(const void *ptr)
95} 94}
96#endif 95#endif
97 96
98#else
99extern inline void prefetch(const void *ptr)
100{
101 __asm__ ("ldl $31,%0" : : "m"(*(char *)ptr));
102}
103
104extern inline void prefetchw(const void *ptr)
105{
106 __asm__ ("ldq $31,%0" : : "m"(*(char *)ptr));
107}
108
109#ifdef CONFIG_SMP
110extern inline void spin_lock_prefetch(const void *ptr)
111{
112 __asm__ ("ldq $31,%0" : : "m"(*(char *)ptr));
113}
114#endif
115
116#endif /* GCC 3.1 */
117
118#endif /* __ASM_ALPHA_PROCESSOR_H */ 97#endif /* __ASM_ALPHA_PROCESSOR_H */
diff --git a/include/asm-arm/cache.h b/include/asm-arm/cache.h
index 8d161f7c87ff..31332c8ac04e 100644
--- a/include/asm-arm/cache.h
+++ b/include/asm-arm/cache.h
@@ -7,9 +7,4 @@
7#define L1_CACHE_SHIFT 5 7#define L1_CACHE_SHIFT 5
8#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) 8#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
9 9
10/*
11 * largest L1 which this arch supports
12 */
13#define L1_CACHE_SHIFT_MAX 5
14
15#endif 10#endif
diff --git a/include/asm-arm/futex.h b/include/asm-arm/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-arm/futex.h
+++ b/include/asm-arm/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-arm/irq.h b/include/asm-arm/irq.h
index 59975ee43cf1..7772432d3fd7 100644
--- a/include/asm-arm/irq.h
+++ b/include/asm-arm/irq.h
@@ -25,10 +25,14 @@ extern void disable_irq_nosync(unsigned int);
25extern void disable_irq(unsigned int); 25extern void disable_irq(unsigned int);
26extern void enable_irq(unsigned int); 26extern void enable_irq(unsigned int);
27 27
28#define __IRQT_FALEDGE (1 << 0) 28/*
29#define __IRQT_RISEDGE (1 << 1) 29 * These correspond with the SA_TRIGGER_* defines, and therefore the
30#define __IRQT_LOWLVL (1 << 2) 30 * IRQRESOURCE_IRQ_* defines.
31#define __IRQT_HIGHLVL (1 << 3) 31 */
32#define __IRQT_RISEDGE (1 << 0)
33#define __IRQT_FALEDGE (1 << 1)
34#define __IRQT_HIGHLVL (1 << 2)
35#define __IRQT_LOWLVL (1 << 3)
32 36
33#define IRQT_NOEDGE (0) 37#define IRQT_NOEDGE (0)
34#define IRQT_RISING (__IRQT_RISEDGE) 38#define IRQT_RISING (__IRQT_RISEDGE)
diff --git a/include/asm-arm26/futex.h b/include/asm-arm26/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-arm26/futex.h
+++ b/include/asm-arm26/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-cris/arch-v10/cache.h b/include/asm-cris/arch-v10/cache.h
index 1d1d1ba65b1a..aea27184d2d2 100644
--- a/include/asm-cris/arch-v10/cache.h
+++ b/include/asm-cris/arch-v10/cache.h
@@ -4,6 +4,5 @@
4/* Etrax 100LX have 32-byte cache-lines. */ 4/* Etrax 100LX have 32-byte cache-lines. */
5#define L1_CACHE_BYTES 32 5#define L1_CACHE_BYTES 32
6#define L1_CACHE_SHIFT 5 6#define L1_CACHE_SHIFT 5
7#define L1_CACHE_SHIFT_MAX 5
8 7
9#endif /* _ASM_ARCH_CACHE_H */ 8#endif /* _ASM_ARCH_CACHE_H */
diff --git a/include/asm-cris/arch-v32/cache.h b/include/asm-cris/arch-v32/cache.h
index 4fed8d62ccc8..80b236b15319 100644
--- a/include/asm-cris/arch-v32/cache.h
+++ b/include/asm-cris/arch-v32/cache.h
@@ -4,6 +4,5 @@
4/* A cache-line is 32 bytes. */ 4/* A cache-line is 32 bytes. */
5#define L1_CACHE_BYTES 32 5#define L1_CACHE_BYTES 32
6#define L1_CACHE_SHIFT 5 6#define L1_CACHE_SHIFT 5
7#define L1_CACHE_SHIFT_MAX 5
8 7
9#endif /* _ASM_CRIS_ARCH_CACHE_H */ 8#endif /* _ASM_CRIS_ARCH_CACHE_H */
diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h
index 8eff51349ae7..cbf1a98f0129 100644
--- a/include/asm-cris/dma-mapping.h
+++ b/include/asm-cris/dma-mapping.h
@@ -153,7 +153,7 @@ dma_set_mask(struct device *dev, u64 mask)
153static inline int 153static inline int
154dma_get_cache_alignment(void) 154dma_get_cache_alignment(void)
155{ 155{
156 return (1 << L1_CACHE_SHIFT_MAX); 156 return (1 << INTERNODE_CACHE_SHIFT);
157} 157}
158 158
159#define dma_is_consistent(d) (1) 159#define dma_is_consistent(d) (1)
diff --git a/include/asm-cris/futex.h b/include/asm-cris/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-cris/futex.h
+++ b/include/asm-cris/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-frv/atomic.h b/include/asm-frv/atomic.h
index 3f54fea2b051..9c9e9499cfd8 100644
--- a/include/asm-frv/atomic.h
+++ b/include/asm-frv/atomic.h
@@ -218,51 +218,12 @@ extern unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsig
218 __typeof__(*(ptr)) __xg_orig; \ 218 __typeof__(*(ptr)) __xg_orig; \
219 \ 219 \
220 switch (sizeof(__xg_orig)) { \ 220 switch (sizeof(__xg_orig)) { \
221 case 1: \
222 asm volatile( \
223 "0: \n" \
224 " orcc gr0,gr0,gr0,icc3 \n" \
225 " ckeq icc3,cc7 \n" \
226 " ldub.p %M0,%1 \n" \
227 " orcr cc7,cc7,cc3 \n" \
228 " cstb.p %2,%M0 ,cc3,#1 \n" \
229 " corcc gr29,gr29,gr0 ,cc3,#1 \n" \
230 " beq icc3,#0,0b \n" \
231 : "+U"(*__xg_ptr), "=&r"(__xg_orig) \
232 : "r"(x) \
233 : "memory", "cc7", "cc3", "icc3" \
234 ); \
235 break; \
236 \
237 case 2: \
238 asm volatile( \
239 "0: \n" \
240 " orcc gr0,gr0,gr0,icc3 \n" \
241 " ckeq icc3,cc7 \n" \
242 " lduh.p %M0,%1 \n" \
243 " orcr cc7,cc7,cc3 \n" \
244 " csth.p %2,%M0 ,cc3,#1 \n" \
245 " corcc gr29,gr29,gr0 ,cc3,#1 \n" \
246 " beq icc3,#0,0b \n" \
247 : "+U"(*__xg_ptr), "=&r"(__xg_orig) \
248 : "r"(x) \
249 : "memory", "cc7", "cc3", "icc3" \
250 ); \
251 break; \
252 \
253 case 4: \ 221 case 4: \
254 asm volatile( \ 222 asm volatile( \
255 "0: \n" \ 223 "swap%I0 %2,%M0" \
256 " orcc gr0,gr0,gr0,icc3 \n" \ 224 : "+m"(*__xg_ptr), "=&r"(__xg_orig) \
257 " ckeq icc3,cc7 \n" \
258 " ld.p %M0,%1 \n" \
259 " orcr cc7,cc7,cc3 \n" \
260 " cst.p %2,%M0 ,cc3,#1 \n" \
261 " corcc gr29,gr29,gr0 ,cc3,#1 \n" \
262 " beq icc3,#0,0b \n" \
263 : "+U"(*__xg_ptr), "=&r"(__xg_orig) \
264 : "r"(x) \ 225 : "r"(x) \
265 : "memory", "cc7", "cc3", "icc3" \ 226 : "memory" \
266 ); \ 227 ); \
267 break; \ 228 break; \
268 \ 229 \
@@ -277,8 +238,6 @@ extern unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsig
277 238
278#else 239#else
279 240
280extern uint8_t __xchg_8 (uint8_t i, volatile void *v);
281extern uint16_t __xchg_16(uint16_t i, volatile void *v);
282extern uint32_t __xchg_32(uint32_t i, volatile void *v); 241extern uint32_t __xchg_32(uint32_t i, volatile void *v);
283 242
284#define xchg(ptr, x) \ 243#define xchg(ptr, x) \
@@ -287,8 +246,6 @@ extern uint32_t __xchg_32(uint32_t i, volatile void *v);
287 __typeof__(*(ptr)) __xg_orig; \ 246 __typeof__(*(ptr)) __xg_orig; \
288 \ 247 \
289 switch (sizeof(__xg_orig)) { \ 248 switch (sizeof(__xg_orig)) { \
290 case 1: __xg_orig = (__typeof__(*(ptr))) __xchg_8 ((uint8_t) x, __xg_ptr); break; \
291 case 2: __xg_orig = (__typeof__(*(ptr))) __xchg_16((uint16_t) x, __xg_ptr); break; \
292 case 4: __xg_orig = (__typeof__(*(ptr))) __xchg_32((uint32_t) x, __xg_ptr); break; \ 249 case 4: __xg_orig = (__typeof__(*(ptr))) __xchg_32((uint32_t) x, __xg_ptr); break; \
293 default: \ 250 default: \
294 __xg_orig = 0; \ 251 __xg_orig = 0; \
@@ -318,46 +275,6 @@ extern uint32_t __xchg_32(uint32_t i, volatile void *v);
318 __typeof__(*(ptr)) __xg_new = (new); \ 275 __typeof__(*(ptr)) __xg_new = (new); \
319 \ 276 \
320 switch (sizeof(__xg_orig)) { \ 277 switch (sizeof(__xg_orig)) { \
321 case 1: \
322 asm volatile( \
323 "0: \n" \
324 " orcc gr0,gr0,gr0,icc3 \n" \
325 " ckeq icc3,cc7 \n" \
326 " ldub.p %M0,%1 \n" \
327 " orcr cc7,cc7,cc3 \n" \
328 " sub%I4 %1,%4,%2 \n" \
329 " sllcc %2,#24,gr0,icc0 \n" \
330 " bne icc0,#0,1f \n" \
331 " cstb.p %3,%M0 ,cc3,#1 \n" \
332 " corcc gr29,gr29,gr0 ,cc3,#1 \n" \
333 " beq icc3,#0,0b \n" \
334 "1: \n" \
335 : "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp) \
336 : "r"(__xg_new), "NPr"(__xg_test) \
337 : "memory", "cc7", "cc3", "icc3", "icc0" \
338 ); \
339 break; \
340 \
341 case 2: \
342 asm volatile( \
343 "0: \n" \
344 " orcc gr0,gr0,gr0,icc3 \n" \
345 " ckeq icc3,cc7 \n" \
346 " lduh.p %M0,%1 \n" \
347 " orcr cc7,cc7,cc3 \n" \
348 " sub%I4 %1,%4,%2 \n" \
349 " sllcc %2,#16,gr0,icc0 \n" \
350 " bne icc0,#0,1f \n" \
351 " csth.p %3,%M0 ,cc3,#1 \n" \
352 " corcc gr29,gr29,gr0 ,cc3,#1 \n" \
353 " beq icc3,#0,0b \n" \
354 "1: \n" \
355 : "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp) \
356 : "r"(__xg_new), "NPr"(__xg_test) \
357 : "memory", "cc7", "cc3", "icc3", "icc0" \
358 ); \
359 break; \
360 \
361 case 4: \ 278 case 4: \
362 asm volatile( \ 279 asm volatile( \
363 "0: \n" \ 280 "0: \n" \
@@ -388,8 +305,6 @@ extern uint32_t __xchg_32(uint32_t i, volatile void *v);
388 305
389#else 306#else
390 307
391extern uint8_t __cmpxchg_8 (uint8_t *v, uint8_t test, uint8_t new);
392extern uint16_t __cmpxchg_16(uint16_t *v, uint16_t test, uint16_t new);
393extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new); 308extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
394 309
395#define cmpxchg(ptr, test, new) \ 310#define cmpxchg(ptr, test, new) \
@@ -400,8 +315,6 @@ extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
400 __typeof__(*(ptr)) __xg_new = (new); \ 315 __typeof__(*(ptr)) __xg_new = (new); \
401 \ 316 \
402 switch (sizeof(__xg_orig)) { \ 317 switch (sizeof(__xg_orig)) { \
403 case 1: __xg_orig = __cmpxchg_8 (__xg_ptr, __xg_test, __xg_new); break; \
404 case 2: __xg_orig = __cmpxchg_16(__xg_ptr, __xg_test, __xg_new); break; \
405 case 4: __xg_orig = __cmpxchg_32(__xg_ptr, __xg_test, __xg_new); break; \ 318 case 4: __xg_orig = __cmpxchg_32(__xg_ptr, __xg_test, __xg_new); break; \
406 default: \ 319 default: \
407 __xg_orig = 0; \ 320 __xg_orig = 0; \
@@ -414,7 +327,7 @@ extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
414 327
415#endif 328#endif
416 329
417#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new)) 330#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
418 331
419#define atomic_add_unless(v, a, u) \ 332#define atomic_add_unless(v, a, u) \
420({ \ 333({ \
@@ -424,6 +337,7 @@ extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
424 c = old; \ 337 c = old; \
425 c != (u); \ 338 c != (u); \
426}) 339})
340
427#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) 341#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
428 342
429#include <asm-generic/atomic.h> 343#include <asm-generic/atomic.h>
diff --git a/include/asm-frv/bug.h b/include/asm-frv/bug.h
index 074c0d5770eb..451712cc3060 100644
--- a/include/asm-frv/bug.h
+++ b/include/asm-frv/bug.h
@@ -12,6 +12,7 @@
12#define _ASM_BUG_H 12#define _ASM_BUG_H
13 13
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/linkage.h>
15 16
16#ifdef CONFIG_BUG 17#ifdef CONFIG_BUG
17/* 18/*
diff --git a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h
index 5003e017fd1e..e9fc1d47797e 100644
--- a/include/asm-frv/dma-mapping.h
+++ b/include/asm-frv/dma-mapping.h
@@ -23,7 +23,7 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t
23 * returns, or alternatively stop on the first sg_dma_len(sg) which 23 * returns, or alternatively stop on the first sg_dma_len(sg) which
24 * is 0. 24 * is 0.
25 */ 25 */
26#define sg_dma_address(sg) ((unsigned long) (page_to_phys((sg)->page) + (sg)->offset)) 26#define sg_dma_address(sg) ((sg)->dma_address)
27#define sg_dma_len(sg) ((sg)->length) 27#define sg_dma_len(sg) ((sg)->length)
28 28
29/* 29/*
diff --git a/include/asm-frv/io.h b/include/asm-frv/io.h
index 48829f727242..075369b1a34b 100644
--- a/include/asm-frv/io.h
+++ b/include/asm-frv/io.h
@@ -18,6 +18,7 @@
18#ifdef __KERNEL__ 18#ifdef __KERNEL__
19 19
20#include <linux/config.h> 20#include <linux/config.h>
21#include <linux/types.h>
21#include <asm/virtconvert.h> 22#include <asm/virtconvert.h>
22#include <asm/string.h> 23#include <asm/string.h>
23#include <asm/mb-regs.h> 24#include <asm/mb-regs.h>
@@ -104,6 +105,8 @@ static inline void __insl(unsigned long addr, void *buf, int len, int swap)
104 __insl_sw(addr, buf, len); 105 __insl_sw(addr, buf, len);
105} 106}
106 107
108#define mmiowb() mb()
109
107/* 110/*
108 * make the short names macros so specific devices 111 * make the short names macros so specific devices
109 * can override them as required 112 * can override them as required
@@ -209,6 +212,10 @@ static inline uint32_t readl(const volatile void __iomem *addr)
209 return ret; 212 return ret;
210} 213}
211 214
215#define readb_relaxed readb
216#define readw_relaxed readw
217#define readl_relaxed readl
218
212static inline void writeb(uint8_t datum, volatile void __iomem *addr) 219static inline void writeb(uint8_t datum, volatile void __iomem *addr)
213{ 220{
214 __builtin_write8((volatile uint8_t __force *) addr, datum); 221 __builtin_write8((volatile uint8_t __force *) addr, datum);
@@ -268,11 +275,106 @@ static inline void __iomem *ioremap_fullcache(unsigned long physaddr, unsigned l
268 275
269extern void iounmap(void __iomem *addr); 276extern void iounmap(void __iomem *addr);
270 277
278static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
279{
280 return (void __iomem *) port;
281}
282
283static inline void ioport_unmap(void __iomem *p)
284{
285}
286
271static inline void flush_write_buffers(void) 287static inline void flush_write_buffers(void)
272{ 288{
273 __asm__ __volatile__ ("membar" : : :"memory"); 289 __asm__ __volatile__ ("membar" : : :"memory");
274} 290}
275 291
292/*
293 * do appropriate I/O accesses for token type
294 */
295static inline unsigned int ioread8(void __iomem *p)
296{
297 return __builtin_read8(p);
298}
299
300static inline unsigned int ioread16(void __iomem *p)
301{
302 uint16_t ret = __builtin_read16(p);
303 if (__is_PCI_addr(p))
304 ret = _swapw(ret);
305 return ret;
306}
307
308static inline unsigned int ioread32(void __iomem *p)
309{
310 uint32_t ret = __builtin_read32(p);
311 if (__is_PCI_addr(p))
312 ret = _swapl(ret);
313 return ret;
314}
315
316static inline void iowrite8(u8 val, void __iomem *p)
317{
318 __builtin_write8(p, val);
319 if (__is_PCI_MEM(p))
320 __flush_PCI_writes();
321}
322
323static inline void iowrite16(u16 val, void __iomem *p)
324{
325 if (__is_PCI_addr(p))
326 val = _swapw(val);
327 __builtin_write16(p, val);
328 if (__is_PCI_MEM(p))
329 __flush_PCI_writes();
330}
331
332static inline void iowrite32(u32 val, void __iomem *p)
333{
334 if (__is_PCI_addr(p))
335 val = _swapl(val);
336 __builtin_write32(p, val);
337 if (__is_PCI_MEM(p))
338 __flush_PCI_writes();
339}
340
341static inline void ioread8_rep(void __iomem *p, void *dst, unsigned long count)
342{
343 io_insb((unsigned long) p, dst, count);
344}
345
346static inline void ioread16_rep(void __iomem *p, void *dst, unsigned long count)
347{
348 io_insw((unsigned long) p, dst, count);
349}
350
351static inline void ioread32_rep(void __iomem *p, void *dst, unsigned long count)
352{
353 __insl_ns((unsigned long) p, dst, count);
354}
355
356static inline void iowrite8_rep(void __iomem *p, const void *src, unsigned long count)
357{
358 io_outsb((unsigned long) p, src, count);
359}
360
361static inline void iowrite16_rep(void __iomem *p, const void *src, unsigned long count)
362{
363 io_outsw((unsigned long) p, src, count);
364}
365
366static inline void iowrite32_rep(void __iomem *p, const void *src, unsigned long count)
367{
368 __outsl_ns((unsigned long) p, src, count);
369}
370
371/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
372struct pci_dev;
373extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
374static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
375{
376}
377
276 378
277/* 379/*
278 * Convert a physical pointer to a virtual kernel pointer for /dev/mem 380 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
@@ -285,6 +387,27 @@ static inline void flush_write_buffers(void)
285 */ 387 */
286#define xlate_dev_kmem_ptr(p) p 388#define xlate_dev_kmem_ptr(p) p
287 389
390/*
391 * Check BIOS signature
392 */
393static inline int check_signature(volatile void __iomem *io_addr,
394 const unsigned char *signature, int length)
395{
396 int retval = 0;
397
398 do {
399 if (readb(io_addr) != *signature)
400 goto out;
401 io_addr++;
402 signature++;
403 length--;
404 } while (length);
405
406 retval = 1;
407out:
408 return retval;
409}
410
288#endif /* __KERNEL__ */ 411#endif /* __KERNEL__ */
289 412
290#endif /* _ASM_IO_H */ 413#endif /* _ASM_IO_H */
diff --git a/include/asm-frv/mb-regs.h b/include/asm-frv/mb-regs.h
index c8f575fc42fa..93fa732fb0cd 100644
--- a/include/asm-frv/mb-regs.h
+++ b/include/asm-frv/mb-regs.h
@@ -68,6 +68,9 @@ do { \
68#define __is_PCI_MEM(addr) \ 68#define __is_PCI_MEM(addr) \
69 ((unsigned long)(addr) - __region_PCI_MEM < 0x08000000UL) 69 ((unsigned long)(addr) - __region_PCI_MEM < 0x08000000UL)
70 70
71#define __is_PCI_addr(addr) \
72 ((unsigned long)(addr) - __region_PCI_IO < 0x0c000000UL)
73
71#define __get_CLKSW() ({ *(volatile unsigned long *)(__region_CS2 + 0x0130000cUL) & 0xffUL; }) 74#define __get_CLKSW() ({ *(volatile unsigned long *)(__region_CS2 + 0x0130000cUL) & 0xffUL; })
72#define __get_CLKIN() (__get_CLKSW() * 125U * 100000U / 24U) 75#define __get_CLKIN() (__get_CLKSW() * 125U * 100000U / 24U)
73 76
@@ -149,6 +152,7 @@ do { \
149 152
150#define __is_PCI_IO(addr) 0 /* no PCI */ 153#define __is_PCI_IO(addr) 0 /* no PCI */
151#define __is_PCI_MEM(addr) 0 154#define __is_PCI_MEM(addr) 0
155#define __is_PCI_addr(addr) 0
152#define __region_PCI_IO 0 156#define __region_PCI_IO 0
153#define __region_PCI_MEM 0 157#define __region_PCI_MEM 0
154#define __flush_PCI_writes() do { } while(0) 158#define __flush_PCI_writes() do { } while(0)
diff --git a/include/asm-frv/mc146818rtc.h b/include/asm-frv/mc146818rtc.h
new file mode 100644
index 000000000000..90dfb7a633d1
--- /dev/null
+++ b/include/asm-frv/mc146818rtc.h
@@ -0,0 +1,16 @@
1/* mc146818rtc.h: RTC defs
2 *
3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#ifndef _ASM_MC146818RTC_H
13#define _ASM_MC146818RTC_H
14
15
16#endif /* _ASM_MC146818RTC_H */
diff --git a/include/asm-frv/module.h b/include/asm-frv/module.h
index 3223cfaef743..3d5c6360289a 100644
--- a/include/asm-frv/module.h
+++ b/include/asm-frv/module.h
@@ -11,10 +11,18 @@
11#ifndef _ASM_MODULE_H 11#ifndef _ASM_MODULE_H
12#define _ASM_MODULE_H 12#define _ASM_MODULE_H
13 13
14#define module_map(x) vmalloc(x) 14struct mod_arch_specific
15#define module_unmap(x) vfree(x) 15{
16#define module_arch_init(x) (0) 16};
17#define arch_init_modules(x) do { } while (0) 17
18#define Elf_Shdr Elf32_Shdr
19#define Elf_Sym Elf32_Sym
20#define Elf_Ehdr Elf32_Ehdr
21
22/*
23 * Include the architecture version.
24 */
25#define MODULE_ARCH_VERMAGIC __stringify(PROCESSOR_MODEL_NAME) " "
18 26
19#endif /* _ASM_MODULE_H */ 27#endif /* _ASM_MODULE_H */
20 28
diff --git a/include/asm-frv/pci.h b/include/asm-frv/pci.h
index 1168451c275f..598b0c6b695d 100644
--- a/include/asm-frv/pci.h
+++ b/include/asm-frv/pci.h
@@ -57,6 +57,14 @@ extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
57 */ 57 */
58#define PCI_DMA_BUS_IS_PHYS (1) 58#define PCI_DMA_BUS_IS_PHYS (1)
59 59
60/* pci_unmap_{page,single} is a nop so... */
61#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
62#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
63#define pci_unmap_addr(PTR, ADDR_NAME) (0)
64#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
65#define pci_unmap_len(PTR, LEN_NAME) (0)
66#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
67
60#ifdef CONFIG_PCI 68#ifdef CONFIG_PCI
61static inline void pci_dma_burst_advice(struct pci_dev *pdev, 69static inline void pci_dma_burst_advice(struct pci_dev *pdev,
62 enum pci_dma_burst_strategy *strat, 70 enum pci_dma_burst_strategy *strat,
diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h
index 844666377dcb..d1c3b182c691 100644
--- a/include/asm-frv/pgtable.h
+++ b/include/asm-frv/pgtable.h
@@ -421,6 +421,11 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
421} 421}
422 422
423/* 423/*
424 * Macro to mark a page protection value as "uncacheable"
425 */
426#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE))
427
428/*
424 * Conversion functions: convert a page and protection to a page entry, 429 * Conversion functions: convert a page and protection to a page entry,
425 * and a page entry and page directory to the page they refer to. 430 * and a page entry and page directory to the page they refer to.
426 */ 431 */
diff --git a/include/asm-frv/types.h b/include/asm-frv/types.h
index 50605df6d8ac..2560f596a75d 100644
--- a/include/asm-frv/types.h
+++ b/include/asm-frv/types.h
@@ -59,7 +59,6 @@ typedef unsigned int u32;
59 59
60typedef signed long long s64; 60typedef signed long long s64;
61typedef unsigned long long u64; 61typedef unsigned long long u64;
62typedef u64 u_quad_t;
63 62
64/* Dma addresses are 32-bits wide. */ 63/* Dma addresses are 32-bits wide. */
65 64
diff --git a/include/asm-frv/uaccess.h b/include/asm-frv/uaccess.h
index 991b50fbba24..b6bcbe01f6ee 100644
--- a/include/asm-frv/uaccess.h
+++ b/include/asm-frv/uaccess.h
@@ -180,16 +180,16 @@ do { \
180 \ 180 \
181 switch (sizeof(*(ptr))) { \ 181 switch (sizeof(*(ptr))) { \
182 case 1: \ 182 case 1: \
183 __get_user_asm(__gu_err, __gu_val, ptr, "ub", "=r"); \ 183 __get_user_asm(__gu_err, *(u8*)&__gu_val, ptr, "ub", "=r"); \
184 break; \ 184 break; \
185 case 2: \ 185 case 2: \
186 __get_user_asm(__gu_err, __gu_val, ptr, "uh", "=r"); \ 186 __get_user_asm(__gu_err, *(u16*)&__gu_val, ptr, "uh", "=r"); \
187 break; \ 187 break; \
188 case 4: \ 188 case 4: \
189 __get_user_asm(__gu_err, __gu_val, ptr, "", "=r"); \ 189 __get_user_asm(__gu_err, *(u32*)&__gu_val, ptr, "", "=r"); \
190 break; \ 190 break; \
191 case 8: \ 191 case 8: \
192 __get_user_asm(__gu_err, __gu_val, ptr, "d", "=e"); \ 192 __get_user_asm(__gu_err, *(u64*)&__gu_val, ptr, "d", "=e"); \
193 break; \ 193 break; \
194 default: \ 194 default: \
195 __gu_err = __get_user_bad(); \ 195 __gu_err = __get_user_bad(); \
diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h
index 5cf989b448d5..cde376a7a857 100644
--- a/include/asm-frv/unistd.h
+++ b/include/asm-frv/unistd.h
@@ -313,7 +313,7 @@ do { \
313 unsigned long __sr2 = (res); \ 313 unsigned long __sr2 = (res); \
314 if (__builtin_expect(__sr2 >= (unsigned long)(-4095), 0)) { \ 314 if (__builtin_expect(__sr2 >= (unsigned long)(-4095), 0)) { \
315 errno = (-__sr2); \ 315 errno = (-__sr2); \
316 __sr2 = ULONG_MAX; \ 316 __sr2 = ~0UL; \
317 } \ 317 } \
318 return (type) __sr2; \ 318 return (type) __sr2; \
319} while (0) 319} while (0)
diff --git a/include/asm-frv/vga.h b/include/asm-frv/vga.h
new file mode 100644
index 000000000000..a702c800a229
--- /dev/null
+++ b/include/asm-frv/vga.h
@@ -0,0 +1,17 @@
1/* vga.h: VGA register stuff
2 *
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#ifndef _ASM_VGA_H
13#define _ASM_VGA_H
14
15
16
17#endif /* _ASM_VGA_H */
diff --git a/include/asm-frv/xor.h b/include/asm-frv/xor.h
new file mode 100644
index 000000000000..c82eb12a5b18
--- /dev/null
+++ b/include/asm-frv/xor.h
@@ -0,0 +1 @@
#include <asm-generic/xor.h>
diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h
index e0a28b925ef0..0fada8f16dc6 100644
--- a/include/asm-generic/atomic.h
+++ b/include/asm-generic/atomic.h
@@ -8,6 +8,7 @@
8 * edit all arch specific atomic.h files. 8 * edit all arch specific atomic.h files.
9 */ 9 */
10 10
11#include <asm/types.h>
11 12
12/* 13/*
13 * Suppport for atomic_long_t 14 * Suppport for atomic_long_t
diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h
index 747d790295f3..1b356207712c 100644
--- a/include/asm-generic/dma-mapping.h
+++ b/include/asm-generic/dma-mapping.h
@@ -274,7 +274,7 @@ dma_get_cache_alignment(void)
274{ 274{
275 /* no easy way to get cache size on all processors, so return 275 /* no easy way to get cache size on all processors, so return
276 * the maximum possible, to be safe */ 276 * the maximum possible, to be safe */
277 return (1 << L1_CACHE_SHIFT_MAX); 277 return (1 << INTERNODE_CACHE_SHIFT);
278} 278}
279 279
280static inline void 280static inline void
diff --git a/include/asm-generic/futex.h b/include/asm-generic/futex.h
new file mode 100644
index 000000000000..3ae2c7347549
--- /dev/null
+++ b/include/asm-generic/futex.h
@@ -0,0 +1,53 @@
1#ifndef _ASM_GENERIC_FUTEX_H
2#define _ASM_GENERIC_FUTEX_H
3
4#ifdef __KERNEL__
5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif
diff --git a/include/asm-h8300/futex.h b/include/asm-h8300/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-h8300/futex.h
+++ b/include/asm-h8300/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-i386/cache.h b/include/asm-i386/cache.h
index 849788710feb..615911e5bd24 100644
--- a/include/asm-i386/cache.h
+++ b/include/asm-i386/cache.h
@@ -10,6 +10,4 @@
10#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT) 10#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
11#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) 11#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
12 12
13#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
14
15#endif 13#endif
diff --git a/include/asm-i386/dma-mapping.h b/include/asm-i386/dma-mapping.h
index e56c335f8ef9..6c37a9ab8d60 100644
--- a/include/asm-i386/dma-mapping.h
+++ b/include/asm-i386/dma-mapping.h
@@ -150,7 +150,7 @@ dma_get_cache_alignment(void)
150{ 150{
151 /* no easy way to get cache size on all x86, so return the 151 /* no easy way to get cache size on all x86, so return the
152 * maximum possible, to be safe */ 152 * maximum possible, to be safe */
153 return (1 << L1_CACHE_SHIFT_MAX); 153 return (1 << INTERNODE_CACHE_SHIFT);
154} 154}
155 155
156#define dma_is_consistent(d) (1) 156#define dma_is_consistent(d) (1)
diff --git a/include/asm-i386/irq.h b/include/asm-i386/irq.h
index 270f1986b19f..5169d7af456f 100644
--- a/include/asm-i386/irq.h
+++ b/include/asm-i386/irq.h
@@ -21,8 +21,6 @@ static __inline__ int irq_canonicalize(int irq)
21 return ((irq == 2) ? 9 : irq); 21 return ((irq == 2) ? 9 : irq);
22} 22}
23 23
24extern void release_vm86_irqs(struct task_struct *);
25
26#ifdef CONFIG_X86_LOCAL_APIC 24#ifdef CONFIG_X86_LOCAL_APIC
27# define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */ 25# define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */
28#endif 26#endif
diff --git a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h
index 7e0f2945d17d..f324c53b6f9a 100644
--- a/include/asm-i386/ptrace.h
+++ b/include/asm-i386/ptrace.h
@@ -54,6 +54,9 @@ struct pt_regs {
54#define PTRACE_GET_THREAD_AREA 25 54#define PTRACE_GET_THREAD_AREA 25
55#define PTRACE_SET_THREAD_AREA 26 55#define PTRACE_SET_THREAD_AREA 26
56 56
57#define PTRACE_SYSEMU 31
58#define PTRACE_SYSEMU_SINGLESTEP 32
59
57#ifdef __KERNEL__ 60#ifdef __KERNEL__
58 61
59#include <asm/vm86.h> 62#include <asm/vm86.h>
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index fe38b9a96233..481c3c0ea720 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -299,8 +299,9 @@
299#define __NR_inotify_init 291 299#define __NR_inotify_init 291
300#define __NR_inotify_add_watch 292 300#define __NR_inotify_add_watch 292
301#define __NR_inotify_rm_watch 293 301#define __NR_inotify_rm_watch 293
302#define __NR_migrate_pages 294
302 303
303#define NR_syscalls 294 304#define NR_syscalls 295
304 305
305/* 306/*
306 * user-visible error numbers are in the range -1 - -128: see 307 * user-visible error numbers are in the range -1 - -128: see
diff --git a/include/asm-i386/vm86.h b/include/asm-i386/vm86.h
index 40ec82c6914d..952fd6957380 100644
--- a/include/asm-i386/vm86.h
+++ b/include/asm-i386/vm86.h
@@ -16,7 +16,11 @@
16#define IF_MASK 0x00000200 16#define IF_MASK 0x00000200
17#define IOPL_MASK 0x00003000 17#define IOPL_MASK 0x00003000
18#define NT_MASK 0x00004000 18#define NT_MASK 0x00004000
19#ifdef CONFIG_VM86
19#define VM_MASK 0x00020000 20#define VM_MASK 0x00020000
21#else
22#define VM_MASK 0 /* ignored */
23#endif
20#define AC_MASK 0x00040000 24#define AC_MASK 0x00040000
21#define VIF_MASK 0x00080000 /* virtual interrupt flag */ 25#define VIF_MASK 0x00080000 /* virtual interrupt flag */
22#define VIP_MASK 0x00100000 /* virtual interrupt pending */ 26#define VIP_MASK 0x00100000 /* virtual interrupt pending */
@@ -200,9 +204,25 @@ struct kernel_vm86_struct {
200 */ 204 */
201}; 205};
202 206
207#ifdef CONFIG_VM86
208
203void handle_vm86_fault(struct kernel_vm86_regs *, long); 209void handle_vm86_fault(struct kernel_vm86_regs *, long);
204int handle_vm86_trap(struct kernel_vm86_regs *, long, int); 210int handle_vm86_trap(struct kernel_vm86_regs *, long, int);
205 211
212struct task_struct;
213void release_vm86_irqs(struct task_struct *);
214
215#else
216
217#define handle_vm86_fault(a, b)
218#define release_vm86_irqs(a)
219
220static inline int handle_vm86_trap(struct kernel_vm86_regs *a, long b, int c) {
221 return 0;
222}
223
224#endif /* CONFIG_VM86 */
225
206#endif /* __KERNEL__ */ 226#endif /* __KERNEL__ */
207 227
208#endif 228#endif
diff --git a/include/asm-ia64/bug.h b/include/asm-ia64/bug.h
index 3aa0a0a5474b..823616b5020b 100644
--- a/include/asm-ia64/bug.h
+++ b/include/asm-ia64/bug.h
@@ -2,11 +2,7 @@
2#define _ASM_IA64_BUG_H 2#define _ASM_IA64_BUG_H
3 3
4#ifdef CONFIG_BUG 4#ifdef CONFIG_BUG
5#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) 5#define ia64_abort() __builtin_trap()
6# define ia64_abort() __builtin_trap()
7#else
8# define ia64_abort() (*(volatile int *) 0 = 0)
9#endif
10#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0) 6#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0)
11 7
12/* should this BUG be made generic? */ 8/* should this BUG be made generic? */
diff --git a/include/asm-ia64/cache.h b/include/asm-ia64/cache.h
index 666d8f175cb3..40dd25195d65 100644
--- a/include/asm-ia64/cache.h
+++ b/include/asm-ia64/cache.h
@@ -12,8 +12,6 @@
12#define L1_CACHE_SHIFT CONFIG_IA64_L1_CACHE_SHIFT 12#define L1_CACHE_SHIFT CONFIG_IA64_L1_CACHE_SHIFT
13#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) 13#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
14 14
15#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
16
17#ifdef CONFIG_SMP 15#ifdef CONFIG_SMP
18# define SMP_CACHE_SHIFT L1_CACHE_SHIFT 16# define SMP_CACHE_SHIFT L1_CACHE_SHIFT
19# define SMP_CACHE_BYTES L1_CACHE_BYTES 17# define SMP_CACHE_BYTES L1_CACHE_BYTES
diff --git a/include/asm-ia64/futex.h b/include/asm-ia64/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-ia64/futex.h
+++ b/include/asm-ia64/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-ia64/io.h b/include/asm-ia64/io.h
index cf772a67f858..b64fdb985494 100644
--- a/include/asm-ia64/io.h
+++ b/include/asm-ia64/io.h
@@ -89,6 +89,7 @@ phys_to_virt (unsigned long address)
89 89
90#define ARCH_HAS_VALID_PHYS_ADDR_RANGE 90#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
91extern int valid_phys_addr_range (unsigned long addr, size_t *count); /* efi.c */ 91extern int valid_phys_addr_range (unsigned long addr, size_t *count); /* efi.c */
92extern int valid_mmap_phys_addr_range (unsigned long addr, size_t *count);
92 93
93/* 94/*
94 * The following two macros are deprecated and scheduled for removal. 95 * The following two macros are deprecated and scheduled for removal.
diff --git a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h
index 0c91a76c5ea3..9e83210dc312 100644
--- a/include/asm-ia64/spinlock.h
+++ b/include/asm-ia64/spinlock.h
@@ -34,7 +34,7 @@ __raw_spin_lock_flags (raw_spinlock_t *lock, unsigned long flags)
34{ 34{
35 register volatile unsigned int *ptr asm ("r31") = &lock->lock; 35 register volatile unsigned int *ptr asm ("r31") = &lock->lock;
36 36
37#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) 37#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
38# ifdef CONFIG_ITANIUM 38# ifdef CONFIG_ITANIUM
39 /* don't use brl on Itanium... */ 39 /* don't use brl on Itanium... */
40 asm volatile ("{\n\t" 40 asm volatile ("{\n\t"
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
index 2bf543493cb8..962f9bd1bdff 100644
--- a/include/asm-ia64/unistd.h
+++ b/include/asm-ia64/unistd.h
@@ -269,12 +269,13 @@
269#define __NR_inotify_init 1277 269#define __NR_inotify_init 1277
270#define __NR_inotify_add_watch 1278 270#define __NR_inotify_add_watch 1278
271#define __NR_inotify_rm_watch 1279 271#define __NR_inotify_rm_watch 1279
272#define __NR_migrate_pages 1280
272 273
273#ifdef __KERNEL__ 274#ifdef __KERNEL__
274 275
275#include <linux/config.h> 276#include <linux/config.h>
276 277
277#define NR_syscalls 256 /* length of syscall table */ 278#define NR_syscalls 270 /* length of syscall table */
278 279
279#define __ARCH_WANT_SYS_RT_SIGACTION 280#define __ARCH_WANT_SYS_RT_SIGACTION
280 281
diff --git a/include/asm-m32r/cache.h b/include/asm-m32r/cache.h
index 724820596980..9c2b2d9998bc 100644
--- a/include/asm-m32r/cache.h
+++ b/include/asm-m32r/cache.h
@@ -7,6 +7,4 @@
7#define L1_CACHE_SHIFT 4 7#define L1_CACHE_SHIFT 4
8#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) 8#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
9 9
10#define L1_CACHE_SHIFT_MAX 4
11
12#endif /* _ASM_M32R_CACHE_H */ 10#endif /* _ASM_M32R_CACHE_H */
diff --git a/include/asm-m32r/futex.h b/include/asm-m32r/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-m32r/futex.h
+++ b/include/asm-m32r/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-m68k/cache.h b/include/asm-m68k/cache.h
index 6161fd3d8600..fed3fd30de7e 100644
--- a/include/asm-m68k/cache.h
+++ b/include/asm-m68k/cache.h
@@ -8,6 +8,4 @@
8#define L1_CACHE_SHIFT 4 8#define L1_CACHE_SHIFT 4
9#define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT) 9#define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT)
10 10
11#define L1_CACHE_SHIFT_MAX 4 /* largest L1 which this arch supports */
12
13#endif 11#endif
diff --git a/include/asm-m68k/futex.h b/include/asm-m68k/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-m68k/futex.h
+++ b/include/asm-m68k/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-m68knommu/futex.h b/include/asm-m68knommu/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-m68knommu/futex.h
+++ b/include/asm-m68knommu/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-mips/cache.h b/include/asm-mips/cache.h
index 1a5d1a669db3..55e19f2ff0e0 100644
--- a/include/asm-mips/cache.h
+++ b/include/asm-mips/cache.h
@@ -15,7 +15,6 @@
15#define L1_CACHE_SHIFT CONFIG_MIPS_L1_CACHE_SHIFT 15#define L1_CACHE_SHIFT CONFIG_MIPS_L1_CACHE_SHIFT
16#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) 16#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
17 17
18#define L1_CACHE_SHIFT_MAX 6
19#define SMP_CACHE_SHIFT L1_CACHE_SHIFT 18#define SMP_CACHE_SHIFT L1_CACHE_SHIFT
20#define SMP_CACHE_BYTES L1_CACHE_BYTES 19#define SMP_CACHE_BYTES L1_CACHE_BYTES
21 20
diff --git a/include/asm-parisc/cache.h b/include/asm-parisc/cache.h
index 5da72e38bdde..38d201b5652d 100644
--- a/include/asm-parisc/cache.h
+++ b/include/asm-parisc/cache.h
@@ -28,7 +28,6 @@
28#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) 28#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
29 29
30#define SMP_CACHE_BYTES L1_CACHE_BYTES 30#define SMP_CACHE_BYTES L1_CACHE_BYTES
31#define L1_CACHE_SHIFT_MAX 5 /* largest L1 which this arch supports */
32 31
33extern void flush_data_cache_local(void); /* flushes local data-cache only */ 32extern void flush_data_cache_local(void); /* flushes local data-cache only */
34extern void flush_instruction_cache_local(void); /* flushes local code-cache only */ 33extern void flush_instruction_cache_local(void); /* flushes local code-cache only */
diff --git a/include/asm-parisc/futex.h b/include/asm-parisc/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-parisc/futex.h
+++ b/include/asm-parisc/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-powerpc/abs_addr.h b/include/asm-powerpc/abs_addr.h
index 18415108fc56..c5c3259e0f86 100644
--- a/include/asm-powerpc/abs_addr.h
+++ b/include/asm-powerpc/abs_addr.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_ABS_ADDR_H 1#ifndef _ASM_POWERPC_ABS_ADDR_H
2#define _ASM_POWERPC_ABS_ADDR_H 2#define _ASM_POWERPC_ABS_ADDR_H
3#ifdef __KERNEL__
3 4
4#include <linux/config.h> 5#include <linux/config.h>
5 6
@@ -70,4 +71,5 @@ static inline unsigned long phys_to_abs(unsigned long pa)
70#define iseries_hv_addr(virtaddr) \ 71#define iseries_hv_addr(virtaddr) \
71 (0x8000000000000000 | virt_to_abs(virtaddr)) 72 (0x8000000000000000 | virt_to_abs(virtaddr))
72 73
74#endif /* __KERNEL__ */
73#endif /* _ASM_POWERPC_ABS_ADDR_H */ 75#endif /* _ASM_POWERPC_ABS_ADDR_H */
diff --git a/include/asm-powerpc/agp.h b/include/asm-powerpc/agp.h
index 885b4631a6cf..e5ccaca2f5a4 100644
--- a/include/asm-powerpc/agp.h
+++ b/include/asm-powerpc/agp.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_AGP_H 1#ifndef _ASM_POWERPC_AGP_H
2#define _ASM_POWERPC_AGP_H 2#define _ASM_POWERPC_AGP_H
3#ifdef __KERNEL__
3 4
4#include <asm/io.h> 5#include <asm/io.h>
5 6
@@ -18,4 +19,5 @@
18#define free_gatt_pages(table, order) \ 19#define free_gatt_pages(table, order) \
19 free_pages((unsigned long)(table), (order)) 20 free_pages((unsigned long)(table), (order))
20 21
22#endif /* __KERNEL__ */
21#endif /* _ASM_POWERPC_AGP_H */ 23#endif /* _ASM_POWERPC_AGP_H */
diff --git a/include/asm-powerpc/asm-compat.h b/include/asm-powerpc/asm-compat.h
index 8b133efc9f79..8e64be0cc47d 100644
--- a/include/asm-powerpc/asm-compat.h
+++ b/include/asm-powerpc/asm-compat.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_POWERPC_ASM_COMPAT_H 1#ifndef _ASM_POWERPC_ASM_COMPAT_H
2#define _ASM_POWERPC_ASM_COMPAT_H 2#define _ASM_POWERPC_ASM_COMPAT_H
3 3
4#include <linux/config.h>
5#include <asm/types.h> 4#include <asm/types.h>
6 5
7#ifdef __ASSEMBLY__ 6#ifdef __ASSEMBLY__
@@ -41,6 +40,7 @@
41 40
42#endif 41#endif
43 42
43#ifdef __KERNEL__
44#ifdef CONFIG_IBM405_ERR77 44#ifdef CONFIG_IBM405_ERR77
45/* Erratum #77 on the 405 means we need a sync or dcbt before every 45/* Erratum #77 on the 405 means we need a sync or dcbt before every
46 * stwcx. The old ATOMIC_SYNC_FIX covered some but not all of this. 46 * stwcx. The old ATOMIC_SYNC_FIX covered some but not all of this.
@@ -51,5 +51,6 @@
51#define PPC405_ERR77(ra,rb) 51#define PPC405_ERR77(ra,rb)
52#define PPC405_ERR77_SYNC 52#define PPC405_ERR77_SYNC
53#endif 53#endif
54#endif
54 55
55#endif /* _ASM_POWERPC_ASM_COMPAT_H */ 56#endif /* _ASM_POWERPC_ASM_COMPAT_H */
diff --git a/include/asm-powerpc/bootx.h b/include/asm-powerpc/bootx.h
new file mode 100644
index 000000000000..57b82e3f89ce
--- /dev/null
+++ b/include/asm-powerpc/bootx.h
@@ -0,0 +1,171 @@
1/*
2 * This file describes the structure passed from the BootX application
3 * (for MacOS) when it is used to boot Linux.
4 *
5 * Written by Benjamin Herrenschmidt.
6 */
7
8
9#ifndef __ASM_BOOTX_H__
10#define __ASM_BOOTX_H__
11
12#include <asm/types.h>
13
14#ifdef macintosh
15#include <Types.h>
16#include "linux_type_defs.h"
17#endif
18
19#ifdef macintosh
20/* All this requires PowerPC alignment */
21#pragma options align=power
22#endif
23
24/* On kernel entry:
25 *
26 * r3 = 0x426f6f58 ('BooX')
27 * r4 = pointer to boot_infos
28 * r5 = NULL
29 *
30 * Data and instruction translation disabled, interrupts
31 * disabled, kernel loaded at physical 0x00000000 on PCI
32 * machines (will be different on NuBus).
33 */
34
35#define BOOT_INFO_VERSION 5
36#define BOOT_INFO_COMPATIBLE_VERSION 1
37
38/* Bit in the architecture flag mask. More to be defined in
39 future versions. Note that either BOOT_ARCH_PCI or
40 BOOT_ARCH_NUBUS is set. The other BOOT_ARCH_NUBUS_xxx are
41 set additionally when BOOT_ARCH_NUBUS is set.
42 */
43#define BOOT_ARCH_PCI 0x00000001UL
44#define BOOT_ARCH_NUBUS 0x00000002UL
45#define BOOT_ARCH_NUBUS_PDM 0x00000010UL
46#define BOOT_ARCH_NUBUS_PERFORMA 0x00000020UL
47#define BOOT_ARCH_NUBUS_POWERBOOK 0x00000040UL
48
49/* Maximum number of ranges in phys memory map */
50#define MAX_MEM_MAP_SIZE 26
51
52/* This is the format of an element in the physical memory map. Note that
53 the map is optional and current BootX will only build it for pre-PCI
54 machines */
55typedef struct boot_info_map_entry
56{
57 __u32 physAddr; /* Physical starting address */
58 __u32 size; /* Size in bytes */
59} boot_info_map_entry_t;
60
61
62/* Here are the boot informations that are passed to the bootstrap
63 * Note that the kernel arguments and the device tree are appended
64 * at the end of this structure. */
65typedef struct boot_infos
66{
67 /* Version of this structure */
68 __u32 version;
69 /* backward compatible down to version: */
70 __u32 compatible_version;
71
72 /* NEW (vers. 2) this holds the current _logical_ base addr of
73 the frame buffer (for use by early boot message) */
74 __u8* logicalDisplayBase;
75
76 /* NEW (vers. 4) Apple's machine identification */
77 __u32 machineID;
78
79 /* NEW (vers. 4) Detected hw architecture */
80 __u32 architecture;
81
82 /* The device tree (internal addresses relative to the beginning of the tree,
83 * device tree offset relative to the beginning of this structure).
84 * On pre-PCI macintosh (BOOT_ARCH_PCI bit set to 0 in architecture), this
85 * field is 0.
86 */
87 __u32 deviceTreeOffset; /* Device tree offset */
88 __u32 deviceTreeSize; /* Size of the device tree */
89
90 /* Some infos about the current MacOS display */
91 __u32 dispDeviceRect[4]; /* left,top,right,bottom */
92 __u32 dispDeviceDepth; /* (8, 16 or 32) */
93 __u8* dispDeviceBase; /* base address (physical) */
94 __u32 dispDeviceRowBytes; /* rowbytes (in bytes) */
95 __u32 dispDeviceColorsOffset; /* Colormap (8 bits only) or 0 (*) */
96 /* Optional offset in the registry to the current
97 * MacOS display. (Can be 0 when not detected) */
98 __u32 dispDeviceRegEntryOffset;
99
100 /* Optional pointer to boot ramdisk (offset from this structure) */
101 __u32 ramDisk;
102 __u32 ramDiskSize; /* size of ramdisk image */
103
104 /* Kernel command line arguments (offset from this structure) */
105 __u32 kernelParamsOffset;
106
107 /* ALL BELOW NEW (vers. 4) */
108
109 /* This defines the physical memory. Valid with BOOT_ARCH_NUBUS flag
110 (non-PCI) only. On PCI, memory is contiguous and it's size is in the
111 device-tree. */
112 boot_info_map_entry_t
113 physMemoryMap[MAX_MEM_MAP_SIZE]; /* Where the phys memory is */
114 __u32 physMemoryMapSize; /* How many entries in map */
115
116
117 /* The framebuffer size (optional, currently 0) */
118 __u32 frameBufferSize; /* Represents a max size, can be 0. */
119
120 /* NEW (vers. 5) */
121
122 /* Total params size (args + colormap + device tree + ramdisk) */
123 __u32 totalParamsSize;
124
125} boot_infos_t;
126
127#ifdef __KERNEL__
128/* (*) The format of the colormap is 256 * 3 * 2 bytes. Each color index
129 * is represented by 3 short words containing a 16 bits (unsigned) color
130 * component. Later versions may contain the gamma table for direct-color
131 * devices here.
132 */
133#define BOOTX_COLORTABLE_SIZE (256UL*3UL*2UL)
134
135/* BootX passes the device-tree using a format that comes from earlier
136 * ppc32 kernels. This used to match what is in prom.h, but not anymore
137 * so we now define it here
138 */
139struct bootx_dt_prop {
140 u32 name;
141 int length;
142 u32 value;
143 u32 next;
144};
145
146struct bootx_dt_node {
147 u32 unused0;
148 u32 unused1;
149 u32 phandle; /* not really available */
150 u32 unused2;
151 u32 unused3;
152 u32 unused4;
153 u32 unused5;
154 u32 full_name;
155 u32 properties;
156 u32 parent;
157 u32 child;
158 u32 sibling;
159 u32 next;
160 u32 allnext;
161};
162
163extern void bootx_init(unsigned long r4, unsigned long phys);
164
165#endif /* __KERNEL__ */
166
167#ifdef macintosh
168#pragma options align=reset
169#endif
170
171#endif
diff --git a/include/asm-powerpc/btext.h b/include/asm-powerpc/btext.h
index 71cce36bc630..906f46e31006 100644
--- a/include/asm-powerpc/btext.h
+++ b/include/asm-powerpc/btext.h
@@ -7,21 +7,22 @@
7#define __PPC_BTEXT_H 7#define __PPC_BTEXT_H
8#ifdef __KERNEL__ 8#ifdef __KERNEL__
9 9
10extern void btext_clearscreen(void); 10extern int btext_find_display(int allow_nonstdout);
11extern void btext_flushscreen(void);
12
13extern int boot_text_mapped;
14
15extern int btext_initialize(struct device_node *np);
16
17extern void map_boot_text(void);
18extern void init_boot_display(void);
19extern void btext_update_display(unsigned long phys, int width, int height, 11extern void btext_update_display(unsigned long phys, int width, int height,
20 int depth, int pitch); 12 int depth, int pitch);
13extern void btext_setup_display(int width, int height, int depth, int pitch,
14 unsigned long address);
15extern void btext_prepare_BAT(void);
16extern void btext_unmap(void);
21 17
22extern void btext_drawchar(char c); 18extern void btext_drawchar(char c);
23extern void btext_drawstring(const char *str); 19extern void btext_drawstring(const char *str);
24extern void btext_drawhex(unsigned long v); 20extern void btext_drawhex(unsigned long v);
21extern void btext_drawtext(const char *c, unsigned int len);
22
23extern void btext_clearscreen(void);
24extern void btext_flushscreen(void);
25extern void btext_flushline(void);
25 26
26#endif /* __KERNEL__ */ 27#endif /* __KERNEL__ */
27#endif /* __PPC_BTEXT_H */ 28#endif /* __PPC_BTEXT_H */
diff --git a/include/asm-powerpc/bug.h b/include/asm-powerpc/bug.h
index b001ecb3cd99..99817a802ca4 100644
--- a/include/asm-powerpc/bug.h
+++ b/include/asm-powerpc/bug.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_BUG_H 1#ifndef _ASM_POWERPC_BUG_H
2#define _ASM_POWERPC_BUG_H 2#define _ASM_POWERPC_BUG_H
3#ifdef __KERNEL__
3 4
4#include <asm/asm-compat.h> 5#include <asm/asm-compat.h>
5/* 6/*
@@ -67,4 +68,5 @@ struct bug_entry *find_bug(unsigned long bugaddr);
67 68
68#include <asm-generic/bug.h> 69#include <asm-generic/bug.h>
69 70
71#endif /* __KERNEL__ */
70#endif /* _ASM_POWERPC_BUG_H */ 72#endif /* _ASM_POWERPC_BUG_H */
diff --git a/include/asm-powerpc/cache.h b/include/asm-powerpc/cache.h
index 26ce502e76e8..6379c2df5c40 100644
--- a/include/asm-powerpc/cache.h
+++ b/include/asm-powerpc/cache.h
@@ -19,7 +19,6 @@
19#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) 19#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
20 20
21#define SMP_CACHE_BYTES L1_CACHE_BYTES 21#define SMP_CACHE_BYTES L1_CACHE_BYTES
22#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
23 22
24#if defined(__powerpc64__) && !defined(__ASSEMBLY__) 23#if defined(__powerpc64__) && !defined(__ASSEMBLY__)
25struct ppc64_caches { 24struct ppc64_caches {
diff --git a/include/asm-powerpc/checksum.h b/include/asm-powerpc/checksum.h
index d8354d8a49ce..609ecbbd7210 100644
--- a/include/asm-powerpc/checksum.h
+++ b/include/asm-powerpc/checksum.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_CHECKSUM_H 1#ifndef _ASM_POWERPC_CHECKSUM_H
2#define _ASM_POWERPC_CHECKSUM_H 2#define _ASM_POWERPC_CHECKSUM_H
3#ifdef __KERNEL__
3 4
4/* 5/*
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -129,4 +130,5 @@ static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
129} 130}
130 131
131#endif 132#endif
133#endif /* __KERNEL__ */
132#endif 134#endif
diff --git a/include/asm-powerpc/compat.h b/include/asm-powerpc/compat.h
index 4db4360c4d4a..accb80c9a339 100644
--- a/include/asm-powerpc/compat.h
+++ b/include/asm-powerpc/compat.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_COMPAT_H 1#ifndef _ASM_POWERPC_COMPAT_H
2#define _ASM_POWERPC_COMPAT_H 2#define _ASM_POWERPC_COMPAT_H
3#ifdef __KERNEL__
3/* 4/*
4 * Architecture specific compatibility types 5 * Architecture specific compatibility types
5 */ 6 */
@@ -202,4 +203,5 @@ struct compat_shmid64_ds {
202 compat_ulong_t __unused6; 203 compat_ulong_t __unused6;
203}; 204};
204 205
206#endif /* __KERNEL__ */
205#endif /* _ASM_POWERPC_COMPAT_H */ 207#endif /* _ASM_POWERPC_COMPAT_H */
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index d1cfa3f515ea..ef6ead34a773 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_POWERPC_CPUTABLE_H 1#ifndef __ASM_POWERPC_CPUTABLE_H
2#define __ASM_POWERPC_CPUTABLE_H 2#define __ASM_POWERPC_CPUTABLE_H
3 3
4#include <linux/config.h>
5#include <asm/asm-compat.h> 4#include <asm/asm-compat.h>
6 5
7#define PPC_FEATURE_32 0x80000000 6#define PPC_FEATURE_32 0x80000000
@@ -28,10 +27,17 @@
28 * via the mkdefs mechanism. 27 * via the mkdefs mechanism.
29 */ 28 */
30struct cpu_spec; 29struct cpu_spec;
31struct op_powerpc_model;
32 30
33typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec); 31typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec);
34 32
33enum powerpc_oprofile_type {
34 INVALID = 0,
35 RS64 = 1,
36 POWER4 = 2,
37 G4 = 3,
38 BOOKE = 4,
39};
40
35struct cpu_spec { 41struct cpu_spec {
36 /* CPU is matched via (PVR & pvr_mask) == pvr_value */ 42 /* CPU is matched via (PVR & pvr_mask) == pvr_value */
37 unsigned int pvr_mask; 43 unsigned int pvr_mask;
@@ -57,7 +63,7 @@ struct cpu_spec {
57 char *oprofile_cpu_type; 63 char *oprofile_cpu_type;
58 64
59 /* Processor specific oprofile operations */ 65 /* Processor specific oprofile operations */
60 struct op_powerpc_model *oprofile_model; 66 enum powerpc_oprofile_type oprofile_type;
61}; 67};
62 68
63extern struct cpu_spec *cur_cpu_spec; 69extern struct cpu_spec *cur_cpu_spec;
@@ -106,6 +112,7 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
106#define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0000040000000000) 112#define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0000040000000000)
107#define CPU_FTR_MMCRA_SIHV ASM_CONST(0x0000080000000000) 113#define CPU_FTR_MMCRA_SIHV ASM_CONST(0x0000080000000000)
108#define CPU_FTR_CI_LARGE_PAGE ASM_CONST(0x0000100000000000) 114#define CPU_FTR_CI_LARGE_PAGE ASM_CONST(0x0000100000000000)
115#define CPU_FTR_PAUSE_ZERO ASM_CONST(0x0000200000000000)
109#else 116#else
110/* ensure on 32b processors the flags are available for compiling but 117/* ensure on 32b processors the flags are available for compiling but
111 * don't do anything */ 118 * don't do anything */
@@ -305,12 +312,18 @@ enum {
305 CPU_FTR_MMCRA_SIHV, 312 CPU_FTR_MMCRA_SIHV,
306 CPU_FTRS_CELL = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | 313 CPU_FTRS_CELL = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
307 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | 314 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 |
308 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT, 315 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT |
316 CPU_FTR_CTRL | CPU_FTR_PAUSE_ZERO,
309 CPU_FTRS_COMPATIBLE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | 317 CPU_FTRS_COMPATIBLE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
310 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2, 318 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2,
311#endif 319#endif
312 320
313 CPU_FTRS_POSSIBLE = 321 CPU_FTRS_POSSIBLE =
322#ifdef __powerpc64__
323 CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 |
324 CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_CELL |
325 CPU_FTR_CI_LARGE_PAGE |
326#else
314#if CLASSIC_PPC 327#if CLASSIC_PPC
315 CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU | 328 CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU |
316 CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 | 329 CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 |
@@ -344,14 +357,14 @@ enum {
344#ifdef CONFIG_E500 357#ifdef CONFIG_E500
345 CPU_FTRS_E500 | CPU_FTRS_E500_2 | 358 CPU_FTRS_E500 | CPU_FTRS_E500_2 |
346#endif 359#endif
347#ifdef __powerpc64__ 360#endif /* __powerpc64__ */
348 CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 |
349 CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_CELL |
350 CPU_FTR_CI_LARGE_PAGE |
351#endif
352 0, 361 0,
353 362
354 CPU_FTRS_ALWAYS = 363 CPU_FTRS_ALWAYS =
364#ifdef __powerpc64__
365 CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 &
366 CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_CELL &
367#else
355#if CLASSIC_PPC 368#if CLASSIC_PPC
356 CPU_FTRS_PPC601 & CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU & 369 CPU_FTRS_PPC601 & CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU &
357 CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 & 370 CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 &
@@ -385,10 +398,7 @@ enum {
385#ifdef CONFIG_E500 398#ifdef CONFIG_E500
386 CPU_FTRS_E500 & CPU_FTRS_E500_2 & 399 CPU_FTRS_E500 & CPU_FTRS_E500_2 &
387#endif 400#endif
388#ifdef __powerpc64__ 401#endif /* __powerpc64__ */
389 CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 &
390 CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_CELL &
391#endif
392 CPU_FTRS_POSSIBLE, 402 CPU_FTRS_POSSIBLE,
393}; 403};
394 404
diff --git a/include/asm-powerpc/current.h b/include/asm-powerpc/current.h
index 82cd4a9ca99a..1938d6abd255 100644
--- a/include/asm-powerpc/current.h
+++ b/include/asm-powerpc/current.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_CURRENT_H 1#ifndef _ASM_POWERPC_CURRENT_H
2#define _ASM_POWERPC_CURRENT_H 2#define _ASM_POWERPC_CURRENT_H
3#ifdef __KERNEL__
3 4
4/* 5/*
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -24,4 +25,5 @@ register struct task_struct *current asm ("r2");
24 25
25#endif 26#endif
26 27
28#endif /* __KERNEL__ */
27#endif /* _ASM_POWERPC_CURRENT_H */ 29#endif /* _ASM_POWERPC_CURRENT_H */
diff --git a/include/asm-powerpc/delay.h b/include/asm-powerpc/delay.h
index 54fe1f4f8fd0..057a60955474 100644
--- a/include/asm-powerpc/delay.h
+++ b/include/asm-powerpc/delay.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_DELAY_H 1#ifndef _ASM_POWERPC_DELAY_H
2#define _ASM_POWERPC_DELAY_H 2#define _ASM_POWERPC_DELAY_H
3#ifdef __KERNEL__
3 4
4/* 5/*
5 * Copyright 1996, Paul Mackerras. 6 * Copyright 1996, Paul Mackerras.
@@ -16,4 +17,5 @@
16extern void __delay(unsigned long loops); 17extern void __delay(unsigned long loops);
17extern void udelay(unsigned long usecs); 18extern void udelay(unsigned long usecs);
18 19
20#endif /* __KERNEL__ */
19#endif /* _ASM_POWERPC_DELAY_H */ 21#endif /* _ASM_POWERPC_DELAY_H */
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 59a80163f75f..837756ab7dc7 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -6,6 +6,7 @@
6 */ 6 */
7#ifndef _ASM_DMA_MAPPING_H 7#ifndef _ASM_DMA_MAPPING_H
8#define _ASM_DMA_MAPPING_H 8#define _ASM_DMA_MAPPING_H
9#ifdef __KERNEL__
9 10
10#include <linux/config.h> 11#include <linux/config.h>
11#include <linux/types.h> 12#include <linux/types.h>
@@ -229,7 +230,7 @@ static inline int dma_get_cache_alignment(void)
229#ifdef CONFIG_PPC64 230#ifdef CONFIG_PPC64
230 /* no easy way to get cache size on all processors, so return 231 /* no easy way to get cache size on all processors, so return
231 * the maximum possible, to be safe */ 232 * the maximum possible, to be safe */
232 return (1 << L1_CACHE_SHIFT_MAX); 233 return (1 << INTERNODE_CACHE_SHIFT);
233#else 234#else
234 /* 235 /*
235 * Each processor family will define its own L1_CACHE_SHIFT, 236 * Each processor family will define its own L1_CACHE_SHIFT,
@@ -282,4 +283,5 @@ struct dma_mapping_ops {
282 int (*dac_dma_supported)(struct device *dev, u64 mask); 283 int (*dac_dma_supported)(struct device *dev, u64 mask);
283}; 284};
284 285
286#endif /* __KERNEL__ */
285#endif /* _ASM_DMA_MAPPING_H */ 287#endif /* _ASM_DMA_MAPPING_H */
diff --git a/include/asm-powerpc/dma.h b/include/asm-powerpc/dma.h
index 926378d2cd94..4bb57fe37097 100644
--- a/include/asm-powerpc/dma.h
+++ b/include/asm-powerpc/dma.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_DMA_H 1#ifndef _ASM_POWERPC_DMA_H
2#define _ASM_POWERPC_DMA_H 2#define _ASM_POWERPC_DMA_H
3#ifdef __KERNEL__
3 4
4/* 5/*
5 * Defines for using and allocating dma channels. 6 * Defines for using and allocating dma channels.
@@ -387,4 +388,5 @@ extern int isa_dma_bridge_buggy;
387 388
388#endif /* !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) */ 389#endif /* !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) */
389 390
391#endif /* __KERNEL__ */
390#endif /* _ASM_POWERPC_DMA_H */ 392#endif /* _ASM_POWERPC_DMA_H */
diff --git a/include/asm-powerpc/eeh.h b/include/asm-powerpc/eeh.h
index f8633aafe4ba..4395b7bc1ed4 100644
--- a/include/asm-powerpc/eeh.h
+++ b/include/asm-powerpc/eeh.h
@@ -19,6 +19,7 @@
19 19
20#ifndef _PPC64_EEH_H 20#ifndef _PPC64_EEH_H
21#define _PPC64_EEH_H 21#define _PPC64_EEH_H
22#ifdef __KERNEL__
22 23
23#include <linux/config.h> 24#include <linux/config.h>
24#include <linux/init.h> 25#include <linux/init.h>
@@ -57,6 +58,7 @@ void __init pci_addr_cache_build(void);
57 * to finish the eeh setup for this device. 58 * to finish the eeh setup for this device.
58 */ 59 */
59void eeh_add_device_early(struct device_node *); 60void eeh_add_device_early(struct device_node *);
61void eeh_add_device_tree_early(struct device_node *);
60void eeh_add_device_late(struct pci_dev *); 62void eeh_add_device_late(struct pci_dev *);
61 63
62/** 64/**
@@ -72,6 +74,15 @@ void eeh_add_device_late(struct pci_dev *);
72void eeh_remove_device(struct pci_dev *); 74void eeh_remove_device(struct pci_dev *);
73 75
74/** 76/**
77 * eeh_remove_device_recursive - undo EEH for device & children.
78 * @dev: pci device to be removed
79 *
80 * As above, this removes the device; it also removes child
81 * pci devices as well.
82 */
83void eeh_remove_bus_device(struct pci_dev *);
84
85/**
75 * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. 86 * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
76 * 87 *
77 * If this macro yields TRUE, the caller relays to eeh_check_failure() 88 * If this macro yields TRUE, the caller relays to eeh_check_failure()
@@ -107,6 +118,9 @@ static inline void eeh_add_device_late(struct pci_dev *dev) { }
107 118
108static inline void eeh_remove_device(struct pci_dev *dev) { } 119static inline void eeh_remove_device(struct pci_dev *dev) { }
109 120
121static inline void eeh_add_device_tree_early(struct device_node *dn) { }
122
123static inline void eeh_remove_bus_device(struct pci_dev *dev) { }
110#define EEH_POSSIBLE_ERROR(val, type) (0) 124#define EEH_POSSIBLE_ERROR(val, type) (0)
111#define EEH_IO_ERROR_VALUE(size) (-1UL) 125#define EEH_IO_ERROR_VALUE(size) (-1UL)
112#endif /* CONFIG_EEH */ 126#endif /* CONFIG_EEH */
@@ -363,4 +377,5 @@ static inline void eeh_insl_ns(unsigned long port, void * buf, int nl)
363 eeh_check_failure((void __iomem *)(port), *(u32*)buf); 377 eeh_check_failure((void __iomem *)(port), *(u32*)buf);
364} 378}
365 379
380#endif /* __KERNEL__ */
366#endif /* _PPC64_EEH_H */ 381#endif /* _PPC64_EEH_H */
diff --git a/include/asm-powerpc/eeh_event.h b/include/asm-powerpc/eeh_event.h
index d168a30b3866..5e11a00b6fa0 100644
--- a/include/asm-powerpc/eeh_event.h
+++ b/include/asm-powerpc/eeh_event.h
@@ -20,6 +20,7 @@
20 20
21#ifndef ASM_PPC64_EEH_EVENT_H 21#ifndef ASM_PPC64_EEH_EVENT_H
22#define ASM_PPC64_EEH_EVENT_H 22#define ASM_PPC64_EEH_EVENT_H
23#ifdef __KERNEL__
23 24
24/** EEH event -- structure holding pci controller data that describes 25/** EEH event -- structure holding pci controller data that describes
25 * a change in the isolation status of a PCI slot. A pointer 26 * a change in the isolation status of a PCI slot. A pointer
@@ -49,4 +50,5 @@ int eeh_send_failure_event (struct device_node *dn,
49 int reset_state, 50 int reset_state,
50 int time_unavail); 51 int time_unavail);
51 52
53#endif /* __KERNEL__ */
52#endif /* ASM_PPC64_EEH_EVENT_H */ 54#endif /* ASM_PPC64_EEH_EVENT_H */
diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
index 3dcd65edf978..c5a635d9bba4 100644
--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -1,7 +1,10 @@
1#ifndef _ASM_POWERPC_ELF_H 1#ifndef _ASM_POWERPC_ELF_H
2#define _ASM_POWERPC_ELF_H 2#define _ASM_POWERPC_ELF_H
3 3
4#ifdef __KERNEL__
4#include <linux/sched.h> /* for task_struct */ 5#include <linux/sched.h> /* for task_struct */
6#endif
7
5#include <asm/types.h> 8#include <asm/types.h>
6#include <asm/ptrace.h> 9#include <asm/ptrace.h>
7#include <asm/cputable.h> 10#include <asm/cputable.h>
diff --git a/include/asm-powerpc/firmware.h b/include/asm-powerpc/firmware.h
index 12fabbcb04f0..f804b34cf06a 100644
--- a/include/asm-powerpc/firmware.h
+++ b/include/asm-powerpc/firmware.h
@@ -98,6 +98,12 @@ typedef struct {
98extern firmware_feature_t firmware_features_table[]; 98extern firmware_feature_t firmware_features_table[];
99#endif 99#endif
100 100
101extern void system_reset_fwnmi(void);
102extern void machine_check_fwnmi(void);
103
104/* This is true if we are using the firmware NMI handler (typically LPAR) */
105extern int fwnmi_active;
106
101#endif /* __ASSEMBLY__ */ 107#endif /* __ASSEMBLY__ */
102#endif /* __KERNEL__ */ 108#endif /* __KERNEL__ */
103#endif /* __ASM_POWERPC_FIRMWARE_H */ 109#endif /* __ASM_POWERPC_FIRMWARE_H */
diff --git a/include/asm-powerpc/floppy.h b/include/asm-powerpc/floppy.h
index 64276a3f6153..e258778ca429 100644
--- a/include/asm-powerpc/floppy.h
+++ b/include/asm-powerpc/floppy.h
@@ -9,6 +9,7 @@
9 */ 9 */
10#ifndef __ASM_POWERPC_FLOPPY_H 10#ifndef __ASM_POWERPC_FLOPPY_H
11#define __ASM_POWERPC_FLOPPY_H 11#define __ASM_POWERPC_FLOPPY_H
12#ifdef __KERNEL__
12 13
13#include <linux/config.h> 14#include <linux/config.h>
14#include <asm/machdep.h> 15#include <asm/machdep.h>
@@ -102,4 +103,5 @@ static int FDC2 = -1;
102 103
103#define EXTRA_FLOPPY_PARAMS 104#define EXTRA_FLOPPY_PARAMS
104 105
106#endif /* __KERNEL__ */
105#endif /* __ASM_POWERPC_FLOPPY_H */ 107#endif /* __ASM_POWERPC_FLOPPY_H */
diff --git a/include/asm-powerpc/grackle.h b/include/asm-powerpc/grackle.h
index 563c7a5e64c9..bd7812a519d4 100644
--- a/include/asm-powerpc/grackle.h
+++ b/include/asm-powerpc/grackle.h
@@ -1,3 +1,6 @@
1#ifndef _ASM_POWERPC_GRACKLE_H
2#define _ASM_POWERPC_GRACKLE_H
3#ifdef __KERNEL__
1/* 4/*
2 * Functions for setting up and using a MPC106 northbridge 5 * Functions for setting up and using a MPC106 northbridge
3 */ 6 */
@@ -5,3 +8,5 @@
5#include <asm/pci-bridge.h> 8#include <asm/pci-bridge.h>
6 9
7extern void setup_grackle(struct pci_controller *hose); 10extern void setup_grackle(struct pci_controller *hose);
11#endif /* __KERNEL__ */
12#endif /* _ASM_POWERPC_GRACKLE_H */
diff --git a/include/asm-powerpc/hardirq.h b/include/asm-powerpc/hardirq.h
index 3b3e3b49ec12..288e14d53b7f 100644
--- a/include/asm-powerpc/hardirq.h
+++ b/include/asm-powerpc/hardirq.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_HARDIRQ_H 1#ifndef _ASM_POWERPC_HARDIRQ_H
2#define _ASM_POWERPC_HARDIRQ_H 2#define _ASM_POWERPC_HARDIRQ_H
3#ifdef __KERNEL__
3 4
4#include <asm/irq.h> 5#include <asm/irq.h>
5#include <asm/bug.h> 6#include <asm/bug.h>
@@ -24,4 +25,5 @@ static inline void ack_bad_irq(int irq)
24 BUG(); 25 BUG();
25} 26}
26 27
28#endif /* __KERNEL__ */
27#endif /* _ASM_POWERPC_HARDIRQ_H */ 29#endif /* _ASM_POWERPC_HARDIRQ_H */
diff --git a/include/asm-powerpc/heathrow.h b/include/asm-powerpc/heathrow.h
index 22ac179856b9..93f54958a9d1 100644
--- a/include/asm-powerpc/heathrow.h
+++ b/include/asm-powerpc/heathrow.h
@@ -1,3 +1,6 @@
1#ifndef _ASM_POWERPC_HEATHROW_H
2#define _ASM_POWERPC_HEATHROW_H
3#ifdef __KERNEL__
1/* 4/*
2 * heathrow.h: definitions for using the "Heathrow" I/O controller chip. 5 * heathrow.h: definitions for using the "Heathrow" I/O controller chip.
3 * 6 *
@@ -60,3 +63,5 @@
60/* Looks like Heathrow has some sort of GPIOs as well... */ 63/* Looks like Heathrow has some sort of GPIOs as well... */
61#define HRW_GPIO_MODEM_RESET 0x6d 64#define HRW_GPIO_MODEM_RESET 0x6d
62 65
66#endif /* __KERNEL__ */
67#endif /* _ASM_POWERPC_HEATHROW_H */
diff --git a/include/asm-powerpc/hvcall.h b/include/asm-powerpc/hvcall.h
index d36da61dbc53..da7af5a720e0 100644
--- a/include/asm-powerpc/hvcall.h
+++ b/include/asm-powerpc/hvcall.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_HVCALL_H 1#ifndef _ASM_POWERPC_HVCALL_H
2#define _ASM_POWERPC_HVCALL_H 2#define _ASM_POWERPC_HVCALL_H
3#ifdef __KERNEL__
3 4
4#define HVSC .long 0x44000022 5#define HVSC .long 0x44000022
5 6
@@ -170,4 +171,5 @@ long plpar_hcall_4out(unsigned long opcode,
170 unsigned long *out4); 171 unsigned long *out4);
171 172
172#endif /* __ASSEMBLY__ */ 173#endif /* __ASSEMBLY__ */
174#endif /* __KERNEL__ */
173#endif /* _ASM_POWERPC_HVCALL_H */ 175#endif /* _ASM_POWERPC_HVCALL_H */
diff --git a/include/asm-powerpc/hvconsole.h b/include/asm-powerpc/hvconsole.h
index 6da93ce74dc0..34daf7b9b62f 100644
--- a/include/asm-powerpc/hvconsole.h
+++ b/include/asm-powerpc/hvconsole.h
@@ -21,6 +21,7 @@
21 21
22#ifndef _PPC64_HVCONSOLE_H 22#ifndef _PPC64_HVCONSOLE_H
23#define _PPC64_HVCONSOLE_H 23#define _PPC64_HVCONSOLE_H
24#ifdef __KERNEL__
24 25
25/* 26/*
26 * This is the max number of console adapters that can/will be found as 27 * This is the max number of console adapters that can/will be found as
@@ -46,4 +47,5 @@ extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
46 struct hv_ops *ops); 47 struct hv_ops *ops);
47/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ 48/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
48extern int __devexit hvc_remove(struct hvc_struct *hp); 49extern int __devexit hvc_remove(struct hvc_struct *hp);
50#endif /* __KERNEL__ */
49#endif /* _PPC64_HVCONSOLE_H */ 51#endif /* _PPC64_HVCONSOLE_H */
diff --git a/include/asm-powerpc/hvcserver.h b/include/asm-powerpc/hvcserver.h
index aecba9665796..67d7da3a4da4 100644
--- a/include/asm-powerpc/hvcserver.h
+++ b/include/asm-powerpc/hvcserver.h
@@ -21,6 +21,7 @@
21 21
22#ifndef _PPC64_HVCSERVER_H 22#ifndef _PPC64_HVCSERVER_H
23#define _PPC64_HVCSERVER_H 23#define _PPC64_HVCSERVER_H
24#ifdef __KERNEL__
24 25
25#include <linux/list.h> 26#include <linux/list.h>
26 27
@@ -54,4 +55,5 @@ extern int hvcs_register_connection(uint32_t unit_address,
54 uint32_t p_partition_ID, uint32_t p_unit_address); 55 uint32_t p_partition_ID, uint32_t p_unit_address);
55extern int hvcs_free_connection(uint32_t unit_address); 56extern int hvcs_free_connection(uint32_t unit_address);
56 57
58#endif /* __KERNEL__ */
57#endif /* _PPC64_HVCSERVER_H */ 59#endif /* _PPC64_HVCSERVER_H */
diff --git a/include/asm-powerpc/i8259.h b/include/asm-powerpc/i8259.h
index fc4bfee124d7..0392159e16e4 100644
--- a/include/asm-powerpc/i8259.h
+++ b/include/asm-powerpc/i8259.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_I8259_H 1#ifndef _ASM_POWERPC_I8259_H
2#define _ASM_POWERPC_I8259_H 2#define _ASM_POWERPC_I8259_H
3#ifdef __KERNEL__
3 4
4#include <linux/irq.h> 5#include <linux/irq.h>
5 6
@@ -9,4 +10,5 @@ extern void i8259_init(unsigned long intack_addr, int offset);
9extern int i8259_irq(struct pt_regs *regs); 10extern int i8259_irq(struct pt_regs *regs);
10extern int i8259_irq_cascade(struct pt_regs *regs, void *unused); 11extern int i8259_irq_cascade(struct pt_regs *regs, void *unused);
11 12
13#endif /* __KERNEL__ */
12#endif /* _ASM_POWERPC_I8259_H */ 14#endif /* _ASM_POWERPC_I8259_H */
diff --git a/include/asm-powerpc/ibmebus.h b/include/asm-powerpc/ibmebus.h
new file mode 100644
index 000000000000..7a42723d107c
--- /dev/null
+++ b/include/asm-powerpc/ibmebus.h
@@ -0,0 +1,85 @@
1/*
2 * IBM PowerPC eBus Infrastructure Support.
3 *
4 * Copyright (c) 2005 IBM Corporation
5 * Heiko J Schick <schickhj@de.ibm.com>
6 *
7 * All rights reserved.
8 *
9 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
10 * BSD.
11 *
12 * OpenIB BSD License
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are met:
16 *
17 * Redistributions of source code must retain the above copyright notice, this
18 * list of conditions and the following disclaimer.
19 *
20 * Redistributions in binary form must reproduce the above copyright notice,
21 * this list of conditions and the following disclaimer in the documentation
22 * and/or other materials
23 * provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
32 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
33 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifndef _ASM_EBUS_H
39#define _ASM_EBUS_H
40#ifdef __KERNEL__
41
42#include <linux/device.h>
43#include <linux/interrupt.h>
44#include <linux/mod_devicetable.h>
45#include <asm/of_device.h>
46
47extern struct dma_mapping_ops ibmebus_dma_ops;
48extern struct bus_type ibmebus_bus_type;
49
50struct ibmebus_dev {
51 char *name;
52 struct of_device ofdev;
53};
54
55struct ibmebus_driver {
56 char *name;
57 struct of_device_id *id_table;
58 int (*probe) (struct ibmebus_dev *dev, const struct of_device_id *id);
59 int (*remove) (struct ibmebus_dev *dev);
60 struct device_driver driver;
61};
62
63int ibmebus_register_driver(struct ibmebus_driver *drv);
64void ibmebus_unregister_driver(struct ibmebus_driver *drv);
65
66int ibmebus_request_irq(struct ibmebus_dev *dev,
67 u32 ist,
68 irqreturn_t (*handler)(int, void*, struct pt_regs *),
69 unsigned long irq_flags, const char * devname,
70 void *dev_id);
71void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id);
72
73static inline struct ibmebus_driver *to_ibmebus_driver(struct device_driver *drv)
74{
75 return container_of(drv, struct ibmebus_driver, driver);
76}
77
78static inline struct ibmebus_dev *to_ibmebus_dev(struct device *dev)
79{
80 return container_of(dev, struct ibmebus_dev, ofdev.dev);
81}
82
83
84#endif /* __KERNEL__ */
85#endif /* _ASM_IBMEBUS_H */
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index 48938d84d055..68efbea379c9 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_IO_H 1#ifndef _ASM_POWERPC_IO_H
2#define _ASM_POWERPC_IO_H 2#define _ASM_POWERPC_IO_H
3#ifdef __KERNEL__
3 4
4/* 5/*
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -186,7 +187,6 @@ extern void _outsl_ns(volatile u32 __iomem *port, const void *buf, int nl);
186#define IO_SPACE_LIMIT ~(0UL) 187#define IO_SPACE_LIMIT ~(0UL)
187 188
188 189
189#ifdef __KERNEL__
190extern int __ioremap_explicit(unsigned long p_addr, unsigned long v_addr, 190extern int __ioremap_explicit(unsigned long p_addr, unsigned long v_addr,
191 unsigned long size, unsigned long flags); 191 unsigned long size, unsigned long flags);
192extern void __iomem *__ioremap(unsigned long address, unsigned long size, 192extern void __iomem *__ioremap(unsigned long address, unsigned long size,
@@ -256,8 +256,6 @@ static inline void * phys_to_virt(unsigned long address)
256 */ 256 */
257#define BIO_VMERGE_BOUNDARY 0 257#define BIO_VMERGE_BOUNDARY 0
258 258
259#endif /* __KERNEL__ */
260
261static inline void iosync(void) 259static inline void iosync(void)
262{ 260{
263 __asm__ __volatile__ ("sync" : : : "memory"); 261 __asm__ __volatile__ ("sync" : : : "memory");
@@ -405,8 +403,6 @@ static inline void out_be64(volatile unsigned long __iomem *addr, unsigned long
405#include <asm/eeh.h> 403#include <asm/eeh.h>
406#endif 404#endif
407 405
408#ifdef __KERNEL__
409
410/** 406/**
411 * check_signature - find BIOS signatures 407 * check_signature - find BIOS signatures
412 * @io_addr: mmio address to check 408 * @io_addr: mmio address to check
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index f89f06050893..8a8393e50774 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -20,6 +20,7 @@
20 20
21#ifndef _ASM_IOMMU_H 21#ifndef _ASM_IOMMU_H
22#define _ASM_IOMMU_H 22#define _ASM_IOMMU_H
23#ifdef __KERNEL__
23 24
24#include <linux/config.h> 25#include <linux/config.h>
25#include <asm/types.h> 26#include <asm/types.h>
@@ -56,7 +57,7 @@ struct device_node;
56 57
57/* Walks all buses and creates iommu tables */ 58/* Walks all buses and creates iommu tables */
58extern void iommu_setup_pSeries(void); 59extern void iommu_setup_pSeries(void);
59extern void iommu_setup_u3(void); 60extern void iommu_setup_dart(void);
60 61
61/* Frees table for an individual device node */ 62/* Frees table for an individual device node */
62extern void iommu_free_table(struct device_node *dn); 63extern void iommu_free_table(struct device_node *dn);
@@ -104,7 +105,7 @@ extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
104 105
105extern void iommu_init_early_pSeries(void); 106extern void iommu_init_early_pSeries(void);
106extern void iommu_init_early_iSeries(void); 107extern void iommu_init_early_iSeries(void);
107extern void iommu_init_early_u3(void); 108extern void iommu_init_early_dart(void);
108 109
109#ifdef CONFIG_PCI 110#ifdef CONFIG_PCI
110extern void pci_iommu_init(void); 111extern void pci_iommu_init(void);
@@ -113,6 +114,7 @@ extern void pci_direct_iommu_init(void);
113static inline void pci_iommu_init(void) { } 114static inline void pci_iommu_init(void) { }
114#endif 115#endif
115 116
116extern void alloc_u3_dart_table(void); 117extern void alloc_dart_table(void);
117 118
119#endif /* __KERNEL__ */
118#endif /* _ASM_IOMMU_H */ 120#endif /* _ASM_IOMMU_H */
diff --git a/include/asm-ppc/ipic.h b/include/asm-powerpc/ipic.h
index 0fe396a2b666..0fe396a2b666 100644
--- a/include/asm-ppc/ipic.h
+++ b/include/asm-powerpc/ipic.h
diff --git a/include/asm-powerpc/iseries/it_lp_reg_save.h b/include/asm-powerpc/iseries/it_lp_reg_save.h
index 288044b702de..81824e1bb767 100644
--- a/include/asm-powerpc/iseries/it_lp_reg_save.h
+++ b/include/asm-powerpc/iseries/it_lp_reg_save.h
@@ -81,4 +81,6 @@ struct ItLpRegSave {
81 u8 xRsvd3[176]; // Reserved 350-3FF 81 u8 xRsvd3[176]; // Reserved 350-3FF
82}; 82};
83 83
84extern struct ItLpRegSave iseries_reg_save[];
85
84#endif /* _ITLPREGSAVE_H */ 86#endif /* _ITLPREGSAVE_H */
diff --git a/include/asm-powerpc/kdebug.h b/include/asm-powerpc/kdebug.h
index 9dcbac674811..7c16265568e0 100644
--- a/include/asm-powerpc/kdebug.h
+++ b/include/asm-powerpc/kdebug.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_KDEBUG_H 1#ifndef _ASM_POWERPC_KDEBUG_H
2#define _ASM_POWERPC_KDEBUG_H 2#define _ASM_POWERPC_KDEBUG_H
3#ifdef __KERNEL__
3 4
4/* nearly identical to x86_64/i386 code */ 5/* nearly identical to x86_64/i386 code */
5 6
@@ -39,4 +40,5 @@ static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,lon
39 return notifier_call_chain(&powerpc_die_chain, val, &args); 40 return notifier_call_chain(&powerpc_die_chain, val, &args);
40} 41}
41 42
43#endif /* __KERNEL__ */
42#endif /* _ASM_POWERPC_KDEBUG_H */ 44#endif /* _ASM_POWERPC_KDEBUG_H */
diff --git a/include/asm-powerpc/kdump.h b/include/asm-powerpc/kdump.h
new file mode 100644
index 000000000000..a87aed00d61f
--- /dev/null
+++ b/include/asm-powerpc/kdump.h
@@ -0,0 +1,13 @@
1#ifndef _PPC64_KDUMP_H
2#define _PPC64_KDUMP_H
3
4/* How many bytes to reserve at zero for kdump. The reserve limit should
5 * be greater or equal to the trampoline's end address. */
6#define KDUMP_RESERVE_LIMIT 0x8000
7
8#define KDUMP_TRAMPOLINE_START 0x0100
9#define KDUMP_TRAMPOLINE_END 0x3000
10
11extern void kdump_setup(void);
12
13#endif /* __PPC64_KDUMP_H */
diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h
index c72ffc709ea8..4263af3cadfd 100644
--- a/include/asm-powerpc/kexec.h
+++ b/include/asm-powerpc/kexec.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_KEXEC_H 1#ifndef _ASM_POWERPC_KEXEC_H
2#define _ASM_POWERPC_KEXEC_H 2#define _ASM_POWERPC_KEXEC_H
3#ifdef __KERNEL__
3 4
4/* 5/*
5 * Maximum page that is mapped directly into kernel memory. 6 * Maximum page that is mapped directly into kernel memory.
@@ -30,8 +31,12 @@
30#define KEXEC_ARCH KEXEC_ARCH_PPC 31#define KEXEC_ARCH KEXEC_ARCH_PPC
31#endif 32#endif
32 33
34#define HAVE_ARCH_COPY_OLDMEM_PAGE
35
33#ifndef __ASSEMBLY__ 36#ifndef __ASSEMBLY__
34 37
38#ifdef CONFIG_KEXEC
39
35#define MAX_NOTE_BYTES 1024 40#define MAX_NOTE_BYTES 1024
36typedef u32 note_buf_t[MAX_NOTE_BYTES / sizeof(u32)]; 41typedef u32 note_buf_t[MAX_NOTE_BYTES / sizeof(u32)];
37 42
@@ -41,10 +46,18 @@ extern note_buf_t crash_notes[];
41extern void kexec_smp_wait(void); /* get and clear naca physid, wait for 46extern void kexec_smp_wait(void); /* get and clear naca physid, wait for
42 master to copy new code to 0 */ 47 master to copy new code to 0 */
43extern void __init kexec_setup(void); 48extern void __init kexec_setup(void);
44#else 49extern int crashing_cpu;
50extern void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *));
51#endif /* __powerpc64 __ */
52
45struct kimage; 53struct kimage;
46extern void machine_kexec_simple(struct kimage *image); 54struct pt_regs;
47#endif 55extern void default_machine_kexec(struct kimage *image);
56extern int default_machine_kexec_prepare(struct kimage *image);
57extern void default_machine_crash_shutdown(struct pt_regs *regs);
58
59#endif /* !CONFIG_KEXEC */
48 60
49#endif /* ! __ASSEMBLY__ */ 61#endif /* ! __ASSEMBLY__ */
62#endif /* __KERNEL__ */
50#endif /* _ASM_POWERPC_KEXEC_H */ 63#endif /* _ASM_POWERPC_KEXEC_H */
diff --git a/include/asm-powerpc/keylargo.h b/include/asm-powerpc/keylargo.h
index a669a3f0f5a2..d8520ef121f9 100644
--- a/include/asm-powerpc/keylargo.h
+++ b/include/asm-powerpc/keylargo.h
@@ -1,3 +1,6 @@
1#ifndef _ASM_POWERPC_KEYLARGO_H
2#define _ASM_POWERPC_KEYLARGO_H
3#ifdef __KERNEL__
1/* 4/*
2 * keylargo.h: definitions for using the "KeyLargo" I/O controller chip. 5 * keylargo.h: definitions for using the "KeyLargo" I/O controller chip.
3 * 6 *
@@ -232,10 +235,12 @@
232#define K2_FCR1_I2S0_RESET 0x00000800 235#define K2_FCR1_I2S0_RESET 0x00000800
233#define K2_FCR1_I2S0_CLK_ENABLE_BIT 0x00001000 236#define K2_FCR1_I2S0_CLK_ENABLE_BIT 0x00001000
234#define K2_FCR1_I2S0_ENABLE 0x00002000 237#define K2_FCR1_I2S0_ENABLE 0x00002000
235
236#define K2_FCR1_PCI1_CLK_ENABLE 0x00004000 238#define K2_FCR1_PCI1_CLK_ENABLE 0x00004000
237#define K2_FCR1_FW_CLK_ENABLE 0x00008000 239#define K2_FCR1_FW_CLK_ENABLE 0x00008000
238#define K2_FCR1_FW_RESET_N 0x00010000 240#define K2_FCR1_FW_RESET_N 0x00010000
241#define K2_FCR1_I2S1_CELL_ENABLE 0x00020000
242#define K2_FCR1_I2S1_CLK_ENABLE_BIT 0x00080000
243#define K2_FCR1_I2S1_ENABLE 0x00100000
239#define K2_FCR1_GMAC_CLK_ENABLE 0x00400000 244#define K2_FCR1_GMAC_CLK_ENABLE 0x00400000
240#define K2_FCR1_GMAC_POWER_DOWN 0x00800000 245#define K2_FCR1_GMAC_POWER_DOWN 0x00800000
241#define K2_FCR1_GMAC_RESET_N 0x01000000 246#define K2_FCR1_GMAC_RESET_N 0x01000000
@@ -246,3 +251,11 @@
246#define K2_FCR1_UATA_RESET_N 0x40000000 251#define K2_FCR1_UATA_RESET_N 0x40000000
247#define K2_FCR1_UATA_CHOOSE_CLK66 0x80000000 252#define K2_FCR1_UATA_CHOOSE_CLK66 0x80000000
248 253
254/* Shasta definitions */
255#define SH_FCR1_I2S2_CELL_ENABLE 0x00000010
256#define SH_FCR1_I2S2_CLK_ENABLE_BIT 0x00000040
257#define SH_FCR1_I2S2_ENABLE 0x00000080
258#define SH_FCR3_I2S2_CLK18_ENABLE 0x00008000
259
260#endif /* __KERNEL__ */
261#endif /* _ASM_POWERPC_KEYLARGO_H */
diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h
index 6cd0a3bfa280..0654f79b06df 100644
--- a/include/asm-powerpc/kprobes.h
+++ b/include/asm-powerpc/kprobes.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_KPROBES_H 1#ifndef _ASM_POWERPC_KPROBES_H
2#define _ASM_POWERPC_KPROBES_H 2#define _ASM_POWERPC_KPROBES_H
3#ifdef __KERNEL__
3/* 4/*
4 * Kernel Probes (KProbes) 5 * Kernel Probes (KProbes)
5 * 6 *
@@ -78,4 +79,5 @@ static inline int kprobe_exceptions_notify(struct notifier_block *self,
78 return 0; 79 return 0;
79} 80}
80#endif 81#endif
82#endif /* __KERNEL__ */
81#endif /* _ASM_POWERPC_KPROBES_H */ 83#endif /* _ASM_POWERPC_KPROBES_H */
diff --git a/include/asm-powerpc/lmb.h b/include/asm-powerpc/lmb.h
index ea0afe343545..d3546c4c9f46 100644
--- a/include/asm-powerpc/lmb.h
+++ b/include/asm-powerpc/lmb.h
@@ -1,5 +1,6 @@
1#ifndef _PPC64_LMB_H 1#ifndef _PPC64_LMB_H
2#define _PPC64_LMB_H 2#define _PPC64_LMB_H
3#ifdef __KERNEL__
3 4
4/* 5/*
5 * Definitions for talking to the Open Firmware PROM on 6 * Definitions for talking to the Open Firmware PROM on
@@ -78,4 +79,5 @@ lmb_end_pfn(struct lmb_region *type, unsigned long region_nr)
78 lmb_size_pages(type, region_nr); 79 lmb_size_pages(type, region_nr);
79} 80}
80 81
82#endif /* __KERNEL__ */
81#endif /* _PPC64_LMB_H */ 83#endif /* _PPC64_LMB_H */
diff --git a/include/asm-powerpc/lppaca.h b/include/asm-powerpc/lppaca.h
index c1bedab1515b..ff82ea7c4829 100644
--- a/include/asm-powerpc/lppaca.h
+++ b/include/asm-powerpc/lppaca.h
@@ -18,6 +18,7 @@
18 */ 18 */
19#ifndef _ASM_POWERPC_LPPACA_H 19#ifndef _ASM_POWERPC_LPPACA_H
20#define _ASM_POWERPC_LPPACA_H 20#define _ASM_POWERPC_LPPACA_H
21#ifdef __KERNEL__
21 22
22//============================================================================= 23//=============================================================================
23// 24//
@@ -128,4 +129,5 @@ struct lppaca {
128 u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF 129 u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF
129}; 130};
130 131
132#endif /* __KERNEL__ */
131#endif /* _ASM_POWERPC_LPPACA_H */ 133#endif /* _ASM_POWERPC_LPPACA_H */
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index c011abb8b600..5348b820788c 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -27,6 +27,9 @@ struct device_node;
27struct iommu_table; 27struct iommu_table;
28struct rtc_time; 28struct rtc_time;
29struct file; 29struct file;
30#ifdef CONFIG_KEXEC
31struct kimage;
32#endif
30 33
31#ifdef CONFIG_SMP 34#ifdef CONFIG_SMP
32struct smp_ops_t { 35struct smp_ops_t {
@@ -131,7 +134,7 @@ struct machdep_calls {
131 void (*nvram_sync)(void); 134 void (*nvram_sync)(void);
132 135
133 /* Exception handlers */ 136 /* Exception handlers */
134 void (*system_reset_exception)(struct pt_regs *regs); 137 int (*system_reset_exception)(struct pt_regs *regs);
135 int (*machine_check_exception)(struct pt_regs *regs); 138 int (*machine_check_exception)(struct pt_regs *regs);
136 139
137 /* Motherboard/chipset features. This is a kind of general purpose 140 /* Motherboard/chipset features. This is a kind of general purpose
@@ -207,19 +210,19 @@ struct machdep_calls {
207 210
208 /* this is for modules, since _machine can be a define -- Cort */ 211 /* this is for modules, since _machine can be a define -- Cort */
209 int ppc_machine; 212 int ppc_machine;
213#endif /* CONFIG_PPC32 */
210 214
211#ifdef CONFIG_KEXEC
212 /* Called to shutdown machine specific hardware not already controlled 215 /* Called to shutdown machine specific hardware not already controlled
213 * by other drivers. 216 * by other drivers.
214 * XXX Should we move this one out of kexec scope?
215 */ 217 */
216 void (*machine_shutdown)(void); 218 void (*machine_shutdown)(void);
217 219
220#ifdef CONFIG_KEXEC
218 /* Called to do the minimal shutdown needed to run a kexec'd kernel 221 /* Called to do the minimal shutdown needed to run a kexec'd kernel
219 * to run successfully. 222 * to run successfully.
220 * XXX Should we move this one out of kexec scope? 223 * XXX Should we move this one out of kexec scope?
221 */ 224 */
222 void (*machine_crash_shutdown)(void); 225 void (*machine_crash_shutdown)(struct pt_regs *regs);
223 226
224 /* Called to do what every setup is needed on image and the 227 /* Called to do what every setup is needed on image and the
225 * reboot code buffer. Returns 0 on success. 228 * reboot code buffer. Returns 0 on success.
@@ -237,7 +240,6 @@ struct machdep_calls {
237 */ 240 */
238 void (*machine_kexec)(struct kimage *image); 241 void (*machine_kexec)(struct kimage *image);
239#endif /* CONFIG_KEXEC */ 242#endif /* CONFIG_KEXEC */
240#endif /* CONFIG_PPC32 */
241}; 243};
242 244
243extern void default_idle(void); 245extern void default_idle(void);
diff --git a/include/asm-powerpc/macio.h b/include/asm-powerpc/macio.h
index b553dd4b139e..3a6cb1a513b7 100644
--- a/include/asm-powerpc/macio.h
+++ b/include/asm-powerpc/macio.h
@@ -1,5 +1,6 @@
1#ifndef __MACIO_ASIC_H__ 1#ifndef __MACIO_ASIC_H__
2#define __MACIO_ASIC_H__ 2#define __MACIO_ASIC_H__
3#ifdef __KERNEL__
3 4
4#include <asm/of_device.h> 5#include <asm/of_device.h>
5 6
@@ -137,4 +138,5 @@ struct macio_driver
137extern int macio_register_driver(struct macio_driver *); 138extern int macio_register_driver(struct macio_driver *);
138extern void macio_unregister_driver(struct macio_driver *); 139extern void macio_unregister_driver(struct macio_driver *);
139 140
141#endif /* __KERNEL__ */
140#endif /* __MACIO_ASIC_H__ */ 142#endif /* __MACIO_ASIC_H__ */
diff --git a/include/asm-powerpc/mmu.h b/include/asm-powerpc/mmu.h
index 29b0bb0086d3..d096d9e76ad7 100644
--- a/include/asm-powerpc/mmu.h
+++ b/include/asm-powerpc/mmu.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_MMU_H_ 1#ifndef _ASM_POWERPC_MMU_H_
2#define _ASM_POWERPC_MMU_H_ 2#define _ASM_POWERPC_MMU_H_
3#ifdef __KERNEL__
3 4
4#ifndef CONFIG_PPC64 5#ifndef CONFIG_PPC64
5#include <asm-ppc/mmu.h> 6#include <asm-ppc/mmu.h>
@@ -33,7 +34,8 @@
33 34
34/* Location of cpu0's segment table */ 35/* Location of cpu0's segment table */
35#define STAB0_PAGE 0x6 36#define STAB0_PAGE 0x6
36#define STAB0_PHYS_ADDR (STAB0_PAGE<<12) 37#define STAB0_OFFSET (STAB0_PAGE << 12)
38#define STAB0_PHYS_ADDR (STAB0_OFFSET + PHYSICAL_START)
37 39
38#ifndef __ASSEMBLY__ 40#ifndef __ASSEMBLY__
39extern char initial_stab[]; 41extern char initial_stab[];
@@ -394,7 +396,12 @@ static inline unsigned long get_vsid(unsigned long context, unsigned long ea)
394#define VSID_SCRAMBLE(pvsid) (((pvsid) * VSID_MULTIPLIER) % VSID_MODULUS) 396#define VSID_SCRAMBLE(pvsid) (((pvsid) * VSID_MULTIPLIER) % VSID_MODULUS)
395#define KERNEL_VSID(ea) VSID_SCRAMBLE(GET_ESID(ea)) 397#define KERNEL_VSID(ea) VSID_SCRAMBLE(GET_ESID(ea))
396 398
399/* Physical address used by some IO functions */
400typedef unsigned long phys_addr_t;
401
402
397#endif /* __ASSEMBLY */ 403#endif /* __ASSEMBLY */
398 404
399#endif /* CONFIG_PPC64 */ 405#endif /* CONFIG_PPC64 */
406#endif /* __KERNEL__ */
400#endif /* _ASM_POWERPC_MMU_H_ */ 407#endif /* _ASM_POWERPC_MMU_H_ */
diff --git a/include/asm-powerpc/mmu_context.h b/include/asm-powerpc/mmu_context.h
index ea6798c7d5fc..1b8a25fd48f3 100644
--- a/include/asm-powerpc/mmu_context.h
+++ b/include/asm-powerpc/mmu_context.h
@@ -1,5 +1,6 @@
1#ifndef __ASM_POWERPC_MMU_CONTEXT_H 1#ifndef __ASM_POWERPC_MMU_CONTEXT_H
2#define __ASM_POWERPC_MMU_CONTEXT_H 2#define __ASM_POWERPC_MMU_CONTEXT_H
3#ifdef __KERNEL__
3 4
4#ifndef CONFIG_PPC64 5#ifndef CONFIG_PPC64
5#include <asm-ppc/mmu_context.h> 6#include <asm-ppc/mmu_context.h>
@@ -86,4 +87,5 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
86} 87}
87 88
88#endif /* CONFIG_PPC64 */ 89#endif /* CONFIG_PPC64 */
90#endif /* __KERNEL__ */
89#endif /* __ASM_POWERPC_MMU_CONTEXT_H */ 91#endif /* __ASM_POWERPC_MMU_CONTEXT_H */
diff --git a/include/asm-powerpc/mmzone.h b/include/asm-powerpc/mmzone.h
index 54958d6cae04..88d70bae7769 100644
--- a/include/asm-powerpc/mmzone.h
+++ b/include/asm-powerpc/mmzone.h
@@ -6,6 +6,7 @@
6 */ 6 */
7#ifndef _ASM_MMZONE_H_ 7#ifndef _ASM_MMZONE_H_
8#define _ASM_MMZONE_H_ 8#define _ASM_MMZONE_H_
9#ifdef __KERNEL__
9 10
10#include <linux/config.h> 11#include <linux/config.h>
11 12
@@ -47,4 +48,5 @@ extern unsigned long max_pfn;
47extern int __init early_pfn_to_nid(unsigned long pfn); 48extern int __init early_pfn_to_nid(unsigned long pfn);
48#endif 49#endif
49 50
51#endif /* __KERNEL__ */
50#endif /* _ASM_MMZONE_H_ */ 52#endif /* _ASM_MMZONE_H_ */
diff --git a/include/asm-powerpc/module.h b/include/asm-powerpc/module.h
index 7ecd05e03051..584fabfb4f08 100644
--- a/include/asm-powerpc/module.h
+++ b/include/asm-powerpc/module.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_MODULE_H 1#ifndef _ASM_POWERPC_MODULE_H
2#define _ASM_POWERPC_MODULE_H 2#define _ASM_POWERPC_MODULE_H
3#ifdef __KERNEL__
3 4
4/* 5/*
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -74,4 +75,5 @@ struct exception_table_entry;
74void sort_ex_table(struct exception_table_entry *start, 75void sort_ex_table(struct exception_table_entry *start,
75 struct exception_table_entry *finish); 76 struct exception_table_entry *finish);
76 77
78#endif /* __KERNEL__ */
77#endif /* _ASM_POWERPC_MODULE_H */ 79#endif /* _ASM_POWERPC_MODULE_H */
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
index 7083d1f74260..6b9e78142f4f 100644
--- a/include/asm-powerpc/mpic.h
+++ b/include/asm-powerpc/mpic.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_MPIC_H 1#ifndef _ASM_POWERPC_MPIC_H
2#define _ASM_POWERPC_MPIC_H 2#define _ASM_POWERPC_MPIC_H
3#ifdef __KERNEL__
3 4
4#include <linux/irq.h> 5#include <linux/irq.h>
5 6
@@ -117,7 +118,9 @@ typedef int (*mpic_cascade_t)(struct pt_regs *regs, void *data);
117struct mpic_irq_fixup 118struct mpic_irq_fixup
118{ 119{
119 u8 __iomem *base; 120 u8 __iomem *base;
120 unsigned int irq; 121 u8 __iomem *applebase;
122 u32 data;
123 unsigned int index;
121}; 124};
122#endif /* CONFIG_MPIC_BROKEN_U3 */ 125#endif /* CONFIG_MPIC_BROKEN_U3 */
123 126
@@ -284,4 +287,5 @@ extern int mpic_get_irq(struct pt_regs *regs);
284/* global mpic for pSeries */ 287/* global mpic for pSeries */
285extern struct mpic *pSeries_mpic; 288extern struct mpic *pSeries_mpic;
286 289
290#endif /* __KERNEL__ */
287#endif /* _ASM_POWERPC_MPIC_H */ 291#endif /* _ASM_POWERPC_MPIC_H */
diff --git a/include/asm-powerpc/numnodes.h b/include/asm-powerpc/numnodes.h
index 795533aca095..e138edae09dd 100644
--- a/include/asm-powerpc/numnodes.h
+++ b/include/asm-powerpc/numnodes.h
@@ -1,7 +1,9 @@
1#ifndef _ASM_POWERPC_MAX_NUMNODES_H 1#ifndef _ASM_POWERPC_MAX_NUMNODES_H
2#define _ASM_POWERPC_MAX_NUMNODES_H 2#define _ASM_POWERPC_MAX_NUMNODES_H
3#ifdef __KERNEL__
3 4
4/* Max 16 Nodes */ 5/* Max 16 Nodes */
5#define NODES_SHIFT 4 6#define NODES_SHIFT 4
6 7
8#endif /* __KERNEL__ */
7#endif /* _ASM_POWERPC_MAX_NUMNODES_H */ 9#endif /* _ASM_POWERPC_MAX_NUMNODES_H */
diff --git a/include/asm-powerpc/nvram.h b/include/asm-powerpc/nvram.h
index 24bd8c2388ea..f3563e11e260 100644
--- a/include/asm-powerpc/nvram.h
+++ b/include/asm-powerpc/nvram.h
@@ -55,6 +55,7 @@ struct nvram_header {
55 char name[12]; 55 char name[12];
56}; 56};
57 57
58#ifdef __KERNEL__
58struct nvram_partition { 59struct nvram_partition {
59 struct list_head partition; 60 struct list_head partition;
60 struct nvram_header header; 61 struct nvram_header header;
@@ -69,6 +70,7 @@ extern struct nvram_partition *nvram_find_partition(int sig, const char *name);
69 70
70extern int pSeries_nvram_init(void); 71extern int pSeries_nvram_init(void);
71extern int mmio_nvram_init(void); 72extern int mmio_nvram_init(void);
73#endif /* __KERNEL__ */
72 74
73/* PowerMac specific nvram stuffs */ 75/* PowerMac specific nvram stuffs */
74 76
@@ -78,6 +80,7 @@ enum {
78 pmac_nvram_NR /* MacOS Name Registry partition */ 80 pmac_nvram_NR /* MacOS Name Registry partition */
79}; 81};
80 82
83#ifdef __KERNEL__
81/* Return partition offset in nvram */ 84/* Return partition offset in nvram */
82extern int pmac_get_partition(int partition); 85extern int pmac_get_partition(int partition);
83 86
@@ -91,6 +94,7 @@ extern void nvram_sync(void);
91/* Normal access to NVRAM */ 94/* Normal access to NVRAM */
92extern unsigned char nvram_read_byte(int i); 95extern unsigned char nvram_read_byte(int i);
93extern void nvram_write_byte(unsigned char c, int i); 96extern void nvram_write_byte(unsigned char c, int i);
97#endif
94 98
95/* Some offsets in XPRAM */ 99/* Some offsets in XPRAM */
96#define PMAC_XPRAM_MACHINE_LOC 0xe4 100#define PMAC_XPRAM_MACHINE_LOC 0xe4
diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h
index ddb16aae0bd6..6249a7c39639 100644
--- a/include/asm-powerpc/of_device.h
+++ b/include/asm-powerpc/of_device.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_OF_DEVICE_H 1#ifndef _ASM_POWERPC_OF_DEVICE_H
2#define _ASM_POWERPC_OF_DEVICE_H 2#define _ASM_POWERPC_OF_DEVICE_H
3#ifdef __KERNEL__
3 4
4#include <linux/device.h> 5#include <linux/device.h>
5#include <linux/mod_devicetable.h> 6#include <linux/mod_devicetable.h>
@@ -61,4 +62,5 @@ extern struct of_device *of_platform_device_create(struct device_node *np,
61 struct device *parent); 62 struct device *parent);
62extern void of_release_dev(struct device *dev); 63extern void of_release_dev(struct device *dev);
63 64
65#endif /* __KERNEL__ */
64#endif /* _ASM_POWERPC_OF_DEVICE_H */ 66#endif /* _ASM_POWERPC_OF_DEVICE_H */
diff --git a/include/asm-powerpc/ohare.h b/include/asm-powerpc/ohare.h
index 023b59772231..0d030f9dea24 100644
--- a/include/asm-powerpc/ohare.h
+++ b/include/asm-powerpc/ohare.h
@@ -1,3 +1,6 @@
1#ifndef _ASM_POWERPC_OHARE_H
2#define _ASM_POWERPC_OHARE_H
3#ifdef __KERNEL__
1/* 4/*
2 * ohare.h: definitions for using the "O'Hare" I/O controller chip. 5 * ohare.h: definitions for using the "O'Hare" I/O controller chip.
3 * 6 *
@@ -46,3 +49,6 @@
46 * Contributed by Harry Eaton. 49 * Contributed by Harry Eaton.
47 */ 50 */
48#define STARMAX_FEATURES 0xbeff7a 51#define STARMAX_FEATURES 0xbeff7a
52
53#endif /* __KERNEL__ */
54#endif /* _ASM_POWERPC_OHARE_H */
diff --git a/include/asm-powerpc/oprofile_impl.h b/include/asm-powerpc/oprofile_impl.h
index 8013cd273ced..338e6a7cff4a 100644
--- a/include/asm-powerpc/oprofile_impl.h
+++ b/include/asm-powerpc/oprofile_impl.h
@@ -11,6 +11,7 @@
11 11
12#ifndef _ASM_POWERPC_OPROFILE_IMPL_H 12#ifndef _ASM_POWERPC_OPROFILE_IMPL_H
13#define _ASM_POWERPC_OPROFILE_IMPL_H 13#define _ASM_POWERPC_OPROFILE_IMPL_H
14#ifdef __KERNEL__
14 15
15#define OP_MAX_COUNTER 8 16#define OP_MAX_COUNTER 8
16 17
@@ -22,24 +23,22 @@ struct op_counter_config {
22 unsigned long enabled; 23 unsigned long enabled;
23 unsigned long event; 24 unsigned long event;
24 unsigned long count; 25 unsigned long count;
26 /* Classic doesn't support per-counter user/kernel selection */
25 unsigned long kernel; 27 unsigned long kernel;
26#ifdef __powerpc64__
27 /* We dont support per counter user/kernel selection */
28#endif
29 unsigned long user; 28 unsigned long user;
30 unsigned long unit_mask; 29 unsigned long unit_mask;
31}; 30};
32 31
33/* System-wide configuration as set via oprofilefs. */ 32/* System-wide configuration as set via oprofilefs. */
34struct op_system_config { 33struct op_system_config {
35#ifdef __powerpc64__ 34#ifdef CONFIG_PPC64
36 unsigned long mmcr0; 35 unsigned long mmcr0;
37 unsigned long mmcr1; 36 unsigned long mmcr1;
38 unsigned long mmcra; 37 unsigned long mmcra;
39#endif 38#endif
40 unsigned long enable_kernel; 39 unsigned long enable_kernel;
41 unsigned long enable_user; 40 unsigned long enable_user;
42#ifdef __powerpc64__ 41#ifdef CONFIG_PPC64
43 unsigned long backtrace_spinlocks; 42 unsigned long backtrace_spinlocks;
44#endif 43#endif
45}; 44};
@@ -49,9 +48,7 @@ struct op_powerpc_model {
49 void (*reg_setup) (struct op_counter_config *, 48 void (*reg_setup) (struct op_counter_config *,
50 struct op_system_config *, 49 struct op_system_config *,
51 int num_counters); 50 int num_counters);
52#ifdef __powerpc64__
53 void (*cpu_setup) (void *); 51 void (*cpu_setup) (void *);
54#endif
55 void (*start) (struct op_counter_config *); 52 void (*start) (struct op_counter_config *);
56 void (*stop) (void); 53 void (*stop) (void);
57 void (*handle_interrupt) (struct pt_regs *, 54 void (*handle_interrupt) (struct pt_regs *,
@@ -59,10 +56,19 @@ struct op_powerpc_model {
59 int num_counters; 56 int num_counters;
60}; 57};
61 58
62#ifdef __powerpc64__ 59#ifdef CONFIG_FSL_BOOKE
60extern struct op_powerpc_model op_model_fsl_booke;
61#else /* Otherwise, it's classic */
62
63#ifdef CONFIG_PPC64
63extern struct op_powerpc_model op_model_rs64; 64extern struct op_powerpc_model op_model_rs64;
64extern struct op_powerpc_model op_model_power4; 65extern struct op_powerpc_model op_model_power4;
65 66
67#else /* Otherwise, CONFIG_PPC32 */
68extern struct op_powerpc_model op_model_7450;
69#endif
70
71/* All the classic PPC parts use these */
66static inline unsigned int ctr_read(unsigned int i) 72static inline unsigned int ctr_read(unsigned int i)
67{ 73{
68 switch(i) { 74 switch(i) {
@@ -78,10 +84,14 @@ static inline unsigned int ctr_read(unsigned int i)
78 return mfspr(SPRN_PMC5); 84 return mfspr(SPRN_PMC5);
79 case 5: 85 case 5:
80 return mfspr(SPRN_PMC6); 86 return mfspr(SPRN_PMC6);
87
88/* No PPC32 chip has more than 6 so far */
89#ifdef CONFIG_PPC64
81 case 6: 90 case 6:
82 return mfspr(SPRN_PMC7); 91 return mfspr(SPRN_PMC7);
83 case 7: 92 case 7:
84 return mfspr(SPRN_PMC8); 93 return mfspr(SPRN_PMC8);
94#endif
85 default: 95 default:
86 return 0; 96 return 0;
87 } 97 }
@@ -108,16 +118,21 @@ static inline void ctr_write(unsigned int i, unsigned int val)
108 case 5: 118 case 5:
109 mtspr(SPRN_PMC6, val); 119 mtspr(SPRN_PMC6, val);
110 break; 120 break;
121
122/* No PPC32 chip has more than 6, yet */
123#ifdef CONFIG_PPC64
111 case 6: 124 case 6:
112 mtspr(SPRN_PMC7, val); 125 mtspr(SPRN_PMC7, val);
113 break; 126 break;
114 case 7: 127 case 7:
115 mtspr(SPRN_PMC8, val); 128 mtspr(SPRN_PMC8, val);
116 break; 129 break;
130#endif
117 default: 131 default:
118 break; 132 break;
119 } 133 }
120} 134}
121#endif /* __powerpc64__ */ 135#endif /* !CONFIG_FSL_BOOKE */
122 136
137#endif /* __KERNEL__ */
123#endif /* _ASM_POWERPC_OPROFILE_IMPL_H */ 138#endif /* _ASM_POWERPC_OPROFILE_IMPL_H */
diff --git a/include/asm-powerpc/pSeries_reconfig.h b/include/asm-powerpc/pSeries_reconfig.h
index c0db1ea7f7d1..ea6cfb8efb84 100644
--- a/include/asm-powerpc/pSeries_reconfig.h
+++ b/include/asm-powerpc/pSeries_reconfig.h
@@ -1,5 +1,6 @@
1#ifndef _PPC64_PSERIES_RECONFIG_H 1#ifndef _PPC64_PSERIES_RECONFIG_H
2#define _PPC64_PSERIES_RECONFIG_H 2#define _PPC64_PSERIES_RECONFIG_H
3#ifdef __KERNEL__
3 4
4#include <linux/notifier.h> 5#include <linux/notifier.h>
5 6
@@ -22,4 +23,5 @@ static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb)
22static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { } 23static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { }
23#endif /* CONFIG_PPC_PSERIES */ 24#endif /* CONFIG_PPC_PSERIES */
24 25
26#endif /* __KERNEL__ */
25#endif /* _PPC64_PSERIES_RECONFIG_H */ 27#endif /* _PPC64_PSERIES_RECONFIG_H */
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h
index 92c765c35bd0..3ae52d9dc9ff 100644
--- a/include/asm-powerpc/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -14,11 +14,11 @@
14 */ 14 */
15#ifndef _ASM_POWERPC_PACA_H 15#ifndef _ASM_POWERPC_PACA_H
16#define _ASM_POWERPC_PACA_H 16#define _ASM_POWERPC_PACA_H
17#ifdef __KERNEL__
17 18
18#include <linux/config.h> 19#include <linux/config.h>
19#include <asm/types.h> 20#include <asm/types.h>
20#include <asm/lppaca.h> 21#include <asm/lppaca.h>
21#include <asm/iseries/it_lp_reg_save.h>
22#include <asm/mmu.h> 22#include <asm/mmu.h>
23 23
24register struct paca_struct *local_paca asm("r13"); 24register struct paca_struct *local_paca asm("r13");
@@ -31,9 +31,9 @@ struct task_struct;
31 * 31 *
32 * This structure is not directly accessed by firmware or the service 32 * This structure is not directly accessed by firmware or the service
33 * processor except for the first two pointers that point to the 33 * processor except for the first two pointers that point to the
34 * lppaca area and the ItLpRegSave area for this CPU. Both the 34 * lppaca area and the ItLpRegSave area for this CPU. The lppaca
35 * lppaca and ItLpRegSave objects are currently contained within the 35 * object is currently contained within the PACA but it doesn't need
36 * PACA but they do not need to be. 36 * to be.
37 */ 37 */
38struct paca_struct { 38struct paca_struct {
39 /* 39 /*
@@ -48,7 +48,9 @@ struct paca_struct {
48 * accessed by the firmware 48 * accessed by the firmware
49 */ 49 */
50 struct lppaca *lppaca_ptr; /* Pointer to LpPaca for PLIC */ 50 struct lppaca *lppaca_ptr; /* Pointer to LpPaca for PLIC */
51 struct ItLpRegSave *reg_save_ptr; /* Pointer to LpRegSave for PLIC */ 51#ifdef CONFIG_PPC_ISERIES
52 void *reg_save_ptr; /* Pointer to LpRegSave for PLIC */
53#endif /* CONFIG_PPC_ISERIES */
52 54
53 /* 55 /*
54 * MAGIC: the spinlock functions in arch/ppc64/lib/locks.c 56 * MAGIC: the spinlock functions in arch/ppc64/lib/locks.c
@@ -59,7 +61,6 @@ struct paca_struct {
59 u16 lock_token; /* Constant 0x8000, used in locks */ 61 u16 lock_token; /* Constant 0x8000, used in locks */
60 u16 paca_index; /* Logical processor number */ 62 u16 paca_index; /* Logical processor number */
61 63
62 u32 default_decr; /* Default decrementer value */
63 u64 kernel_toc; /* Kernel TOC address */ 64 u64 kernel_toc; /* Kernel TOC address */
64 u64 stab_real; /* Absolute address of segment table */ 65 u64 stab_real; /* Absolute address of segment table */
65 u64 stab_addr; /* Virtual address of segment table */ 66 u64 stab_addr; /* Virtual address of segment table */
@@ -90,14 +91,10 @@ struct paca_struct {
90 struct task_struct *__current; /* Pointer to current */ 91 struct task_struct *__current; /* Pointer to current */
91 u64 kstack; /* Saved Kernel stack addr */ 92 u64 kstack; /* Saved Kernel stack addr */
92 u64 stab_rr; /* stab/slb round-robin counter */ 93 u64 stab_rr; /* stab/slb round-robin counter */
93 u64 next_jiffy_update_tb; /* TB value for next jiffy update */
94 u64 saved_r1; /* r1 save for RTAS calls */ 94 u64 saved_r1; /* r1 save for RTAS calls */
95 u64 saved_msr; /* MSR saved here by enter_rtas */ 95 u64 saved_msr; /* MSR saved here by enter_rtas */
96 u8 proc_enabled; /* irq soft-enable flag */ 96 u8 proc_enabled; /* irq soft-enable flag */
97 97
98 /* not yet used */
99 u64 exdsi[8]; /* used for linear mapping hash table misses */
100
101 /* 98 /*
102 * iSeries structure which the hypervisor knows about - 99 * iSeries structure which the hypervisor knows about -
103 * this structure should not cross a page boundary. 100 * this structure should not cross a page boundary.
@@ -110,11 +107,9 @@ struct paca_struct {
110 * cross a page boundary. 107 * cross a page boundary.
111 */ 108 */
112 struct lppaca lppaca __attribute__((__aligned__(0x400))); 109 struct lppaca lppaca __attribute__((__aligned__(0x400)));
113#ifdef CONFIG_PPC_ISERIES
114 struct ItLpRegSave reg_save;
115#endif
116}; 110};
117 111
118extern struct paca_struct paca[]; 112extern struct paca_struct paca[];
119 113
114#endif /* __KERNEL__ */
120#endif /* _ASM_POWERPC_PACA_H */ 115#endif /* _ASM_POWERPC_PACA_H */
diff --git a/include/asm-powerpc/page.h b/include/asm-powerpc/page.h
index 18c1e5ee81a3..76d7cb4b4ffc 100644
--- a/include/asm-powerpc/page.h
+++ b/include/asm-powerpc/page.h
@@ -37,8 +37,30 @@
37 */ 37 */
38#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) 38#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
39 39
40/*
41 * KERNELBASE is the virtual address of the start of the kernel, it's often
42 * the same as PAGE_OFFSET, but _might not be_.
43 *
44 * The kdump dump kernel is one example where KERNELBASE != PAGE_OFFSET.
45 *
46 * To get a physical address from a virtual one you subtract PAGE_OFFSET,
47 * _not_ KERNELBASE.
48 *
49 * If you want to know something's offset from the start of the kernel you
50 * should subtract KERNELBASE.
51 *
52 * If you want to test if something's a kernel address, use is_kernel_addr().
53 */
54
55#ifdef CONFIG_CRASH_DUMP
56/* Kdump kernel runs at 32 MB, change at your peril. */
57#define PHYSICAL_START 0x2000000
58#else
59#define PHYSICAL_START 0x0
60#endif
61
40#define PAGE_OFFSET ASM_CONST(CONFIG_KERNEL_START) 62#define PAGE_OFFSET ASM_CONST(CONFIG_KERNEL_START)
41#define KERNELBASE PAGE_OFFSET 63#define KERNELBASE (PAGE_OFFSET + PHYSICAL_START)
42 64
43#ifdef CONFIG_DISCONTIGMEM 65#ifdef CONFIG_DISCONTIGMEM
44#define page_to_pfn(page) discontigmem_page_to_pfn(page) 66#define page_to_pfn(page) discontigmem_page_to_pfn(page)
@@ -56,7 +78,7 @@
56#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) 78#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
57#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 79#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
58 80
59#define __va(x) ((void *)((unsigned long)(x) + KERNELBASE)) 81#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET))
60#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) 82#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET)
61 83
62/* 84/*
@@ -86,6 +108,12 @@
86/* to align the pointer to the (next) page boundary */ 108/* to align the pointer to the (next) page boundary */
87#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE) 109#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
88 110
111/*
112 * Don't compare things with KERNELBASE or PAGE_OFFSET to test for
113 * "kernelness", use is_kernel_addr() - it should do what you want.
114 */
115#define is_kernel_addr(x) ((x) >= PAGE_OFFSET)
116
89#ifndef __ASSEMBLY__ 117#ifndef __ASSEMBLY__
90 118
91#undef STRICT_MM_TYPECHECKS 119#undef STRICT_MM_TYPECHECKS
diff --git a/include/asm-powerpc/page_32.h b/include/asm-powerpc/page_32.h
index 7259cfd85da9..2677bad70f40 100644
--- a/include/asm-powerpc/page_32.h
+++ b/include/asm-powerpc/page_32.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_PAGE_32_H 1#ifndef _ASM_POWERPC_PAGE_32_H
2#define _ASM_POWERPC_PAGE_32_H 2#define _ASM_POWERPC_PAGE_32_H
3#ifdef __KERNEL__
3 4
4#define VM_DATA_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS32 5#define VM_DATA_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS32
5 6
@@ -37,4 +38,5 @@ extern __inline__ int get_order(unsigned long size)
37 38
38#endif /* __ASSEMBLY__ */ 39#endif /* __ASSEMBLY__ */
39 40
41#endif /* __KERNEL__ */
40#endif /* _ASM_POWERPC_PAGE_32_H */ 42#endif /* _ASM_POWERPC_PAGE_32_H */
diff --git a/include/asm-powerpc/page_64.h b/include/asm-powerpc/page_64.h
index 6642c0125001..3fb061bab9ec 100644
--- a/include/asm-powerpc/page_64.h
+++ b/include/asm-powerpc/page_64.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_PAGE_64_H 1#ifndef _ASM_POWERPC_PAGE_64_H
2#define _ASM_POWERPC_PAGE_64_H 2#define _ASM_POWERPC_PAGE_64_H
3#ifdef __KERNEL__
3 4
4/* 5/*
5 * Copyright (C) 2001 PPC64 Team, IBM Corp 6 * Copyright (C) 2001 PPC64 Team, IBM Corp
@@ -25,16 +26,6 @@
25 */ 26 */
26#define PAGE_FACTOR (PAGE_SHIFT - HW_PAGE_SHIFT) 27#define PAGE_FACTOR (PAGE_SHIFT - HW_PAGE_SHIFT)
27 28
28#define REGION_SIZE 4UL
29#define REGION_SHIFT 60UL
30#define REGION_MASK (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT)
31
32#define VMALLOCBASE ASM_CONST(0xD000000000000000)
33#define VMALLOC_REGION_ID (VMALLOCBASE >> REGION_SHIFT)
34#define KERNEL_REGION_ID (KERNELBASE >> REGION_SHIFT)
35#define USER_REGION_ID (0UL)
36#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT)
37
38/* Segment size */ 29/* Segment size */
39#define SID_SHIFT 28 30#define SID_SHIFT 28
40#define SID_MASK 0xfffffffffUL 31#define SID_MASK 0xfffffffffUL
@@ -180,4 +171,5 @@ extern unsigned int HPAGE_SHIFT;
180 171
181#include <asm-generic/page.h> 172#include <asm-generic/page.h>
182 173
174#endif /* __KERNEL__ */
183#endif /* _ASM_POWERPC_PAGE_64_H */ 175#endif /* _ASM_POWERPC_PAGE_64_H */
diff --git a/include/asm-powerpc/param.h b/include/asm-powerpc/param.h
index bdc724f70884..094f63d4d5ca 100644
--- a/include/asm-powerpc/param.h
+++ b/include/asm-powerpc/param.h
@@ -1,8 +1,6 @@
1#ifndef _ASM_POWERPC_PARAM_H 1#ifndef _ASM_POWERPC_PARAM_H
2#define _ASM_POWERPC_PARAM_H 2#define _ASM_POWERPC_PARAM_H
3 3
4#include <linux/config.h>
5
6#ifdef __KERNEL__ 4#ifdef __KERNEL__
7#define HZ CONFIG_HZ /* internal kernel timer frequency */ 5#define HZ CONFIG_HZ /* internal kernel timer frequency */
8#define USER_HZ 100 /* for user interfaces in "ticks" */ 6#define USER_HZ 100 /* for user interfaces in "ticks" */
diff --git a/include/asm-powerpc/parport.h b/include/asm-powerpc/parport.h
index d86b410a6f8b..897e49a88a6b 100644
--- a/include/asm-powerpc/parport.h
+++ b/include/asm-powerpc/parport.h
@@ -8,6 +8,7 @@
8 8
9#ifndef _ASM_POWERPC_PARPORT_H 9#ifndef _ASM_POWERPC_PARPORT_H
10#define _ASM_POWERPC_PARPORT_H 10#define _ASM_POWERPC_PARPORT_H
11#ifdef __KERNEL__
11 12
12static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); 13static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
13static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) 14static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
@@ -15,4 +16,5 @@ static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
15 return parport_pc_find_isa_ports (autoirq, autodma); 16 return parport_pc_find_isa_ports (autoirq, autodma);
16} 17}
17 18
19#endif /* __KERNEL__ */
18#endif /* !(_ASM_POWERPC_PARPORT_H) */ 20#endif /* !(_ASM_POWERPC_PARPORT_H) */
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index 223ec7bd81da..1a08860e789e 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_PCI_BRIDGE_H 1#ifndef _ASM_POWERPC_PCI_BRIDGE_H
2#define _ASM_POWERPC_PCI_BRIDGE_H 2#define _ASM_POWERPC_PCI_BRIDGE_H
3#ifdef __KERNEL__
3 4
4#ifndef CONFIG_PPC64 5#ifndef CONFIG_PPC64
5#include <asm-ppc/pci-bridge.h> 6#include <asm-ppc/pci-bridge.h>
@@ -125,9 +126,19 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
125 return bus->sysdata; /* Must be root bus (PHB) */ 126 return bus->sysdata; /* Must be root bus (PHB) */
126} 127}
127 128
129/** Find the bus corresponding to the indicated device node */
130struct pci_bus * pcibios_find_pci_bus(struct device_node *dn);
131
128extern void pci_process_bridge_OF_ranges(struct pci_controller *hose, 132extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
129 struct device_node *dev, int primary); 133 struct device_node *dev, int primary);
130 134
135/** Remove all of the PCI devices under this bus */
136void pcibios_remove_pci_devices(struct pci_bus *bus);
137
138/** Discover new pci devices under this bus, and add them */
139void pcibios_add_pci_devices(struct pci_bus * bus);
140void pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus);
141
131extern int pcibios_remove_root_bus(struct pci_controller *phb); 142extern int pcibios_remove_root_bus(struct pci_controller *phb);
132 143
133extern void phbs_remap_io(void); 144extern void phbs_remap_io(void);
@@ -140,14 +151,27 @@ static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
140 return PCI_DN(busdn)->phb; 151 return PCI_DN(busdn)->phb;
141} 152}
142 153
154extern struct pci_controller*
155pci_find_hose_for_OF_device(struct device_node* node);
156
143extern struct pci_controller * 157extern struct pci_controller *
144pcibios_alloc_controller(struct device_node *dev); 158pcibios_alloc_controller(struct device_node *dev);
145extern void pcibios_free_controller(struct pci_controller *phb); 159extern void pcibios_free_controller(struct pci_controller *phb);
146 160
161#ifdef CONFIG_PCI
162extern unsigned long pci_address_to_pio(phys_addr_t address);
163#else
164static inline unsigned long pci_address_to_pio(phys_addr_t address)
165{
166 return (unsigned long)-1;
167}
168#endif
169
147/* Return values for ppc_md.pci_probe_mode function */ 170/* Return values for ppc_md.pci_probe_mode function */
148#define PCI_PROBE_NONE -1 /* Don't look at this bus at all */ 171#define PCI_PROBE_NONE -1 /* Don't look at this bus at all */
149#define PCI_PROBE_NORMAL 0 /* Do normal PCI probing */ 172#define PCI_PROBE_NORMAL 0 /* Do normal PCI probing */
150#define PCI_PROBE_DEVTREE 1 /* Instantiate from device tree */ 173#define PCI_PROBE_DEVTREE 1 /* Instantiate from device tree */
151 174
152#endif /* CONFIG_PPC64 */ 175#endif /* CONFIG_PPC64 */
176#endif /* __KERNEL__ */
153#endif 177#endif
diff --git a/include/asm-powerpc/pci.h b/include/asm-powerpc/pci.h
index d5934a076bd0..5d2c9e6c4be2 100644
--- a/include/asm-powerpc/pci.h
+++ b/include/asm-powerpc/pci.h
@@ -216,6 +216,8 @@ extern int remap_bus_range(struct pci_bus *bus);
216extern void pcibios_fixup_device_resources(struct pci_dev *dev, 216extern void pcibios_fixup_device_resources(struct pci_dev *dev,
217 struct pci_bus *bus); 217 struct pci_bus *bus);
218 218
219extern void pcibios_claim_one_bus(struct pci_bus *b);
220
219extern struct pci_controller *init_phb_dynamic(struct device_node *dn); 221extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
220 222
221extern struct pci_dev *of_create_pci_dev(struct device_node *node, 223extern struct pci_dev *of_create_pci_dev(struct device_node *node,
diff --git a/include/asm-powerpc/pgalloc.h b/include/asm-powerpc/pgalloc.h
index bfc2113b3630..9f5b052784a5 100644
--- a/include/asm-powerpc/pgalloc.h
+++ b/include/asm-powerpc/pgalloc.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_PGALLOC_H 1#ifndef _ASM_POWERPC_PGALLOC_H
2#define _ASM_POWERPC_PGALLOC_H 2#define _ASM_POWERPC_PGALLOC_H
3#ifdef __KERNEL__
3 4
4#ifndef CONFIG_PPC64 5#ifndef CONFIG_PPC64
5#include <asm-ppc/pgalloc.h> 6#include <asm-ppc/pgalloc.h>
@@ -153,4 +154,5 @@ extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
153#define check_pgt_cache() do { } while (0) 154#define check_pgt_cache() do { } while (0)
154 155
155#endif /* CONFIG_PPC64 */ 156#endif /* CONFIG_PPC64 */
157#endif /* __KERNEL__ */
156#endif /* _ASM_POWERPC_PGALLOC_H */ 158#endif /* _ASM_POWERPC_PGALLOC_H */
diff --git a/include/asm-powerpc/pgtable-64k.h b/include/asm-powerpc/pgtable-64k.h
index 154f1840ece4..653915014dcd 100644
--- a/include/asm-powerpc/pgtable-64k.h
+++ b/include/asm-powerpc/pgtable-64k.h
@@ -1,3 +1,7 @@
1#ifndef _ASM_POWERPC_PGTABLE_64K_H
2#define _ASM_POWERPC_PGTABLE_64K_H
3#ifdef __KERNEL__
4
1#include <asm-generic/pgtable-nopud.h> 5#include <asm-generic/pgtable-nopud.h>
2 6
3 7
@@ -88,3 +92,5 @@
88 92
89 93
90#endif /* __ASSEMBLY__ */ 94#endif /* __ASSEMBLY__ */
95#endif /* __KERNEL__ */
96#endif /* _ASM_POWERPC_PGTABLE_64K_H */
diff --git a/include/asm-powerpc/pgtable.h b/include/asm-powerpc/pgtable.h
index 0303f57366c1..e38931379a72 100644
--- a/include/asm-powerpc/pgtable.h
+++ b/include/asm-powerpc/pgtable.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_PGTABLE_H 1#ifndef _ASM_POWERPC_PGTABLE_H
2#define _ASM_POWERPC_PGTABLE_H 2#define _ASM_POWERPC_PGTABLE_H
3#ifdef __KERNEL__
3 4
4#ifndef CONFIG_PPC64 5#ifndef CONFIG_PPC64
5#include <asm-ppc/pgtable.h> 6#include <asm-ppc/pgtable.h>
@@ -58,6 +59,17 @@ struct mm_struct;
58#define IMALLOC_END (VMALLOC_START + PGTABLE_RANGE) 59#define IMALLOC_END (VMALLOC_START + PGTABLE_RANGE)
59 60
60/* 61/*
62 * Region IDs
63 */
64#define REGION_SHIFT 60UL
65#define REGION_MASK (0xfUL << REGION_SHIFT)
66#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT)
67
68#define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START))
69#define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET))
70#define USER_REGION_ID (0UL)
71
72/*
61 * Common bits in a linux-style PTE. These match the bits in the 73 * Common bits in a linux-style PTE. These match the bits in the
62 * (hardware-defined) PowerPC PTE as closely as possible. Additional 74 * (hardware-defined) PowerPC PTE as closely as possible. Additional
63 * bits may be defined in pgtable-*.h 75 * bits may be defined in pgtable-*.h
@@ -521,4 +533,5 @@ void pgtable_cache_init(void);
521#endif /* __ASSEMBLY__ */ 533#endif /* __ASSEMBLY__ */
522 534
523#endif /* CONFIG_PPC64 */ 535#endif /* CONFIG_PPC64 */
536#endif /* __KERNEL__ */
524#endif /* _ASM_POWERPC_PGTABLE_H */ 537#endif /* _ASM_POWERPC_PGTABLE_H */
diff --git a/include/asm-powerpc/pmac_feature.h b/include/asm-powerpc/pmac_feature.h
index e9683bcff19b..3221628130c4 100644
--- a/include/asm-powerpc/pmac_feature.h
+++ b/include/asm-powerpc/pmac_feature.h
@@ -121,6 +121,7 @@
121#define PMAC_TYPE_IMAC_G5 0x152 /* iMac G5 */ 121#define PMAC_TYPE_IMAC_G5 0x152 /* iMac G5 */
122#define PMAC_TYPE_XSERVE_G5 0x153 /* Xserve G5 */ 122#define PMAC_TYPE_XSERVE_G5 0x153 /* Xserve G5 */
123#define PMAC_TYPE_UNKNOWN_K2 0x19f /* Any other K2 based */ 123#define PMAC_TYPE_UNKNOWN_K2 0x19f /* Any other K2 based */
124#define PMAC_TYPE_UNKNOWN_SHASTA 0x19e /* Any other Shasta based */
124 125
125/* 126/*
126 * Motherboard flags 127 * Motherboard flags
@@ -317,10 +318,6 @@ extern void pmac_register_agp_pm(struct pci_dev *bridge,
317extern void pmac_suspend_agp_for_card(struct pci_dev *dev); 318extern void pmac_suspend_agp_for_card(struct pci_dev *dev);
318extern void pmac_resume_agp_for_card(struct pci_dev *dev); 319extern void pmac_resume_agp_for_card(struct pci_dev *dev);
319 320
320/* Used by the via-pmu driver for suspend/resume
321 */
322extern void pmac_tweak_clock_spreading(int enable);
323
324/* 321/*
325 * The part below is for use by macio_asic.c only, do not rely 322 * The part below is for use by macio_asic.c only, do not rely
326 * on the data structures or constants below in a normal driver 323 * on the data structures or constants below in a normal driver
@@ -341,6 +338,7 @@ enum {
341 macio_pangea, 338 macio_pangea,
342 macio_intrepid, 339 macio_intrepid,
343 macio_keylargo2, 340 macio_keylargo2,
341 macio_shasta,
344}; 342};
345 343
346struct macio_chip 344struct macio_chip
@@ -376,5 +374,24 @@ extern struct macio_chip* macio_find(struct device_node* child, int type);
376#define MACIO_IN8(r) (in_8(MACIO_FCR8(macio,r))) 374#define MACIO_IN8(r) (in_8(MACIO_FCR8(macio,r)))
377#define MACIO_OUT8(r,v) (out_8(MACIO_FCR8(macio,r), (v))) 375#define MACIO_OUT8(r,v) (out_8(MACIO_FCR8(macio,r), (v)))
378 376
377/*
378 * Those are exported by pmac feature for internal use by arch code
379 * only like the platform function callbacks, do not use directly in drivers
380 */
381extern spinlock_t feature_lock;
382extern struct device_node *uninorth_node;
383extern u32 __iomem *uninorth_base;
384
385/*
386 * Uninorth reg. access. Note that Uni-N regs are big endian
387 */
388
389#define UN_REG(r) (uninorth_base + ((r) >> 2))
390#define UN_IN(r) (in_be32(UN_REG(r)))
391#define UN_OUT(r,v) (out_be32(UN_REG(r), (v)))
392#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
393#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
394
395
379#endif /* __PPC_ASM_PMAC_FEATURE_H */ 396#endif /* __PPC_ASM_PMAC_FEATURE_H */
380#endif /* __KERNEL__ */ 397#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/pmac_low_i2c.h b/include/asm-powerpc/pmac_low_i2c.h
index 809a5963d5e7..131011bd7e76 100644
--- a/include/asm-powerpc/pmac_low_i2c.h
+++ b/include/asm-powerpc/pmac_low_i2c.h
@@ -11,33 +11,97 @@
11 */ 11 */
12#ifndef __PMAC_LOW_I2C_H__ 12#ifndef __PMAC_LOW_I2C_H__
13#define __PMAC_LOW_I2C_H__ 13#define __PMAC_LOW_I2C_H__
14#ifdef __KERNEL__
14 15
15/* i2c mode (based on the platform functions format) */ 16/* i2c mode (based on the platform functions format) */
16enum { 17enum {
17 pmac_low_i2c_mode_dumb = 1, 18 pmac_i2c_mode_dumb = 1,
18 pmac_low_i2c_mode_std = 2, 19 pmac_i2c_mode_std = 2,
19 pmac_low_i2c_mode_stdsub = 3, 20 pmac_i2c_mode_stdsub = 3,
20 pmac_low_i2c_mode_combined = 4, 21 pmac_i2c_mode_combined = 4,
21}; 22};
22 23
23/* RW bit in address */ 24/* RW bit in address */
24enum { 25enum {
25 pmac_low_i2c_read = 0x01, 26 pmac_i2c_read = 0x01,
26 pmac_low_i2c_write = 0x00 27 pmac_i2c_write = 0x00
27}; 28};
28 29
30/* i2c bus type */
31enum {
32 pmac_i2c_bus_keywest = 0,
33 pmac_i2c_bus_pmu = 1,
34 pmac_i2c_bus_smu = 2,
35};
36
37/* i2c bus features */
38enum {
39 /* can_largesub : supports >1 byte subaddresses (SMU only) */
40 pmac_i2c_can_largesub = 0x00000001u,
41
42 /* multibus : device node holds multiple busses, bus number is
43 * encoded in bits 0xff00 of "reg" of a given device
44 */
45 pmac_i2c_multibus = 0x00000002u,
46};
47
48/* i2c busses in the system */
49struct pmac_i2c_bus;
50struct i2c_adapter;
51
29/* Init, called early during boot */ 52/* Init, called early during boot */
30extern void pmac_init_low_i2c(void); 53extern int pmac_i2c_init(void);
54
55/* Lookup an i2c bus for a device-node. The node can be either the bus
56 * node itself or a device below it. In the case of a multibus, the bus
57 * node itself is the controller node, else, it's a child of the controller
58 * node
59 */
60extern struct pmac_i2c_bus *pmac_i2c_find_bus(struct device_node *node);
61
62/* Get the address for an i2c device. This strips the bus number if
63 * necessary. The 7 bits address is returned 1 bit right shifted so that the
64 * direction can be directly ored in
65 */
66extern u8 pmac_i2c_get_dev_addr(struct device_node *device);
67
68/* Get infos about a bus */
69extern struct device_node *pmac_i2c_get_controller(struct pmac_i2c_bus *bus);
70extern struct device_node *pmac_i2c_get_bus_node(struct pmac_i2c_bus *bus);
71extern int pmac_i2c_get_type(struct pmac_i2c_bus *bus);
72extern int pmac_i2c_get_flags(struct pmac_i2c_bus *bus);
73extern int pmac_i2c_get_channel(struct pmac_i2c_bus *bus);
74
75/* i2c layer adapter attach/detach */
76extern void pmac_i2c_attach_adapter(struct pmac_i2c_bus *bus,
77 struct i2c_adapter *adapter);
78extern void pmac_i2c_detach_adapter(struct pmac_i2c_bus *bus,
79 struct i2c_adapter *adapter);
80extern struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus);
81extern struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter);
82
83/* March a device or bus with an i2c adapter structure, to be used by drivers
84 * to match device-tree nodes with i2c adapters during adapter discovery
85 * callbacks
86 */
87extern int pmac_i2c_match_adapter(struct device_node *dev,
88 struct i2c_adapter *adapter);
89
31 90
32/* Locking functions exposed to i2c-keywest */ 91/* (legacy) Locking functions exposed to i2c-keywest */
33int pmac_low_i2c_lock(struct device_node *np); 92extern int pmac_low_i2c_lock(struct device_node *np);
34int pmac_low_i2c_unlock(struct device_node *np); 93extern int pmac_low_i2c_unlock(struct device_node *np);
35 94
36/* Access functions for platform code */ 95/* Access functions for platform code */
37int pmac_low_i2c_open(struct device_node *np, int channel); 96extern int pmac_i2c_open(struct pmac_i2c_bus *bus, int polled);
38int pmac_low_i2c_close(struct device_node *np); 97extern void pmac_i2c_close(struct pmac_i2c_bus *bus);
39int pmac_low_i2c_setmode(struct device_node *np, int mode); 98extern int pmac_i2c_setmode(struct pmac_i2c_bus *bus, int mode);
40int pmac_low_i2c_xfer(struct device_node *np, u8 addrdir, u8 subaddr, u8 *data, int len); 99extern int pmac_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
100 u32 subaddr, u8 *data, int len);
41 101
102/* Suspend/resume code called by via-pmu directly for now */
103extern void pmac_pfunc_i2c_suspend(void);
104extern void pmac_pfunc_i2c_resume(void);
42 105
106#endif /* __KERNEL__ */
43#endif /* __PMAC_LOW_I2C_H__ */ 107#endif /* __PMAC_LOW_I2C_H__ */
diff --git a/include/asm-powerpc/pmac_pfunc.h b/include/asm-powerpc/pmac_pfunc.h
new file mode 100644
index 000000000000..d9728c80f86d
--- /dev/null
+++ b/include/asm-powerpc/pmac_pfunc.h
@@ -0,0 +1,253 @@
1#ifndef __PMAC_PFUNC_H__
2#define __PMAC_PFUNC_H__
3
4#include <linux/types.h>
5#include <linux/list.h>
6
7/* Flags in command lists */
8#define PMF_FLAGS_ON_INIT 0x80000000u
9#define PMF_FLGAS_ON_TERM 0x40000000u
10#define PMF_FLAGS_ON_SLEEP 0x20000000u
11#define PMF_FLAGS_ON_WAKE 0x10000000u
12#define PMF_FLAGS_ON_DEMAND 0x08000000u
13#define PMF_FLAGS_INT_GEN 0x04000000u
14#define PMF_FLAGS_HIGH_SPEED 0x02000000u
15#define PMF_FLAGS_LOW_SPEED 0x01000000u
16#define PMF_FLAGS_SIDE_EFFECTS 0x00800000u
17
18/*
19 * Arguments to a platform function call.
20 *
21 * NOTE: By convention, pointer arguments point to an u32
22 */
23struct pmf_args {
24 union {
25 u32 v;
26 u32 *p;
27 } u[4];
28 unsigned int count;
29};
30
31/*
32 * A driver capable of interpreting commands provides a handlers
33 * structure filled with whatever handlers are implemented by this
34 * driver. Non implemented handlers are left NULL.
35 *
36 * PMF_STD_ARGS are the same arguments that are passed to the parser
37 * and that gets passed back to the various handlers.
38 *
39 * Interpreting a given function always start with a begin() call which
40 * returns an instance data to be passed around subsequent calls, and
41 * ends with an end() call. This allows the low level driver to implement
42 * locking policy or per-function instance data.
43 *
44 * For interrupt capable functions, irq_enable() is called when a client
45 * registers, and irq_disable() is called when the last client unregisters
46 * Note that irq_enable & irq_disable are called within a semaphore held
47 * by the core, thus you should not try to register yourself to some other
48 * pmf interrupt during those calls.
49 */
50
51#define PMF_STD_ARGS struct pmf_function *func, void *instdata, \
52 struct pmf_args *args
53
54struct pmf_function;
55
56struct pmf_handlers {
57 void * (*begin)(struct pmf_function *func, struct pmf_args *args);
58 void (*end)(struct pmf_function *func, void *instdata);
59
60 int (*irq_enable)(struct pmf_function *func);
61 int (*irq_disable)(struct pmf_function *func);
62
63 int (*write_gpio)(PMF_STD_ARGS, u8 value, u8 mask);
64 int (*read_gpio)(PMF_STD_ARGS, u8 mask, int rshift, u8 xor);
65
66 int (*write_reg32)(PMF_STD_ARGS, u32 offset, u32 value, u32 mask);
67 int (*read_reg32)(PMF_STD_ARGS, u32 offset);
68 int (*write_reg16)(PMF_STD_ARGS, u32 offset, u16 value, u16 mask);
69 int (*read_reg16)(PMF_STD_ARGS, u32 offset);
70 int (*write_reg8)(PMF_STD_ARGS, u32 offset, u8 value, u8 mask);
71 int (*read_reg8)(PMF_STD_ARGS, u32 offset);
72
73 int (*delay)(PMF_STD_ARGS, u32 duration);
74
75 int (*wait_reg32)(PMF_STD_ARGS, u32 offset, u32 value, u32 mask);
76 int (*wait_reg16)(PMF_STD_ARGS, u32 offset, u16 value, u16 mask);
77 int (*wait_reg8)(PMF_STD_ARGS, u32 offset, u8 value, u8 mask);
78
79 int (*read_i2c)(PMF_STD_ARGS, u32 len);
80 int (*write_i2c)(PMF_STD_ARGS, u32 len, const u8 *data);
81 int (*rmw_i2c)(PMF_STD_ARGS, u32 masklen, u32 valuelen, u32 totallen,
82 const u8 *maskdata, const u8 *valuedata);
83
84 int (*read_cfg)(PMF_STD_ARGS, u32 offset, u32 len);
85 int (*write_cfg)(PMF_STD_ARGS, u32 offset, u32 len, const u8 *data);
86 int (*rmw_cfg)(PMF_STD_ARGS, u32 offset, u32 masklen, u32 valuelen,
87 u32 totallen, const u8 *maskdata, const u8 *valuedata);
88
89 int (*read_i2c_sub)(PMF_STD_ARGS, u8 subaddr, u32 len);
90 int (*write_i2c_sub)(PMF_STD_ARGS, u8 subaddr, u32 len, const u8 *data);
91 int (*set_i2c_mode)(PMF_STD_ARGS, int mode);
92 int (*rmw_i2c_sub)(PMF_STD_ARGS, u8 subaddr, u32 masklen, u32 valuelen,
93 u32 totallen, const u8 *maskdata,
94 const u8 *valuedata);
95
96 int (*read_reg32_msrx)(PMF_STD_ARGS, u32 offset, u32 mask, u32 shift,
97 u32 xor);
98 int (*read_reg16_msrx)(PMF_STD_ARGS, u32 offset, u32 mask, u32 shift,
99 u32 xor);
100 int (*read_reg8_msrx)(PMF_STD_ARGS, u32 offset, u32 mask, u32 shift,
101 u32 xor);
102
103 int (*write_reg32_slm)(PMF_STD_ARGS, u32 offset, u32 shift, u32 mask);
104 int (*write_reg16_slm)(PMF_STD_ARGS, u32 offset, u32 shift, u32 mask);
105 int (*write_reg8_slm)(PMF_STD_ARGS, u32 offset, u32 shift, u32 mask);
106
107 int (*mask_and_compare)(PMF_STD_ARGS, u32 len, const u8 *maskdata,
108 const u8 *valuedata);
109
110 struct module *owner;
111};
112
113
114/*
115 * Drivers who expose platform functions register at init time, this
116 * causes the platform functions for that device node to be parsed in
117 * advance and associated with the device. The data structures are
118 * partially public so a driver can walk the list of platform functions
119 * and eventually inspect the flags
120 */
121struct pmf_device;
122
123struct pmf_function {
124 /* All functions for a given driver are linked */
125 struct list_head link;
126
127 /* Function node & driver data */
128 struct device_node *node;
129 void *driver_data;
130
131 /* For internal use by core */
132 struct pmf_device *dev;
133
134 /* The name is the "xxx" in "platform-do-xxx", this is how
135 * platform functions are identified by this code. Some functions
136 * only operate for a given target, in which case the phandle is
137 * here (or 0 if the filter doesn't apply)
138 */
139 const char *name;
140 u32 phandle;
141
142 /* The flags for that function. You can have several functions
143 * with the same name and different flag
144 */
145 u32 flags;
146
147 /* The actual tokenized function blob */
148 const void *data;
149 unsigned int length;
150
151 /* Interrupt clients */
152 struct list_head irq_clients;
153
154 /* Refcounting */
155 struct kref ref;
156};
157
158/*
159 * For platform functions that are interrupts, one can register
160 * irq_client structures. You canNOT use the same structure twice
161 * as it contains a link member. Also, the callback is called with
162 * a spinlock held, you must not call back into any of the pmf_* functions
163 * from within that callback
164 */
165struct pmf_irq_client {
166 void (*handler)(void *data);
167 void *data;
168 struct module *owner;
169 struct list_head link;
170};
171
172
173/*
174 * Register/Unregister a function-capable driver and its handlers
175 */
176extern int pmf_register_driver(struct device_node *np,
177 struct pmf_handlers *handlers,
178 void *driverdata);
179
180extern void pmf_unregister_driver(struct device_node *np);
181
182
183/*
184 * Register/Unregister interrupt clients
185 */
186extern int pmf_register_irq_client(struct device_node *np,
187 const char *name,
188 struct pmf_irq_client *client);
189
190extern void pmf_unregister_irq_client(struct device_node *np,
191 const char *name,
192 struct pmf_irq_client *client);
193
194/*
195 * Called by the handlers when an irq happens
196 */
197extern void pmf_do_irq(struct pmf_function *func);
198
199
200/*
201 * Low level call to platform functions.
202 *
203 * The phandle can filter on the target object for functions that have
204 * multiple targets, the flags allow you to restrict the call to a given
205 * combination of flags.
206 *
207 * The args array contains as many arguments as is required by the function,
208 * this is dependent on the function you are calling, unfortunately Apple
209 * mecanism provides no way to encode that so you have to get it right at
210 * the call site. Some functions require no args, in which case, you can
211 * pass NULL.
212 *
213 * You can also pass NULL to the name. This will match any function that has
214 * the appropriate combination of flags & phandle or you can pass 0 to the
215 * phandle to match any
216 */
217extern int pmf_do_functions(struct device_node *np, const char *name,
218 u32 phandle, u32 flags, struct pmf_args *args);
219
220
221
222/*
223 * High level call to a platform function.
224 *
225 * This one looks for the platform-xxx first so you should call it to the
226 * actual target if any. It will fallback to platform-do-xxx if it can't
227 * find one. It will also exclusively target functions that have
228 * the "OnDemand" flag.
229 */
230
231extern int pmf_call_function(struct device_node *target, const char *name,
232 struct pmf_args *args);
233
234
235/*
236 * For low latency interrupt usage, you can lookup for on-demand functions
237 * using the functions below
238 */
239
240extern struct pmf_function *pmf_find_function(struct device_node *target,
241 const char *name);
242
243extern struct pmf_function * pmf_get_function(struct pmf_function *func);
244extern void pmf_put_function(struct pmf_function *func);
245
246extern int pmf_call_one(struct pmf_function *func, struct pmf_args *args);
247
248
249/* Suspend/resume code called by via-pmu directly for now */
250extern void pmac_pfunc_base_suspend(void);
251extern void pmac_pfunc_base_resume(void);
252
253#endif /* __PMAC_PFUNC_H__ */
diff --git a/include/asm-powerpc/pmc.h b/include/asm-powerpc/pmc.h
index 5f41f3a2b293..07d6a4279319 100644
--- a/include/asm-powerpc/pmc.h
+++ b/include/asm-powerpc/pmc.h
@@ -18,6 +18,7 @@
18 */ 18 */
19#ifndef _POWERPC_PMC_H 19#ifndef _POWERPC_PMC_H
20#define _POWERPC_PMC_H 20#define _POWERPC_PMC_H
21#ifdef __KERNEL__
21 22
22#include <asm/ptrace.h> 23#include <asm/ptrace.h>
23 24
@@ -44,4 +45,5 @@ void dump_pmcs(void);
44extern struct op_powerpc_model op_model_fsl_booke; 45extern struct op_powerpc_model op_model_fsl_booke;
45#endif 46#endif
46 47
48#endif /* __KERNEL__ */
47#endif /* _POWERPC_PMC_H */ 49#endif /* _POWERPC_PMC_H */
diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h
index 36cdc869e580..bdef312900a1 100644
--- a/include/asm-powerpc/ppc-pci.h
+++ b/include/asm-powerpc/ppc-pci.h
@@ -8,6 +8,7 @@
8 */ 8 */
9#ifndef _ASM_POWERPC_PPC_PCI_H 9#ifndef _ASM_POWERPC_PPC_PCI_H
10#define _ASM_POWERPC_PPC_PCI_H 10#define _ASM_POWERPC_PPC_PCI_H
11#ifdef __KERNEL__
11 12
12#include <linux/pci.h> 13#include <linux/pci.h>
13#include <asm/pci-bridge.h> 14#include <asm/pci-bridge.h>
@@ -93,4 +94,5 @@ void eeh_clear_slot (struct device_node *dn, int mode_flag);
93 94
94#endif 95#endif
95 96
97#endif /* __KERNEL__ */
96#endif /* _ASM_POWERPC_PPC_PCI_H */ 98#endif /* _ASM_POWERPC_PPC_PCI_H */
diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h
index c27baa0563fe..0dc798d46ea4 100644
--- a/include/asm-powerpc/ppc_asm.h
+++ b/include/asm-powerpc/ppc_asm.h
@@ -94,6 +94,7 @@
94#define RFDI .long 0x4c00004e /* rfdi instruction */ 94#define RFDI .long 0x4c00004e /* rfdi instruction */
95#define RFMCI .long 0x4c00004c /* rfmci instruction */ 95#define RFMCI .long 0x4c00004c /* rfmci instruction */
96 96
97#ifdef __KERNEL__
97#ifdef CONFIG_PPC64 98#ifdef CONFIG_PPC64
98 99
99#define XGLUE(a,b) a##b 100#define XGLUE(a,b) a##b
@@ -325,6 +326,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
325#define CLR_TOP32(r) 326#define CLR_TOP32(r)
326#endif 327#endif
327 328
329#endif /* __KERNEL__ */
330
328/* The boring bits... */ 331/* The boring bits... */
329 332
330/* Condition Register Bit Fields */ 333/* Condition Register Bit Fields */
diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h
index d12382d292d4..415fa393b00c 100644
--- a/include/asm-powerpc/processor.h
+++ b/include/asm-powerpc/processor.h
@@ -10,7 +10,6 @@
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 */ 11 */
12 12
13#include <linux/config.h>
14#include <asm/reg.h> 13#include <asm/reg.h>
15 14
16#ifndef __ASSEMBLY__ 15#ifndef __ASSEMBLY__
@@ -50,6 +49,7 @@
50#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ 49#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */
51#define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */ 50#define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */
52 51
52#ifdef __KERNEL__
53#define platform_is_pseries() (_machine == PLATFORM_PSERIES || \ 53#define platform_is_pseries() (_machine == PLATFORM_PSERIES || \
54 _machine == PLATFORM_PSERIES_LPAR) 54 _machine == PLATFORM_PSERIES_LPAR)
55#define platform_is_lpar() (!!(_machine & PLATFORM_LPAR)) 55#define platform_is_lpar() (!!(_machine & PLATFORM_LPAR))
@@ -68,7 +68,6 @@ extern int _chrp_type;
68 * vendor. Board revision is also made available. This will be moved 68 * vendor. Board revision is also made available. This will be moved
69 * elsewhere soon 69 * elsewhere soon
70 */ 70 */
71extern unsigned char ucSystemType;
72extern unsigned char ucBoardRev; 71extern unsigned char ucBoardRev;
73extern unsigned char ucBoardRevMaj, ucBoardRevMin; 72extern unsigned char ucBoardRevMaj, ucBoardRevMin;
74 73
@@ -82,7 +81,7 @@ extern unsigned char ucBoardRevMaj, ucBoardRevMin;
82#else 81#else
83#define _machine 0 82#define _machine 0
84#endif /* CONFIG_PPC_MULTIPLATFORM */ 83#endif /* CONFIG_PPC_MULTIPLATFORM */
85 84#endif /* __KERNEL__ */
86/* 85/*
87 * Default implementation of macro that returns current 86 * Default implementation of macro that returns current
88 * instruction pointer ("program counter"). 87 * instruction pointer ("program counter").
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index f999df1c5c90..329e9bf62260 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -65,49 +65,11 @@ struct boot_param_header
65typedef u32 phandle; 65typedef u32 phandle;
66typedef u32 ihandle; 66typedef u32 ihandle;
67 67
68struct address_range {
69 unsigned long space;
70 unsigned long address;
71 unsigned long size;
72};
73
74struct interrupt_info { 68struct interrupt_info {
75 int line; 69 int line;
76 int sense; /* +ve/-ve logic, edge or level, etc. */ 70 int sense; /* +ve/-ve logic, edge or level, etc. */
77}; 71};
78 72
79struct pci_address {
80 u32 a_hi;
81 u32 a_mid;
82 u32 a_lo;
83};
84
85struct isa_address {
86 u32 a_hi;
87 u32 a_lo;
88};
89
90struct isa_range {
91 struct isa_address isa_addr;
92 struct pci_address pci_addr;
93 unsigned int size;
94};
95
96struct reg_property {
97 unsigned long address;
98 unsigned long size;
99};
100
101struct reg_property32 {
102 unsigned int address;
103 unsigned int size;
104};
105
106struct reg_property64 {
107 u64 address;
108 u64 size;
109};
110
111struct property { 73struct property {
112 char *name; 74 char *name;
113 int length; 75 int length;
@@ -120,8 +82,6 @@ struct device_node {
120 char *type; 82 char *type;
121 phandle node; 83 phandle node;
122 phandle linux_phandle; 84 phandle linux_phandle;
123 int n_addrs;
124 struct address_range *addrs;
125 int n_intrs; 85 int n_intrs;
126 struct interrupt_info *intrs; 86 struct interrupt_info *intrs;
127 char *full_name; 87 char *full_name;
@@ -223,5 +183,36 @@ extern struct resource *request_OF_resource(struct device_node* node,
223 int index, const char* name_postfix); 183 int index, const char* name_postfix);
224extern int release_OF_resource(struct device_node* node, int index); 184extern int release_OF_resource(struct device_node* node, int index);
225 185
186
187/*
188 * OF address retreival & translation
189 */
190
191
192/* Translate an OF address block into a CPU physical address
193 */
194#define OF_BAD_ADDR ((u64)-1)
195extern u64 of_translate_address(struct device_node *np, u32 *addr);
196
197/* Extract an address from a device, returns the region size and
198 * the address space flags too. The PCI version uses a BAR number
199 * instead of an absolute index
200 */
201extern u32 *of_get_address(struct device_node *dev, int index,
202 u64 *size, unsigned int *flags);
203extern u32 *of_get_pci_address(struct device_node *dev, int bar_no,
204 u64 *size, unsigned int *flags);
205
206/* Get an address as a resource. Note that if your address is
207 * a PIO address, the conversion will fail if the physical address
208 * can't be internally converted to an IO token with
209 * pci_address_to_pio(), that is because it's either called to early
210 * or it can't be matched to any host bridge IO space
211 */
212extern int of_address_to_resource(struct device_node *dev, int index,
213 struct resource *r);
214extern int of_pci_address_to_resource(struct device_node *dev, int bar,
215 struct resource *r);
216
226#endif /* __KERNEL__ */ 217#endif /* __KERNEL__ */
227#endif /* _POWERPC_PROM_H */ 218#endif /* _POWERPC_PROM_H */
diff --git a/include/asm-powerpc/ptrace.h b/include/asm-powerpc/ptrace.h
index 1f7ecdb0b6ce..9c550b314823 100644
--- a/include/asm-powerpc/ptrace.h
+++ b/include/asm-powerpc/ptrace.h
@@ -87,7 +87,7 @@ extern unsigned long profile_pc(struct pt_regs *regs);
87 87
88#define force_successful_syscall_return() \ 88#define force_successful_syscall_return() \
89 do { \ 89 do { \
90 current_thread_info()->syscall_noerror = 1; \ 90 set_thread_flag(TIF_NOERROR); \
91 } while(0) 91 } while(0)
92 92
93/* 93/*
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index eb392d038ed7..12ecc9b9f285 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -145,6 +145,10 @@
145#define SPRN_CTR 0x009 /* Count Register */ 145#define SPRN_CTR 0x009 /* Count Register */
146#define SPRN_CTRLF 0x088 146#define SPRN_CTRLF 0x088
147#define SPRN_CTRLT 0x098 147#define SPRN_CTRLT 0x098
148#define CTRL_CT 0xc0000000 /* current thread */
149#define CTRL_CT0 0x80000000 /* thread 0 */
150#define CTRL_CT1 0x40000000 /* thread 1 */
151#define CTRL_TE 0x00c00000 /* thread enable */
148#define CTRL_RUNLATCH 0x1 152#define CTRL_RUNLATCH 0x1
149#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ 153#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */
150#define DABR_TRANSLATION (1UL << 2) 154#define DABR_TRANSLATION (1UL << 2)
@@ -257,11 +261,11 @@
257#define SPRN_HID6 0x3F9 /* BE HID 6 */ 261#define SPRN_HID6 0x3F9 /* BE HID 6 */
258#define HID6_LB (0x0F<<12) /* Concurrent Large Page Modes */ 262#define HID6_LB (0x0F<<12) /* Concurrent Large Page Modes */
259#define HID6_DLP (1<<20) /* Disable all large page modes (4K only) */ 263#define HID6_DLP (1<<20) /* Disable all large page modes (4K only) */
260#define SPRN_TSCR 0x399 /* Thread switch control on BE */ 264#define SPRN_TSC_CELL 0x399 /* Thread switch control on Cell */
261#define SPRN_TTR 0x39A /* Thread switch timeout on BE */ 265#define TSC_CELL_DEC_ENABLE_0 0x400000 /* Decrementer Interrupt */
262#define TSCR_DEC_ENABLE 0x200000 /* Decrementer Interrupt */ 266#define TSC_CELL_DEC_ENABLE_1 0x200000 /* Decrementer Interrupt */
263#define TSCR_EE_ENABLE 0x100000 /* External Interrupt */ 267#define TSC_CELL_EE_ENABLE 0x100000 /* External Interrupt */
264#define TSCR_EE_BOOST 0x080000 /* External Interrupt Boost */ 268#define TSC_CELL_EE_BOOST 0x080000 /* External Interrupt Boost */
265#define SPRN_TSC 0x3FD /* Thread switch control on others */ 269#define SPRN_TSC 0x3FD /* Thread switch control on others */
266#define SPRN_TST 0x3FC /* Thread switch timeout on others */ 270#define SPRN_TST 0x3FC /* Thread switch timeout on others */
267#if !defined(SPRN_IAC1) && !defined(SPRN_IAC2) 271#if !defined(SPRN_IAC1) && !defined(SPRN_IAC2)
@@ -375,6 +379,14 @@
375#define SPRN_SPRG7 0x117 /* Special Purpose Register General 7 */ 379#define SPRN_SPRG7 0x117 /* Special Purpose Register General 7 */
376#define SPRN_SRR0 0x01A /* Save/Restore Register 0 */ 380#define SPRN_SRR0 0x01A /* Save/Restore Register 0 */
377#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */ 381#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */
382#define SRR1_WAKEMASK 0x00380000 /* reason for wakeup */
383#define SRR1_WAKERESET 0x00380000 /* System reset */
384#define SRR1_WAKESYSERR 0x00300000 /* System error */
385#define SRR1_WAKEEE 0x00200000 /* External interrupt */
386#define SRR1_WAKEMT 0x00280000 /* mtctrl */
387#define SRR1_WAKEDEC 0x00180000 /* Decrementer interrupt */
388#define SRR1_WAKETHERM 0x00100000 /* Thermal management interrupt */
389
378#ifndef SPRN_SVR 390#ifndef SPRN_SVR
379#define SPRN_SVR 0x11E /* System Version Register */ 391#define SPRN_SVR 0x11E /* System Version Register */
380#endif 392#endif
@@ -443,12 +455,35 @@
443#define SPRN_SDAR 781 455#define SPRN_SDAR 781
444 456
445#else /* 32-bit */ 457#else /* 32-bit */
446#define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */ 458#define SPRN_MMCR0 952 /* Monitor Mode Control Register 0 */
447#define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */ 459#define MMCR0_FC 0x80000000UL /* freeze counters */
448#define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */ 460#define MMCR0_FCS 0x40000000UL /* freeze in supervisor state */
449#define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */ 461#define MMCR0_FCP 0x20000000UL /* freeze in problem state */
450#define SPRN_PMC3 0x3BD /* Performance Counter Register 3 */ 462#define MMCR0_FCM1 0x10000000UL /* freeze counters while MSR mark = 1 */
451#define SPRN_PMC4 0x3BE /* Performance Counter Register 4 */ 463#define MMCR0_FCM0 0x08000000UL /* freeze counters while MSR mark = 0 */
464#define MMCR0_PMXE 0x04000000UL /* performance monitor exception enable */
465#define MMCR0_FCECE 0x02000000UL /* freeze ctrs on enabled cond or event */
466#define MMCR0_TBEE 0x00400000UL /* time base exception enable */
467#define MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/
468#define MMCR0_PMCnCE 0x00004000UL /* count enable for all but PMC 1*/
469#define MMCR0_TRIGGER 0x00002000UL /* TRIGGER enable */
470#define MMCR0_PMC1SEL 0x00001fc0UL /* PMC 1 Event */
471#define MMCR0_PMC2SEL 0x0000003fUL /* PMC 2 Event */
472
473#define SPRN_MMCR1 956
474#define MMCR1_PMC3SEL 0xf8000000UL /* PMC 3 Event */
475#define MMCR1_PMC4SEL 0x07c00000UL /* PMC 4 Event */
476#define MMCR1_PMC5SEL 0x003e0000UL /* PMC 5 Event */
477#define MMCR1_PMC6SEL 0x0001f800UL /* PMC 6 Event */
478#define SPRN_MMCR2 944
479#define SPRN_PMC1 953 /* Performance Counter Register 1 */
480#define SPRN_PMC2 954 /* Performance Counter Register 2 */
481#define SPRN_PMC3 957 /* Performance Counter Register 3 */
482#define SPRN_PMC4 958 /* Performance Counter Register 4 */
483#define SPRN_PMC5 945 /* Performance Counter Register 5 */
484#define SPRN_PMC6 946 /* Performance Counter Register 6 */
485
486#define SPRN_SIAR 955 /* Sampled Instruction Address Register */
452 487
453/* Bit definitions for MMCR0 and PMC1 / PMC2. */ 488/* Bit definitions for MMCR0 and PMC1 / PMC2. */
454#define MMCR0_PMC1_CYCLES (1 << 7) 489#define MMCR0_PMC1_CYCLES (1 << 7)
@@ -458,7 +493,6 @@
458#define MMCR0_PMC2_CYCLES 0x1 493#define MMCR0_PMC2_CYCLES 0x1
459#define MMCR0_PMC2_ITLB 0x7 494#define MMCR0_PMC2_ITLB 0x7
460#define MMCR0_PMC2_LOADMISSTIME 0x5 495#define MMCR0_PMC2_LOADMISSTIME 0x5
461#define MMCR0_PMXE (1 << 26)
462#endif 496#endif
463 497
464/* Processor Version Register (PVR) field extraction */ 498/* Processor Version Register (PVR) field extraction */
diff --git a/include/asm-powerpc/rtas.h b/include/asm-powerpc/rtas.h
index d1bb611ea626..3428889e27b7 100644
--- a/include/asm-powerpc/rtas.h
+++ b/include/asm-powerpc/rtas.h
@@ -1,5 +1,6 @@
1#ifndef _POWERPC_RTAS_H 1#ifndef _POWERPC_RTAS_H
2#define _POWERPC_RTAS_H 2#define _POWERPC_RTAS_H
3#ifdef __KERNEL__
3 4
4#include <linux/spinlock.h> 5#include <linux/spinlock.h>
5#include <asm/page.h> 6#include <asm/page.h>
@@ -229,4 +230,5 @@ extern unsigned long rtas_rmo_buf;
229 230
230#define GLOBAL_INTERRUPT_QUEUE 9005 231#define GLOBAL_INTERRUPT_QUEUE 9005
231 232
233#endif /* __KERNEL__ */
232#endif /* _POWERPC_RTAS_H */ 234#endif /* _POWERPC_RTAS_H */
diff --git a/include/asm-powerpc/seccomp.h b/include/asm-powerpc/seccomp.h
index 1e1cfe12882b..853765eb1f65 100644
--- a/include/asm-powerpc/seccomp.h
+++ b/include/asm-powerpc/seccomp.h
@@ -1,6 +1,10 @@
1#ifndef _ASM_POWERPC_SECCOMP_H 1#ifndef _ASM_POWERPC_SECCOMP_H
2#define _ASM_POWERPC_SECCOMP_H
2 3
4#ifdef __KERNEL__
3#include <linux/thread_info.h> 5#include <linux/thread_info.h>
6#endif
7
4#include <linux/unistd.h> 8#include <linux/unistd.h>
5 9
6#define __NR_seccomp_read __NR_read 10#define __NR_seccomp_read __NR_read
diff --git a/include/asm-powerpc/sections.h b/include/asm-powerpc/sections.h
index 47be2ac2a925..916018e425c4 100644
--- a/include/asm-powerpc/sections.h
+++ b/include/asm-powerpc/sections.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_SECTIONS_H 1#ifndef _ASM_POWERPC_SECTIONS_H
2#define _ASM_POWERPC_SECTIONS_H 2#define _ASM_POWERPC_SECTIONS_H
3#ifdef __KERNEL__
3 4
4#include <asm-generic/sections.h> 5#include <asm-generic/sections.h>
5 6
@@ -17,4 +18,5 @@ static inline int in_kernel_text(unsigned long addr)
17 18
18#endif 19#endif
19 20
21#endif /* __KERNEL__ */
20#endif /* _ASM_POWERPC_SECTIONS_H */ 22#endif /* _ASM_POWERPC_SECTIONS_H */
diff --git a/include/asm-powerpc/serial.h b/include/asm-powerpc/serial.h
index b273d630b32f..6dc9546d6908 100644
--- a/include/asm-powerpc/serial.h
+++ b/include/asm-powerpc/serial.h
@@ -15,4 +15,6 @@
15/* Default baud base if not found in device-tree */ 15/* Default baud base if not found in device-tree */
16#define BASE_BAUD ( 1843200 / 16 ) 16#define BASE_BAUD ( 1843200 / 16 )
17 17
18extern void find_legacy_serial_ports(void);
19
18#endif /* _PPC64_SERIAL_H */ 20#endif /* _PPC64_SERIAL_H */
diff --git a/include/asm-powerpc/signal.h b/include/asm-powerpc/signal.h
index 694c8d2dab87..a4d8f8648541 100644
--- a/include/asm-powerpc/signal.h
+++ b/include/asm-powerpc/signal.h
@@ -2,10 +2,13 @@
2#define _ASM_POWERPC_SIGNAL_H 2#define _ASM_POWERPC_SIGNAL_H
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include <linux/config.h>
6 5
7#define _NSIG 64 6#define _NSIG 64
8#define _NSIG_BPW BITS_PER_LONG 7#ifdef __powerpc64__
8#define _NSIG_BPW 64
9#else
10#define _NSIG_BPW 32
11#endif
9#define _NSIG_WORDS (_NSIG / _NSIG_BPW) 12#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
10 13
11typedef unsigned long old_sigset_t; /* at least 32 bits */ 14typedef unsigned long old_sigset_t; /* at least 32 bits */
diff --git a/include/asm-powerpc/smu.h b/include/asm-powerpc/smu.h
index 76c29a9784dd..134c2b5be0f2 100644
--- a/include/asm-powerpc/smu.h
+++ b/include/asm-powerpc/smu.h
@@ -4,9 +4,11 @@
4/* 4/*
5 * Definitions for talking to the SMU chip in newer G5 PowerMacs 5 * Definitions for talking to the SMU chip in newer G5 PowerMacs
6 */ 6 */
7 7#ifdef __KERNEL__
8#include <linux/config.h> 8#include <linux/config.h>
9#include <linux/list.h> 9#include <linux/list.h>
10#endif
11#include <linux/types.h>
10 12
11/* 13/*
12 * Known SMU commands 14 * Known SMU commands
@@ -356,6 +358,9 @@ extern unsigned long smu_cmdbuf_abs;
356 * Kenrel asynchronous i2c interface 358 * Kenrel asynchronous i2c interface
357 */ 359 */
358 360
361#define SMU_I2C_READ_MAX 0x1d
362#define SMU_I2C_WRITE_MAX 0x15
363
359/* SMU i2c header, exactly matches i2c header on wire */ 364/* SMU i2c header, exactly matches i2c header on wire */
360struct smu_i2c_param 365struct smu_i2c_param
361{ 366{
@@ -366,12 +371,9 @@ struct smu_i2c_param
366 u8 subaddr[3]; /* subaddress */ 371 u8 subaddr[3]; /* subaddress */
367 u8 caddr; /* combined address, filled by SMU driver */ 372 u8 caddr; /* combined address, filled by SMU driver */
368 u8 datalen; /* length of transfer */ 373 u8 datalen; /* length of transfer */
369 u8 data[7]; /* data */ 374 u8 data[SMU_I2C_READ_MAX]; /* data */
370}; 375};
371 376
372#define SMU_I2C_READ_MAX 0x0d
373#define SMU_I2C_WRITE_MAX 0x05
374
375struct smu_i2c_cmd 377struct smu_i2c_cmd
376{ 378{
377 /* public */ 379 /* public */
@@ -385,7 +387,7 @@ struct smu_i2c_cmd
385 int read; 387 int read;
386 int stage; 388 int stage;
387 int retries; 389 int retries;
388 u8 pdata[0x10]; 390 u8 pdata[32];
389 struct list_head link; 391 struct list_head link;
390}; 392};
391 393
@@ -487,8 +489,8 @@ struct smu_sdbp_slotspow {
487#define SMU_SDB_SENSORTREE_ID 0x25 489#define SMU_SDB_SENSORTREE_ID 0x25
488 490
489struct smu_sdbp_sensortree { 491struct smu_sdbp_sensortree {
490 u8 model_id; 492 __u8 model_id;
491 u8 unknown[3]; 493 __u8 unknown[3];
492}; 494};
493 495
494/* This partition contains CPU thermal control PID informations. So far 496/* This partition contains CPU thermal control PID informations. So far
@@ -498,13 +500,13 @@ struct smu_sdbp_sensortree {
498#define SMU_SDB_CPUPIDDATA_ID 0x17 500#define SMU_SDB_CPUPIDDATA_ID 0x17
499 501
500struct smu_sdbp_cpupiddata { 502struct smu_sdbp_cpupiddata {
501 u8 unknown1; 503 __u8 unknown1;
502 u8 target_temp_delta; 504 __u8 target_temp_delta;
503 u8 unknown2; 505 __u8 unknown2;
504 u8 history_len; 506 __u8 history_len;
505 s16 power_adj; 507 __s16 power_adj;
506 u16 max_power; 508 __u16 max_power;
507 s32 gp,gr,gd; 509 __s32 gp,gr,gd;
508}; 510};
509 511
510 512
@@ -517,7 +519,7 @@ struct smu_sdbp_cpupiddata {
517 * if not found. The data format is described below 519 * if not found. The data format is described below
518 */ 520 */
519extern struct smu_sdbp_header *smu_get_sdb_partition(int id, 521extern struct smu_sdbp_header *smu_get_sdb_partition(int id,
520 unsigned int *size); 522 unsigned int *size);
521 523
522#endif /* __KERNEL__ */ 524#endif /* __KERNEL__ */
523 525
diff --git a/include/asm-powerpc/sparsemem.h b/include/asm-powerpc/sparsemem.h
index ba1b34fdb967..38b1ea3b58fd 100644
--- a/include/asm-powerpc/sparsemem.h
+++ b/include/asm-powerpc/sparsemem.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_SPARSEMEM_H 1#ifndef _ASM_POWERPC_SPARSEMEM_H
2#define _ASM_POWERPC_SPARSEMEM_H 1 2#define _ASM_POWERPC_SPARSEMEM_H 1
3#ifdef __KERNEL__
3 4
4#ifdef CONFIG_SPARSEMEM 5#ifdef CONFIG_SPARSEMEM
5/* 6/*
@@ -13,8 +14,17 @@
13 14
14#ifdef CONFIG_MEMORY_HOTPLUG 15#ifdef CONFIG_MEMORY_HOTPLUG
15extern void create_section_mapping(unsigned long start, unsigned long end); 16extern void create_section_mapping(unsigned long start, unsigned long end);
17#ifdef CONFIG_NUMA
18extern int hot_add_scn_to_nid(unsigned long scn_addr);
19#else
20static inline int hot_add_scn_to_nid(unsigned long scn_addr)
21{
22 return 0;
23}
24#endif /* CONFIG_NUMA */
16#endif /* CONFIG_MEMORY_HOTPLUG */ 25#endif /* CONFIG_MEMORY_HOTPLUG */
17 26
18#endif /* CONFIG_SPARSEMEM */ 27#endif /* CONFIG_SPARSEMEM */
19 28
29#endif /* __KERNEL__ */
20#endif /* _ASM_POWERPC_SPARSEMEM_H */ 30#endif /* _ASM_POWERPC_SPARSEMEM_H */
diff --git a/include/asm-powerpc/spinlock.h b/include/asm-powerpc/spinlock.h
index caa4b14e0e94..754900901cd8 100644
--- a/include/asm-powerpc/spinlock.h
+++ b/include/asm-powerpc/spinlock.h
@@ -1,5 +1,6 @@
1#ifndef __ASM_SPINLOCK_H 1#ifndef __ASM_SPINLOCK_H
2#define __ASM_SPINLOCK_H 2#define __ASM_SPINLOCK_H
3#ifdef __KERNEL__
3 4
4/* 5/*
5 * Simple spin lock operations. 6 * Simple spin lock operations.
@@ -266,4 +267,5 @@ static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
266 rw->lock = 0; 267 rw->lock = 0;
267} 268}
268 269
270#endif /* __KERNEL__ */
269#endif /* __ASM_SPINLOCK_H */ 271#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
new file mode 100644
index 000000000000..38bacf2f6e0c
--- /dev/null
+++ b/include/asm-powerpc/spu.h
@@ -0,0 +1,600 @@
1/*
2 * SPU core / file system interface and HW structures
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 *
6 * Author: Arnd Bergmann <arndb@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef _SPU_H
24#define _SPU_H
25#ifdef __KERNEL__
26
27#include <linux/config.h>
28#include <linux/kref.h>
29#include <linux/workqueue.h>
30
31#define LS_SIZE (256 * 1024)
32#define LS_ADDR_MASK (LS_SIZE - 1)
33
34#define MFC_PUT_CMD 0x20
35#define MFC_PUTS_CMD 0x28
36#define MFC_PUTR_CMD 0x30
37#define MFC_PUTF_CMD 0x22
38#define MFC_PUTB_CMD 0x21
39#define MFC_PUTFS_CMD 0x2A
40#define MFC_PUTBS_CMD 0x29
41#define MFC_PUTRF_CMD 0x32
42#define MFC_PUTRB_CMD 0x31
43#define MFC_PUTL_CMD 0x24
44#define MFC_PUTRL_CMD 0x34
45#define MFC_PUTLF_CMD 0x26
46#define MFC_PUTLB_CMD 0x25
47#define MFC_PUTRLF_CMD 0x36
48#define MFC_PUTRLB_CMD 0x35
49
50#define MFC_GET_CMD 0x40
51#define MFC_GETS_CMD 0x48
52#define MFC_GETF_CMD 0x42
53#define MFC_GETB_CMD 0x41
54#define MFC_GETFS_CMD 0x4A
55#define MFC_GETBS_CMD 0x49
56#define MFC_GETL_CMD 0x44
57#define MFC_GETLF_CMD 0x46
58#define MFC_GETLB_CMD 0x45
59
60#define MFC_SDCRT_CMD 0x80
61#define MFC_SDCRTST_CMD 0x81
62#define MFC_SDCRZ_CMD 0x89
63#define MFC_SDCRS_CMD 0x8D
64#define MFC_SDCRF_CMD 0x8F
65
66#define MFC_GETLLAR_CMD 0xD0
67#define MFC_PUTLLC_CMD 0xB4
68#define MFC_PUTLLUC_CMD 0xB0
69#define MFC_PUTQLLUC_CMD 0xB8
70#define MFC_SNDSIG_CMD 0xA0
71#define MFC_SNDSIGB_CMD 0xA1
72#define MFC_SNDSIGF_CMD 0xA2
73#define MFC_BARRIER_CMD 0xC0
74#define MFC_EIEIO_CMD 0xC8
75#define MFC_SYNC_CMD 0xCC
76
77#define MFC_MIN_DMA_SIZE_SHIFT 4 /* 16 bytes */
78#define MFC_MAX_DMA_SIZE_SHIFT 14 /* 16384 bytes */
79#define MFC_MIN_DMA_SIZE (1 << MFC_MIN_DMA_SIZE_SHIFT)
80#define MFC_MAX_DMA_SIZE (1 << MFC_MAX_DMA_SIZE_SHIFT)
81#define MFC_MIN_DMA_SIZE_MASK (MFC_MIN_DMA_SIZE - 1)
82#define MFC_MAX_DMA_SIZE_MASK (MFC_MAX_DMA_SIZE - 1)
83#define MFC_MIN_DMA_LIST_SIZE 0x0008 /* 8 bytes */
84#define MFC_MAX_DMA_LIST_SIZE 0x4000 /* 16K bytes */
85
86#define MFC_TAGID_TO_TAGMASK(tag_id) (1 << (tag_id & 0x1F))
87
88/* Events for Channels 0-2 */
89#define MFC_DMA_TAG_STATUS_UPDATE_EVENT 0x00000001
90#define MFC_DMA_TAG_CMD_STALL_NOTIFY_EVENT 0x00000002
91#define MFC_DMA_QUEUE_AVAILABLE_EVENT 0x00000008
92#define MFC_SPU_MAILBOX_WRITTEN_EVENT 0x00000010
93#define MFC_DECREMENTER_EVENT 0x00000020
94#define MFC_PU_INT_MAILBOX_AVAILABLE_EVENT 0x00000040
95#define MFC_PU_MAILBOX_AVAILABLE_EVENT 0x00000080
96#define MFC_SIGNAL_2_EVENT 0x00000100
97#define MFC_SIGNAL_1_EVENT 0x00000200
98#define MFC_LLR_LOST_EVENT 0x00000400
99#define MFC_PRIV_ATTN_EVENT 0x00000800
100#define MFC_MULTI_SRC_EVENT 0x00001000
101
102/* Flags indicating progress during context switch. */
103#define SPU_CONTEXT_SWITCH_PENDING 0UL
104#define SPU_CONTEXT_SWITCH_ACTIVE 1UL
105
106struct spu_context;
107struct spu_runqueue;
108
109struct spu {
110 char *name;
111 unsigned long local_store_phys;
112 u8 *local_store;
113 struct spu_problem __iomem *problem;
114 struct spu_priv1 __iomem *priv1;
115 struct spu_priv2 __iomem *priv2;
116 struct list_head list;
117 struct list_head sched_list;
118 int number;
119 u32 isrc;
120 u32 node;
121 u64 flags;
122 u64 dar;
123 u64 dsisr;
124 struct kref kref;
125 size_t ls_size;
126 unsigned int slb_replace;
127 struct mm_struct *mm;
128 struct spu_context *ctx;
129 struct spu_runqueue *rq;
130 unsigned long long timestamp;
131 pid_t pid;
132 int prio;
133 int class_0_pending;
134 spinlock_t register_lock;
135
136 u32 stop_code;
137 void (* wbox_callback)(struct spu *spu);
138 void (* ibox_callback)(struct spu *spu);
139 void (* stop_callback)(struct spu *spu);
140
141 char irq_c0[8];
142 char irq_c1[8];
143 char irq_c2[8];
144};
145
146struct spu *spu_alloc(void);
147void spu_free(struct spu *spu);
148int spu_irq_class_0_bottom(struct spu *spu);
149int spu_irq_class_1_bottom(struct spu *spu);
150void spu_irq_setaffinity(struct spu *spu, int cpu);
151
152extern struct spufs_calls {
153 asmlinkage long (*create_thread)(const char __user *name,
154 unsigned int flags, mode_t mode);
155 asmlinkage long (*spu_run)(struct file *filp, __u32 __user *unpc,
156 __u32 __user *ustatus);
157 struct module *owner;
158} spufs_calls;
159
160#ifdef CONFIG_SPU_FS_MODULE
161int register_spu_syscalls(struct spufs_calls *calls);
162void unregister_spu_syscalls(struct spufs_calls *calls);
163#else
164static inline int register_spu_syscalls(struct spufs_calls *calls)
165{
166 return 0;
167}
168static inline void unregister_spu_syscalls(struct spufs_calls *calls)
169{
170}
171#endif /* MODULE */
172
173
174/* access to priv1 registers */
175void spu_int_mask_and(struct spu *spu, int class, u64 mask);
176void spu_int_mask_or(struct spu *spu, int class, u64 mask);
177void spu_int_mask_set(struct spu *spu, int class, u64 mask);
178u64 spu_int_mask_get(struct spu *spu, int class);
179void spu_int_stat_clear(struct spu *spu, int class, u64 stat);
180u64 spu_int_stat_get(struct spu *spu, int class);
181void spu_int_route_set(struct spu *spu, u64 route);
182u64 spu_mfc_dar_get(struct spu *spu);
183u64 spu_mfc_dsisr_get(struct spu *spu);
184void spu_mfc_dsisr_set(struct spu *spu, u64 dsisr);
185void spu_mfc_sdr_set(struct spu *spu, u64 sdr);
186void spu_mfc_sr1_set(struct spu *spu, u64 sr1);
187u64 spu_mfc_sr1_get(struct spu *spu);
188void spu_mfc_tclass_id_set(struct spu *spu, u64 tclass_id);
189u64 spu_mfc_tclass_id_get(struct spu *spu);
190void spu_tlb_invalidate(struct spu *spu);
191void spu_resource_allocation_groupID_set(struct spu *spu, u64 id);
192u64 spu_resource_allocation_groupID_get(struct spu *spu);
193void spu_resource_allocation_enable_set(struct spu *spu, u64 enable);
194u64 spu_resource_allocation_enable_get(struct spu *spu);
195
196
197/*
198 * This defines the Local Store, Problem Area and Privlege Area of an SPU.
199 */
200
201union mfc_tag_size_class_cmd {
202 struct {
203 u16 mfc_size;
204 u16 mfc_tag;
205 u8 pad;
206 u8 mfc_rclassid;
207 u16 mfc_cmd;
208 } u;
209 struct {
210 u32 mfc_size_tag32;
211 u32 mfc_class_cmd32;
212 } by32;
213 u64 all64;
214};
215
216struct mfc_cq_sr {
217 u64 mfc_cq_data0_RW;
218 u64 mfc_cq_data1_RW;
219 u64 mfc_cq_data2_RW;
220 u64 mfc_cq_data3_RW;
221};
222
223struct spu_problem {
224#define MS_SYNC_PENDING 1L
225 u64 spc_mssync_RW; /* 0x0000 */
226 u8 pad_0x0008_0x3000[0x3000 - 0x0008];
227
228 /* DMA Area */
229 u8 pad_0x3000_0x3004[0x4]; /* 0x3000 */
230 u32 mfc_lsa_W; /* 0x3004 */
231 u64 mfc_ea_W; /* 0x3008 */
232 union mfc_tag_size_class_cmd mfc_union_W; /* 0x3010 */
233 u8 pad_0x3018_0x3104[0xec]; /* 0x3018 */
234 u32 dma_qstatus_R; /* 0x3104 */
235 u8 pad_0x3108_0x3204[0xfc]; /* 0x3108 */
236 u32 dma_querytype_RW; /* 0x3204 */
237 u8 pad_0x3208_0x321c[0x14]; /* 0x3208 */
238 u32 dma_querymask_RW; /* 0x321c */
239 u8 pad_0x3220_0x322c[0xc]; /* 0x3220 */
240 u32 dma_tagstatus_R; /* 0x322c */
241#define DMA_TAGSTATUS_INTR_ANY 1u
242#define DMA_TAGSTATUS_INTR_ALL 2u
243 u8 pad_0x3230_0x4000[0x4000 - 0x3230]; /* 0x3230 */
244
245 /* SPU Control Area */
246 u8 pad_0x4000_0x4004[0x4]; /* 0x4000 */
247 u32 pu_mb_R; /* 0x4004 */
248 u8 pad_0x4008_0x400c[0x4]; /* 0x4008 */
249 u32 spu_mb_W; /* 0x400c */
250 u8 pad_0x4010_0x4014[0x4]; /* 0x4010 */
251 u32 mb_stat_R; /* 0x4014 */
252 u8 pad_0x4018_0x401c[0x4]; /* 0x4018 */
253 u32 spu_runcntl_RW; /* 0x401c */
254#define SPU_RUNCNTL_STOP 0L
255#define SPU_RUNCNTL_RUNNABLE 1L
256 u8 pad_0x4020_0x4024[0x4]; /* 0x4020 */
257 u32 spu_status_R; /* 0x4024 */
258#define SPU_STOP_STATUS_SHIFT 16
259#define SPU_STATUS_STOPPED 0x0
260#define SPU_STATUS_RUNNING 0x1
261#define SPU_STATUS_STOPPED_BY_STOP 0x2
262#define SPU_STATUS_STOPPED_BY_HALT 0x4
263#define SPU_STATUS_WAITING_FOR_CHANNEL 0x8
264#define SPU_STATUS_SINGLE_STEP 0x10
265#define SPU_STATUS_INVALID_INSTR 0x20
266#define SPU_STATUS_INVALID_CH 0x40
267#define SPU_STATUS_ISOLATED_STATE 0x80
268#define SPU_STATUS_ISOLATED_LOAD_STAUTUS 0x200
269#define SPU_STATUS_ISOLATED_EXIT_STAUTUS 0x400
270 u8 pad_0x4028_0x402c[0x4]; /* 0x4028 */
271 u32 spu_spe_R; /* 0x402c */
272 u8 pad_0x4030_0x4034[0x4]; /* 0x4030 */
273 u32 spu_npc_RW; /* 0x4034 */
274 u8 pad_0x4038_0x14000[0x14000 - 0x4038]; /* 0x4038 */
275
276 /* Signal Notification Area */
277 u8 pad_0x14000_0x1400c[0xc]; /* 0x14000 */
278 u32 signal_notify1; /* 0x1400c */
279 u8 pad_0x14010_0x1c00c[0x7ffc]; /* 0x14010 */
280 u32 signal_notify2; /* 0x1c00c */
281} __attribute__ ((aligned(0x20000)));
282
283/* SPU Privilege 2 State Area */
284struct spu_priv2 {
285 /* MFC Registers */
286 u8 pad_0x0000_0x1100[0x1100 - 0x0000]; /* 0x0000 */
287
288 /* SLB Management Registers */
289 u8 pad_0x1100_0x1108[0x8]; /* 0x1100 */
290 u64 slb_index_W; /* 0x1108 */
291#define SLB_INDEX_MASK 0x7L
292 u64 slb_esid_RW; /* 0x1110 */
293 u64 slb_vsid_RW; /* 0x1118 */
294#define SLB_VSID_SUPERVISOR_STATE (0x1ull << 11)
295#define SLB_VSID_SUPERVISOR_STATE_MASK (0x1ull << 11)
296#define SLB_VSID_PROBLEM_STATE (0x1ull << 10)
297#define SLB_VSID_PROBLEM_STATE_MASK (0x1ull << 10)
298#define SLB_VSID_EXECUTE_SEGMENT (0x1ull << 9)
299#define SLB_VSID_NO_EXECUTE_SEGMENT (0x1ull << 9)
300#define SLB_VSID_EXECUTE_SEGMENT_MASK (0x1ull << 9)
301#define SLB_VSID_4K_PAGE (0x0 << 8)
302#define SLB_VSID_LARGE_PAGE (0x1ull << 8)
303#define SLB_VSID_PAGE_SIZE_MASK (0x1ull << 8)
304#define SLB_VSID_CLASS_MASK (0x1ull << 7)
305#define SLB_VSID_VIRTUAL_PAGE_SIZE_MASK (0x1ull << 6)
306 u64 slb_invalidate_entry_W; /* 0x1120 */
307 u64 slb_invalidate_all_W; /* 0x1128 */
308 u8 pad_0x1130_0x2000[0x2000 - 0x1130]; /* 0x1130 */
309
310 /* Context Save / Restore Area */
311 struct mfc_cq_sr spuq[16]; /* 0x2000 */
312 struct mfc_cq_sr puq[8]; /* 0x2200 */
313 u8 pad_0x2300_0x3000[0x3000 - 0x2300]; /* 0x2300 */
314
315 /* MFC Control */
316 u64 mfc_control_RW; /* 0x3000 */
317#define MFC_CNTL_RESUME_DMA_QUEUE (0ull << 0)
318#define MFC_CNTL_SUSPEND_DMA_QUEUE (1ull << 0)
319#define MFC_CNTL_SUSPEND_DMA_QUEUE_MASK (1ull << 0)
320#define MFC_CNTL_NORMAL_DMA_QUEUE_OPERATION (0ull << 8)
321#define MFC_CNTL_SUSPEND_IN_PROGRESS (1ull << 8)
322#define MFC_CNTL_SUSPEND_COMPLETE (3ull << 8)
323#define MFC_CNTL_SUSPEND_DMA_STATUS_MASK (3ull << 8)
324#define MFC_CNTL_DMA_QUEUES_EMPTY (1ull << 14)
325#define MFC_CNTL_DMA_QUEUES_EMPTY_MASK (1ull << 14)
326#define MFC_CNTL_PURGE_DMA_REQUEST (1ull << 15)
327#define MFC_CNTL_PURGE_DMA_IN_PROGRESS (1ull << 24)
328#define MFC_CNTL_PURGE_DMA_COMPLETE (3ull << 24)
329#define MFC_CNTL_PURGE_DMA_STATUS_MASK (3ull << 24)
330#define MFC_CNTL_RESTART_DMA_COMMAND (1ull << 32)
331#define MFC_CNTL_DMA_COMMAND_REISSUE_PENDING (1ull << 32)
332#define MFC_CNTL_DMA_COMMAND_REISSUE_STATUS_MASK (1ull << 32)
333#define MFC_CNTL_MFC_PRIVILEGE_STATE (2ull << 33)
334#define MFC_CNTL_MFC_PROBLEM_STATE (3ull << 33)
335#define MFC_CNTL_MFC_KEY_PROTECTION_STATE_MASK (3ull << 33)
336#define MFC_CNTL_DECREMENTER_HALTED (1ull << 35)
337#define MFC_CNTL_DECREMENTER_RUNNING (1ull << 40)
338#define MFC_CNTL_DECREMENTER_STATUS_MASK (1ull << 40)
339 u8 pad_0x3008_0x4000[0x4000 - 0x3008]; /* 0x3008 */
340
341 /* Interrupt Mailbox */
342 u64 puint_mb_R; /* 0x4000 */
343 u8 pad_0x4008_0x4040[0x4040 - 0x4008]; /* 0x4008 */
344
345 /* SPU Control */
346 u64 spu_privcntl_RW; /* 0x4040 */
347#define SPU_PRIVCNTL_MODE_NORMAL (0x0ull << 0)
348#define SPU_PRIVCNTL_MODE_SINGLE_STEP (0x1ull << 0)
349#define SPU_PRIVCNTL_MODE_MASK (0x1ull << 0)
350#define SPU_PRIVCNTL_NO_ATTENTION_EVENT (0x0ull << 1)
351#define SPU_PRIVCNTL_ATTENTION_EVENT (0x1ull << 1)
352#define SPU_PRIVCNTL_ATTENTION_EVENT_MASK (0x1ull << 1)
353#define SPU_PRIVCNT_LOAD_REQUEST_NORMAL (0x0ull << 2)
354#define SPU_PRIVCNT_LOAD_REQUEST_ENABLE_MASK (0x1ull << 2)
355 u8 pad_0x4048_0x4058[0x10]; /* 0x4048 */
356 u64 spu_lslr_RW; /* 0x4058 */
357 u64 spu_chnlcntptr_RW; /* 0x4060 */
358 u64 spu_chnlcnt_RW; /* 0x4068 */
359 u64 spu_chnldata_RW; /* 0x4070 */
360 u64 spu_cfg_RW; /* 0x4078 */
361 u8 pad_0x4080_0x5000[0x5000 - 0x4080]; /* 0x4080 */
362
363 /* PV2_ImplRegs: Implementation-specific privileged-state 2 regs */
364 u64 spu_pm_trace_tag_status_RW; /* 0x5000 */
365 u64 spu_tag_status_query_RW; /* 0x5008 */
366#define TAG_STATUS_QUERY_CONDITION_BITS (0x3ull << 32)
367#define TAG_STATUS_QUERY_MASK_BITS (0xffffffffull)
368 u64 spu_cmd_buf1_RW; /* 0x5010 */
369#define SPU_COMMAND_BUFFER_1_LSA_BITS (0x7ffffull << 32)
370#define SPU_COMMAND_BUFFER_1_EAH_BITS (0xffffffffull)
371 u64 spu_cmd_buf2_RW; /* 0x5018 */
372#define SPU_COMMAND_BUFFER_2_EAL_BITS ((0xffffffffull) << 32)
373#define SPU_COMMAND_BUFFER_2_TS_BITS (0xffffull << 16)
374#define SPU_COMMAND_BUFFER_2_TAG_BITS (0x3full)
375 u64 spu_atomic_status_RW; /* 0x5020 */
376} __attribute__ ((aligned(0x20000)));
377
378/* SPU Privilege 1 State Area */
379struct spu_priv1 {
380 /* Control and Configuration Area */
381 u64 mfc_sr1_RW; /* 0x000 */
382#define MFC_STATE1_LOCAL_STORAGE_DECODE_MASK 0x01ull
383#define MFC_STATE1_BUS_TLBIE_MASK 0x02ull
384#define MFC_STATE1_REAL_MODE_OFFSET_ENABLE_MASK 0x04ull
385#define MFC_STATE1_PROBLEM_STATE_MASK 0x08ull
386#define MFC_STATE1_RELOCATE_MASK 0x10ull
387#define MFC_STATE1_MASTER_RUN_CONTROL_MASK 0x20ull
388 u64 mfc_lpid_RW; /* 0x008 */
389 u64 spu_idr_RW; /* 0x010 */
390 u64 mfc_vr_RO; /* 0x018 */
391#define MFC_VERSION_BITS (0xffff << 16)
392#define MFC_REVISION_BITS (0xffff)
393#define MFC_GET_VERSION_BITS(vr) (((vr) & MFC_VERSION_BITS) >> 16)
394#define MFC_GET_REVISION_BITS(vr) ((vr) & MFC_REVISION_BITS)
395 u64 spu_vr_RO; /* 0x020 */
396#define SPU_VERSION_BITS (0xffff << 16)
397#define SPU_REVISION_BITS (0xffff)
398#define SPU_GET_VERSION_BITS(vr) (vr & SPU_VERSION_BITS) >> 16
399#define SPU_GET_REVISION_BITS(vr) (vr & SPU_REVISION_BITS)
400 u8 pad_0x28_0x100[0x100 - 0x28]; /* 0x28 */
401
402
403 /* Interrupt Area */
404 u64 int_mask_RW[3]; /* 0x100 */
405#define CLASS0_ENABLE_DMA_ALIGNMENT_INTR 0x1L
406#define CLASS0_ENABLE_INVALID_DMA_COMMAND_INTR 0x2L
407#define CLASS0_ENABLE_SPU_ERROR_INTR 0x4L
408#define CLASS0_ENABLE_MFC_FIR_INTR 0x8L
409#define CLASS1_ENABLE_SEGMENT_FAULT_INTR 0x1L
410#define CLASS1_ENABLE_STORAGE_FAULT_INTR 0x2L
411#define CLASS1_ENABLE_LS_COMPARE_SUSPEND_ON_GET_INTR 0x4L
412#define CLASS1_ENABLE_LS_COMPARE_SUSPEND_ON_PUT_INTR 0x8L
413#define CLASS2_ENABLE_MAILBOX_INTR 0x1L
414#define CLASS2_ENABLE_SPU_STOP_INTR 0x2L
415#define CLASS2_ENABLE_SPU_HALT_INTR 0x4L
416#define CLASS2_ENABLE_SPU_DMA_TAG_GROUP_COMPLETE_INTR 0x8L
417 u8 pad_0x118_0x140[0x28]; /* 0x118 */
418 u64 int_stat_RW[3]; /* 0x140 */
419 u8 pad_0x158_0x180[0x28]; /* 0x158 */
420 u64 int_route_RW; /* 0x180 */
421
422 /* Interrupt Routing */
423 u8 pad_0x188_0x200[0x200 - 0x188]; /* 0x188 */
424
425 /* Atomic Unit Control Area */
426 u64 mfc_atomic_flush_RW; /* 0x200 */
427#define mfc_atomic_flush_enable 0x1L
428 u8 pad_0x208_0x280[0x78]; /* 0x208 */
429 u64 resource_allocation_groupID_RW; /* 0x280 */
430 u64 resource_allocation_enable_RW; /* 0x288 */
431 u8 pad_0x290_0x3c8[0x3c8 - 0x290]; /* 0x290 */
432
433 /* SPU_Cache_ImplRegs: Implementation-dependent cache registers */
434
435 u64 smf_sbi_signal_sel; /* 0x3c8 */
436#define smf_sbi_mask_lsb 56
437#define smf_sbi_shift (63 - smf_sbi_mask_lsb)
438#define smf_sbi_mask (0x301LL << smf_sbi_shift)
439#define smf_sbi_bus0_bits (0x001LL << smf_sbi_shift)
440#define smf_sbi_bus2_bits (0x100LL << smf_sbi_shift)
441#define smf_sbi2_bus0_bits (0x201LL << smf_sbi_shift)
442#define smf_sbi2_bus2_bits (0x300LL << smf_sbi_shift)
443 u64 smf_ato_signal_sel; /* 0x3d0 */
444#define smf_ato_mask_lsb 35
445#define smf_ato_shift (63 - smf_ato_mask_lsb)
446#define smf_ato_mask (0x3LL << smf_ato_shift)
447#define smf_ato_bus0_bits (0x2LL << smf_ato_shift)
448#define smf_ato_bus2_bits (0x1LL << smf_ato_shift)
449 u8 pad_0x3d8_0x400[0x400 - 0x3d8]; /* 0x3d8 */
450
451 /* TLB Management Registers */
452 u64 mfc_sdr_RW; /* 0x400 */
453 u8 pad_0x408_0x500[0xf8]; /* 0x408 */
454 u64 tlb_index_hint_RO; /* 0x500 */
455 u64 tlb_index_W; /* 0x508 */
456 u64 tlb_vpn_RW; /* 0x510 */
457 u64 tlb_rpn_RW; /* 0x518 */
458 u8 pad_0x520_0x540[0x20]; /* 0x520 */
459 u64 tlb_invalidate_entry_W; /* 0x540 */
460 u64 tlb_invalidate_all_W; /* 0x548 */
461 u8 pad_0x550_0x580[0x580 - 0x550]; /* 0x550 */
462
463 /* SPU_MMU_ImplRegs: Implementation-dependent MMU registers */
464 u64 smm_hid; /* 0x580 */
465#define PAGE_SIZE_MASK 0xf000000000000000ull
466#define PAGE_SIZE_16MB_64KB 0x2000000000000000ull
467 u8 pad_0x588_0x600[0x600 - 0x588]; /* 0x588 */
468
469 /* MFC Status/Control Area */
470 u64 mfc_accr_RW; /* 0x600 */
471#define MFC_ACCR_EA_ACCESS_GET (1 << 0)
472#define MFC_ACCR_EA_ACCESS_PUT (1 << 1)
473#define MFC_ACCR_LS_ACCESS_GET (1 << 3)
474#define MFC_ACCR_LS_ACCESS_PUT (1 << 4)
475 u8 pad_0x608_0x610[0x8]; /* 0x608 */
476 u64 mfc_dsisr_RW; /* 0x610 */
477#define MFC_DSISR_PTE_NOT_FOUND (1 << 30)
478#define MFC_DSISR_ACCESS_DENIED (1 << 27)
479#define MFC_DSISR_ATOMIC (1 << 26)
480#define MFC_DSISR_ACCESS_PUT (1 << 25)
481#define MFC_DSISR_ADDR_MATCH (1 << 22)
482#define MFC_DSISR_LS (1 << 17)
483#define MFC_DSISR_L (1 << 16)
484#define MFC_DSISR_ADDRESS_OVERFLOW (1 << 0)
485 u8 pad_0x618_0x620[0x8]; /* 0x618 */
486 u64 mfc_dar_RW; /* 0x620 */
487 u8 pad_0x628_0x700[0x700 - 0x628]; /* 0x628 */
488
489 /* Replacement Management Table (RMT) Area */
490 u64 rmt_index_RW; /* 0x700 */
491 u8 pad_0x708_0x710[0x8]; /* 0x708 */
492 u64 rmt_data1_RW; /* 0x710 */
493 u8 pad_0x718_0x800[0x800 - 0x718]; /* 0x718 */
494
495 /* Control/Configuration Registers */
496 u64 mfc_dsir_R; /* 0x800 */
497#define MFC_DSIR_Q (1 << 31)
498#define MFC_DSIR_SPU_QUEUE MFC_DSIR_Q
499 u64 mfc_lsacr_RW; /* 0x808 */
500#define MFC_LSACR_COMPARE_MASK ((~0ull) << 32)
501#define MFC_LSACR_COMPARE_ADDR ((~0ull) >> 32)
502 u64 mfc_lscrr_R; /* 0x810 */
503#define MFC_LSCRR_Q (1 << 31)
504#define MFC_LSCRR_SPU_QUEUE MFC_LSCRR_Q
505#define MFC_LSCRR_QI_SHIFT 32
506#define MFC_LSCRR_QI_MASK ((~0ull) << MFC_LSCRR_QI_SHIFT)
507 u8 pad_0x818_0x820[0x8]; /* 0x818 */
508 u64 mfc_tclass_id_RW; /* 0x820 */
509#define MFC_TCLASS_ID_ENABLE (1L << 0L)
510#define MFC_TCLASS_SLOT2_ENABLE (1L << 5L)
511#define MFC_TCLASS_SLOT1_ENABLE (1L << 6L)
512#define MFC_TCLASS_SLOT0_ENABLE (1L << 7L)
513#define MFC_TCLASS_QUOTA_2_SHIFT 8L
514#define MFC_TCLASS_QUOTA_1_SHIFT 16L
515#define MFC_TCLASS_QUOTA_0_SHIFT 24L
516#define MFC_TCLASS_QUOTA_2_MASK (0x1FL << MFC_TCLASS_QUOTA_2_SHIFT)
517#define MFC_TCLASS_QUOTA_1_MASK (0x1FL << MFC_TCLASS_QUOTA_1_SHIFT)
518#define MFC_TCLASS_QUOTA_0_MASK (0x1FL << MFC_TCLASS_QUOTA_0_SHIFT)
519 u8 pad_0x828_0x900[0x900 - 0x828]; /* 0x828 */
520
521 /* Real Mode Support Registers */
522 u64 mfc_rm_boundary; /* 0x900 */
523 u8 pad_0x908_0x938[0x30]; /* 0x908 */
524 u64 smf_dma_signal_sel; /* 0x938 */
525#define mfc_dma1_mask_lsb 41
526#define mfc_dma1_shift (63 - mfc_dma1_mask_lsb)
527#define mfc_dma1_mask (0x3LL << mfc_dma1_shift)
528#define mfc_dma1_bits (0x1LL << mfc_dma1_shift)
529#define mfc_dma2_mask_lsb 43
530#define mfc_dma2_shift (63 - mfc_dma2_mask_lsb)
531#define mfc_dma2_mask (0x3LL << mfc_dma2_shift)
532#define mfc_dma2_bits (0x1LL << mfc_dma2_shift)
533 u8 pad_0x940_0xa38[0xf8]; /* 0x940 */
534 u64 smm_signal_sel; /* 0xa38 */
535#define smm_sig_mask_lsb 12
536#define smm_sig_shift (63 - smm_sig_mask_lsb)
537#define smm_sig_mask (0x3LL << smm_sig_shift)
538#define smm_sig_bus0_bits (0x2LL << smm_sig_shift)
539#define smm_sig_bus2_bits (0x1LL << smm_sig_shift)
540 u8 pad_0xa40_0xc00[0xc00 - 0xa40]; /* 0xa40 */
541
542 /* DMA Command Error Area */
543 u64 mfc_cer_R; /* 0xc00 */
544#define MFC_CER_Q (1 << 31)
545#define MFC_CER_SPU_QUEUE MFC_CER_Q
546 u8 pad_0xc08_0x1000[0x1000 - 0xc08]; /* 0xc08 */
547
548 /* PV1_ImplRegs: Implementation-dependent privileged-state 1 regs */
549 /* DMA Command Error Area */
550 u64 spu_ecc_cntl_RW; /* 0x1000 */
551#define SPU_ECC_CNTL_E (1ull << 0ull)
552#define SPU_ECC_CNTL_ENABLE SPU_ECC_CNTL_E
553#define SPU_ECC_CNTL_DISABLE (~SPU_ECC_CNTL_E & 1L)
554#define SPU_ECC_CNTL_S (1ull << 1ull)
555#define SPU_ECC_STOP_AFTER_ERROR SPU_ECC_CNTL_S
556#define SPU_ECC_CONTINUE_AFTER_ERROR (~SPU_ECC_CNTL_S & 2L)
557#define SPU_ECC_CNTL_B (1ull << 2ull)
558#define SPU_ECC_BACKGROUND_ENABLE SPU_ECC_CNTL_B
559#define SPU_ECC_BACKGROUND_DISABLE (~SPU_ECC_CNTL_B & 4L)
560#define SPU_ECC_CNTL_I_SHIFT 3ull
561#define SPU_ECC_CNTL_I_MASK (3ull << SPU_ECC_CNTL_I_SHIFT)
562#define SPU_ECC_WRITE_ALWAYS (~SPU_ECC_CNTL_I & 12L)
563#define SPU_ECC_WRITE_CORRECTABLE (1ull << SPU_ECC_CNTL_I_SHIFT)
564#define SPU_ECC_WRITE_UNCORRECTABLE (3ull << SPU_ECC_CNTL_I_SHIFT)
565#define SPU_ECC_CNTL_D (1ull << 5ull)
566#define SPU_ECC_DETECTION_ENABLE SPU_ECC_CNTL_D
567#define SPU_ECC_DETECTION_DISABLE (~SPU_ECC_CNTL_D & 32L)
568 u64 spu_ecc_stat_RW; /* 0x1008 */
569#define SPU_ECC_CORRECTED_ERROR (1ull << 0ul)
570#define SPU_ECC_UNCORRECTED_ERROR (1ull << 1ul)
571#define SPU_ECC_SCRUB_COMPLETE (1ull << 2ul)
572#define SPU_ECC_SCRUB_IN_PROGRESS (1ull << 3ul)
573#define SPU_ECC_INSTRUCTION_ERROR (1ull << 4ul)
574#define SPU_ECC_DATA_ERROR (1ull << 5ul)
575#define SPU_ECC_DMA_ERROR (1ull << 6ul)
576#define SPU_ECC_STATUS_CNT_MASK (256ull << 8)
577 u64 spu_ecc_addr_RW; /* 0x1010 */
578 u64 spu_err_mask_RW; /* 0x1018 */
579#define SPU_ERR_ILLEGAL_INSTR (1ull << 0ul)
580#define SPU_ERR_ILLEGAL_CHANNEL (1ull << 1ul)
581 u8 pad_0x1020_0x1028[0x1028 - 0x1020]; /* 0x1020 */
582
583 /* SPU Debug-Trace Bus (DTB) Selection Registers */
584 u64 spu_trig0_sel; /* 0x1028 */
585 u64 spu_trig1_sel; /* 0x1030 */
586 u64 spu_trig2_sel; /* 0x1038 */
587 u64 spu_trig3_sel; /* 0x1040 */
588 u64 spu_trace_sel; /* 0x1048 */
589#define spu_trace_sel_mask 0x1f1fLL
590#define spu_trace_sel_bus0_bits 0x1000LL
591#define spu_trace_sel_bus2_bits 0x0010LL
592 u64 spu_event0_sel; /* 0x1050 */
593 u64 spu_event1_sel; /* 0x1058 */
594 u64 spu_event2_sel; /* 0x1060 */
595 u64 spu_event3_sel; /* 0x1068 */
596 u64 spu_trace_cntl; /* 0x1070 */
597} __attribute__ ((aligned(0x2000)));
598
599#endif /* __KERNEL__ */
600#endif
diff --git a/include/asm-powerpc/spu_csa.h b/include/asm-powerpc/spu_csa.h
new file mode 100644
index 000000000000..ba18d7d4dde2
--- /dev/null
+++ b/include/asm-powerpc/spu_csa.h
@@ -0,0 +1,255 @@
1/*
2 * spu_csa.h: Definitions for SPU context save area (CSA).
3 *
4 * (C) Copyright IBM 2005
5 *
6 * Author: Mark Nutter <mnutter@us.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef _SPU_CSA_H_
24#define _SPU_CSA_H_
25#ifdef __KERNEL__
26
27/*
28 * Total number of 128-bit registers.
29 */
30#define NR_SPU_GPRS 128
31#define NR_SPU_SPRS 9
32#define NR_SPU_REGS_PAD 7
33#define NR_SPU_SPILL_REGS 144 /* GPRS + SPRS + PAD */
34#define SIZEOF_SPU_SPILL_REGS NR_SPU_SPILL_REGS * 16
35
36#define SPU_SAVE_COMPLETE 0x3FFB
37#define SPU_RESTORE_COMPLETE 0x3FFC
38
39/*
40 * Definitions for various 'stopped' status conditions,
41 * to be recreated during context restore.
42 */
43#define SPU_STOPPED_STATUS_P 1
44#define SPU_STOPPED_STATUS_I 2
45#define SPU_STOPPED_STATUS_H 3
46#define SPU_STOPPED_STATUS_S 4
47#define SPU_STOPPED_STATUS_S_I 5
48#define SPU_STOPPED_STATUS_S_P 6
49#define SPU_STOPPED_STATUS_P_H 7
50#define SPU_STOPPED_STATUS_P_I 8
51#define SPU_STOPPED_STATUS_R 9
52
53#ifndef __ASSEMBLY__
54/**
55 * spu_reg128 - generic 128-bit register definition.
56 */
57struct spu_reg128 {
58 u32 slot[4];
59};
60
61/**
62 * struct spu_lscsa - Local Store Context Save Area.
63 * @gprs: Array of saved registers.
64 * @fpcr: Saved floating point status control register.
65 * @decr: Saved decrementer value.
66 * @decr_status: Indicates decrementer run status.
67 * @ppu_mb: Saved PPU mailbox data.
68 * @ppuint_mb: Saved PPU interrupting mailbox data.
69 * @tag_mask: Saved tag group mask.
70 * @event_mask: Saved event mask.
71 * @srr0: Saved SRR0.
72 * @stopped_status: Conditions to be recreated by restore.
73 * @ls: Saved contents of Local Storage Area.
74 *
75 * The LSCSA represents state that is primarily saved and
76 * restored by SPU-side code.
77 */
78struct spu_lscsa {
79 struct spu_reg128 gprs[128];
80 struct spu_reg128 fpcr;
81 struct spu_reg128 decr;
82 struct spu_reg128 decr_status;
83 struct spu_reg128 ppu_mb;
84 struct spu_reg128 ppuint_mb;
85 struct spu_reg128 tag_mask;
86 struct spu_reg128 event_mask;
87 struct spu_reg128 srr0;
88 struct spu_reg128 stopped_status;
89 struct spu_reg128 pad[119]; /* 'ls' must be page-aligned. */
90 unsigned char ls[LS_SIZE];
91};
92
93/*
94 * struct spu_problem_collapsed - condensed problem state area, w/o pads.
95 */
96struct spu_problem_collapsed {
97 u64 spc_mssync_RW;
98 u32 mfc_lsa_W;
99 u32 unused_pad0;
100 u64 mfc_ea_W;
101 union mfc_tag_size_class_cmd mfc_union_W;
102 u32 dma_qstatus_R;
103 u32 dma_querytype_RW;
104 u32 dma_querymask_RW;
105 u32 dma_tagstatus_R;
106 u32 pu_mb_R;
107 u32 spu_mb_W;
108 u32 mb_stat_R;
109 u32 spu_runcntl_RW;
110 u32 spu_status_R;
111 u32 spu_spc_R;
112 u32 spu_npc_RW;
113 u32 signal_notify1;
114 u32 signal_notify2;
115 u32 unused_pad1;
116};
117
118/*
119 * struct spu_priv1_collapsed - condensed privileged 1 area, w/o pads.
120 */
121struct spu_priv1_collapsed {
122 u64 mfc_sr1_RW;
123 u64 mfc_lpid_RW;
124 u64 spu_idr_RW;
125 u64 mfc_vr_RO;
126 u64 spu_vr_RO;
127 u64 int_mask_class0_RW;
128 u64 int_mask_class1_RW;
129 u64 int_mask_class2_RW;
130 u64 int_stat_class0_RW;
131 u64 int_stat_class1_RW;
132 u64 int_stat_class2_RW;
133 u64 int_route_RW;
134 u64 mfc_atomic_flush_RW;
135 u64 resource_allocation_groupID_RW;
136 u64 resource_allocation_enable_RW;
137 u64 mfc_fir_R;
138 u64 mfc_fir_status_or_W;
139 u64 mfc_fir_status_and_W;
140 u64 mfc_fir_mask_R;
141 u64 mfc_fir_mask_or_W;
142 u64 mfc_fir_mask_and_W;
143 u64 mfc_fir_chkstp_enable_RW;
144 u64 smf_sbi_signal_sel;
145 u64 smf_ato_signal_sel;
146 u64 mfc_sdr_RW;
147 u64 tlb_index_hint_RO;
148 u64 tlb_index_W;
149 u64 tlb_vpn_RW;
150 u64 tlb_rpn_RW;
151 u64 tlb_invalidate_entry_W;
152 u64 tlb_invalidate_all_W;
153 u64 smm_hid;
154 u64 mfc_accr_RW;
155 u64 mfc_dsisr_RW;
156 u64 mfc_dar_RW;
157 u64 rmt_index_RW;
158 u64 rmt_data1_RW;
159 u64 mfc_dsir_R;
160 u64 mfc_lsacr_RW;
161 u64 mfc_lscrr_R;
162 u64 mfc_tclass_id_RW;
163 u64 mfc_rm_boundary;
164 u64 smf_dma_signal_sel;
165 u64 smm_signal_sel;
166 u64 mfc_cer_R;
167 u64 pu_ecc_cntl_RW;
168 u64 pu_ecc_stat_RW;
169 u64 spu_ecc_addr_RW;
170 u64 spu_err_mask_RW;
171 u64 spu_trig0_sel;
172 u64 spu_trig1_sel;
173 u64 spu_trig2_sel;
174 u64 spu_trig3_sel;
175 u64 spu_trace_sel;
176 u64 spu_event0_sel;
177 u64 spu_event1_sel;
178 u64 spu_event2_sel;
179 u64 spu_event3_sel;
180 u64 spu_trace_cntl;
181};
182
183/*
184 * struct spu_priv2_collapsed - condensed priviliged 2 area, w/o pads.
185 */
186struct spu_priv2_collapsed {
187 u64 slb_index_W;
188 u64 slb_esid_RW;
189 u64 slb_vsid_RW;
190 u64 slb_invalidate_entry_W;
191 u64 slb_invalidate_all_W;
192 struct mfc_cq_sr spuq[16];
193 struct mfc_cq_sr puq[8];
194 u64 mfc_control_RW;
195 u64 puint_mb_R;
196 u64 spu_privcntl_RW;
197 u64 spu_lslr_RW;
198 u64 spu_chnlcntptr_RW;
199 u64 spu_chnlcnt_RW;
200 u64 spu_chnldata_RW;
201 u64 spu_cfg_RW;
202 u64 spu_tag_status_query_RW;
203 u64 spu_cmd_buf1_RW;
204 u64 spu_cmd_buf2_RW;
205 u64 spu_atomic_status_RW;
206};
207
208/**
209 * struct spu_state
210 * @lscsa: Local Store Context Save Area.
211 * @prob: Collapsed Problem State Area, w/o pads.
212 * @priv1: Collapsed Privileged 1 Area, w/o pads.
213 * @priv2: Collapsed Privileged 2 Area, w/o pads.
214 * @spu_chnlcnt_RW: Array of saved channel counts.
215 * @spu_chnldata_RW: Array of saved channel data.
216 * @suspend_time: Time stamp when decrementer disabled.
217 * @slb_esid_RW: Array of saved SLB esid entries.
218 * @slb_vsid_RW: Array of saved SLB vsid entries.
219 *
220 * Structure representing the whole of the SPU
221 * context save area (CSA). This struct contains
222 * all of the state necessary to suspend and then
223 * later optionally resume execution of an SPU
224 * context.
225 *
226 * The @lscsa region is by far the largest, and is
227 * allocated separately so that it may either be
228 * pinned or mapped to/from application memory, as
229 * appropriate for the OS environment.
230 */
231struct spu_state {
232 struct spu_lscsa *lscsa;
233 struct spu_problem_collapsed prob;
234 struct spu_priv1_collapsed priv1;
235 struct spu_priv2_collapsed priv2;
236 u64 spu_chnlcnt_RW[32];
237 u64 spu_chnldata_RW[32];
238 u32 spu_mailbox_data[4];
239 u32 pu_mailbox_data[1];
240 unsigned long suspend_time;
241 u64 slb_esid_RW[8];
242 u64 slb_vsid_RW[8];
243 spinlock_t register_lock;
244};
245
246extern void spu_init_csa(struct spu_state *csa);
247extern void spu_fini_csa(struct spu_state *csa);
248extern int spu_save(struct spu_state *prev, struct spu *spu);
249extern int spu_restore(struct spu_state *new, struct spu *spu);
250extern int spu_switch(struct spu_state *prev, struct spu_state *new,
251 struct spu *spu);
252
253#endif /* __KERNEL__ */
254#endif /* !__ASSEMBLY__ */
255#endif /* _SPU_CSA_H_ */
diff --git a/include/asm-powerpc/synch.h b/include/asm-powerpc/synch.h
index 4660c0394a77..794870ab8fd3 100644
--- a/include/asm-powerpc/synch.h
+++ b/include/asm-powerpc/synch.h
@@ -1,7 +1,6 @@
1#ifndef _ASM_POWERPC_SYNCH_H 1#ifndef _ASM_POWERPC_SYNCH_H
2#define _ASM_POWERPC_SYNCH_H 2#define _ASM_POWERPC_SYNCH_H
3 3#ifdef __KERNEL__
4#include <linux/config.h>
5 4
6#ifdef __powerpc64__ 5#ifdef __powerpc64__
7#define __SUBARCH_HAS_LWSYNC 6#define __SUBARCH_HAS_LWSYNC
@@ -47,5 +46,6 @@ static inline void isync(void)
47#define isync_on_smp() __asm__ __volatile__("": : :"memory") 46#define isync_on_smp() __asm__ __volatile__("": : :"memory")
48#endif 47#endif
49 48
49#endif /* __KERNEL__ */
50#endif /* _ASM_POWERPC_SYNCH_H */ 50#endif /* _ASM_POWERPC_SYNCH_H */
51 51
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 5341b75c75cb..0c58e32a9570 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -4,7 +4,6 @@
4#ifndef _ASM_POWERPC_SYSTEM_H 4#ifndef _ASM_POWERPC_SYSTEM_H
5#define _ASM_POWERPC_SYSTEM_H 5#define _ASM_POWERPC_SYSTEM_H
6 6
7#include <linux/config.h>
8#include <linux/kernel.h> 7#include <linux/kernel.h>
9 8
10#include <asm/hw_irq.h> 9#include <asm/hw_irq.h>
@@ -42,6 +41,7 @@
42#define set_mb(var, value) do { var = value; mb(); } while (0) 41#define set_mb(var, value) do { var = value; mb(); } while (0)
43#define set_wmb(var, value) do { var = value; wmb(); } while (0) 42#define set_wmb(var, value) do { var = value; wmb(); } while (0)
44 43
44#ifdef __KERNEL__
45#ifdef CONFIG_SMP 45#ifdef CONFIG_SMP
46#define smp_mb() mb() 46#define smp_mb() mb()
47#define smp_rmb() rmb() 47#define smp_rmb() rmb()
@@ -54,7 +54,6 @@
54#define smp_read_barrier_depends() do { } while(0) 54#define smp_read_barrier_depends() do { } while(0)
55#endif /* CONFIG_SMP */ 55#endif /* CONFIG_SMP */
56 56
57#ifdef __KERNEL__
58struct task_struct; 57struct task_struct;
59struct pt_regs; 58struct pt_regs;
60 59
diff --git a/include/asm-powerpc/tce.h b/include/asm-powerpc/tce.h
index 980a094fd5a7..6fa200ad7a7f 100644
--- a/include/asm-powerpc/tce.h
+++ b/include/asm-powerpc/tce.h
@@ -20,6 +20,7 @@
20 20
21#ifndef _ASM_POWERPC_TCE_H 21#ifndef _ASM_POWERPC_TCE_H
22#define _ASM_POWERPC_TCE_H 22#define _ASM_POWERPC_TCE_H
23#ifdef __KERNEL__
23 24
24/* 25/*
25 * Tces come in two formats, one for the virtual bus and a different 26 * Tces come in two formats, one for the virtual bus and a different
@@ -61,4 +62,5 @@ union tce_entry {
61}; 62};
62 63
63 64
65#endif /* __KERNEL__ */
64#endif /* _ASM_POWERPC_TCE_H */ 66#endif /* _ASM_POWERPC_TCE_H */
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index e525f49bd179..ac1e80e6033e 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -37,8 +37,7 @@ struct thread_info {
37 int preempt_count; /* 0 => preemptable, 37 int preempt_count; /* 0 => preemptable,
38 <0 => BUG */ 38 <0 => BUG */
39 struct restart_block restart_block; 39 struct restart_block restart_block;
40 /* set by force_successful_syscall_return */ 40 void *nvgprs_frame;
41 unsigned char syscall_noerror;
42 /* low level flags - has atomic operations done on it */ 41 /* low level flags - has atomic operations done on it */
43 unsigned long flags ____cacheline_aligned_in_smp; 42 unsigned long flags ____cacheline_aligned_in_smp;
44}; 43};
@@ -123,6 +122,9 @@ static inline struct thread_info *current_thread_info(void)
123#define TIF_SINGLESTEP 9 /* singlestepping active */ 122#define TIF_SINGLESTEP 9 /* singlestepping active */
124#define TIF_MEMDIE 10 123#define TIF_MEMDIE 10
125#define TIF_SECCOMP 11 /* secure computing */ 124#define TIF_SECCOMP 11 /* secure computing */
125#define TIF_RESTOREALL 12 /* Restore all regs (implies NOERROR) */
126#define TIF_SAVE_NVGPRS 13 /* Save r14-r31 in signal frame */
127#define TIF_NOERROR 14 /* Force successful syscall return */
126 128
127/* as above, but as bit values */ 129/* as above, but as bit values */
128#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) 130#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -136,10 +138,14 @@ static inline struct thread_info *current_thread_info(void)
136#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 138#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
137#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) 139#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
138#define _TIF_SECCOMP (1<<TIF_SECCOMP) 140#define _TIF_SECCOMP (1<<TIF_SECCOMP)
141#define _TIF_RESTOREALL (1<<TIF_RESTOREALL)
142#define _TIF_SAVE_NVGPRS (1<<TIF_SAVE_NVGPRS)
143#define _TIF_NOERROR (1<<TIF_NOERROR)
139#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP) 144#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
140 145
141#define _TIF_USER_WORK_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \ 146#define _TIF_USER_WORK_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
142 _TIF_NEED_RESCHED) 147 _TIF_NEED_RESCHED | _TIF_RESTOREALL)
148#define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR|_TIF_SAVE_NVGPRS)
143 149
144#endif /* __KERNEL__ */ 150#endif /* __KERNEL__ */
145 151
diff --git a/include/asm-powerpc/tlb.h b/include/asm-powerpc/tlb.h
index 56659f121779..601a53cf96d5 100644
--- a/include/asm-powerpc/tlb.h
+++ b/include/asm-powerpc/tlb.h
@@ -11,6 +11,7 @@
11 */ 11 */
12#ifndef _ASM_POWERPC_TLB_H 12#ifndef _ASM_POWERPC_TLB_H
13#define _ASM_POWERPC_TLB_H 13#define _ASM_POWERPC_TLB_H
14#ifdef __KERNEL__
14 15
15#include <linux/config.h> 16#include <linux/config.h>
16#ifndef __powerpc64__ 17#ifndef __powerpc64__
@@ -67,4 +68,5 @@ static inline void __tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep,
67} 68}
68 69
69#endif 70#endif
71#endif /* __KERNEL__ */
70#endif /* __ASM_POWERPC_TLB_H */ 72#endif /* __ASM_POWERPC_TLB_H */
diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h
index db8095cbe09b..9f3d4da261c4 100644
--- a/include/asm-powerpc/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -1,5 +1,6 @@
1#ifndef _ASM_POWERPC_TOPOLOGY_H 1#ifndef _ASM_POWERPC_TOPOLOGY_H
2#define _ASM_POWERPC_TOPOLOGY_H 2#define _ASM_POWERPC_TOPOLOGY_H
3#ifdef __KERNEL__
3 4
4#include <linux/config.h> 5#include <linux/config.h>
5 6
@@ -55,10 +56,15 @@ static inline int node_to_first_cpu(int node)
55 .nr_balance_failed = 0, \ 56 .nr_balance_failed = 0, \
56} 57}
57 58
59extern void __init dump_numa_cpu_topology(void);
60
58#else 61#else
59 62
63static inline void dump_numa_cpu_topology(void) {}
64
60#include <asm-generic/topology.h> 65#include <asm-generic/topology.h>
61 66
62#endif /* CONFIG_NUMA */ 67#endif /* CONFIG_NUMA */
63 68
69#endif /* __KERNEL__ */
64#endif /* _ASM_POWERPC_TOPOLOGY_H */ 70#endif /* _ASM_POWERPC_TOPOLOGY_H */
diff --git a/include/asm-powerpc/udbg.h b/include/asm-powerpc/udbg.h
index a383383bc4d4..479f2d8ff74a 100644
--- a/include/asm-powerpc/udbg.h
+++ b/include/asm-powerpc/udbg.h
@@ -9,12 +9,13 @@
9 9
10#ifndef _ASM_POWERPC_UDBG_H 10#ifndef _ASM_POWERPC_UDBG_H
11#define _ASM_POWERPC_UDBG_H 11#define _ASM_POWERPC_UDBG_H
12#ifdef __KERNEL__
12 13
13#include <linux/compiler.h> 14#include <linux/compiler.h>
14#include <linux/init.h> 15#include <linux/init.h>
15 16
16extern void (*udbg_putc)(unsigned char c); 17extern void (*udbg_putc)(char c);
17extern unsigned char (*udbg_getc)(void); 18extern int (*udbg_getc)(void);
18extern int (*udbg_getc_poll)(void); 19extern int (*udbg_getc_poll)(void);
19 20
20extern void udbg_puts(const char *s); 21extern void udbg_puts(const char *s);
@@ -23,9 +24,17 @@ extern int udbg_read(char *buf, int buflen);
23 24
24extern void register_early_udbg_console(void); 25extern void register_early_udbg_console(void);
25extern void udbg_printf(const char *fmt, ...); 26extern void udbg_printf(const char *fmt, ...);
27extern void udbg_progress(char *s, unsigned short hex);
26 28
27extern void udbg_init_uart(void __iomem *comport, unsigned int speed); 29extern void udbg_init_uart(void __iomem *comport, unsigned int speed,
30 unsigned int clock);
31extern unsigned int udbg_probe_uart_speed(void __iomem *comport,
32 unsigned int clock);
28 33
29struct device_node; 34struct device_node;
30extern void udbg_init_scc(struct device_node *np); 35extern void udbg_scc_init(int force_scc);
36extern int udbg_adb_init(int force_btext);
37extern void udbg_adb_init_early(void);
38
39#endif /* __KERNEL__ */
31#endif /* _ASM_POWERPC_UDBG_H */ 40#endif /* _ASM_POWERPC_UDBG_H */
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
index 0991dfceef1d..19eaac3fbbf9 100644
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -296,8 +296,10 @@
296#define __NR_inotify_init 275 296#define __NR_inotify_init 275
297#define __NR_inotify_add_watch 276 297#define __NR_inotify_add_watch 276
298#define __NR_inotify_rm_watch 277 298#define __NR_inotify_rm_watch 277
299#define __NR_spu_run 278
300#define __NR_spu_create 279
299 301
300#define __NR_syscalls 278 302#define __NR_syscalls 280
301 303
302#ifdef __KERNEL__ 304#ifdef __KERNEL__
303#define __NR__exit __NR_exit 305#define __NR__exit __NR_exit
diff --git a/include/asm-powerpc/vdso_datapage.h b/include/asm-powerpc/vdso_datapage.h
index 411832d5bbdb..7aa92086c3fb 100644
--- a/include/asm-powerpc/vdso_datapage.h
+++ b/include/asm-powerpc/vdso_datapage.h
@@ -1,5 +1,6 @@
1#ifndef _VDSO_DATAPAGE_H 1#ifndef _VDSO_DATAPAGE_H
2#define _VDSO_DATAPAGE_H 2#define _VDSO_DATAPAGE_H
3#ifdef __KERNEL__
3 4
4/* 5/*
5 * Copyright (C) 2002 Peter Bergner <bergner@vnet.ibm.com>, IBM 6 * Copyright (C) 2002 Peter Bergner <bergner@vnet.ibm.com>, IBM
@@ -105,4 +106,5 @@ extern struct vdso_data *vdso_data;
105 106
106#endif /* __ASSEMBLY__ */ 107#endif /* __ASSEMBLY__ */
107 108
109#endif /* __KERNEL__ */
108#endif /* _SYSTEMCFG_H */ 110#endif /* _SYSTEMCFG_H */
diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h
index e0ccf108277c..0544ece51761 100644
--- a/include/asm-powerpc/vio.h
+++ b/include/asm-powerpc/vio.h
@@ -13,6 +13,7 @@
13 13
14#ifndef _ASM_POWERPC_VIO_H 14#ifndef _ASM_POWERPC_VIO_H
15#define _ASM_POWERPC_VIO_H 15#define _ASM_POWERPC_VIO_H
16#ifdef __KERNEL__
16 17
17#include <linux/config.h> 18#include <linux/config.h>
18#include <linux/init.h> 19#include <linux/init.h>
@@ -103,4 +104,5 @@ static inline struct vio_dev *to_vio_dev(struct device *dev)
103 return container_of(dev, struct vio_dev, dev); 104 return container_of(dev, struct vio_dev, dev);
104} 105}
105 106
107#endif /* __KERNEL__ */
106#endif /* _ASM_POWERPC_VIO_H */ 108#endif /* _ASM_POWERPC_VIO_H */
diff --git a/include/asm-ppc/bseip.h b/include/asm-ppc/bseip.h
deleted file mode 100644
index 691f4a52b0a5..000000000000
--- a/include/asm-ppc/bseip.h
+++ /dev/null
@@ -1,38 +0,0 @@
1/*
2 * A collection of structures, addresses, and values associated with
3 * the Bright Star Engineering ip-Engine board. Copied from the MBX stuff.
4 *
5 * Copyright (c) 1998 Dan Malek (dmalek@jlc.net)
6 */
7#ifndef __MACH_BSEIP_DEFS
8#define __MACH_BSEIP_DEFS
9
10#ifndef __ASSEMBLY__
11/* A Board Information structure that is given to a program when
12 * prom starts it up.
13 */
14typedef struct bd_info {
15 unsigned int bi_memstart; /* Memory start address */
16 unsigned int bi_memsize; /* Memory (end) size in bytes */
17 unsigned int bi_intfreq; /* Internal Freq, in Hz */
18 unsigned int bi_busfreq; /* Bus Freq, in Hz */
19 unsigned char bi_enetaddr[6];
20 unsigned int bi_baudrate;
21} bd_t;
22
23extern bd_t m8xx_board_info;
24
25/* Memory map is configured by the PROM startup.
26 * All we need to get started is the IMMR.
27 */
28#define IMAP_ADDR ((uint)0xff000000)
29#define IMAP_SIZE ((uint)(64 * 1024))
30#define PCMCIA_MEM_ADDR ((uint)0x04000000)
31#define PCMCIA_MEM_SIZE ((uint)(64 * 1024))
32#endif /* !__ASSEMBLY__ */
33
34/* We don't use the 8259.
35*/
36#define NR_8259_INTS 0
37
38#endif
diff --git a/include/asm-ppc/btext.h b/include/asm-ppc/btext.h
index ccaefabe0bf5..ed3630251b3b 100644
--- a/include/asm-ppc/btext.h
+++ b/include/asm-ppc/btext.h
@@ -17,7 +17,7 @@ extern unsigned long disp_BAT[2];
17extern boot_infos_t disp_bi; 17extern boot_infos_t disp_bi;
18extern int boot_text_mapped; 18extern int boot_text_mapped;
19 19
20extern void init_boot_display(void); 20extern void btext_init(boot_infos_t *bi);
21extern void btext_welcome(void); 21extern void btext_welcome(void);
22extern void btext_prepare_BAT(void); 22extern void btext_prepare_BAT(void);
23extern void btext_setup_display(int width, int height, int depth, int pitch, 23extern void btext_setup_display(int width, int height, int depth, int pitch,
diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h
index f01255bd1dc3..39200def8d11 100644
--- a/include/asm-ppc/machdep.h
+++ b/include/asm-ppc/machdep.h
@@ -35,8 +35,10 @@ struct machdep_calls {
35 int (*get_irq)(struct pt_regs *); 35 int (*get_irq)(struct pt_regs *);
36 36
37 /* A general init function, called by ppc_init in init/main.c. 37 /* A general init function, called by ppc_init in init/main.c.
38 May be NULL. */ 38 May be NULL. DEPRECATED ! */
39 void (*init)(void); 39 void (*init)(void);
40 /* For compatibility with merged platforms */
41 void (*init_early)(void);
40 42
41 void (*restart)(char *cmd); 43 void (*restart)(char *cmd);
42 void (*power_off)(void); 44 void (*power_off)(void);
diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
index 9d14baea3d71..c8a96aa44fb7 100644
--- a/include/asm-ppc/mpc85xx.h
+++ b/include/asm-ppc/mpc85xx.h
@@ -37,6 +37,10 @@
37#ifdef CONFIG_STX_GP3 37#ifdef CONFIG_STX_GP3
38#include <platforms/85xx/stx_gp3.h> 38#include <platforms/85xx/stx_gp3.h>
39#endif 39#endif
40#if defined(CONFIG_TQM8540) || defined(CONFIG_TQM8541) || \
41 defined(CONFIG_TQM8555) || defined(CONFIG_TQM8560)
42#include <platforms/85xx/tqm85xx.h>
43#endif
40 44
41#define _IO_BASE isa_io_base 45#define _IO_BASE isa_io_base
42#define _ISA_MEM_BASE isa_mem_base 46#define _ISA_MEM_BASE isa_mem_base
diff --git a/include/asm-ppc/pci-bridge.h b/include/asm-ppc/pci-bridge.h
index e58c78f90a5a..9d5230689b31 100644
--- a/include/asm-ppc/pci-bridge.h
+++ b/include/asm-ppc/pci-bridge.h
@@ -137,5 +137,14 @@ static inline unsigned char bridge_swizzle(unsigned char pin,
137 */ 137 */
138extern int pciauto_bus_scan(struct pci_controller *, int); 138extern int pciauto_bus_scan(struct pci_controller *, int);
139 139
140#ifdef CONFIG_PCI
141extern unsigned long pci_address_to_pio(phys_addr_t address);
142#else
143static inline unsigned long pci_address_to_pio(phys_addr_t address)
144{
145 return (unsigned long)-1;
146}
147#endif
148
140#endif 149#endif
141#endif /* __KERNEL__ */ 150#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/prom.h b/include/asm-ppc/prom.h
index 3e39827ed566..eb317a0806e4 100644
--- a/include/asm-ppc/prom.h
+++ b/include/asm-ppc/prom.h
@@ -136,5 +136,37 @@ extern unsigned long sub_reloc_offset(unsigned long);
136#define PTRRELOC(x) ((typeof(x))add_reloc_offset((unsigned long)(x))) 136#define PTRRELOC(x) ((typeof(x))add_reloc_offset((unsigned long)(x)))
137#define PTRUNRELOC(x) ((typeof(x))sub_reloc_offset((unsigned long)(x))) 137#define PTRUNRELOC(x) ((typeof(x))sub_reloc_offset((unsigned long)(x)))
138 138
139
140/*
141 * OF address retreival & translation
142 */
143
144
145/* Translate an OF address block into a CPU physical address
146 */
147#define OF_BAD_ADDR ((u64)-1)
148extern u64 of_translate_address(struct device_node *np, u32 *addr);
149
150/* Extract an address from a device, returns the region size and
151 * the address space flags too. The PCI version uses a BAR number
152 * instead of an absolute index
153 */
154extern u32 *of_get_address(struct device_node *dev, int index,
155 u64 *size, unsigned int *flags);
156extern u32 *of_get_pci_address(struct device_node *dev, int bar_no,
157 u64 *size, unsigned int *flags);
158
159/* Get an address as a resource. Note that if your address is
160 * a PIO address, the conversion will fail if the physical address
161 * can't be internally converted to an IO token with
162 * pci_address_to_pio(), that is because it's either called to early
163 * or it can't be matched to any host bridge IO space
164 */
165extern int of_address_to_resource(struct device_node *dev, int index,
166 struct resource *r);
167extern int of_pci_address_to_resource(struct device_node *dev, int bar,
168 struct resource *r);
169
170
139#endif /* _PPC_PROM_H */ 171#endif /* _PPC_PROM_H */
140#endif /* __KERNEL__ */ 172#endif /* __KERNEL__ */
diff --git a/include/asm-s390/cache.h b/include/asm-s390/cache.h
index 29845378b206..e20cdd9074db 100644
--- a/include/asm-s390/cache.h
+++ b/include/asm-s390/cache.h
@@ -13,7 +13,6 @@
13 13
14#define L1_CACHE_BYTES 256 14#define L1_CACHE_BYTES 256
15#define L1_CACHE_SHIFT 8 15#define L1_CACHE_SHIFT 8
16#define L1_CACHE_SHIFT_MAX 8 /* largest L1 which this arch supports */
17 16
18#define ARCH_KMALLOC_MINALIGN 8 17#define ARCH_KMALLOC_MINALIGN 8
19 18
diff --git a/include/asm-s390/futex.h b/include/asm-s390/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-s390/futex.h
+++ b/include/asm-s390/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-sh/cache.h b/include/asm-sh/cache.h
index 9b4dd6d8212e..656fdfe9e8b4 100644
--- a/include/asm-sh/cache.h
+++ b/include/asm-sh/cache.h
@@ -22,8 +22,6 @@
22 22
23#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) 23#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
24 24
25#define L1_CACHE_SHIFT_MAX 5 /* largest L1 which this arch supports */
26
27struct cache_info { 25struct cache_info {
28 unsigned int ways; 26 unsigned int ways;
29 unsigned int sets; 27 unsigned int sets;
diff --git a/include/asm-sh/futex.h b/include/asm-sh/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-sh/futex.h
+++ b/include/asm-sh/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-sh64/cache.h b/include/asm-sh64/cache.h
index f54e85e8a470..a4f36f0036e1 100644
--- a/include/asm-sh64/cache.h
+++ b/include/asm-sh64/cache.h
@@ -20,8 +20,6 @@
20#define L1_CACHE_ALIGN_MASK (~(L1_CACHE_BYTES - 1)) 20#define L1_CACHE_ALIGN_MASK (~(L1_CACHE_BYTES - 1))
21#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES - 1)) & L1_CACHE_ALIGN_MASK) 21#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES - 1)) & L1_CACHE_ALIGN_MASK)
22#define L1_CACHE_SIZE_BYTES (L1_CACHE_BYTES << 10) 22#define L1_CACHE_SIZE_BYTES (L1_CACHE_BYTES << 10)
23/* Largest L1 which this arch supports */
24#define L1_CACHE_SHIFT_MAX 5
25 23
26#ifdef MODULE 24#ifdef MODULE
27#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES))) 25#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
diff --git a/include/asm-sh64/futex.h b/include/asm-sh64/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-sh64/futex.h
+++ b/include/asm-sh64/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-sparc/cache.h b/include/asm-sparc/cache.h
index a10522cb21b7..cb971e88aea4 100644
--- a/include/asm-sparc/cache.h
+++ b/include/asm-sparc/cache.h
@@ -13,7 +13,6 @@
13#define L1_CACHE_SHIFT 5 13#define L1_CACHE_SHIFT 5
14#define L1_CACHE_BYTES 32 14#define L1_CACHE_BYTES 32
15#define L1_CACHE_ALIGN(x) ((((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))) 15#define L1_CACHE_ALIGN(x) ((((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)))
16#define L1_CACHE_SHIFT_MAX 5 /* largest L1 which this arch supports */
17 16
18#define SMP_CACHE_BYTES 32 17#define SMP_CACHE_BYTES 32
19 18
diff --git a/include/asm-sparc/futex.h b/include/asm-sparc/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-sparc/futex.h
+++ b/include/asm-sparc/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-sparc64/cache.h b/include/asm-sparc64/cache.h
index ade5ec3bfd5a..f7d35a2ae9b8 100644
--- a/include/asm-sparc64/cache.h
+++ b/include/asm-sparc64/cache.h
@@ -9,7 +9,6 @@
9#define L1_CACHE_BYTES 32 /* Two 16-byte sub-blocks per line. */ 9#define L1_CACHE_BYTES 32 /* Two 16-byte sub-blocks per line. */
10 10
11#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) 11#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
12#define L1_CACHE_SHIFT_MAX 5 /* largest L1 which this arch supports */
13 12
14#define SMP_CACHE_BYTES_SHIFT 6 13#define SMP_CACHE_BYTES_SHIFT 6
15#define SMP_CACHE_BYTES (1 << SMP_CACHE_BYTES_SHIFT) /* L2 cache line size. */ 14#define SMP_CACHE_BYTES (1 << SMP_CACHE_BYTES_SHIFT) /* L2 cache line size. */
diff --git a/include/asm-sparc64/futex.h b/include/asm-sparc64/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-sparc64/futex.h
+++ b/include/asm-sparc64/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index b5417529f6f1..309f1466b6fa 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -193,11 +193,7 @@ do { \
193 * not preserve it's value. Hairy, but it lets us remove 2 loads 193 * not preserve it's value. Hairy, but it lets us remove 2 loads
194 * and 2 stores in this critical code path. -DaveM 194 * and 2 stores in this critical code path. -DaveM
195 */ 195 */
196#if __GNUC__ >= 3
197#define EXTRA_CLOBBER ,"%l1" 196#define EXTRA_CLOBBER ,"%l1"
198#else
199#define EXTRA_CLOBBER
200#endif
201#define switch_to(prev, next, last) \ 197#define switch_to(prev, next, last) \
202do { if (test_thread_flag(TIF_PERFCTR)) { \ 198do { if (test_thread_flag(TIF_PERFCTR)) { \
203 unsigned long __tmp; \ 199 unsigned long __tmp; \
diff --git a/include/asm-um/cache.h b/include/asm-um/cache.h
index a10602a5b2d6..3d0587075521 100644
--- a/include/asm-um/cache.h
+++ b/include/asm-um/cache.h
@@ -13,9 +13,6 @@
13# define L1_CACHE_SHIFT 5 13# define L1_CACHE_SHIFT 5
14#endif 14#endif
15 15
16/* XXX: this is valid for x86 and x86_64. */
17#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
18
19#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) 16#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
20 17
21#endif 18#endif
diff --git a/include/asm-um/futex.h b/include/asm-um/futex.h
index 142ee2d8e0fd..6a332a9f099c 100644
--- a/include/asm-um/futex.h
+++ b/include/asm-um/futex.h
@@ -1,12 +1,6 @@
1#ifndef __UM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define __UM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#include <linux/futex.h> 4#include <asm-generic/futex.h>
5#include <asm/errno.h>
6#include <asm/system.h>
7#include <asm/processor.h>
8#include <asm/uaccess.h>
9
10#include "asm/arch/futex.h"
11 5
12#endif 6#endif
diff --git a/include/asm-um/rwsem.h b/include/asm-um/rwsem.h
index 661c0e54702b..b5fc449dc86b 100644
--- a/include/asm-um/rwsem.h
+++ b/include/asm-um/rwsem.h
@@ -1,10 +1,6 @@
1#ifndef __UM_RWSEM_H__ 1#ifndef __UM_RWSEM_H__
2#define __UM_RWSEM_H__ 2#define __UM_RWSEM_H__
3 3
4#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
5#define __builtin_expect(exp,c) (exp)
6#endif
7
8#include "asm/arch/rwsem.h" 4#include "asm/arch/rwsem.h"
9 5
10#endif 6#endif
diff --git a/include/asm-v850/cache.h b/include/asm-v850/cache.h
index cbf9096e8517..8832c7ea3242 100644
--- a/include/asm-v850/cache.h
+++ b/include/asm-v850/cache.h
@@ -23,6 +23,4 @@
23#define L1_CACHE_SHIFT 4 23#define L1_CACHE_SHIFT 4
24#endif 24#endif
25 25
26#define L1_CACHE_SHIFT_MAX L1_CACHE_SHIFT
27
28#endif /* __V850_CACHE_H__ */ 26#endif /* __V850_CACHE_H__ */
diff --git a/include/asm-v850/futex.h b/include/asm-v850/futex.h
index 9feff4ce1424..6a332a9f099c 100644
--- a/include/asm-v850/futex.h
+++ b/include/asm-v850/futex.h
@@ -1,53 +1,6 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_FUTEX_H
3 3
4#ifdef __KERNEL__ 4#include <asm-generic/futex.h>
5 5
6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10static inline int
11futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
12{
13 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20;
16 int cmparg = (encoded_op << 20) >> 20;
17 int oldval = 0, ret;
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg;
20
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
22 return -EFAULT;
23
24 inc_preempt_count();
25
26 switch (op) {
27 case FUTEX_OP_SET:
28 case FUTEX_OP_ADD:
29 case FUTEX_OP_OR:
30 case FUTEX_OP_ANDN:
31 case FUTEX_OP_XOR:
32 default:
33 ret = -ENOSYS;
34 }
35
36 dec_preempt_count();
37
38 if (!ret) {
39 switch (cmp) {
40 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
41 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
42 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
43 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
44 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
45 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
46 default: ret = -ENOSYS;
47 }
48 }
49 return ret;
50}
51
52#endif
53#endif 6#endif
diff --git a/include/asm-v850/unistd.h b/include/asm-v850/unistd.h
index 5a86f8e976ec..82460a7bb233 100644
--- a/include/asm-v850/unistd.h
+++ b/include/asm-v850/unistd.h
@@ -241,9 +241,6 @@
241/* User programs sometimes end up including this header file 241/* User programs sometimes end up including this header file
242 (indirectly, via uClibc header files), so I'm a bit nervous just 242 (indirectly, via uClibc header files), so I'm a bit nervous just
243 including <linux/compiler.h>. */ 243 including <linux/compiler.h>. */
244#if !defined(__builtin_expect) && __GNUC__ == 2 && __GNUC_MINOR__ < 96
245#define __builtin_expect(x, expected_value) (x)
246#endif
247 244
248#define __syscall_return(type, res) \ 245#define __syscall_return(type, res) \
249 do { \ 246 do { \
@@ -346,20 +343,6 @@ type name (atype a, btype b, ctype c, dtype d, etype e) \
346 __syscall_return (type, __ret); \ 343 __syscall_return (type, __ret); \
347} 344}
348 345
349#if __GNUC__ < 3
350/* In older versions of gcc, `asm' statements with more than 10
351 input/output arguments produce a fatal error. To work around this
352 problem, we use two versions, one for gcc-3.x and one for earlier
353 versions of gcc (the `earlier gcc' version doesn't work with gcc-3.x
354 because gcc-3.x doesn't allow clobbers to also be input arguments). */
355#define __SYSCALL6_TRAP(syscall, ret, a, b, c, d, e, f) \
356 __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP \
357 : "=r" (ret), "=r" (syscall) \
358 : "1" (syscall), \
359 "r" (a), "r" (b), "r" (c), "r" (d), \
360 "r" (e), "r" (f) \
361 : SYSCALL_CLOBBERS, SYSCALL_ARG4, SYSCALL_ARG5);
362#else /* __GNUC__ >= 3 */
363#define __SYSCALL6_TRAP(syscall, ret, a, b, c, d, e, f) \ 346#define __SYSCALL6_TRAP(syscall, ret, a, b, c, d, e, f) \
364 __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP \ 347 __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP \
365 : "=r" (ret), "=r" (syscall), \ 348 : "=r" (ret), "=r" (syscall), \
@@ -368,7 +351,6 @@ type name (atype a, btype b, ctype c, dtype d, etype e) \
368 "r" (a), "r" (b), "r" (c), "r" (d), \ 351 "r" (a), "r" (b), "r" (c), "r" (d), \
369 "2" (e), "3" (f) \ 352 "2" (e), "3" (f) \
370 : SYSCALL_CLOBBERS); 353 : SYSCALL_CLOBBERS);
371#endif
372 354
373#define _syscall6(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e, ftype, f) \ 355#define _syscall6(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e, ftype, f) \
374type name (atype a, btype b, ctype c, dtype d, etype e, ftype f) \ 356type name (atype a, btype b, ctype c, dtype d, etype e, ftype f) \
diff --git a/include/asm-x86_64/cache.h b/include/asm-x86_64/cache.h
index 33e53424128b..b4a2401de77b 100644
--- a/include/asm-x86_64/cache.h
+++ b/include/asm-x86_64/cache.h
@@ -9,6 +9,5 @@
9/* L1 cache line size */ 9/* L1 cache line size */
10#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT) 10#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
11#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) 11#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
12#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
13 12
14#endif 13#endif
diff --git a/include/asm-x86_64/ia32_unistd.h b/include/asm-x86_64/ia32_unistd.h
index d5166ec3868d..e8843362a6cc 100644
--- a/include/asm-x86_64/ia32_unistd.h
+++ b/include/asm-x86_64/ia32_unistd.h
@@ -299,7 +299,8 @@
299#define __NR_ia32_inotify_init 291 299#define __NR_ia32_inotify_init 291
300#define __NR_ia32_inotify_add_watch 292 300#define __NR_ia32_inotify_add_watch 292
301#define __NR_ia32_inotify_rm_watch 293 301#define __NR_ia32_inotify_rm_watch 293
302#define __NR_ia32_migrate_pages 294
302 303
303#define IA32_NR_syscalls 294 /* must be > than biggest syscall! */ 304#define IA32_NR_syscalls 295 /* must be > than biggest syscall! */
304 305
305#endif /* _ASM_X86_64_IA32_UNISTD_H_ */ 306#endif /* _ASM_X86_64_IA32_UNISTD_H_ */
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index 2c42150bce0c..e6f896161c11 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -571,8 +571,10 @@ __SYSCALL(__NR_inotify_init, sys_inotify_init)
571__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch) 571__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
572#define __NR_inotify_rm_watch 255 572#define __NR_inotify_rm_watch 255
573__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch) 573__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
574#define __NR_migrate_pages 256
575__SYSCALL(__NR_migrate_pages, sys_migrate_pages)
574 576
575#define __NR_syscall_max __NR_inotify_rm_watch 577#define __NR_syscall_max __NR_migrate_pages
576#ifndef __NO_STUBS 578#ifndef __NO_STUBS
577 579
578/* user-visible error numbers are in the range -1 - -4095 */ 580/* user-visible error numbers are in the range -1 - -4095 */
diff --git a/include/linux/aio.h b/include/linux/aio.h
index 49fd37629ee4..00c8efa95cc3 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -94,26 +94,27 @@ struct kiocb {
94 ssize_t (*ki_retry)(struct kiocb *); 94 ssize_t (*ki_retry)(struct kiocb *);
95 void (*ki_dtor)(struct kiocb *); 95 void (*ki_dtor)(struct kiocb *);
96 96
97 struct list_head ki_list; /* the aio core uses this
98 * for cancellation */
99
100 union { 97 union {
101 void __user *user; 98 void __user *user;
102 struct task_struct *tsk; 99 struct task_struct *tsk;
103 } ki_obj; 100 } ki_obj;
101
104 __u64 ki_user_data; /* user's data for completion */ 102 __u64 ki_user_data; /* user's data for completion */
103 wait_queue_t ki_wait;
105 loff_t ki_pos; 104 loff_t ki_pos;
105
106 void *private;
106 /* State that we remember to be able to restart/retry */ 107 /* State that we remember to be able to restart/retry */
107 unsigned short ki_opcode; 108 unsigned short ki_opcode;
108 size_t ki_nbytes; /* copy of iocb->aio_nbytes */ 109 size_t ki_nbytes; /* copy of iocb->aio_nbytes */
109 char __user *ki_buf; /* remaining iocb->aio_buf */ 110 char __user *ki_buf; /* remaining iocb->aio_buf */
110 size_t ki_left; /* remaining bytes */ 111 size_t ki_left; /* remaining bytes */
111 wait_queue_t ki_wait;
112 long ki_retried; /* just for testing */ 112 long ki_retried; /* just for testing */
113 long ki_kicked; /* just for testing */ 113 long ki_kicked; /* just for testing */
114 long ki_queued; /* just for testing */ 114 long ki_queued; /* just for testing */
115 115
116 void *private; 116 struct list_head ki_list; /* the aio core uses this
117 * for cancellation */
117}; 118};
118 119
119#define is_sync_kiocb(iocb) ((iocb)->ki_key == KIOCB_SYNC_KEY) 120#define is_sync_kiocb(iocb) ((iocb)->ki_key == KIOCB_SYNC_KEY)
@@ -126,6 +127,7 @@ struct kiocb {
126 (x)->ki_filp = (filp); \ 127 (x)->ki_filp = (filp); \
127 (x)->ki_ctx = NULL; \ 128 (x)->ki_ctx = NULL; \
128 (x)->ki_cancel = NULL; \ 129 (x)->ki_cancel = NULL; \
130 (x)->ki_retry = NULL; \
129 (x)->ki_dtor = NULL; \ 131 (x)->ki_dtor = NULL; \
130 (x)->ki_obj.tsk = tsk; \ 132 (x)->ki_obj.tsk = tsk; \
131 (x)->ki_user_data = 0; \ 133 (x)->ki_user_data = 0; \
diff --git a/include/linux/atalk.h b/include/linux/atalk.h
index 911c09cb9bf9..6ba3aa8a81f4 100644
--- a/include/linux/atalk.h
+++ b/include/linux/atalk.h
@@ -155,15 +155,15 @@ struct elapaarp {
155#define AARP_REQUEST 1 155#define AARP_REQUEST 1
156#define AARP_REPLY 2 156#define AARP_REPLY 2
157#define AARP_PROBE 3 157#define AARP_PROBE 3
158 __u8 hw_src[ETH_ALEN] __attribute__ ((packed)); 158 __u8 hw_src[ETH_ALEN];
159 __u8 pa_src_zero __attribute__ ((packed)); 159 __u8 pa_src_zero;
160 __be16 pa_src_net __attribute__ ((packed)); 160 __be16 pa_src_net;
161 __u8 pa_src_node __attribute__ ((packed)); 161 __u8 pa_src_node;
162 __u8 hw_dst[ETH_ALEN] __attribute__ ((packed)); 162 __u8 hw_dst[ETH_ALEN];
163 __u8 pa_dst_zero __attribute__ ((packed)); 163 __u8 pa_dst_zero;
164 __be16 pa_dst_net __attribute__ ((packed)); 164 __be16 pa_dst_net;
165 __u8 pa_dst_node __attribute__ ((packed)); 165 __u8 pa_dst_node;
166}; 166} __attribute__ ((packed));
167 167
168static __inline__ struct elapaarp *aarp_hdr(struct sk_buff *skb) 168static __inline__ struct elapaarp *aarp_hdr(struct sk_buff *skb)
169{ 169{
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index fb0985377421..02a585faa62c 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -118,9 +118,9 @@ struct request_list {
118 * try to put the fields that are referenced together in the same cacheline 118 * try to put the fields that are referenced together in the same cacheline
119 */ 119 */
120struct request { 120struct request {
121 struct list_head queuelist; /* looking for ->queue? you must _not_ 121 struct list_head queuelist;
122 * access it directly, use 122 struct list_head donelist;
123 * blkdev_dequeue_request! */ 123
124 unsigned long flags; /* see REQ_ bits below */ 124 unsigned long flags; /* see REQ_ bits below */
125 125
126 /* Maintain bio traversal state for part by part I/O submission. 126 /* Maintain bio traversal state for part by part I/O submission.
@@ -141,6 +141,7 @@ struct request {
141 struct bio *biotail; 141 struct bio *biotail;
142 142
143 void *elevator_private; 143 void *elevator_private;
144 void *completion_data;
144 145
145 unsigned short ioprio; 146 unsigned short ioprio;
146 147
@@ -291,6 +292,7 @@ typedef int (merge_bvec_fn) (request_queue_t *, struct bio *, struct bio_vec *);
291typedef void (activity_fn) (void *data, int rw); 292typedef void (activity_fn) (void *data, int rw);
292typedef int (issue_flush_fn) (request_queue_t *, struct gendisk *, sector_t *); 293typedef int (issue_flush_fn) (request_queue_t *, struct gendisk *, sector_t *);
293typedef void (prepare_flush_fn) (request_queue_t *, struct request *); 294typedef void (prepare_flush_fn) (request_queue_t *, struct request *);
295typedef void (softirq_done_fn)(struct request *);
294 296
295enum blk_queue_state { 297enum blk_queue_state {
296 Queue_down, 298 Queue_down,
@@ -332,6 +334,7 @@ struct request_queue
332 activity_fn *activity_fn; 334 activity_fn *activity_fn;
333 issue_flush_fn *issue_flush_fn; 335 issue_flush_fn *issue_flush_fn;
334 prepare_flush_fn *prepare_flush_fn; 336 prepare_flush_fn *prepare_flush_fn;
337 softirq_done_fn *softirq_done_fn;
335 338
336 /* 339 /*
337 * Dispatch queue sorting 340 * Dispatch queue sorting
@@ -592,7 +595,6 @@ extern void generic_make_request(struct bio *bio);
592extern void blk_put_request(struct request *); 595extern void blk_put_request(struct request *);
593extern void __blk_put_request(request_queue_t *, struct request *); 596extern void __blk_put_request(request_queue_t *, struct request *);
594extern void blk_end_sync_rq(struct request *rq, int error); 597extern void blk_end_sync_rq(struct request *rq, int error);
595extern void blk_attempt_remerge(request_queue_t *, struct request *);
596extern struct request *blk_get_request(request_queue_t *, int, gfp_t); 598extern struct request *blk_get_request(request_queue_t *, int, gfp_t);
597extern void blk_insert_request(request_queue_t *, struct request *, int, void *); 599extern void blk_insert_request(request_queue_t *, struct request *, int, void *);
598extern void blk_requeue_request(request_queue_t *, struct request *); 600extern void blk_requeue_request(request_queue_t *, struct request *);
@@ -646,6 +648,17 @@ extern int end_that_request_first(struct request *, int, int);
646extern int end_that_request_chunk(struct request *, int, int); 648extern int end_that_request_chunk(struct request *, int, int);
647extern void end_that_request_last(struct request *, int); 649extern void end_that_request_last(struct request *, int);
648extern void end_request(struct request *req, int uptodate); 650extern void end_request(struct request *req, int uptodate);
651extern void blk_complete_request(struct request *);
652
653static inline int rq_all_done(struct request *rq, unsigned int nr_bytes)
654{
655 if (blk_fs_request(rq))
656 return (nr_bytes >= (rq->hard_nr_sectors << 9));
657 else if (blk_pc_request(rq))
658 return nr_bytes >= rq->data_len;
659
660 return 0;
661}
649 662
650/* 663/*
651 * end_that_request_first/chunk() takes an uptodate argument. we account 664 * end_that_request_first/chunk() takes an uptodate argument. we account
@@ -694,6 +707,7 @@ extern void blk_queue_segment_boundary(request_queue_t *, unsigned long);
694extern void blk_queue_prep_rq(request_queue_t *, prep_rq_fn *pfn); 707extern void blk_queue_prep_rq(request_queue_t *, prep_rq_fn *pfn);
695extern void blk_queue_merge_bvec(request_queue_t *, merge_bvec_fn *); 708extern void blk_queue_merge_bvec(request_queue_t *, merge_bvec_fn *);
696extern void blk_queue_dma_alignment(request_queue_t *, int); 709extern void blk_queue_dma_alignment(request_queue_t *, int);
710extern void blk_queue_softirq_done(request_queue_t *, softirq_done_fn *);
697extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); 711extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
698extern int blk_queue_ordered(request_queue_t *, unsigned, prepare_flush_fn *); 712extern int blk_queue_ordered(request_queue_t *, unsigned, prepare_flush_fn *);
699extern void blk_queue_issue_flush_fn(request_queue_t *, issue_flush_fn *); 713extern void blk_queue_issue_flush_fn(request_queue_t *, issue_flush_fn *);
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 1db061bb6b08..9f159baf153f 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -197,7 +197,8 @@ int block_read_full_page(struct page*, get_block_t*);
197int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*); 197int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
198int cont_prepare_write(struct page*, unsigned, unsigned, get_block_t*, 198int cont_prepare_write(struct page*, unsigned, unsigned, get_block_t*,
199 loff_t *); 199 loff_t *);
200int generic_cont_expand(struct inode *inode, loff_t size) ; 200int generic_cont_expand(struct inode *inode, loff_t size);
201int generic_cont_expand_simple(struct inode *inode, loff_t size);
201int block_commit_write(struct page *page, unsigned from, unsigned to); 202int block_commit_write(struct page *page, unsigned from, unsigned to);
202int block_sync_page(struct page *); 203int block_sync_page(struct page *);
203sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); 204sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
diff --git a/include/linux/byteorder/generic.h b/include/linux/byteorder/generic.h
index 04bd756efc67..e86e4a938373 100644
--- a/include/linux/byteorder/generic.h
+++ b/include/linux/byteorder/generic.h
@@ -156,7 +156,7 @@ extern __be32 htonl(__u32);
156extern __u16 ntohs(__be16); 156extern __u16 ntohs(__be16);
157extern __be16 htons(__u16); 157extern __be16 htons(__u16);
158 158
159#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) 159#if defined(__GNUC__) && defined(__OPTIMIZE__)
160 160
161#define ___htonl(x) __cpu_to_be32(x) 161#define ___htonl(x) __cpu_to_be32(x)
162#define ___htons(x) __cpu_to_be16(x) 162#define ___htons(x) __cpu_to_be16(x)
diff --git a/include/linux/byteorder/swab.h b/include/linux/byteorder/swab.h
index 2f1cb775125a..25f7f32883ec 100644
--- a/include/linux/byteorder/swab.h
+++ b/include/linux/byteorder/swab.h
@@ -110,7 +110,7 @@
110/* 110/*
111 * Allow constant folding 111 * Allow constant folding
112 */ 112 */
113#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) 113#if defined(__GNUC__) && defined(__OPTIMIZE__)
114# define __swab16(x) \ 114# define __swab16(x) \
115(__builtin_constant_p((__u16)(x)) ? \ 115(__builtin_constant_p((__u16)(x)) ? \
116 ___swab16((x)) : \ 116 ___swab16((x)) : \
diff --git a/include/linux/byteorder/swabb.h b/include/linux/byteorder/swabb.h
index d5f2a3205109..ae5e5f914bf4 100644
--- a/include/linux/byteorder/swabb.h
+++ b/include/linux/byteorder/swabb.h
@@ -77,7 +77,7 @@
77/* 77/*
78 * Allow constant folding 78 * Allow constant folding
79 */ 79 */
80#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) 80#if defined(__GNUC__) && defined(__OPTIMIZE__)
81# define __swahw32(x) \ 81# define __swahw32(x) \
82(__builtin_constant_p((__u32)(x)) ? \ 82(__builtin_constant_p((__u32)(x)) ? \
83 ___swahw32((x)) : \ 83 ___swahw32((x)) : \
diff --git a/include/linux/cache.h b/include/linux/cache.h
index 0b7ecf3af78a..ffe52210fc4f 100644
--- a/include/linux/cache.h
+++ b/include/linux/cache.h
@@ -45,12 +45,21 @@
45#endif /* CONFIG_SMP */ 45#endif /* CONFIG_SMP */
46#endif 46#endif
47 47
48#if !defined(____cacheline_maxaligned_in_smp) 48/*
49 * The maximum alignment needed for some critical structures
50 * These could be inter-node cacheline sizes/L3 cacheline
51 * size etc. Define this in asm/cache.h for your arch
52 */
53#ifndef INTERNODE_CACHE_SHIFT
54#define INTERNODE_CACHE_SHIFT L1_CACHE_SHIFT
55#endif
56
57#if !defined(____cacheline_internodealigned_in_smp)
49#if defined(CONFIG_SMP) 58#if defined(CONFIG_SMP)
50#define ____cacheline_maxaligned_in_smp \ 59#define ____cacheline_internodealigned_in_smp \
51 __attribute__((__aligned__(1 << (L1_CACHE_SHIFT_MAX)))) 60 __attribute__((__aligned__(1 << (INTERNODE_CACHE_SHIFT))))
52#else 61#else
53#define ____cacheline_maxaligned_in_smp 62#define ____cacheline_internodealigned_in_smp
54#endif 63#endif
55#endif 64#endif
56 65
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
index 119f9d064cc6..339878952f12 100644
--- a/include/linux/compat_ioctl.h
+++ b/include/linux/compat_ioctl.h
@@ -218,32 +218,6 @@ COMPATIBLE_IOCTL(VT_RESIZE)
218COMPATIBLE_IOCTL(VT_RESIZEX) 218COMPATIBLE_IOCTL(VT_RESIZEX)
219COMPATIBLE_IOCTL(VT_LOCKSWITCH) 219COMPATIBLE_IOCTL(VT_LOCKSWITCH)
220COMPATIBLE_IOCTL(VT_UNLOCKSWITCH) 220COMPATIBLE_IOCTL(VT_UNLOCKSWITCH)
221/* Little v */
222/* Little v, the video4linux ioctls (conflict?) */
223COMPATIBLE_IOCTL(VIDIOCGCAP)
224COMPATIBLE_IOCTL(VIDIOCGCHAN)
225COMPATIBLE_IOCTL(VIDIOCSCHAN)
226COMPATIBLE_IOCTL(VIDIOCGPICT)
227COMPATIBLE_IOCTL(VIDIOCSPICT)
228COMPATIBLE_IOCTL(VIDIOCCAPTURE)
229COMPATIBLE_IOCTL(VIDIOCKEY)
230COMPATIBLE_IOCTL(VIDIOCGAUDIO)
231COMPATIBLE_IOCTL(VIDIOCSAUDIO)
232COMPATIBLE_IOCTL(VIDIOCSYNC)
233COMPATIBLE_IOCTL(VIDIOCMCAPTURE)
234COMPATIBLE_IOCTL(VIDIOCGMBUF)
235COMPATIBLE_IOCTL(VIDIOCGUNIT)
236COMPATIBLE_IOCTL(VIDIOCGCAPTURE)
237COMPATIBLE_IOCTL(VIDIOCSCAPTURE)
238/* BTTV specific... */
239COMPATIBLE_IOCTL(_IOW('v', BASE_VIDIOCPRIVATE+0, char [256]))
240COMPATIBLE_IOCTL(_IOR('v', BASE_VIDIOCPRIVATE+1, char [256]))
241COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int))
242COMPATIBLE_IOCTL(_IOW('v' , BASE_VIDIOCPRIVATE+3, char [16])) /* struct bttv_pll_info */
243COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+4, int))
244COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+5, int))
245COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+6, int))
246COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int))
247/* Little p (/dev/rtc, /dev/envctrl, etc.) */ 221/* Little p (/dev/rtc, /dev/envctrl, etc.) */
248COMPATIBLE_IOCTL(RTC_AIE_ON) 222COMPATIBLE_IOCTL(RTC_AIE_ON)
249COMPATIBLE_IOCTL(RTC_AIE_OFF) 223COMPATIBLE_IOCTL(RTC_AIE_OFF)
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 152734055403..2e05e1e6b0e6 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -15,3 +15,12 @@
15 ({ unsigned long __ptr; \ 15 ({ unsigned long __ptr; \
16 __asm__ ("" : "=g"(__ptr) : "0"(ptr)); \ 16 __asm__ ("" : "=g"(__ptr) : "0"(ptr)); \
17 (typeof(ptr)) (__ptr + (off)); }) 17 (typeof(ptr)) (__ptr + (off)); })
18
19
20#define inline inline __attribute__((always_inline))
21#define __inline__ __inline__ __attribute__((always_inline))
22#define __inline __inline __attribute__((always_inline))
23#define __deprecated __attribute__((deprecated))
24#define noinline __attribute__((noinline))
25#define __attribute_pure__ __attribute__((pure))
26#define __attribute_const__ __attribute__((__const__))
diff --git a/include/linux/compiler-gcc2.h b/include/linux/compiler-gcc2.h
deleted file mode 100644
index ebed17660c5f..000000000000
--- a/include/linux/compiler-gcc2.h
+++ /dev/null
@@ -1,29 +0,0 @@
1/* Never include this file directly. Include <linux/compiler.h> instead. */
2
3/* These definitions are for GCC v2.x. */
4
5/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
6 a mechanism by which the user can annotate likely branch directions and
7 expect the blocks to be reordered appropriately. Define __builtin_expect
8 to nothing for earlier compilers. */
9#include <linux/compiler-gcc.h>
10
11#if __GNUC_MINOR__ < 96
12# define __builtin_expect(x, expected_value) (x)
13#endif
14
15#define __attribute_used__ __attribute__((__unused__))
16
17/*
18 * The attribute `pure' is not implemented in GCC versions earlier
19 * than 2.96.
20 */
21#if __GNUC_MINOR__ >= 96
22# define __attribute_pure__ __attribute__((pure))
23# define __attribute_const__ __attribute__((__const__))
24#endif
25
26/* GCC 2.95.x/2.96 recognize __va_copy, but not va_copy. Actually later GCC's
27 * define both va_copy and __va_copy, but the latter may go away, so limit this
28 * to this header */
29#define va_copy __va_copy
diff --git a/include/linux/compiler-gcc3.h b/include/linux/compiler-gcc3.h
index a6fa615afab5..4209082ee934 100644
--- a/include/linux/compiler-gcc3.h
+++ b/include/linux/compiler-gcc3.h
@@ -3,29 +3,12 @@
3/* These definitions are for GCC v3.x. */ 3/* These definitions are for GCC v3.x. */
4#include <linux/compiler-gcc.h> 4#include <linux/compiler-gcc.h>
5 5
6#if __GNUC_MINOR__ >= 1
7# define inline inline __attribute__((always_inline))
8# define __inline__ __inline__ __attribute__((always_inline))
9# define __inline __inline __attribute__((always_inline))
10#endif
11
12#if __GNUC_MINOR__ > 0
13# define __deprecated __attribute__((deprecated))
14#endif
15
16#if __GNUC_MINOR__ >= 3 6#if __GNUC_MINOR__ >= 3
17# define __attribute_used__ __attribute__((__used__)) 7# define __attribute_used__ __attribute__((__used__))
18#else 8#else
19# define __attribute_used__ __attribute__((__unused__)) 9# define __attribute_used__ __attribute__((__unused__))
20#endif 10#endif
21 11
22#define __attribute_pure__ __attribute__((pure))
23#define __attribute_const__ __attribute__((__const__))
24
25#if __GNUC_MINOR__ >= 1
26#define noinline __attribute__((noinline))
27#endif
28
29#if __GNUC_MINOR__ >= 4 12#if __GNUC_MINOR__ >= 4
30#define __must_check __attribute__((warn_unused_result)) 13#define __must_check __attribute__((warn_unused_result))
31#endif 14#endif
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index 53686c037a06..e913e9beaf69 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -3,14 +3,7 @@
3/* These definitions are for GCC v4.x. */ 3/* These definitions are for GCC v4.x. */
4#include <linux/compiler-gcc.h> 4#include <linux/compiler-gcc.h>
5 5
6#define inline inline __attribute__((always_inline))
7#define __inline__ __inline__ __attribute__((always_inline))
8#define __inline __inline __attribute__((always_inline))
9#define __deprecated __attribute__((deprecated))
10#define __attribute_used__ __attribute__((__used__)) 6#define __attribute_used__ __attribute__((__used__))
11#define __attribute_pure__ __attribute__((pure))
12#define __attribute_const__ __attribute__((__const__))
13#define noinline __attribute__((noinline))
14#define __must_check __attribute__((warn_unused_result)) 7#define __must_check __attribute__((warn_unused_result))
15#define __compiler_offsetof(a,b) __builtin_offsetof(a,b) 8#define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
16 9
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index d7378215b851..f23d3c6fc2c0 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -42,8 +42,6 @@ extern void __chk_io_ptr(void __iomem *);
42# include <linux/compiler-gcc4.h> 42# include <linux/compiler-gcc4.h>
43#elif __GNUC__ == 3 43#elif __GNUC__ == 3
44# include <linux/compiler-gcc3.h> 44# include <linux/compiler-gcc3.h>
45#elif __GNUC__ == 2
46# include <linux/compiler-gcc2.h>
47#else 45#else
48# error Sorry, your compiler is too old/not recognized. 46# error Sorry, your compiler is too old/not recognized.
49#endif 47#endif
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 6e2deef96b34..c472f972bd6d 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -14,22 +14,43 @@
14 14
15#ifdef CONFIG_CPUSETS 15#ifdef CONFIG_CPUSETS
16 16
17extern int number_of_cpusets; /* How many cpusets are defined in system? */
18
19extern int cpuset_init_early(void);
17extern int cpuset_init(void); 20extern int cpuset_init(void);
18extern void cpuset_init_smp(void); 21extern void cpuset_init_smp(void);
19extern void cpuset_fork(struct task_struct *p); 22extern void cpuset_fork(struct task_struct *p);
20extern void cpuset_exit(struct task_struct *p); 23extern void cpuset_exit(struct task_struct *p);
21extern cpumask_t cpuset_cpus_allowed(const struct task_struct *p); 24extern cpumask_t cpuset_cpus_allowed(struct task_struct *p);
25extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
22void cpuset_init_current_mems_allowed(void); 26void cpuset_init_current_mems_allowed(void);
23void cpuset_update_current_mems_allowed(void); 27void cpuset_update_task_memory_state(void);
24void cpuset_restrict_to_mems_allowed(unsigned long *nodes); 28#define cpuset_nodes_subset_current_mems_allowed(nodes) \
29 nodes_subset((nodes), current->mems_allowed)
25int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl); 30int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl);
26extern int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask); 31
32extern int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask);
33static int inline cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
34{
35 return number_of_cpusets <= 1 || __cpuset_zone_allowed(z, gfp_mask);
36}
37
27extern int cpuset_excl_nodes_overlap(const struct task_struct *p); 38extern int cpuset_excl_nodes_overlap(const struct task_struct *p);
39
40#define cpuset_memory_pressure_bump() \
41 do { \
42 if (cpuset_memory_pressure_enabled) \
43 __cpuset_memory_pressure_bump(); \
44 } while (0)
45extern int cpuset_memory_pressure_enabled;
46extern void __cpuset_memory_pressure_bump(void);
47
28extern struct file_operations proc_cpuset_operations; 48extern struct file_operations proc_cpuset_operations;
29extern char *cpuset_task_status_allowed(struct task_struct *task, char *buffer); 49extern char *cpuset_task_status_allowed(struct task_struct *task, char *buffer);
30 50
31#else /* !CONFIG_CPUSETS */ 51#else /* !CONFIG_CPUSETS */
32 52
53static inline int cpuset_init_early(void) { return 0; }
33static inline int cpuset_init(void) { return 0; } 54static inline int cpuset_init(void) { return 0; }
34static inline void cpuset_init_smp(void) {} 55static inline void cpuset_init_smp(void) {}
35static inline void cpuset_fork(struct task_struct *p) {} 56static inline void cpuset_fork(struct task_struct *p) {}
@@ -40,9 +61,14 @@ static inline cpumask_t cpuset_cpus_allowed(struct task_struct *p)
40 return cpu_possible_map; 61 return cpu_possible_map;
41} 62}
42 63
64static inline nodemask_t cpuset_mems_allowed(struct task_struct *p)
65{
66 return node_possible_map;
67}
68
43static inline void cpuset_init_current_mems_allowed(void) {} 69static inline void cpuset_init_current_mems_allowed(void) {}
44static inline void cpuset_update_current_mems_allowed(void) {} 70static inline void cpuset_update_task_memory_state(void) {}
45static inline void cpuset_restrict_to_mems_allowed(unsigned long *nodes) {} 71#define cpuset_nodes_subset_current_mems_allowed(nodes) (1)
46 72
47static inline int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl) 73static inline int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl)
48{ 74{
@@ -59,6 +85,8 @@ static inline int cpuset_excl_nodes_overlap(const struct task_struct *p)
59 return 1; 85 return 1;
60} 86}
61 87
88static inline void cpuset_memory_pressure_bump(void) {}
89
62static inline char *cpuset_task_status_allowed(struct task_struct *task, 90static inline char *cpuset_task_status_allowed(struct task_struct *task,
63 char *buffer) 91 char *buffer)
64{ 92{
diff --git a/include/linux/cycx_x25.h b/include/linux/cycx_x25.h
index b10a7f3a8cac..f7a906583463 100644
--- a/include/linux/cycx_x25.h
+++ b/include/linux/cycx_x25.h
@@ -38,11 +38,11 @@ extern unsigned int cycx_debug;
38/* Data Structures */ 38/* Data Structures */
39/* X.25 Command Block. */ 39/* X.25 Command Block. */
40struct cycx_x25_cmd { 40struct cycx_x25_cmd {
41 u16 command PACKED; 41 u16 command;
42 u16 link PACKED; /* values: 0 or 1 */ 42 u16 link; /* values: 0 or 1 */
43 u16 len PACKED; /* values: 0 thru 0x205 (517) */ 43 u16 len; /* values: 0 thru 0x205 (517) */
44 u32 buf PACKED; 44 u32 buf;
45}; 45} PACKED;
46 46
47/* Defines for the 'command' field. */ 47/* Defines for the 'command' field. */
48#define X25_CONNECT_REQUEST 0x4401 48#define X25_CONNECT_REQUEST 0x4401
@@ -92,34 +92,34 @@ struct cycx_x25_cmd {
92 * @flags - see dosx25.doc, in portuguese, for details 92 * @flags - see dosx25.doc, in portuguese, for details
93 */ 93 */
94struct cycx_x25_config { 94struct cycx_x25_config {
95 u8 link PACKED; 95 u8 link;
96 u8 speed PACKED; 96 u8 speed;
97 u8 clock PACKED; 97 u8 clock;
98 u8 n2 PACKED; 98 u8 n2;
99 u8 n2win PACKED; 99 u8 n2win;
100 u8 n3win PACKED; 100 u8 n3win;
101 u8 nvc PACKED; 101 u8 nvc;
102 u8 pktlen PACKED; 102 u8 pktlen;
103 u8 locaddr PACKED; 103 u8 locaddr;
104 u8 remaddr PACKED; 104 u8 remaddr;
105 u16 t1 PACKED; 105 u16 t1;
106 u16 t2 PACKED; 106 u16 t2;
107 u8 t21 PACKED; 107 u8 t21;
108 u8 npvc PACKED; 108 u8 npvc;
109 u8 t23 PACKED; 109 u8 t23;
110 u8 flags PACKED; 110 u8 flags;
111}; 111} PACKED;
112 112
113struct cycx_x25_stats { 113struct cycx_x25_stats {
114 u16 rx_crc_errors PACKED; 114 u16 rx_crc_errors;
115 u16 rx_over_errors PACKED; 115 u16 rx_over_errors;
116 u16 n2_tx_frames PACKED; 116 u16 n2_tx_frames;
117 u16 n2_rx_frames PACKED; 117 u16 n2_rx_frames;
118 u16 tx_timeouts PACKED; 118 u16 tx_timeouts;
119 u16 rx_timeouts PACKED; 119 u16 rx_timeouts;
120 u16 n3_tx_packets PACKED; 120 u16 n3_tx_packets;
121 u16 n3_rx_packets PACKED; 121 u16 n3_rx_packets;
122 u16 tx_aborts PACKED; 122 u16 tx_aborts;
123 u16 rx_aborts PACKED; 123 u16 rx_aborts;
124}; 124} PACKED;
125#endif /* _CYCX_X25_H */ 125#endif /* _CYCX_X25_H */
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 46a2ba617595..a3ed5e059d47 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -95,14 +95,19 @@ struct dentry {
95 struct qstr d_name; 95 struct qstr d_name;
96 96
97 struct list_head d_lru; /* LRU list */ 97 struct list_head d_lru; /* LRU list */
98 struct list_head d_child; /* child of parent list */ 98 /*
99 * d_child and d_rcu can share memory
100 */
101 union {
102 struct list_head d_child; /* child of parent list */
103 struct rcu_head d_rcu;
104 } d_u;
99 struct list_head d_subdirs; /* our children */ 105 struct list_head d_subdirs; /* our children */
100 struct list_head d_alias; /* inode alias list */ 106 struct list_head d_alias; /* inode alias list */
101 unsigned long d_time; /* used by d_revalidate */ 107 unsigned long d_time; /* used by d_revalidate */
102 struct dentry_operations *d_op; 108 struct dentry_operations *d_op;
103 struct super_block *d_sb; /* The root of the dentry tree */ 109 struct super_block *d_sb; /* The root of the dentry tree */
104 void *d_fsdata; /* fs-specific data */ 110 void *d_fsdata; /* fs-specific data */
105 struct rcu_head d_rcu;
106 struct dcookie_struct *d_cookie; /* cookie, if any */ 111 struct dcookie_struct *d_cookie; /* cookie, if any */
107 int d_mounted; 112 int d_mounted;
108 unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */ 113 unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h
index d41df7047ed7..c8cbd90ba375 100644
--- a/include/linux/dvb/frontend.h
+++ b/include/linux/dvb/frontend.h
@@ -240,6 +240,15 @@ struct dvb_frontend_event {
240}; 240};
241 241
242 242
243/**
244 * When set, this flag will disable any zigzagging or other "normal" tuning
245 * behaviour. Additionally, there will be no automatic monitoring of the lock
246 * status, and hence no frontend events will be generated. If a frontend device
247 * is closed, this flag will be automatically turned off when the device is
248 * reopened read-write.
249 */
250#define FE_TUNE_MODE_ONESHOT 0x01
251
243 252
244#define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info) 253#define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info)
245 254
@@ -260,6 +269,7 @@ struct dvb_frontend_event {
260 269
261#define FE_SET_FRONTEND _IOW('o', 76, struct dvb_frontend_parameters) 270#define FE_SET_FRONTEND _IOW('o', 76, struct dvb_frontend_parameters)
262#define FE_GET_FRONTEND _IOR('o', 77, struct dvb_frontend_parameters) 271#define FE_GET_FRONTEND _IOR('o', 77, struct dvb_frontend_parameters)
272#define FE_SET_FRONTEND_TUNE_MODE _IO('o', 81) /* unsigned int */
263#define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event) 273#define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event)
264 274
265#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */ 275#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index fb80fa44c4dd..4a6f50e31c73 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -114,8 +114,6 @@ extern ssize_t elv_iosched_store(request_queue_t *, const char *, size_t);
114extern int elevator_init(request_queue_t *, char *); 114extern int elevator_init(request_queue_t *, char *);
115extern void elevator_exit(elevator_t *); 115extern void elevator_exit(elevator_t *);
116extern int elv_rq_merge_ok(struct request *, struct bio *); 116extern int elv_rq_merge_ok(struct request *, struct bio *);
117extern int elv_try_merge(struct request *, struct bio *);
118extern int elv_try_last_merge(request_queue_t *, struct bio *);
119 117
120/* 118/*
121 * Return values from elevator merger 119 * Return values from elevator merger
diff --git a/include/linux/elf.h b/include/linux/elf.h
index ff955dbf510d..d3bfacb24496 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -151,6 +151,8 @@ typedef __s64 Elf64_Sxword;
151#define STT_FUNC 2 151#define STT_FUNC 2
152#define STT_SECTION 3 152#define STT_SECTION 3
153#define STT_FILE 4 153#define STT_FILE 4
154#define STT_COMMON 5
155#define STT_TLS 6
154 156
155#define ELF_ST_BIND(x) ((x) >> 4) 157#define ELF_ST_BIND(x) ((x) >> 4)
156#define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf) 158#define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 2c9c48d65630..4c82219b0fae 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -9,7 +9,6 @@
9#include <linux/config.h> 9#include <linux/config.h>
10#include <linux/limits.h> 10#include <linux/limits.h>
11#include <linux/ioctl.h> 11#include <linux/ioctl.h>
12#include <linux/rcuref.h>
13 12
14/* 13/*
15 * It's silly to have NR_OPEN bigger than NR_FILE, but you can change 14 * It's silly to have NR_OPEN bigger than NR_FILE, but you can change
@@ -104,11 +103,11 @@ extern int dir_notify_enable;
104#define MS_MOVE 8192 103#define MS_MOVE 8192
105#define MS_REC 16384 104#define MS_REC 16384
106#define MS_VERBOSE 32768 105#define MS_VERBOSE 32768
106#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */
107#define MS_UNBINDABLE (1<<17) /* change to unbindable */ 107#define MS_UNBINDABLE (1<<17) /* change to unbindable */
108#define MS_PRIVATE (1<<18) /* change to private */ 108#define MS_PRIVATE (1<<18) /* change to private */
109#define MS_SLAVE (1<<19) /* change to slave */ 109#define MS_SLAVE (1<<19) /* change to slave */
110#define MS_SHARED (1<<20) /* change to shared */ 110#define MS_SHARED (1<<20) /* change to shared */
111#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */
112#define MS_ACTIVE (1<<30) 111#define MS_ACTIVE (1<<30)
113#define MS_NOUSER (1<<31) 112#define MS_NOUSER (1<<31)
114 113
@@ -225,6 +224,7 @@ extern int dir_notify_enable;
225#include <asm/semaphore.h> 224#include <asm/semaphore.h>
226#include <asm/byteorder.h> 225#include <asm/byteorder.h>
227 226
227struct hd_geometry;
228struct iovec; 228struct iovec;
229struct nameidata; 229struct nameidata;
230struct kiocb; 230struct kiocb;
@@ -653,7 +653,7 @@ extern spinlock_t files_lock;
653#define file_list_lock() spin_lock(&files_lock); 653#define file_list_lock() spin_lock(&files_lock);
654#define file_list_unlock() spin_unlock(&files_lock); 654#define file_list_unlock() spin_unlock(&files_lock);
655 655
656#define get_file(x) rcuref_inc(&(x)->f_count) 656#define get_file(x) atomic_inc(&(x)->f_count)
657#define file_count(x) atomic_read(&(x)->f_count) 657#define file_count(x) atomic_read(&(x)->f_count)
658 658
659#define MAX_NON_LFS ((1UL<<31) - 1) 659#define MAX_NON_LFS ((1UL<<31) - 1)
@@ -808,7 +808,6 @@ struct super_block {
808 struct list_head s_list; /* Keep this first */ 808 struct list_head s_list; /* Keep this first */
809 dev_t s_dev; /* search index; _not_ kdev_t */ 809 dev_t s_dev; /* search index; _not_ kdev_t */
810 unsigned long s_blocksize; 810 unsigned long s_blocksize;
811 unsigned long s_old_blocksize;
812 unsigned char s_blocksize_bits; 811 unsigned char s_blocksize_bits;
813 unsigned char s_dirt; 812 unsigned char s_dirt;
814 unsigned long long s_maxbytes; /* Max file size */ 813 unsigned long long s_maxbytes; /* Max file size */
@@ -963,6 +962,7 @@ struct block_device_operations {
963 int (*direct_access) (struct block_device *, sector_t, unsigned long *); 962 int (*direct_access) (struct block_device *, sector_t, unsigned long *);
964 int (*media_changed) (struct gendisk *); 963 int (*media_changed) (struct gendisk *);
965 int (*revalidate_disk) (struct gendisk *); 964 int (*revalidate_disk) (struct gendisk *);
965 int (*getgeo)(struct block_device *, struct hd_geometry *);
966 struct module *owner; 966 struct module *owner;
967}; 967};
968 968
@@ -1345,7 +1345,8 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
1345 1345
1346/* fs/open.c */ 1346/* fs/open.c */
1347 1347
1348extern int do_truncate(struct dentry *, loff_t start, struct file *filp); 1348extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
1349 struct file *filp);
1349extern long do_sys_open(const char __user *filename, int flags, int mode); 1350extern long do_sys_open(const char __user *filename, int flags, int mode);
1350extern struct file *filp_open(const char *, int, int); 1351extern struct file *filp_open(const char *, int, int);
1351extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); 1352extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index fb46f8d56999..6ff2d365895f 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -103,6 +103,7 @@
103#define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */ 103#define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */
104#define I2C_DRIVERID_AKITAIOEXP 74 /* IO Expander on Sharp SL-C1000 */ 104#define I2C_DRIVERID_AKITAIOEXP 74 /* IO Expander on Sharp SL-C1000 */
105#define I2C_DRIVERID_INFRARED 75 /* I2C InfraRed on Video boards */ 105#define I2C_DRIVERID_INFRARED 75 /* I2C InfraRed on Video boards */
106#define I2C_DRIVERID_TVP5150 76 /* TVP5150 video decoder */
106 107
107#define I2C_DRIVERID_I2CDEV 900 108#define I2C_DRIVERID_I2CDEV 900
108#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ 109#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 7b6a6a58e465..ef8d0cbb832f 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -801,7 +801,7 @@ typedef struct hwif_s {
801 unsigned dma; 801 unsigned dma;
802 802
803 void (*led_act)(void *data, int rw); 803 void (*led_act)(void *data, int rw);
804} ____cacheline_maxaligned_in_smp ide_hwif_t; 804} ____cacheline_internodealigned_in_smp ide_hwif_t;
805 805
806/* 806/*
807 * internal ide interrupt handler type 807 * internal ide interrupt handler type
@@ -1001,6 +1001,7 @@ extern int noautodma;
1001 1001
1002extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs); 1002extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs);
1003extern int __ide_end_request (ide_drive_t *drive, struct request *rq, int uptodate, int nrsecs); 1003extern int __ide_end_request (ide_drive_t *drive, struct request *rq, int uptodate, int nrsecs);
1004extern void ide_softirq_done(struct request *rq);
1004 1005
1005/* 1006/*
1006 * This is used on exit from the driver to designate the next irq handler 1007 * This is used on exit from the driver to designate the next irq handler
diff --git a/include/linux/if_frad.h b/include/linux/if_frad.h
index 511999c7eeda..395f0aad9cbf 100644
--- a/include/linux/if_frad.h
+++ b/include/linux/if_frad.h
@@ -131,17 +131,17 @@ struct frad_conf
131/* these are the fields of an RFC 1490 header */ 131/* these are the fields of an RFC 1490 header */
132struct frhdr 132struct frhdr
133{ 133{
134 unsigned char control __attribute__((packed)); 134 unsigned char control;
135 135
136 /* for IP packets, this can be the NLPID */ 136 /* for IP packets, this can be the NLPID */
137 unsigned char pad __attribute__((packed)); 137 unsigned char pad;
138 138
139 unsigned char NLPID __attribute__((packed)); 139 unsigned char NLPID;
140 unsigned char OUI[3] __attribute__((packed)); 140 unsigned char OUI[3];
141 unsigned short PID __attribute__((packed)); 141 unsigned short PID;
142 142
143#define IP_NLPID pad 143#define IP_NLPID pad
144}; 144} __attribute__((packed));
145 145
146/* see RFC 1490 for the definition of the following */ 146/* see RFC 1490 for the definition of the following */
147#define FRAD_I_UI 0x03 147#define FRAD_I_UI 0x03
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 41f150a3d2dd..2c08fdc2bdf7 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -79,7 +79,7 @@ static inline void __deprecated save_flags(unsigned long *x)
79{ 79{
80 local_save_flags(*x); 80 local_save_flags(*x);
81} 81}
82#define save_flags(x) save_flags(&x); 82#define save_flags(x) save_flags(&x)
83static inline void __deprecated restore_flags(unsigned long x) 83static inline void __deprecated restore_flags(unsigned long x)
84{ 84{
85 local_irq_restore(x); 85 local_irq_restore(x);
@@ -112,7 +112,7 @@ enum
112 TIMER_SOFTIRQ, 112 TIMER_SOFTIRQ,
113 NET_TX_SOFTIRQ, 113 NET_TX_SOFTIRQ,
114 NET_RX_SOFTIRQ, 114 NET_RX_SOFTIRQ,
115 SCSI_SOFTIRQ, 115 BLOCK_SOFTIRQ,
116 TASKLET_SOFTIRQ 116 TASKLET_SOFTIRQ
117}; 117};
118 118
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 93bbed5c6cf4..9c8f4c9ed429 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -191,6 +191,10 @@ struct inet6_skb_parm {
191 __u16 srcrt; 191 __u16 srcrt;
192 __u16 dst1; 192 __u16 dst1;
193 __u16 lastopt; 193 __u16 lastopt;
194 __u32 nhoff;
195 __u16 flags;
196
197#define IP6SKB_XFRM_TRANSFORMED 1
194}; 198};
195 199
196#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb)) 200#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb))
diff --git a/include/linux/isdnif.h b/include/linux/isdnif.h
index 7a4eacd77cb2..04e10f9f14f8 100644
--- a/include/linux/isdnif.h
+++ b/include/linux/isdnif.h
@@ -282,43 +282,43 @@ typedef struct setup_parm {
282 282
283typedef struct T30_s { 283typedef struct T30_s {
284 /* session parameters */ 284 /* session parameters */
285 __u8 resolution __attribute__ ((packed)); 285 __u8 resolution;
286 __u8 rate __attribute__ ((packed)); 286 __u8 rate;
287 __u8 width __attribute__ ((packed)); 287 __u8 width;
288 __u8 length __attribute__ ((packed)); 288 __u8 length;
289 __u8 compression __attribute__ ((packed)); 289 __u8 compression;
290 __u8 ecm __attribute__ ((packed)); 290 __u8 ecm;
291 __u8 binary __attribute__ ((packed)); 291 __u8 binary;
292 __u8 scantime __attribute__ ((packed)); 292 __u8 scantime;
293 __u8 id[FAXIDLEN] __attribute__ ((packed)); 293 __u8 id[FAXIDLEN];
294 /* additional parameters */ 294 /* additional parameters */
295 __u8 phase __attribute__ ((packed)); 295 __u8 phase;
296 __u8 direction __attribute__ ((packed)); 296 __u8 direction;
297 __u8 code __attribute__ ((packed)); 297 __u8 code;
298 __u8 badlin __attribute__ ((packed)); 298 __u8 badlin;
299 __u8 badmul __attribute__ ((packed)); 299 __u8 badmul;
300 __u8 bor __attribute__ ((packed)); 300 __u8 bor;
301 __u8 fet __attribute__ ((packed)); 301 __u8 fet;
302 __u8 pollid[FAXIDLEN] __attribute__ ((packed)); 302 __u8 pollid[FAXIDLEN];
303 __u8 cq __attribute__ ((packed)); 303 __u8 cq;
304 __u8 cr __attribute__ ((packed)); 304 __u8 cr;
305 __u8 ctcrty __attribute__ ((packed)); 305 __u8 ctcrty;
306 __u8 minsp __attribute__ ((packed)); 306 __u8 minsp;
307 __u8 phcto __attribute__ ((packed)); 307 __u8 phcto;
308 __u8 rel __attribute__ ((packed)); 308 __u8 rel;
309 __u8 nbc __attribute__ ((packed)); 309 __u8 nbc;
310 /* remote station parameters */ 310 /* remote station parameters */
311 __u8 r_resolution __attribute__ ((packed)); 311 __u8 r_resolution;
312 __u8 r_rate __attribute__ ((packed)); 312 __u8 r_rate;
313 __u8 r_width __attribute__ ((packed)); 313 __u8 r_width;
314 __u8 r_length __attribute__ ((packed)); 314 __u8 r_length;
315 __u8 r_compression __attribute__ ((packed)); 315 __u8 r_compression;
316 __u8 r_ecm __attribute__ ((packed)); 316 __u8 r_ecm;
317 __u8 r_binary __attribute__ ((packed)); 317 __u8 r_binary;
318 __u8 r_scantime __attribute__ ((packed)); 318 __u8 r_scantime;
319 __u8 r_id[FAXIDLEN] __attribute__ ((packed)); 319 __u8 r_id[FAXIDLEN];
320 __u8 r_code __attribute__ ((packed)); 320 __u8 r_code;
321} T30_s; 321} __attribute__((packed)) T30_s;
322 322
323#define ISDN_TTY_FAX_CONN_IN 0 323#define ISDN_TTY_FAX_CONN_IN 0
324#define ISDN_TTY_FAX_CONN_OUT 1 324#define ISDN_TTY_FAX_CONN_OUT 1
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index b1e407a4fbda..ca7ff8fdd090 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -316,8 +316,6 @@ extern int randomize_va_space;
316#endif 316#endif
317 317
318/* Trap pasters of __FUNCTION__ at compile-time */ 318/* Trap pasters of __FUNCTION__ at compile-time */
319#if __GNUC__ > 2 || __GNUC_MINOR__ >= 95
320#define __FUNCTION__ (__func__) 319#define __FUNCTION__ (__func__)
321#endif
322 320
323#endif 321#endif
diff --git a/include/linux/key.h b/include/linux/key.h
index 4d189e51bc6c..cbf464ad9589 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -177,6 +177,8 @@ struct key {
177/* 177/*
178 * kernel managed key type definition 178 * kernel managed key type definition
179 */ 179 */
180typedef int (*request_key_actor_t)(struct key *key, struct key *authkey, const char *op);
181
180struct key_type { 182struct key_type {
181 /* name of the type */ 183 /* name of the type */
182 const char *name; 184 const char *name;
@@ -218,6 +220,16 @@ struct key_type {
218 */ 220 */
219 long (*read)(const struct key *key, char __user *buffer, size_t buflen); 221 long (*read)(const struct key *key, char __user *buffer, size_t buflen);
220 222
223 /* handle request_key() for this type instead of invoking
224 * /sbin/request-key (optional)
225 * - key is the key to instantiate
226 * - authkey is the authority to assume when instantiating this key
227 * - op is the operation to be done, usually "create"
228 * - the call must not return until the instantiation process has run
229 * its course
230 */
231 request_key_actor_t request_key;
232
221 /* internal fields */ 233 /* internal fields */
222 struct list_head link; /* link in types list */ 234 struct list_head link; /* link in types list */
223}; 235};
diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h
index 8d7c59a29e09..3365945640c9 100644
--- a/include/linux/keyctl.h
+++ b/include/linux/keyctl.h
@@ -19,6 +19,7 @@
19#define KEY_SPEC_USER_KEYRING -4 /* - key ID for UID-specific keyring */ 19#define KEY_SPEC_USER_KEYRING -4 /* - key ID for UID-specific keyring */
20#define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */ 20#define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */
21#define KEY_SPEC_GROUP_KEYRING -6 /* - key ID for GID-specific keyring */ 21#define KEY_SPEC_GROUP_KEYRING -6 /* - key ID for GID-specific keyring */
22#define KEY_SPEC_REQKEY_AUTH_KEY -7 /* - key ID for assumed request_key auth key */
22 23
23/* request-key default keyrings */ 24/* request-key default keyrings */
24#define KEY_REQKEY_DEFL_NO_CHANGE -1 25#define KEY_REQKEY_DEFL_NO_CHANGE -1
@@ -46,5 +47,7 @@
46#define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */ 47#define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */
47#define KEYCTL_NEGATE 13 /* negate a partially constructed key */ 48#define KEYCTL_NEGATE 13 /* negate a partially constructed key */
48#define KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */ 49#define KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */
50#define KEYCTL_SET_TIMEOUT 15 /* set key timeout */
51#define KEYCTL_ASSUME_AUTHORITY 16 /* assume request_key() authorisation */
49 52
50#endif /* _LINUX_KEYCTL_H */ 53#endif /* _LINUX_KEYCTL_H */
diff --git a/include/linux/memory.h b/include/linux/memory.h
index dc4081b6f161..e251dc43d0f5 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -70,21 +70,15 @@ static inline void unregister_memory_notifier(struct notifier_block *nb)
70{ 70{
71} 71}
72#else 72#else
73extern int register_memory(struct memory_block *, struct mem_section *section, struct node *);
74extern int register_new_memory(struct mem_section *); 73extern int register_new_memory(struct mem_section *);
75extern int unregister_memory_section(struct mem_section *); 74extern int unregister_memory_section(struct mem_section *);
76extern int memory_dev_init(void); 75extern int memory_dev_init(void);
77extern int register_memory_notifier(struct notifier_block *nb); 76extern int remove_memory_block(unsigned long, struct mem_section *, int);
78extern void unregister_memory_notifier(struct notifier_block *nb);
79 77
80#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) 78#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)
81 79
82extern int invalidate_phys_mapping(unsigned long, unsigned long);
83struct notifier_block; 80struct notifier_block;
84 81
85extern int register_memory_notifier(struct notifier_block *nb);
86extern void unregister_memory_notifier(struct notifier_block *nb);
87
88#endif /* CONFIG_MEMORY_HOTPLUG */ 82#endif /* CONFIG_MEMORY_HOTPLUG */
89 83
90#define hotplug_memory_notifier(fn, pri) { \ 84#define hotplug_memory_notifier(fn, pri) { \
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index ed00b278cb93..c7ac77e873b3 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -22,6 +22,9 @@
22 22
23/* Flags for mbind */ 23/* Flags for mbind */
24#define MPOL_MF_STRICT (1<<0) /* Verify existing pages in the mapping */ 24#define MPOL_MF_STRICT (1<<0) /* Verify existing pages in the mapping */
25#define MPOL_MF_MOVE (1<<1) /* Move pages owned by this process to conform to mapping */
26#define MPOL_MF_MOVE_ALL (1<<2) /* Move every page to conform to mapping */
27#define MPOL_MF_INTERNAL (1<<3) /* Internal flags start here */
25 28
26#ifdef __KERNEL__ 29#ifdef __KERNEL__
27 30
@@ -65,6 +68,7 @@ struct mempolicy {
65 nodemask_t nodes; /* interleave */ 68 nodemask_t nodes; /* interleave */
66 /* undefined for default */ 69 /* undefined for default */
67 } v; 70 } v;
71 nodemask_t cpuset_mems_allowed; /* mempolicy relative to these nodes */
68}; 72};
69 73
70/* 74/*
@@ -141,12 +145,21 @@ void mpol_free_shared_policy(struct shared_policy *p);
141struct mempolicy *mpol_shared_policy_lookup(struct shared_policy *sp, 145struct mempolicy *mpol_shared_policy_lookup(struct shared_policy *sp,
142 unsigned long idx); 146 unsigned long idx);
143 147
144struct mempolicy *get_vma_policy(struct task_struct *task,
145 struct vm_area_struct *vma, unsigned long addr);
146
147extern void numa_default_policy(void); 148extern void numa_default_policy(void);
148extern void numa_policy_init(void); 149extern void numa_policy_init(void);
149extern void numa_policy_rebind(const nodemask_t *old, const nodemask_t *new); 150extern void mpol_rebind_policy(struct mempolicy *pol, const nodemask_t *new);
151extern void mpol_rebind_task(struct task_struct *tsk,
152 const nodemask_t *new);
153extern void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new);
154#define set_cpuset_being_rebound(x) (cpuset_being_rebound = (x))
155
156#ifdef CONFIG_CPUSET
157#define current_cpuset_is_being_rebound() \
158 (cpuset_being_rebound == current->cpuset)
159#else
160#define current_cpuset_is_being_rebound() 0
161#endif
162
150extern struct mempolicy default_policy; 163extern struct mempolicy default_policy;
151extern struct zonelist *huge_zonelist(struct vm_area_struct *vma, 164extern struct zonelist *huge_zonelist(struct vm_area_struct *vma,
152 unsigned long addr); 165 unsigned long addr);
@@ -159,6 +172,11 @@ static inline void check_highest_zone(int k)
159 policy_zone = k; 172 policy_zone = k;
160} 173}
161 174
175int do_migrate_pages(struct mm_struct *mm,
176 const nodemask_t *from_nodes, const nodemask_t *to_nodes, int flags);
177
178extern void *cpuset_being_rebound; /* Trigger mpol_copy vma rebind */
179
162#else 180#else
163 181
164struct mempolicy {}; 182struct mempolicy {};
@@ -218,17 +236,35 @@ static inline void numa_default_policy(void)
218{ 236{
219} 237}
220 238
221static inline void numa_policy_rebind(const nodemask_t *old, 239static inline void mpol_rebind_policy(struct mempolicy *pol,
222 const nodemask_t *new) 240 const nodemask_t *new)
223{ 241{
224} 242}
225 243
244static inline void mpol_rebind_task(struct task_struct *tsk,
245 const nodemask_t *new)
246{
247}
248
249static inline void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new)
250{
251}
252
253#define set_cpuset_being_rebound(x) do {} while (0)
254
226static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma, 255static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma,
227 unsigned long addr) 256 unsigned long addr)
228{ 257{
229 return NODE_DATA(0)->node_zonelists + gfp_zone(GFP_HIGHUSER); 258 return NODE_DATA(0)->node_zonelists + gfp_zone(GFP_HIGHUSER);
230} 259}
231 260
261static inline int do_migrate_pages(struct mm_struct *mm,
262 const nodemask_t *from_nodes,
263 const nodemask_t *to_nodes, int flags)
264{
265 return 0;
266}
267
232static inline void check_highest_zone(int k) 268static inline void check_highest_zone(int k)
233{ 269{
234} 270}
diff --git a/include/linux/mm.h b/include/linux/mm.h
index bc01fff3aa01..df80e63903b5 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -223,24 +223,27 @@ struct page {
223 * & limit reverse map searches. 223 * & limit reverse map searches.
224 */ 224 */
225 union { 225 union {
226 unsigned long private; /* Mapping-private opaque data: 226 struct {
227 * usually used for buffer_heads 227 unsigned long private; /* Mapping-private opaque data:
228 * if PagePrivate set; used for 228 * usually used for buffer_heads
229 * swp_entry_t if PageSwapCache 229 * if PagePrivate set; used for
230 * When page is free, this indicates 230 * swp_entry_t if PageSwapCache.
231 * order in the buddy system. 231 * When page is free, this
232 */ 232 * indicates order in the buddy
233 * system.
234 */
235 struct address_space *mapping; /* If low bit clear, points to
236 * inode address_space, or NULL.
237 * If page mapped as anonymous
238 * memory, low bit is set, and
239 * it points to anon_vma object:
240 * see PAGE_MAPPING_ANON below.
241 */
242 };
233#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS 243#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
234 spinlock_t ptl; 244 spinlock_t ptl;
235#endif 245#endif
236 } u; 246 };
237 struct address_space *mapping; /* If low bit clear, points to
238 * inode address_space, or NULL.
239 * If page mapped as anonymous
240 * memory, low bit is set, and
241 * it points to anon_vma object:
242 * see PAGE_MAPPING_ANON below.
243 */
244 pgoff_t index; /* Our offset within mapping. */ 247 pgoff_t index; /* Our offset within mapping. */
245 struct list_head lru; /* Pageout list, eg. active_list 248 struct list_head lru; /* Pageout list, eg. active_list
246 * protected by zone->lru_lock ! 249 * protected by zone->lru_lock !
@@ -261,8 +264,8 @@ struct page {
261#endif /* WANT_PAGE_VIRTUAL */ 264#endif /* WANT_PAGE_VIRTUAL */
262}; 265};
263 266
264#define page_private(page) ((page)->u.private) 267#define page_private(page) ((page)->private)
265#define set_page_private(page, v) ((page)->u.private = (v)) 268#define set_page_private(page, v) ((page)->private = (v))
266 269
267/* 270/*
268 * FIXME: take this include out, include page-flags.h in 271 * FIXME: take this include out, include page-flags.h in
@@ -308,7 +311,7 @@ struct page {
308 */ 311 */
309#define get_page_testone(p) atomic_inc_and_test(&(p)->_count) 312#define get_page_testone(p) atomic_inc_and_test(&(p)->_count)
310 313
311#define set_page_count(p,v) atomic_set(&(p)->_count, v - 1) 314#define set_page_count(p,v) atomic_set(&(p)->_count, (v) - 1)
312#define __put_page(p) atomic_dec(&(p)->_count) 315#define __put_page(p) atomic_dec(&(p)->_count)
313 316
314extern void FASTCALL(__page_cache_release(struct page *)); 317extern void FASTCALL(__page_cache_release(struct page *));
@@ -815,7 +818,7 @@ static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long a
815 * overflow into the next struct page (as it might with DEBUG_SPINLOCK). 818 * overflow into the next struct page (as it might with DEBUG_SPINLOCK).
816 * When freeing, reset page->mapping so free_pages_check won't complain. 819 * When freeing, reset page->mapping so free_pages_check won't complain.
817 */ 820 */
818#define __pte_lockptr(page) &((page)->u.ptl) 821#define __pte_lockptr(page) &((page)->ptl)
819#define pte_lock_init(_page) do { \ 822#define pte_lock_init(_page) do { \
820 spin_lock_init(__pte_lockptr(_page)); \ 823 spin_lock_init(__pte_lockptr(_page)); \
821} while (0) 824} while (0)
@@ -1036,5 +1039,12 @@ int in_gate_area_no_task(unsigned long addr);
1036/* /proc/<pid>/oom_adj set to -17 protects from the oom-killer */ 1039/* /proc/<pid>/oom_adj set to -17 protects from the oom-killer */
1037#define OOM_DISABLE -17 1040#define OOM_DISABLE -17
1038 1041
1042int drop_caches_sysctl_handler(struct ctl_table *, int, struct file *,
1043 void __user *, size_t *, loff_t *);
1044int shrink_slab(unsigned long scanned, gfp_t gfp_mask,
1045 unsigned long lru_pages);
1046void drop_pagecache(void);
1047void drop_slab(void);
1048
1039#endif /* __KERNEL__ */ 1049#endif /* __KERNEL__ */
1040#endif /* _LINUX_MM_H */ 1050#endif /* _LINUX_MM_H */
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index 47762ca695a5..49cc68af01f8 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -38,3 +38,25 @@ del_page_from_lru(struct zone *zone, struct page *page)
38 zone->nr_inactive--; 38 zone->nr_inactive--;
39 } 39 }
40} 40}
41
42/*
43 * Isolate one page from the LRU lists.
44 *
45 * - zone->lru_lock must be held
46 */
47static inline int __isolate_lru_page(struct page *page)
48{
49 if (unlikely(!TestClearPageLRU(page)))
50 return 0;
51
52 if (get_page_testone(page)) {
53 /*
54 * It is being freed elsewhere
55 */
56 __put_page(page);
57 SetPageLRU(page);
58 return -ENOENT;
59 }
60
61 return 1;
62}
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index aef6042f8f0b..ccd3e13de1e8 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -27,14 +27,15 @@ struct mmc_command {
27#define MMC_RSP_MASK (3 << 0) 27#define MMC_RSP_MASK (3 << 0)
28#define MMC_RSP_CRC (1 << 3) /* expect valid crc */ 28#define MMC_RSP_CRC (1 << 3) /* expect valid crc */
29#define MMC_RSP_BUSY (1 << 4) /* card may send busy */ 29#define MMC_RSP_BUSY (1 << 4) /* card may send busy */
30#define MMC_RSP_OPCODE (1 << 5) /* response contains opcode */
30 31
31/* 32/*
32 * These are the response types, and correspond to valid bit 33 * These are the response types, and correspond to valid bit
33 * patterns of the above flags. One additional valid pattern 34 * patterns of the above flags. One additional valid pattern
34 * is all zeros, which means we don't expect a response. 35 * is all zeros, which means we don't expect a response.
35 */ 36 */
36#define MMC_RSP_R1 (MMC_RSP_SHORT|MMC_RSP_CRC) 37#define MMC_RSP_R1 (MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_OPCODE)
37#define MMC_RSP_R1B (MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_BUSY) 38#define MMC_RSP_R1B (MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
38#define MMC_RSP_R2 (MMC_RSP_LONG|MMC_RSP_CRC) 39#define MMC_RSP_R2 (MMC_RSP_LONG|MMC_RSP_CRC)
39#define MMC_RSP_R3 (MMC_RSP_SHORT) 40#define MMC_RSP_R3 (MMC_RSP_SHORT)
40#define MMC_RSP_R6 (MMC_RSP_SHORT|MMC_RSP_CRC) 41#define MMC_RSP_R6 (MMC_RSP_SHORT|MMC_RSP_CRC)
@@ -64,6 +65,7 @@ struct mmc_data {
64#define MMC_DATA_WRITE (1 << 8) 65#define MMC_DATA_WRITE (1 << 8)
65#define MMC_DATA_READ (1 << 9) 66#define MMC_DATA_READ (1 << 9)
66#define MMC_DATA_STREAM (1 << 10) 67#define MMC_DATA_STREAM (1 << 10)
68#define MMC_DATA_MULTI (1 << 11)
67 69
68 unsigned int bytes_xfered; 70 unsigned int bytes_xfered;
69 71
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index c34f4a2c62f8..7e4ae6ab1977 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -38,7 +38,7 @@ struct pglist_data;
38#if defined(CONFIG_SMP) 38#if defined(CONFIG_SMP)
39struct zone_padding { 39struct zone_padding {
40 char x[0]; 40 char x[0];
41} ____cacheline_maxaligned_in_smp; 41} ____cacheline_internodealigned_in_smp;
42#define ZONE_PADDING(name) struct zone_padding name; 42#define ZONE_PADDING(name) struct zone_padding name;
43#else 43#else
44#define ZONE_PADDING(name) 44#define ZONE_PADDING(name)
@@ -233,7 +233,7 @@ struct zone {
233 * rarely used fields: 233 * rarely used fields:
234 */ 234 */
235 char *name; 235 char *name;
236} ____cacheline_maxaligned_in_smp; 236} ____cacheline_internodealigned_in_smp;
237 237
238 238
239/* 239/*
@@ -437,6 +437,8 @@ int min_free_kbytes_sysctl_handler(struct ctl_table *, int, struct file *,
437extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1]; 437extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1];
438int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, struct file *, 438int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, struct file *,
439 void __user *, size_t *, loff_t *); 439 void __user *, size_t *, loff_t *);
440int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *, int, struct file *,
441 void __user *, size_t *, loff_t *);
440 442
441#include <linux/topology.h> 443#include <linux/topology.h>
442/* Returns the number of the current Node. */ 444/* Returns the number of the current Node. */
diff --git a/include/linux/mount.h b/include/linux/mount.h
index dd4e83eba933..b98a709f1794 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -22,7 +22,8 @@
22#define MNT_NOEXEC 0x04 22#define MNT_NOEXEC 0x04
23#define MNT_SHARED 0x10 /* if the vfsmount is a shared mount */ 23#define MNT_SHARED 0x10 /* if the vfsmount is a shared mount */
24#define MNT_UNBINDABLE 0x20 /* if the vfsmount is a unbindable mount */ 24#define MNT_UNBINDABLE 0x20 /* if the vfsmount is a unbindable mount */
25#define MNT_PNODE_MASK 0x30 /* propogation flag mask */ 25
26#define MNT_PNODE_MASK (MNT_SHARED | MNT_UNBINDABLE)
26 27
27struct vfsmount { 28struct vfsmount {
28 struct list_head mnt_hash; 29 struct list_head mnt_hash;
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index 941da5c016a0..e933e2a355ad 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -329,7 +329,8 @@ static inline void fatwchar_to16(__u8 *dst, const wchar_t *src, size_t len)
329extern void fat_cache_inval_inode(struct inode *inode); 329extern void fat_cache_inval_inode(struct inode *inode);
330extern int fat_get_cluster(struct inode *inode, int cluster, 330extern int fat_get_cluster(struct inode *inode, int cluster,
331 int *fclus, int *dclus); 331 int *fclus, int *dclus);
332extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys); 332extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
333 unsigned long *mapped_blocks);
333 334
334/* fat/dir.c */ 335/* fat/dir.c */
335extern struct file_operations fat_dir_operations; 336extern struct file_operations fat_dir_operations;
diff --git a/include/linux/ncp.h b/include/linux/ncp.h
index 99f77876b716..99f0adeeb3f3 100644
--- a/include/linux/ncp.h
+++ b/include/linux/ncp.h
@@ -20,29 +20,29 @@
20#define NCP_DEALLOC_SLOT_REQUEST (0x5555) 20#define NCP_DEALLOC_SLOT_REQUEST (0x5555)
21 21
22struct ncp_request_header { 22struct ncp_request_header {
23 __u16 type __attribute__((packed)); 23 __u16 type;
24 __u8 sequence __attribute__((packed)); 24 __u8 sequence;
25 __u8 conn_low __attribute__((packed)); 25 __u8 conn_low;
26 __u8 task __attribute__((packed)); 26 __u8 task;
27 __u8 conn_high __attribute__((packed)); 27 __u8 conn_high;
28 __u8 function __attribute__((packed)); 28 __u8 function;
29 __u8 data[0] __attribute__((packed)); 29 __u8 data[0];
30}; 30} __attribute__((packed));
31 31
32#define NCP_REPLY (0x3333) 32#define NCP_REPLY (0x3333)
33#define NCP_WATCHDOG (0x3E3E) 33#define NCP_WATCHDOG (0x3E3E)
34#define NCP_POSITIVE_ACK (0x9999) 34#define NCP_POSITIVE_ACK (0x9999)
35 35
36struct ncp_reply_header { 36struct ncp_reply_header {
37 __u16 type __attribute__((packed)); 37 __u16 type;
38 __u8 sequence __attribute__((packed)); 38 __u8 sequence;
39 __u8 conn_low __attribute__((packed)); 39 __u8 conn_low;
40 __u8 task __attribute__((packed)); 40 __u8 task;
41 __u8 conn_high __attribute__((packed)); 41 __u8 conn_high;
42 __u8 completion_code __attribute__((packed)); 42 __u8 completion_code;
43 __u8 connection_state __attribute__((packed)); 43 __u8 connection_state;
44 __u8 data[0] __attribute__((packed)); 44 __u8 data[0];
45}; 45} __attribute__((packed));
46 46
47#define NCP_VOLNAME_LEN (16) 47#define NCP_VOLNAME_LEN (16)
48#define NCP_NUMBER_OF_VOLUMES (256) 48#define NCP_NUMBER_OF_VOLUMES (256)
@@ -128,37 +128,37 @@ struct nw_nfs_info {
128}; 128};
129 129
130struct nw_info_struct { 130struct nw_info_struct {
131 __u32 spaceAlloc __attribute__((packed)); 131 __u32 spaceAlloc;
132 __le32 attributes __attribute__((packed)); 132 __le32 attributes;
133 __u16 flags __attribute__((packed)); 133 __u16 flags;
134 __le32 dataStreamSize __attribute__((packed)); 134 __le32 dataStreamSize;
135 __le32 totalStreamSize __attribute__((packed)); 135 __le32 totalStreamSize;
136 __u16 numberOfStreams __attribute__((packed)); 136 __u16 numberOfStreams;
137 __le16 creationTime __attribute__((packed)); 137 __le16 creationTime;
138 __le16 creationDate __attribute__((packed)); 138 __le16 creationDate;
139 __u32 creatorID __attribute__((packed)); 139 __u32 creatorID;
140 __le16 modifyTime __attribute__((packed)); 140 __le16 modifyTime;
141 __le16 modifyDate __attribute__((packed)); 141 __le16 modifyDate;
142 __u32 modifierID __attribute__((packed)); 142 __u32 modifierID;
143 __le16 lastAccessDate __attribute__((packed)); 143 __le16 lastAccessDate;
144 __u16 archiveTime __attribute__((packed)); 144 __u16 archiveTime;
145 __u16 archiveDate __attribute__((packed)); 145 __u16 archiveDate;
146 __u32 archiverID __attribute__((packed)); 146 __u32 archiverID;
147 __u16 inheritedRightsMask __attribute__((packed)); 147 __u16 inheritedRightsMask;
148 __le32 dirEntNum __attribute__((packed)); 148 __le32 dirEntNum;
149 __le32 DosDirNum __attribute__((packed)); 149 __le32 DosDirNum;
150 __u32 volNumber __attribute__((packed)); 150 __u32 volNumber;
151 __u32 EADataSize __attribute__((packed)); 151 __u32 EADataSize;
152 __u32 EAKeyCount __attribute__((packed)); 152 __u32 EAKeyCount;
153 __u32 EAKeySize __attribute__((packed)); 153 __u32 EAKeySize;
154 __u32 NSCreator __attribute__((packed)); 154 __u32 NSCreator;
155 __u8 nameLen __attribute__((packed)); 155 __u8 nameLen;
156 __u8 entryName[256] __attribute__((packed)); 156 __u8 entryName[256];
157 /* libncp may depend on there being nothing after entryName */ 157 /* libncp may depend on there being nothing after entryName */
158#ifdef __KERNEL__ 158#ifdef __KERNEL__
159 struct nw_nfs_info nfs; 159 struct nw_nfs_info nfs;
160#endif 160#endif
161}; 161} __attribute__((packed));
162 162
163/* modify mask - use with MODIFY_DOS_INFO structure */ 163/* modify mask - use with MODIFY_DOS_INFO structure */
164#define DM_ATTRIBUTES (cpu_to_le32(0x02)) 164#define DM_ATTRIBUTES (cpu_to_le32(0x02))
@@ -176,26 +176,26 @@ struct nw_info_struct {
176#define DM_MAXIMUM_SPACE (cpu_to_le32(0x2000)) 176#define DM_MAXIMUM_SPACE (cpu_to_le32(0x2000))
177 177
178struct nw_modify_dos_info { 178struct nw_modify_dos_info {
179 __le32 attributes __attribute__((packed)); 179 __le32 attributes;
180 __le16 creationDate __attribute__((packed)); 180 __le16 creationDate;
181 __le16 creationTime __attribute__((packed)); 181 __le16 creationTime;
182 __u32 creatorID __attribute__((packed)); 182 __u32 creatorID;
183 __le16 modifyDate __attribute__((packed)); 183 __le16 modifyDate;
184 __le16 modifyTime __attribute__((packed)); 184 __le16 modifyTime;
185 __u32 modifierID __attribute__((packed)); 185 __u32 modifierID;
186 __u16 archiveDate __attribute__((packed)); 186 __u16 archiveDate;
187 __u16 archiveTime __attribute__((packed)); 187 __u16 archiveTime;
188 __u32 archiverID __attribute__((packed)); 188 __u32 archiverID;
189 __le16 lastAccessDate __attribute__((packed)); 189 __le16 lastAccessDate;
190 __u16 inheritanceGrantMask __attribute__((packed)); 190 __u16 inheritanceGrantMask;
191 __u16 inheritanceRevokeMask __attribute__((packed)); 191 __u16 inheritanceRevokeMask;
192 __u32 maximumSpace __attribute__((packed)); 192 __u32 maximumSpace;
193}; 193} __attribute__((packed));
194 194
195struct nw_search_sequence { 195struct nw_search_sequence {
196 __u8 volNumber __attribute__((packed)); 196 __u8 volNumber;
197 __u32 dirBase __attribute__((packed)); 197 __u32 dirBase;
198 __u32 sequence __attribute__((packed)); 198 __u32 sequence;
199}; 199} __attribute__((packed));
200 200
201#endif /* _LINUX_NCP_H */ 201#endif /* _LINUX_NCP_H */
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index be365e70ee99..4cf6088625c1 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -168,6 +168,37 @@ void nf_log_packet(int pf,
168 const struct net_device *out, 168 const struct net_device *out,
169 struct nf_loginfo *li, 169 struct nf_loginfo *li,
170 const char *fmt, ...); 170 const char *fmt, ...);
171
172int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
173 struct net_device *indev, struct net_device *outdev,
174 int (*okfn)(struct sk_buff *), int thresh);
175
176/**
177 * nf_hook_thresh - call a netfilter hook
178 *
179 * Returns 1 if the hook has allowed the packet to pass. The function
180 * okfn must be invoked by the caller in this case. Any other return
181 * value indicates the packet has been consumed by the hook.
182 */
183static inline int nf_hook_thresh(int pf, unsigned int hook,
184 struct sk_buff **pskb,
185 struct net_device *indev,
186 struct net_device *outdev,
187 int (*okfn)(struct sk_buff *), int thresh)
188{
189#ifndef CONFIG_NETFILTER_DEBUG
190 if (list_empty(&nf_hooks[pf][hook]))
191 return 1;
192#endif
193 return nf_hook_slow(pf, hook, pskb, indev, outdev, okfn, thresh);
194}
195
196static inline int nf_hook(int pf, unsigned int hook, struct sk_buff **pskb,
197 struct net_device *indev, struct net_device *outdev,
198 int (*okfn)(struct sk_buff *))
199{
200 return nf_hook_thresh(pf, hook, pskb, indev, outdev, okfn, INT_MIN);
201}
171 202
172/* Activate hook; either okfn or kfree_skb called, unless a hook 203/* Activate hook; either okfn or kfree_skb called, unless a hook
173 returns NF_STOLEN (in which case, it's up to the hook to deal with 204 returns NF_STOLEN (in which case, it's up to the hook to deal with
@@ -188,35 +219,17 @@ void nf_log_packet(int pf,
188 219
189/* This is gross, but inline doesn't cut it for avoiding the function 220/* This is gross, but inline doesn't cut it for avoiding the function
190 call in fast path: gcc doesn't inline (needs value tracking?). --RR */ 221 call in fast path: gcc doesn't inline (needs value tracking?). --RR */
191#ifdef CONFIG_NETFILTER_DEBUG 222
192#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \ 223/* HX: It's slightly less gross now. */
193({int __ret; \ 224
194if ((__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, INT_MIN)) == 1) \
195 __ret = (okfn)(skb); \
196__ret;})
197#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \
198({int __ret; \
199if ((__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, thresh)) == 1) \
200 __ret = (okfn)(skb); \
201__ret;})
202#else
203#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
204({int __ret; \
205if (list_empty(&nf_hooks[pf][hook]) || \
206 (__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, INT_MIN)) == 1) \
207 __ret = (okfn)(skb); \
208__ret;})
209#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \ 225#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \
210({int __ret; \ 226({int __ret; \
211if (list_empty(&nf_hooks[pf][hook]) || \ 227if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, thresh)) == 1)\
212 (__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, thresh)) == 1) \
213 __ret = (okfn)(skb); \ 228 __ret = (okfn)(skb); \
214__ret;}) 229__ret;})
215#endif
216 230
217int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb, 231#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
218 struct net_device *indev, struct net_device *outdev, 232 NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, INT_MIN)
219 int (*okfn)(struct sk_buff *), int thresh);
220 233
221/* Call setsockopt() */ 234/* Call setsockopt() */
222int nf_setsockopt(struct sock *sk, int pf, int optval, char __user *opt, 235int nf_setsockopt(struct sock *sk, int pf, int optval, char __user *opt,
@@ -261,6 +274,20 @@ struct nf_queue_rerouter {
261extern int nf_register_queue_rerouter(int pf, struct nf_queue_rerouter *rer); 274extern int nf_register_queue_rerouter(int pf, struct nf_queue_rerouter *rer);
262extern int nf_unregister_queue_rerouter(int pf); 275extern int nf_unregister_queue_rerouter(int pf);
263 276
277#include <net/flow.h>
278extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
279
280static inline void
281nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family)
282{
283#ifdef CONFIG_IP_NF_NAT_NEEDED
284 void (*decodefn)(struct sk_buff *, struct flowi *);
285
286 if (family == AF_INET && (decodefn = ip_nat_decode_session) != NULL)
287 decodefn(skb, fl);
288#endif
289}
290
264#ifdef CONFIG_PROC_FS 291#ifdef CONFIG_PROC_FS
265#include <linux/proc_fs.h> 292#include <linux/proc_fs.h>
266extern struct proc_dir_entry *proc_net_netfilter; 293extern struct proc_dir_entry *proc_net_netfilter;
@@ -268,7 +295,24 @@ extern struct proc_dir_entry *proc_net_netfilter;
268 295
269#else /* !CONFIG_NETFILTER */ 296#else /* !CONFIG_NETFILTER */
270#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) 297#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
298static inline int nf_hook_thresh(int pf, unsigned int hook,
299 struct sk_buff **pskb,
300 struct net_device *indev,
301 struct net_device *outdev,
302 int (*okfn)(struct sk_buff *), int thresh)
303{
304 return okfn(*pskb);
305}
306static inline int nf_hook(int pf, unsigned int hook, struct sk_buff **pskb,
307 struct net_device *indev, struct net_device *outdev,
308 int (*okfn)(struct sk_buff *))
309{
310 return okfn(*pskb);
311}
271static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} 312static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
313struct flowi;
314static inline void
315nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family) {}
272#endif /*CONFIG_NETFILTER*/ 316#endif /*CONFIG_NETFILTER*/
273 317
274#endif /*__KERNEL__*/ 318#endif /*__KERNEL__*/
diff --git a/include/linux/netfilter_ipv4/ipt_policy.h b/include/linux/netfilter_ipv4/ipt_policy.h
new file mode 100644
index 000000000000..7fd1bec453f1
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ipt_policy.h
@@ -0,0 +1,52 @@
1#ifndef _IPT_POLICY_H
2#define _IPT_POLICY_H
3
4#define IPT_POLICY_MAX_ELEM 4
5
6enum ipt_policy_flags
7{
8 IPT_POLICY_MATCH_IN = 0x1,
9 IPT_POLICY_MATCH_OUT = 0x2,
10 IPT_POLICY_MATCH_NONE = 0x4,
11 IPT_POLICY_MATCH_STRICT = 0x8,
12};
13
14enum ipt_policy_modes
15{
16 IPT_POLICY_MODE_TRANSPORT,
17 IPT_POLICY_MODE_TUNNEL
18};
19
20struct ipt_policy_spec
21{
22 u_int8_t saddr:1,
23 daddr:1,
24 proto:1,
25 mode:1,
26 spi:1,
27 reqid:1;
28};
29
30struct ipt_policy_elem
31{
32 u_int32_t saddr;
33 u_int32_t smask;
34 u_int32_t daddr;
35 u_int32_t dmask;
36 u_int32_t spi;
37 u_int32_t reqid;
38 u_int8_t proto;
39 u_int8_t mode;
40
41 struct ipt_policy_spec match;
42 struct ipt_policy_spec invert;
43};
44
45struct ipt_policy_info
46{
47 struct ipt_policy_elem pol[IPT_POLICY_MAX_ELEM];
48 u_int16_t flags;
49 u_int16_t len;
50};
51
52#endif /* _IPT_POLICY_H */
diff --git a/include/linux/netfilter_ipv6/ip6t_policy.h b/include/linux/netfilter_ipv6/ip6t_policy.h
new file mode 100644
index 000000000000..5a93afcd2ff1
--- /dev/null
+++ b/include/linux/netfilter_ipv6/ip6t_policy.h
@@ -0,0 +1,52 @@
1#ifndef _IP6T_POLICY_H
2#define _IP6T_POLICY_H
3
4#define IP6T_POLICY_MAX_ELEM 4
5
6enum ip6t_policy_flags
7{
8 IP6T_POLICY_MATCH_IN = 0x1,
9 IP6T_POLICY_MATCH_OUT = 0x2,
10 IP6T_POLICY_MATCH_NONE = 0x4,
11 IP6T_POLICY_MATCH_STRICT = 0x8,
12};
13
14enum ip6t_policy_modes
15{
16 IP6T_POLICY_MODE_TRANSPORT,
17 IP6T_POLICY_MODE_TUNNEL
18};
19
20struct ip6t_policy_spec
21{
22 u_int8_t saddr:1,
23 daddr:1,
24 proto:1,
25 mode:1,
26 spi:1,
27 reqid:1;
28};
29
30struct ip6t_policy_elem
31{
32 struct in6_addr saddr;
33 struct in6_addr smask;
34 struct in6_addr daddr;
35 struct in6_addr dmask;
36 u_int32_t spi;
37 u_int32_t reqid;
38 u_int8_t proto;
39 u_int8_t mode;
40
41 struct ip6t_policy_spec match;
42 struct ip6t_policy_spec invert;
43};
44
45struct ip6t_policy_info
46{
47 struct ip6t_policy_elem pol[IP6T_POLICY_MAX_ELEM];
48 u_int16_t flags;
49 u_int16_t len;
50};
51
52#endif /* _IP6T_POLICY_H */
diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
index def32c5715be..8eb7fa76c1d0 100644
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -5,6 +5,9 @@
5 * pages. A pagevec is a multipage container which is used for that. 5 * pages. A pagevec is a multipage container which is used for that.
6 */ 6 */
7 7
8#ifndef _LINUX_PAGEVEC_H
9#define _LINUX_PAGEVEC_H
10
8/* 14 pointers + two long's align the pagevec structure to a power of two */ 11/* 14 pointers + two long's align the pagevec structure to a power of two */
9#define PAGEVEC_SIZE 14 12#define PAGEVEC_SIZE 14
10 13
@@ -83,3 +86,5 @@ static inline void pagevec_lru_add(struct pagevec *pvec)
83 if (pagevec_count(pvec)) 86 if (pagevec_count(pvec))
84 __pagevec_lru_add(pvec); 87 __pagevec_lru_add(pvec);
85} 88}
89
90#endif /* _LINUX_PAGEVEC_H */
diff --git a/include/linux/parport.h b/include/linux/parport.h
index f7ff0b0c4031..f67f838a3a1f 100644
--- a/include/linux/parport.h
+++ b/include/linux/parport.h
@@ -236,12 +236,14 @@ struct pardevice {
236 236
237/* IEEE1284 information */ 237/* IEEE1284 information */
238 238
239/* IEEE1284 phases */ 239/* IEEE1284 phases. These are exposed to userland through ppdev IOCTL
240 * PP[GS]ETPHASE, so do not change existing values. */
240enum ieee1284_phase { 241enum ieee1284_phase {
241 IEEE1284_PH_FWD_DATA, 242 IEEE1284_PH_FWD_DATA,
242 IEEE1284_PH_FWD_IDLE, 243 IEEE1284_PH_FWD_IDLE,
243 IEEE1284_PH_TERMINATE, 244 IEEE1284_PH_TERMINATE,
244 IEEE1284_PH_NEGOTIATION, 245 IEEE1284_PH_NEGOTIATION,
246 IEEE1284_PH_HBUSY_DNA,
245 IEEE1284_PH_REV_IDLE, 247 IEEE1284_PH_REV_IDLE,
246 IEEE1284_PH_HBUSY_DAVAIL, 248 IEEE1284_PH_HBUSY_DAVAIL,
247 IEEE1284_PH_REV_DATA, 249 IEEE1284_PH_REV_DATA,
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index e2a089b051ed..d27a78b71297 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -196,6 +196,7 @@
196#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */ 196#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
197#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */ 197#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
198#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */ 198#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */
199#define PCI_CAP_ID_HT_IRQCONF 0x08 /* HyperTransport IRQ Configuration */
199#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */ 200#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
200#define PCI_CAP_ID_EXP 0x10 /* PCI Express */ 201#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
201#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ 202#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index fb8d2d24e4bb..cb9039a21f2a 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -19,7 +19,6 @@
19 19
20struct percpu_data { 20struct percpu_data {
21 void *ptrs[NR_CPUS]; 21 void *ptrs[NR_CPUS];
22 void *blkp;
23}; 22};
24 23
25/* 24/*
@@ -33,14 +32,14 @@ struct percpu_data {
33 (__typeof__(ptr))__p->ptrs[(cpu)]; \ 32 (__typeof__(ptr))__p->ptrs[(cpu)]; \
34}) 33})
35 34
36extern void *__alloc_percpu(size_t size, size_t align); 35extern void *__alloc_percpu(size_t size);
37extern void free_percpu(const void *); 36extern void free_percpu(const void *);
38 37
39#else /* CONFIG_SMP */ 38#else /* CONFIG_SMP */
40 39
41#define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); }) 40#define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); })
42 41
43static inline void *__alloc_percpu(size_t size, size_t align) 42static inline void *__alloc_percpu(size_t size)
44{ 43{
45 void *ret = kmalloc(size, GFP_KERNEL); 44 void *ret = kmalloc(size, GFP_KERNEL);
46 if (ret) 45 if (ret)
@@ -55,7 +54,6 @@ static inline void free_percpu(const void *ptr)
55#endif /* CONFIG_SMP */ 54#endif /* CONFIG_SMP */
56 55
57/* Simple wrapper for the common case: zeros memory. */ 56/* Simple wrapper for the common case: zeros memory. */
58#define alloc_percpu(type) \ 57#define alloc_percpu(type) ((type *)(__alloc_percpu(sizeof(type))))
59 ((type *)(__alloc_percpu(sizeof(type), __alignof__(type))))
60 58
61#endif /* __LINUX_PERCPU_H */ 59#endif /* __LINUX_PERCPU_H */
diff --git a/include/linux/pmu.h b/include/linux/pmu.h
index 373bd3b9b330..217d3daf7336 100644
--- a/include/linux/pmu.h
+++ b/include/linux/pmu.h
@@ -140,7 +140,7 @@ extern int find_via_pmu(void);
140 140
141extern int pmu_request(struct adb_request *req, 141extern int pmu_request(struct adb_request *req,
142 void (*done)(struct adb_request *), int nbytes, ...); 142 void (*done)(struct adb_request *), int nbytes, ...);
143 143extern int pmu_queue_request(struct adb_request *req);
144extern void pmu_poll(void); 144extern void pmu_poll(void);
145extern void pmu_poll_adb(void); /* For use by xmon */ 145extern void pmu_poll_adb(void); /* For use by xmon */
146extern void pmu_wait_complete(struct adb_request *req); 146extern void pmu_wait_complete(struct adb_request *req);
@@ -160,12 +160,6 @@ extern void pmu_unlock(void);
160extern int pmu_present(void); 160extern int pmu_present(void);
161extern int pmu_get_model(void); 161extern int pmu_get_model(void);
162 162
163extern int pmu_i2c_combined_read(int bus, int addr, int subaddr, u8* data, int len);
164extern int pmu_i2c_stdsub_write(int bus, int addr, int subaddr, u8* data, int len);
165extern int pmu_i2c_simple_read(int bus, int addr, u8* data, int len);
166extern int pmu_i2c_simple_write(int bus, int addr, u8* data, int len);
167
168
169#ifdef CONFIG_PM 163#ifdef CONFIG_PM
170/* 164/*
171 * Stuff for putting the powerbook to sleep and waking it again. 165 * Stuff for putting the powerbook to sleep and waking it again.
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index b2b3dba1298d..9d5cd106b344 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -20,8 +20,6 @@
20#define PTRACE_DETACH 0x11 20#define PTRACE_DETACH 0x11
21 21
22#define PTRACE_SYSCALL 24 22#define PTRACE_SYSCALL 24
23#define PTRACE_SYSEMU 31
24#define PTRACE_SYSEMU_SINGLESTEP 32
25 23
26/* 0x4200-0x4300 are reserved for architecture-independent additions. */ 24/* 0x4200-0x4300 are reserved for architecture-independent additions. */
27#define PTRACE_SETOPTIONS 0x4200 25#define PTRACE_SETOPTIONS 0x4200
@@ -80,6 +78,8 @@
80 78
81 79
82extern long arch_ptrace(struct task_struct *child, long request, long addr, long data); 80extern long arch_ptrace(struct task_struct *child, long request, long addr, long data);
81extern struct task_struct *ptrace_get_task_struct(pid_t pid);
82extern int ptrace_traceme(void);
83extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len); 83extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len);
84extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len); 84extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len);
85extern int ptrace_attach(struct task_struct *tsk); 85extern int ptrace_attach(struct task_struct *tsk);
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index 36e5d269612f..c57ff2fcb30a 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -19,6 +19,7 @@
19#ifndef _LINUX_RADIX_TREE_H 19#ifndef _LINUX_RADIX_TREE_H
20#define _LINUX_RADIX_TREE_H 20#define _LINUX_RADIX_TREE_H
21 21
22#include <linux/sched.h>
22#include <linux/preempt.h> 23#include <linux/preempt.h>
23#include <linux/types.h> 24#include <linux/types.h>
24 25
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index a471f3bb713e..a1d26cb28925 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -65,7 +65,7 @@ struct rcu_ctrlblk {
65 long cur; /* Current batch number. */ 65 long cur; /* Current batch number. */
66 long completed; /* Number of the last completed batch */ 66 long completed; /* Number of the last completed batch */
67 int next_pending; /* Is the next batch already waiting? */ 67 int next_pending; /* Is the next batch already waiting? */
68} ____cacheline_maxaligned_in_smp; 68} ____cacheline_internodealigned_in_smp;
69 69
70/* Is batch a before batch b ? */ 70/* Is batch a before batch b ? */
71static inline int rcu_batch_before(long a, long b) 71static inline int rcu_batch_before(long a, long b)
@@ -125,36 +125,7 @@ static inline void rcu_bh_qsctr_inc(int cpu)
125 rdp->passed_quiesc = 1; 125 rdp->passed_quiesc = 1;
126} 126}
127 127
128static inline int __rcu_pending(struct rcu_ctrlblk *rcp, 128extern int rcu_pending(int cpu);
129 struct rcu_data *rdp)
130{
131 /* This cpu has pending rcu entries and the grace period
132 * for them has completed.
133 */
134 if (rdp->curlist && !rcu_batch_before(rcp->completed, rdp->batch))
135 return 1;
136
137 /* This cpu has no pending entries, but there are new entries */
138 if (!rdp->curlist && rdp->nxtlist)
139 return 1;
140
141 /* This cpu has finished callbacks to invoke */
142 if (rdp->donelist)
143 return 1;
144
145 /* The rcu core waits for a quiescent state from the cpu */
146 if (rdp->quiescbatch != rcp->cur || rdp->qs_pending)
147 return 1;
148
149 /* nothing to do */
150 return 0;
151}
152
153static inline int rcu_pending(int cpu)
154{
155 return __rcu_pending(&rcu_ctrlblk, &per_cpu(rcu_data, cpu)) ||
156 __rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu));
157}
158 129
159/** 130/**
160 * rcu_read_lock - mark the beginning of an RCU read-side critical section. 131 * rcu_read_lock - mark the beginning of an RCU read-side critical section.
diff --git a/include/linux/rcuref.h b/include/linux/rcuref.h
deleted file mode 100644
index e1adbba14b67..000000000000
--- a/include/linux/rcuref.h
+++ /dev/null
@@ -1,220 +0,0 @@
1/*
2 * rcuref.h
3 *
4 * Reference counting for elements of lists/arrays protected by
5 * RCU.
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 as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * Copyright (C) IBM Corporation, 2005
22 *
23 * Author: Dipankar Sarma <dipankar@in.ibm.com>
24 * Ravikiran Thirumalai <kiran_th@gmail.com>
25 *
26 * See Documentation/RCU/rcuref.txt for detailed user guide.
27 *
28 */
29
30#ifndef _RCUREF_H_
31#define _RCUREF_H_
32
33#ifdef __KERNEL__
34
35#include <linux/types.h>
36#include <linux/interrupt.h>
37#include <linux/spinlock.h>
38#include <asm/atomic.h>
39
40/*
41 * These APIs work on traditional atomic_t counters used in the
42 * kernel for reference counting. Under special circumstances
43 * where a lock-free get() operation races with a put() operation
44 * these APIs can be used. See Documentation/RCU/rcuref.txt.
45 */
46
47#ifdef __HAVE_ARCH_CMPXCHG
48
49/**
50 * rcuref_inc - increment refcount for object.
51 * @rcuref: reference counter in the object in question.
52 *
53 * This should be used only for objects where we use RCU and
54 * use the rcuref_inc_lf() api to acquire a reference
55 * in a lock-free reader-side critical section.
56 */
57static inline void rcuref_inc(atomic_t *rcuref)
58{
59 atomic_inc(rcuref);
60}
61
62/**
63 * rcuref_dec - decrement refcount for object.
64 * @rcuref: reference counter in the object in question.
65 *
66 * This should be used only for objects where we use RCU and
67 * use the rcuref_inc_lf() api to acquire a reference
68 * in a lock-free reader-side critical section.
69 */
70static inline void rcuref_dec(atomic_t *rcuref)
71{
72 atomic_dec(rcuref);
73}
74
75/**
76 * rcuref_dec_and_test - decrement refcount for object and test
77 * @rcuref: reference counter in the object.
78 * @release: pointer to the function that will clean up the object
79 * when the last reference to the object is released.
80 * This pointer is required.
81 *
82 * Decrement the refcount, and if 0, return 1. Else return 0.
83 *
84 * This should be used only for objects where we use RCU and
85 * use the rcuref_inc_lf() api to acquire a reference
86 * in a lock-free reader-side critical section.
87 */
88static inline int rcuref_dec_and_test(atomic_t *rcuref)
89{
90 return atomic_dec_and_test(rcuref);
91}
92
93/*
94 * cmpxchg is needed on UP too, if deletions to the list/array can happen
95 * in interrupt context.
96 */
97
98/**
99 * rcuref_inc_lf - Take reference to an object in a read-side
100 * critical section protected by RCU.
101 * @rcuref: reference counter in the object in question.
102 *
103 * Try and increment the refcount by 1. The increment might fail if
104 * the reference counter has been through a 1 to 0 transition and
105 * is no longer part of the lock-free list.
106 * Returns non-zero on successful increment and zero otherwise.
107 */
108static inline int rcuref_inc_lf(atomic_t *rcuref)
109{
110 int c, old;
111 c = atomic_read(rcuref);
112 while (c && (old = cmpxchg(&rcuref->counter, c, c + 1)) != c)
113 c = old;
114 return c;
115}
116
117#else /* !__HAVE_ARCH_CMPXCHG */
118
119extern spinlock_t __rcuref_hash[];
120
121/*
122 * Use a hash table of locks to protect the reference count
123 * since cmpxchg is not available in this arch.
124 */
125#ifdef CONFIG_SMP
126#define RCUREF_HASH_SIZE 4
127#define RCUREF_HASH(k) \
128 (&__rcuref_hash[(((unsigned long)k)>>8) & (RCUREF_HASH_SIZE-1)])
129#else
130#define RCUREF_HASH_SIZE 1
131#define RCUREF_HASH(k) &__rcuref_hash[0]
132#endif /* CONFIG_SMP */
133
134/**
135 * rcuref_inc - increment refcount for object.
136 * @rcuref: reference counter in the object in question.
137 *
138 * This should be used only for objects where we use RCU and
139 * use the rcuref_inc_lf() api to acquire a reference in a lock-free
140 * reader-side critical section.
141 */
142static inline void rcuref_inc(atomic_t *rcuref)
143{
144 unsigned long flags;
145 spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
146 rcuref->counter += 1;
147 spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
148}
149
150/**
151 * rcuref_dec - decrement refcount for object.
152 * @rcuref: reference counter in the object in question.
153 *
154 * This should be used only for objects where we use RCU and
155 * use the rcuref_inc_lf() api to acquire a reference in a lock-free
156 * reader-side critical section.
157 */
158static inline void rcuref_dec(atomic_t *rcuref)
159{
160 unsigned long flags;
161 spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
162 rcuref->counter -= 1;
163 spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
164}
165
166/**
167 * rcuref_dec_and_test - decrement refcount for object and test
168 * @rcuref: reference counter in the object.
169 * @release: pointer to the function that will clean up the object
170 * when the last reference to the object is released.
171 * This pointer is required.
172 *
173 * Decrement the refcount, and if 0, return 1. Else return 0.
174 *
175 * This should be used only for objects where we use RCU and
176 * use the rcuref_inc_lf() api to acquire a reference in a lock-free
177 * reader-side critical section.
178 */
179static inline int rcuref_dec_and_test(atomic_t *rcuref)
180{
181 unsigned long flags;
182 spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
183 rcuref->counter--;
184 if (!rcuref->counter) {
185 spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
186 return 1;
187 } else {
188 spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
189 return 0;
190 }
191}
192
193/**
194 * rcuref_inc_lf - Take reference to an object of a lock-free collection
195 * by traversing a lock-free list/array.
196 * @rcuref: reference counter in the object in question.
197 *
198 * Try and increment the refcount by 1. The increment might fail if
199 * the reference counter has been through a 1 to 0 transition and
200 * object is no longer part of the lock-free list.
201 * Returns non-zero on successful increment and zero otherwise.
202 */
203static inline int rcuref_inc_lf(atomic_t *rcuref)
204{
205 int ret;
206 unsigned long flags;
207 spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
208 if (rcuref->counter)
209 ret = rcuref->counter++;
210 else
211 ret = 0;
212 spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
213 return ret;
214}
215
216
217#endif /* !__HAVE_ARCH_CMPXCHG */
218
219#endif /* __KERNEL__ */
220#endif /* _RCUREF_H_ */
diff --git a/include/linux/relayfs_fs.h b/include/linux/relayfs_fs.h
index fb7e80737325..7342e66247fb 100644
--- a/include/linux/relayfs_fs.h
+++ b/include/linux/relayfs_fs.h
@@ -65,20 +65,6 @@ struct rchan
65}; 65};
66 66
67/* 67/*
68 * Relayfs inode
69 */
70struct relayfs_inode_info
71{
72 struct inode vfs_inode;
73 struct rchan_buf *buf;
74};
75
76static inline struct relayfs_inode_info *RELAYFS_I(struct inode *inode)
77{
78 return container_of(inode, struct relayfs_inode_info, vfs_inode);
79}
80
81/*
82 * Relay channel client callbacks 68 * Relay channel client callbacks
83 */ 69 */
84struct rchan_callbacks 70struct rchan_callbacks
@@ -124,6 +110,46 @@ struct rchan_callbacks
124 */ 110 */
125 void (*buf_unmapped)(struct rchan_buf *buf, 111 void (*buf_unmapped)(struct rchan_buf *buf,
126 struct file *filp); 112 struct file *filp);
113 /*
114 * create_buf_file - create file to represent a relayfs channel buffer
115 * @filename: the name of the file to create
116 * @parent: the parent of the file to create
117 * @mode: the mode of the file to create
118 * @buf: the channel buffer
119 * @is_global: outparam - set non-zero if the buffer should be global
120 *
121 * Called during relay_open(), once for each per-cpu buffer,
122 * to allow the client to create a file to be used to
123 * represent the corresponding channel buffer. If the file is
124 * created outside of relayfs, the parent must also exist in
125 * that filesystem.
126 *
127 * The callback should return the dentry of the file created
128 * to represent the relay buffer.
129 *
130 * Setting the is_global outparam to a non-zero value will
131 * cause relay_open() to create a single global buffer rather
132 * than the default set of per-cpu buffers.
133 *
134 * See Documentation/filesystems/relayfs.txt for more info.
135 */
136 struct dentry *(*create_buf_file)(const char *filename,
137 struct dentry *parent,
138 int mode,
139 struct rchan_buf *buf,
140 int *is_global);
141
142 /*
143 * remove_buf_file - remove file representing a relayfs channel buffer
144 * @dentry: the dentry of the file to remove
145 *
146 * Called during relay_close(), once for each per-cpu buffer,
147 * to allow the client to remove a file used to represent a
148 * channel buffer.
149 *
150 * The callback should return 0 if successful, negative if not.
151 */
152 int (*remove_buf_file)(struct dentry *dentry);
127}; 153};
128 154
129/* 155/*
@@ -148,6 +174,12 @@ extern size_t relay_switch_subbuf(struct rchan_buf *buf,
148extern struct dentry *relayfs_create_dir(const char *name, 174extern struct dentry *relayfs_create_dir(const char *name,
149 struct dentry *parent); 175 struct dentry *parent);
150extern int relayfs_remove_dir(struct dentry *dentry); 176extern int relayfs_remove_dir(struct dentry *dentry);
177extern struct dentry *relayfs_create_file(const char *name,
178 struct dentry *parent,
179 int mode,
180 struct file_operations *fops,
181 void *data);
182extern int relayfs_remove_file(struct dentry *dentry);
151 183
152/** 184/**
153 * relay_write - write data into the channel 185 * relay_write - write data into the channel
@@ -247,10 +279,9 @@ static inline void subbuf_start_reserve(struct rchan_buf *buf,
247} 279}
248 280
249/* 281/*
250 * exported relayfs file operations, fs/relayfs/inode.c 282 * exported relay file operations, fs/relayfs/inode.c
251 */ 283 */
252 284extern struct file_operations relay_file_operations;
253extern struct file_operations relayfs_file_operations;
254 285
255#endif /* _LINUX_RELAYFS_FS_H */ 286#endif /* _LINUX_RELAYFS_FS_H */
256 287
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h
index 3bd7cce19e26..157d7e3236b5 100644
--- a/include/linux/rio_drv.h
+++ b/include/linux/rio_drv.h
@@ -21,6 +21,7 @@
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/errno.h> 22#include <linux/errno.h>
23#include <linux/device.h> 23#include <linux/device.h>
24#include <linux/string.h>
24#include <linux/rio.h> 25#include <linux/rio.h>
25 26
26extern int __rio_local_read_config_32(struct rio_mport *port, u32 offset, 27extern int __rio_local_read_config_32(struct rio_mport *port, u32 offset,
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index e1aaf1fac8e0..0b2ba67ff13c 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -11,6 +11,8 @@
11#ifndef _LINUX_RTC_H_ 11#ifndef _LINUX_RTC_H_
12#define _LINUX_RTC_H_ 12#define _LINUX_RTC_H_
13 13
14#include <linux/interrupt.h>
15
14/* 16/*
15 * The struct used to pass data via the following ioctl. Similar to the 17 * The struct used to pass data via the following ioctl. Similar to the
16 * struct tm in <time.h>, but it needs to be here so that the kernel 18 * struct tm in <time.h>, but it needs to be here so that the kernel
@@ -102,6 +104,7 @@ int rtc_register(rtc_task_t *task);
102int rtc_unregister(rtc_task_t *task); 104int rtc_unregister(rtc_task_t *task);
103int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg); 105int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg);
104void rtc_get_rtc_time(struct rtc_time *rtc_tm); 106void rtc_get_rtc_time(struct rtc_time *rtc_tm);
107irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
105 108
106#endif /* __KERNEL__ */ 109#endif /* __KERNEL__ */
107 110
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 7da33619d5d0..78eb92ae4d94 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -34,6 +34,7 @@
34#include <linux/percpu.h> 34#include <linux/percpu.h>
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 38
38#include <linux/auxvec.h> /* For AT_VECTOR_SIZE */ 39#include <linux/auxvec.h> /* For AT_VECTOR_SIZE */
39 40
@@ -350,8 +351,16 @@ struct sighand_struct {
350 atomic_t count; 351 atomic_t count;
351 struct k_sigaction action[_NSIG]; 352 struct k_sigaction action[_NSIG];
352 spinlock_t siglock; 353 spinlock_t siglock;
354 struct rcu_head rcu;
353}; 355};
354 356
357extern void sighand_free_cb(struct rcu_head *rhp);
358
359static inline void sighand_free(struct sighand_struct *sp)
360{
361 call_rcu(&sp->rcu, sighand_free_cb);
362}
363
355/* 364/*
356 * NOTE! "signal_struct" does not have it's own 365 * NOTE! "signal_struct" does not have it's own
357 * locking, because a shared signal_struct always 366 * locking, because a shared signal_struct always
@@ -762,6 +771,7 @@ struct task_struct {
762 unsigned keep_capabilities:1; 771 unsigned keep_capabilities:1;
763 struct user_struct *user; 772 struct user_struct *user;
764#ifdef CONFIG_KEYS 773#ifdef CONFIG_KEYS
774 struct key *request_key_auth; /* assumed request_key authority */
765 struct key *thread_keyring; /* keyring private to this thread */ 775 struct key *thread_keyring; /* keyring private to this thread */
766 unsigned char jit_keyring; /* default keyring to attach requested keys to */ 776 unsigned char jit_keyring; /* default keyring to attach requested keys to */
767#endif 777#endif
@@ -844,6 +854,7 @@ struct task_struct {
844 int cpuset_mems_generation; 854 int cpuset_mems_generation;
845#endif 855#endif
846 atomic_t fs_excl; /* holding fs exclusive resources */ 856 atomic_t fs_excl; /* holding fs exclusive resources */
857 struct rcu_head rcu;
847}; 858};
848 859
849static inline pid_t process_group(struct task_struct *tsk) 860static inline pid_t process_group(struct task_struct *tsk)
@@ -867,8 +878,14 @@ static inline int pid_alive(struct task_struct *p)
867extern void free_task(struct task_struct *tsk); 878extern void free_task(struct task_struct *tsk);
868extern void __put_task_struct(struct task_struct *tsk); 879extern void __put_task_struct(struct task_struct *tsk);
869#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) 880#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
870#define put_task_struct(tsk) \ 881
871do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0) 882extern void __put_task_struct_cb(struct rcu_head *rhp);
883
884static inline void put_task_struct(struct task_struct *t)
885{
886 if (atomic_dec_and_test(&t->usage))
887 call_rcu(&t->rcu, __put_task_struct_cb);
888}
872 889
873/* 890/*
874 * Per process flags 891 * Per process flags
@@ -895,6 +912,7 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0)
895#define PF_SYNCWRITE 0x00200000 /* I am doing a sync write */ 912#define PF_SYNCWRITE 0x00200000 /* I am doing a sync write */
896#define PF_BORROWED_MM 0x00400000 /* I am a kthread doing use_mm */ 913#define PF_BORROWED_MM 0x00400000 /* I am a kthread doing use_mm */
897#define PF_RANDOMIZE 0x00800000 /* randomize virtual address space */ 914#define PF_RANDOMIZE 0x00800000 /* randomize virtual address space */
915#define PF_SWAPWRITE 0x01000000 /* Allowed to write to swap */
898 916
899/* 917/*
900 * Only the _current_ task can read/write to tsk->flags, but other 918 * Only the _current_ task can read/write to tsk->flags, but other
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
new file mode 100644
index 000000000000..76850b75b3f6
--- /dev/null
+++ b/include/linux/screen_info.h
@@ -0,0 +1,77 @@
1#ifndef _SCREEN_INFO_H
2#define _SCREEN_INFO_H
3
4#include <linux/types.h>
5
6/*
7 * These are set up by the setup-routine at boot-time:
8 */
9
10struct screen_info {
11 u8 orig_x; /* 0x00 */
12 u8 orig_y; /* 0x01 */
13 u16 dontuse1; /* 0x02 -- EXT_MEM_K sits here */
14 u16 orig_video_page; /* 0x04 */
15 u8 orig_video_mode; /* 0x06 */
16 u8 orig_video_cols; /* 0x07 */
17 u16 unused2; /* 0x08 */
18 u16 orig_video_ega_bx; /* 0x0a */
19 u16 unused3; /* 0x0c */
20 u8 orig_video_lines; /* 0x0e */
21 u8 orig_video_isVGA; /* 0x0f */
22 u16 orig_video_points; /* 0x10 */
23
24 /* VESA graphic mode -- linear frame buffer */
25 u16 lfb_width; /* 0x12 */
26 u16 lfb_height; /* 0x14 */
27 u16 lfb_depth; /* 0x16 */
28 u32 lfb_base; /* 0x18 */
29 u32 lfb_size; /* 0x1c */
30 u16 dontuse2, dontuse3; /* 0x20 -- CL_MAGIC and CL_OFFSET here */
31 u16 lfb_linelength; /* 0x24 */
32 u8 red_size; /* 0x26 */
33 u8 red_pos; /* 0x27 */
34 u8 green_size; /* 0x28 */
35 u8 green_pos; /* 0x29 */
36 u8 blue_size; /* 0x2a */
37 u8 blue_pos; /* 0x2b */
38 u8 rsvd_size; /* 0x2c */
39 u8 rsvd_pos; /* 0x2d */
40 u16 vesapm_seg; /* 0x2e */
41 u16 vesapm_off; /* 0x30 */
42 u16 pages; /* 0x32 */
43 u16 vesa_attributes; /* 0x34 */
44 u32 capabilities; /* 0x36 */
45 /* 0x3a -- 0x3f reserved for future expansion */
46};
47
48extern struct screen_info screen_info;
49
50#define ORIG_X (screen_info.orig_x)
51#define ORIG_Y (screen_info.orig_y)
52#define ORIG_VIDEO_MODE (screen_info.orig_video_mode)
53#define ORIG_VIDEO_COLS (screen_info.orig_video_cols)
54#define ORIG_VIDEO_EGA_BX (screen_info.orig_video_ega_bx)
55#define ORIG_VIDEO_LINES (screen_info.orig_video_lines)
56#define ORIG_VIDEO_ISVGA (screen_info.orig_video_isVGA)
57#define ORIG_VIDEO_POINTS (screen_info.orig_video_points)
58
59#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
60#define VIDEO_TYPE_CGA 0x11 /* CGA Display */
61#define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */
62#define VIDEO_TYPE_EGAC 0x21 /* EGA in Color Mode */
63#define VIDEO_TYPE_VGAC 0x22 /* VGA+ in Color Mode */
64#define VIDEO_TYPE_VLFB 0x23 /* VESA VGA in graphic mode */
65
66#define VIDEO_TYPE_PICA_S3 0x30 /* ACER PICA-61 local S3 video */
67#define VIDEO_TYPE_MIPS_G364 0x31 /* MIPS Magnum 4000 G364 video */
68#define VIDEO_TYPE_SGI 0x33 /* Various SGI graphics hardware */
69
70#define VIDEO_TYPE_TGAC 0x40 /* DEC TGA */
71
72#define VIDEO_TYPE_SUN 0x50 /* Sun frame buffer. */
73#define VIDEO_TYPE_SUNPCI 0x51 /* Sun PCI based frame buffer. */
74
75#define VIDEO_TYPE_PMAC 0x60 /* PowerMacintosh frame buffer. */
76
77#endif /* _SCREEN_INFO_H */
diff --git a/include/linux/sdla.h b/include/linux/sdla.h
index 3b6afb8caa42..564acd3a71c1 100644
--- a/include/linux/sdla.h
+++ b/include/linux/sdla.h
@@ -293,46 +293,46 @@ void sdla(void *cfg_info, char *dev, struct frad_conf *conf, int quiet);
293#define SDLA_S508_INTEN 0x10 293#define SDLA_S508_INTEN 0x10
294 294
295struct sdla_cmd { 295struct sdla_cmd {
296 char opp_flag __attribute__((packed)); 296 char opp_flag;
297 char cmd __attribute__((packed)); 297 char cmd;
298 short length __attribute__((packed)); 298 short length;
299 char retval __attribute__((packed)); 299 char retval;
300 short dlci __attribute__((packed)); 300 short dlci;
301 char flags __attribute__((packed)); 301 char flags;
302 short rxlost_int __attribute__((packed)); 302 short rxlost_int;
303 long rxlost_app __attribute__((packed)); 303 long rxlost_app;
304 char reserve[2] __attribute__((packed)); 304 char reserve[2];
305 char data[SDLA_MAX_DATA] __attribute__((packed)); /* transfer data buffer */ 305 char data[SDLA_MAX_DATA]; /* transfer data buffer */
306}; 306} __attribute__((packed));
307 307
308struct intr_info { 308struct intr_info {
309 char flags __attribute__((packed)); 309 char flags;
310 short txlen __attribute__((packed)); 310 short txlen;
311 char irq __attribute__((packed)); 311 char irq;
312 char flags2 __attribute__((packed)); 312 char flags2;
313 short timeout __attribute__((packed)); 313 short timeout;
314}; 314} __attribute__((packed));
315 315
316/* found in the 508's control window at RXBUF_INFO */ 316/* found in the 508's control window at RXBUF_INFO */
317struct buf_info { 317struct buf_info {
318 unsigned short rse_num __attribute__((packed)); 318 unsigned short rse_num;
319 unsigned long rse_base __attribute__((packed)); 319 unsigned long rse_base;
320 unsigned long rse_next __attribute__((packed)); 320 unsigned long rse_next;
321 unsigned long buf_base __attribute__((packed)); 321 unsigned long buf_base;
322 unsigned short reserved __attribute__((packed)); 322 unsigned short reserved;
323 unsigned long buf_top __attribute__((packed)); 323 unsigned long buf_top;
324}; 324} __attribute__((packed));
325 325
326/* structure pointed to by rse_base in RXBUF_INFO struct */ 326/* structure pointed to by rse_base in RXBUF_INFO struct */
327struct buf_entry { 327struct buf_entry {
328 char opp_flag __attribute__((packed)); 328 char opp_flag;
329 short length __attribute__((packed)); 329 short length;
330 short dlci __attribute__((packed)); 330 short dlci;
331 char flags __attribute__((packed)); 331 char flags;
332 short timestamp __attribute__((packed)); 332 short timestamp;
333 short reserved[2] __attribute__((packed)); 333 short reserved[2];
334 long buf_addr __attribute__((packed)); 334 long buf_addr;
335}; 335} __attribute__((packed));
336 336
337#endif 337#endif
338 338
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index dc89116bb1ca..cd2773b29a64 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -26,11 +26,7 @@ static inline int has_secure_computing(struct thread_info *ti)
26 26
27#else /* CONFIG_SECCOMP */ 27#else /* CONFIG_SECCOMP */
28 28
29#if (__GNUC__ > 2) 29typedef struct { } seccomp_t;
30 typedef struct { } seccomp_t;
31#else
32 typedef struct { int gcc_is_buggy; } seccomp_t;
33#endif
34 30
35#define secure_computing(x) do { } while (0) 31#define secure_computing(x) do { } while (0)
36/* static inline to preserve typechecking */ 32/* static inline to preserve typechecking */
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 5dd5f02c5c5f..b7d093520bb6 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -18,6 +18,19 @@
18#define SA_PROBE SA_ONESHOT 18#define SA_PROBE SA_ONESHOT
19#define SA_SAMPLE_RANDOM SA_RESTART 19#define SA_SAMPLE_RANDOM SA_RESTART
20#define SA_SHIRQ 0x04000000 20#define SA_SHIRQ 0x04000000
21/*
22 * As above, these correspond to the IORESOURCE_IRQ_* defines in
23 * linux/ioport.h to select the interrupt line behaviour. When
24 * requesting an interrupt without specifying a SA_TRIGGER, the
25 * setting should be assumed to be "as already configured", which
26 * may be as per machine or firmware initialisation.
27 */
28#define SA_TRIGGER_LOW 0x00000008
29#define SA_TRIGGER_HIGH 0x00000004
30#define SA_TRIGGER_FALLING 0x00000002
31#define SA_TRIGGER_RISING 0x00000001
32#define SA_TRIGGER_MASK (SA_TRIGGER_HIGH|SA_TRIGGER_LOW|\
33 SA_TRIGGER_RISING|SA_TRIGGER_FALLING)
21 34
22/* 35/*
23 * Real Time signals may be queued. 36 * Real Time signals may be queued.
@@ -81,6 +94,23 @@ static inline int sigfindinword(unsigned long word)
81 94
82#endif /* __HAVE_ARCH_SIG_BITOPS */ 95#endif /* __HAVE_ARCH_SIG_BITOPS */
83 96
97static inline int sigisemptyset(sigset_t *set)
98{
99 extern void _NSIG_WORDS_is_unsupported_size(void);
100 switch (_NSIG_WORDS) {
101 case 4:
102 return (set->sig[3] | set->sig[2] |
103 set->sig[1] | set->sig[0]) == 0;
104 case 2:
105 return (set->sig[1] | set->sig[0]) == 0;
106 case 1:
107 return set->sig[0] == 0;
108 default:
109 _NSIG_WORDS_is_unsupported_size();
110 return 0;
111 }
112}
113
84#define sigmask(sig) (1UL << ((sig) - 1)) 114#define sigmask(sig) (1UL << ((sig) - 1))
85 115
86#ifndef __HAVE_ARCH_SIG_SETOPS 116#ifndef __HAVE_ARCH_SIG_SETOPS
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 483cfc47ec34..e5fd66c5650b 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -251,7 +251,7 @@ struct sk_buff {
251 * want to keep them across layers you have to do a skb_clone() 251 * want to keep them across layers you have to do a skb_clone()
252 * first. This is owned by whoever has the skb queued ATM. 252 * first. This is owned by whoever has the skb queued ATM.
253 */ 253 */
254 char cb[40]; 254 char cb[48];
255 255
256 unsigned int len, 256 unsigned int len,
257 data_len, 257 data_len,
diff --git a/include/linux/slab.h b/include/linux/slab.h
index d1ea4051b996..1fb77a9cc148 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -53,6 +53,8 @@ typedef struct kmem_cache kmem_cache_t;
53#define SLAB_CTOR_ATOMIC 0x002UL /* tell constructor it can't sleep */ 53#define SLAB_CTOR_ATOMIC 0x002UL /* tell constructor it can't sleep */
54#define SLAB_CTOR_VERIFY 0x004UL /* tell constructor it's a verify call */ 54#define SLAB_CTOR_VERIFY 0x004UL /* tell constructor it's a verify call */
55 55
56#ifndef CONFIG_SLOB
57
56/* prototypes */ 58/* prototypes */
57extern void __init kmem_cache_init(void); 59extern void __init kmem_cache_init(void);
58 60
@@ -134,6 +136,39 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
134extern int FASTCALL(kmem_cache_reap(int)); 136extern int FASTCALL(kmem_cache_reap(int));
135extern int FASTCALL(kmem_ptr_validate(kmem_cache_t *cachep, void *ptr)); 137extern int FASTCALL(kmem_ptr_validate(kmem_cache_t *cachep, void *ptr));
136 138
139#else /* CONFIG_SLOB */
140
141/* SLOB allocator routines */
142
143void kmem_cache_init(void);
144struct kmem_cache *kmem_find_general_cachep(size_t, gfp_t gfpflags);
145struct kmem_cache *kmem_cache_create(const char *c, size_t, size_t,
146 unsigned long,
147 void (*)(void *, struct kmem_cache *, unsigned long),
148 void (*)(void *, struct kmem_cache *, unsigned long));
149int kmem_cache_destroy(struct kmem_cache *c);
150void *kmem_cache_alloc(struct kmem_cache *c, gfp_t flags);
151void kmem_cache_free(struct kmem_cache *c, void *b);
152const char *kmem_cache_name(struct kmem_cache *);
153void *kmalloc(size_t size, gfp_t flags);
154void *kzalloc(size_t size, gfp_t flags);
155void kfree(const void *m);
156unsigned int ksize(const void *m);
157unsigned int kmem_cache_size(struct kmem_cache *c);
158
159static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
160{
161 return kzalloc(n * size, flags);
162}
163
164#define kmem_cache_shrink(d) (0)
165#define kmem_cache_reap(a)
166#define kmem_ptr_validate(a, b) (0)
167#define kmem_cache_alloc_node(c, f, n) kmem_cache_alloc(c, f)
168#define kmalloc_node(s, f, n) kmalloc(s, f)
169
170#endif /* CONFIG_SLOB */
171
137/* System wide caches */ 172/* System wide caches */
138extern kmem_cache_t *vm_area_cachep; 173extern kmem_cache_t *vm_area_cachep;
139extern kmem_cache_t *names_cachep; 174extern kmem_cache_t *names_cachep;
diff --git a/include/linux/spinlock_types_up.h b/include/linux/spinlock_types_up.h
index def2d173a8db..04135b0e198e 100644
--- a/include/linux/spinlock_types_up.h
+++ b/include/linux/spinlock_types_up.h
@@ -22,30 +22,16 @@ typedef struct {
22 22
23#else 23#else
24 24
25/*
26 * All gcc 2.95 versions and early versions of 2.96 have a nasty bug
27 * with empty initializers.
28 */
29#if (__GNUC__ > 2)
30typedef struct { } raw_spinlock_t; 25typedef struct { } raw_spinlock_t;
31 26
32#define __RAW_SPIN_LOCK_UNLOCKED { } 27#define __RAW_SPIN_LOCK_UNLOCKED { }
33#else
34typedef struct { int gcc_is_buggy; } raw_spinlock_t;
35#define __RAW_SPIN_LOCK_UNLOCKED (raw_spinlock_t) { 0 }
36#endif
37 28
38#endif 29#endif
39 30
40#if (__GNUC__ > 2)
41typedef struct { 31typedef struct {
42 /* no debug version on UP */ 32 /* no debug version on UP */
43} raw_rwlock_t; 33} raw_rwlock_t;
44 34
45#define __RAW_RW_LOCK_UNLOCKED { } 35#define __RAW_RW_LOCK_UNLOCKED { }
46#else
47typedef struct { int gcc_is_buggy; } raw_rwlock_t;
48#define __RAW_RW_LOCK_UNLOCKED (raw_rwlock_t) { 0 }
49#endif
50 36
51#endif /* __LINUX_SPINLOCK_TYPES_UP_H */ 37#endif /* __LINUX_SPINLOCK_TYPES_UP_H */
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 556617bcf7ac..389d1c382e20 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -175,6 +175,13 @@ extern int try_to_free_pages(struct zone **, gfp_t);
175extern int shrink_all_memory(int); 175extern int shrink_all_memory(int);
176extern int vm_swappiness; 176extern int vm_swappiness;
177 177
178#ifdef CONFIG_MIGRATION
179extern int isolate_lru_page(struct page *p);
180extern int putback_lru_pages(struct list_head *l);
181extern int migrate_pages(struct list_head *l, struct list_head *t,
182 struct list_head *moved, struct list_head *failed);
183#endif
184
178#ifdef CONFIG_MMU 185#ifdef CONFIG_MMU
179/* linux/mm/shmem.c */ 186/* linux/mm/shmem.c */
180extern int shmem_unuse(swp_entry_t entry, struct page *page); 187extern int shmem_unuse(swp_entry_t entry, struct page *page);
@@ -192,7 +199,7 @@ extern int rw_swap_page_sync(int, swp_entry_t, struct page *);
192extern struct address_space swapper_space; 199extern struct address_space swapper_space;
193#define total_swapcache_pages swapper_space.nrpages 200#define total_swapcache_pages swapper_space.nrpages
194extern void show_swap_cache_info(void); 201extern void show_swap_cache_info(void);
195extern int add_to_swap(struct page *); 202extern int add_to_swap(struct page *, gfp_t);
196extern void __delete_from_swap_cache(struct page *); 203extern void __delete_from_swap_cache(struct page *);
197extern void delete_from_swap_cache(struct page *); 204extern void delete_from_swap_cache(struct page *);
198extern int move_to_swap_cache(struct page *, swp_entry_t); 205extern int move_to_swap_cache(struct page *, swp_entry_t);
diff --git a/include/linux/synclink.h b/include/linux/synclink.h
index 763bd290f28d..1b7cd8d1a71b 100644
--- a/include/linux/synclink.h
+++ b/include/linux/synclink.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * SyncLink Multiprotocol Serial Adapter Driver 2 * SyncLink Multiprotocol Serial Adapter Driver
3 * 3 *
4 * $Id: synclink.h,v 3.6 2002/02/20 21:58:20 paulkf Exp $ 4 * $Id: synclink.h,v 3.10 2005/11/08 19:50:54 paulkf Exp $
5 * 5 *
6 * Copyright (C) 1998-2000 by Microgate Corporation 6 * Copyright (C) 1998-2000 by Microgate Corporation
7 * 7 *
@@ -128,10 +128,14 @@
128#define MGSL_BUS_TYPE_EISA 2 128#define MGSL_BUS_TYPE_EISA 2
129#define MGSL_BUS_TYPE_PCI 5 129#define MGSL_BUS_TYPE_PCI 5
130 130
131#define MGSL_INTERFACE_MASK 0xf
131#define MGSL_INTERFACE_DISABLE 0 132#define MGSL_INTERFACE_DISABLE 0
132#define MGSL_INTERFACE_RS232 1 133#define MGSL_INTERFACE_RS232 1
133#define MGSL_INTERFACE_V35 2 134#define MGSL_INTERFACE_V35 2
134#define MGSL_INTERFACE_RS422 3 135#define MGSL_INTERFACE_RS422 3
136#define MGSL_INTERFACE_RTS_EN 0x10
137#define MGSL_INTERFACE_LL 0x20
138#define MGSL_INTERFACE_RL 0x40
135 139
136typedef struct _MGSL_PARAMS 140typedef struct _MGSL_PARAMS
137{ 141{
@@ -163,6 +167,9 @@ typedef struct _MGSL_PARAMS
163#define SYNCLINK_DEVICE_ID 0x0010 167#define SYNCLINK_DEVICE_ID 0x0010
164#define MGSCC_DEVICE_ID 0x0020 168#define MGSCC_DEVICE_ID 0x0020
165#define SYNCLINK_SCA_DEVICE_ID 0x0030 169#define SYNCLINK_SCA_DEVICE_ID 0x0030
170#define SYNCLINK_GT_DEVICE_ID 0x0070
171#define SYNCLINK_GT4_DEVICE_ID 0x0080
172#define SYNCLINK_AC_DEVICE_ID 0x0090
166#define MGSL_MAX_SERIAL_NUMBER 30 173#define MGSL_MAX_SERIAL_NUMBER 30
167 174
168/* 175/*
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index c7007b1db91d..3eed47347013 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -511,5 +511,12 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio);
511asmlinkage long sys_ioprio_get(int which, int who); 511asmlinkage long sys_ioprio_get(int which, int who);
512asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask, 512asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
513 unsigned long maxnode); 513 unsigned long maxnode);
514asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
515 const unsigned long __user *from, const unsigned long __user *to);
516
517asmlinkage long sys_spu_run(int fd, __u32 __user *unpc,
518 __u32 __user *ustatus);
519asmlinkage long sys_spu_create(const char __user *name,
520 unsigned int flags, mode_t mode);
514 521
515#endif 522#endif
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index a9b80fc7f0f3..7f472127b7b5 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -180,6 +180,8 @@ enum
180 VM_VFS_CACHE_PRESSURE=26, /* dcache/icache reclaim pressure */ 180 VM_VFS_CACHE_PRESSURE=26, /* dcache/icache reclaim pressure */
181 VM_LEGACY_VA_LAYOUT=27, /* legacy/compatibility virtual address space layout */ 181 VM_LEGACY_VA_LAYOUT=27, /* legacy/compatibility virtual address space layout */
182 VM_SWAP_TOKEN_TIMEOUT=28, /* default time for token time out */ 182 VM_SWAP_TOKEN_TIMEOUT=28, /* default time for token time out */
183 VM_DROP_PAGECACHE=29, /* int: nuke lots of pagecache */
184 VM_PERCPU_PAGELIST_FRACTION=30,/* int: fraction of pages in each percpu_pagelist */
183}; 185};
184 186
185 187
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 1267f88ece6e..57449704a47b 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -23,6 +23,7 @@
23#include <linux/workqueue.h> 23#include <linux/workqueue.h>
24#include <linux/tty_driver.h> 24#include <linux/tty_driver.h>
25#include <linux/tty_ldisc.h> 25#include <linux/tty_ldisc.h>
26#include <linux/screen_info.h>
26 27
27#include <asm/system.h> 28#include <asm/system.h>
28 29
@@ -37,77 +38,6 @@
37#define NR_LDISCS 16 38#define NR_LDISCS 16
38 39
39/* 40/*
40 * These are set up by the setup-routine at boot-time:
41 */
42
43struct screen_info {
44 u8 orig_x; /* 0x00 */
45 u8 orig_y; /* 0x01 */
46 u16 dontuse1; /* 0x02 -- EXT_MEM_K sits here */
47 u16 orig_video_page; /* 0x04 */
48 u8 orig_video_mode; /* 0x06 */
49 u8 orig_video_cols; /* 0x07 */
50 u16 unused2; /* 0x08 */
51 u16 orig_video_ega_bx; /* 0x0a */
52 u16 unused3; /* 0x0c */
53 u8 orig_video_lines; /* 0x0e */
54 u8 orig_video_isVGA; /* 0x0f */
55 u16 orig_video_points; /* 0x10 */
56
57 /* VESA graphic mode -- linear frame buffer */
58 u16 lfb_width; /* 0x12 */
59 u16 lfb_height; /* 0x14 */
60 u16 lfb_depth; /* 0x16 */
61 u32 lfb_base; /* 0x18 */
62 u32 lfb_size; /* 0x1c */
63 u16 dontuse2, dontuse3; /* 0x20 -- CL_MAGIC and CL_OFFSET here */
64 u16 lfb_linelength; /* 0x24 */
65 u8 red_size; /* 0x26 */
66 u8 red_pos; /* 0x27 */
67 u8 green_size; /* 0x28 */
68 u8 green_pos; /* 0x29 */
69 u8 blue_size; /* 0x2a */
70 u8 blue_pos; /* 0x2b */
71 u8 rsvd_size; /* 0x2c */
72 u8 rsvd_pos; /* 0x2d */
73 u16 vesapm_seg; /* 0x2e */
74 u16 vesapm_off; /* 0x30 */
75 u16 pages; /* 0x32 */
76 u16 vesa_attributes; /* 0x34 */
77 u32 capabilities; /* 0x36 */
78 /* 0x3a -- 0x3f reserved for future expansion */
79};
80
81extern struct screen_info screen_info;
82
83#define ORIG_X (screen_info.orig_x)
84#define ORIG_Y (screen_info.orig_y)
85#define ORIG_VIDEO_MODE (screen_info.orig_video_mode)
86#define ORIG_VIDEO_COLS (screen_info.orig_video_cols)
87#define ORIG_VIDEO_EGA_BX (screen_info.orig_video_ega_bx)
88#define ORIG_VIDEO_LINES (screen_info.orig_video_lines)
89#define ORIG_VIDEO_ISVGA (screen_info.orig_video_isVGA)
90#define ORIG_VIDEO_POINTS (screen_info.orig_video_points)
91
92#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
93#define VIDEO_TYPE_CGA 0x11 /* CGA Display */
94#define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */
95#define VIDEO_TYPE_EGAC 0x21 /* EGA in Color Mode */
96#define VIDEO_TYPE_VGAC 0x22 /* VGA+ in Color Mode */
97#define VIDEO_TYPE_VLFB 0x23 /* VESA VGA in graphic mode */
98
99#define VIDEO_TYPE_PICA_S3 0x30 /* ACER PICA-61 local S3 video */
100#define VIDEO_TYPE_MIPS_G364 0x31 /* MIPS Magnum 4000 G364 video */
101#define VIDEO_TYPE_SGI 0x33 /* Various SGI graphics hardware */
102
103#define VIDEO_TYPE_TGAC 0x40 /* DEC TGA */
104
105#define VIDEO_TYPE_SUN 0x50 /* Sun frame buffer. */
106#define VIDEO_TYPE_SUNPCI 0x51 /* Sun PCI based frame buffer. */
107
108#define VIDEO_TYPE_PMAC 0x60 /* PowerMacintosh frame buffer. */
109
110/*
111 * This character is the same as _POSIX_VDISABLE: it cannot be used as 41 * This character is the same as _POSIX_VDISABLE: it cannot be used as
112 * a c_cc[] character, but indicates that a particular special character 42 * a c_cc[] character, but indicates that a particular special character
113 * isn't in use (eg VINTR has no character etc) 43 * isn't in use (eg VINTR has no character etc)
diff --git a/include/linux/video_decoder.h b/include/linux/video_decoder.h
index 0e9e48b83e3b..121e26da2c18 100644
--- a/include/linux/video_decoder.h
+++ b/include/linux/video_decoder.h
@@ -1,6 +1,8 @@
1#ifndef _LINUX_VIDEO_DECODER_H 1#ifndef _LINUX_VIDEO_DECODER_H
2#define _LINUX_VIDEO_DECODER_H 2#define _LINUX_VIDEO_DECODER_H
3 3
4#define HAVE_VIDEO_DECODER 1
5
4struct video_decoder_capability { /* this name is too long */ 6struct video_decoder_capability { /* this name is too long */
5 __u32 flags; 7 __u32 flags;
6#define VIDEO_DECODER_PAL 1 /* can decode PAL signal */ 8#define VIDEO_DECODER_PAL 1 /* can decode PAL signal */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 1cded681eb6d..ce40675324bd 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -642,6 +642,12 @@ typedef __u64 v4l2_std_id;
642#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) 642#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000)
643#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) 643#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000)
644 644
645/* some merged standards */
646#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
647#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
648#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
649#define V4L2_STD_DK (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK)
650
645/* some common needed stuff */ 651/* some common needed stuff */
646#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\ 652#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\
647 V4L2_STD_PAL_B1 |\ 653 V4L2_STD_PAL_B1 |\
@@ -662,7 +668,8 @@ typedef __u64 v4l2_std_id;
662 V4L2_STD_SECAM_G |\ 668 V4L2_STD_SECAM_G |\
663 V4L2_STD_SECAM_H |\ 669 V4L2_STD_SECAM_H |\
664 V4L2_STD_SECAM_DK |\ 670 V4L2_STD_SECAM_DK |\
665 V4L2_STD_SECAM_L) 671 V4L2_STD_SECAM_L |\
672 V4L2_STD_SECAM_LC)
666 673
667#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ 674#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\
668 V4L2_STD_PAL_60 |\ 675 V4L2_STD_PAL_60 |\
@@ -888,7 +895,6 @@ struct v4l2_audio
888 895
889/* Flags for the 'mode' field */ 896/* Flags for the 'mode' field */
890#define V4L2_AUDMODE_AVL 0x00001 897#define V4L2_AUDMODE_AVL 0x00001
891#define V4L2_AUDMODE_32BITS 0x00002
892 898
893struct v4l2_audioout 899struct v4l2_audioout
894{ 900{
@@ -1110,7 +1116,6 @@ int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local);
1110/* names for fancy debug output */ 1116/* names for fancy debug output */
1111extern char *v4l2_field_names[]; 1117extern char *v4l2_field_names[];
1112extern char *v4l2_type_names[]; 1118extern char *v4l2_type_names[];
1113extern char *v4l2_ioctl_names[];
1114 1119
1115/* Compatibility layer interface -- v4l1-compat module */ 1120/* Compatibility layer interface -- v4l1-compat module */
1116typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file, 1121typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
@@ -1118,6 +1123,11 @@ typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
1118int v4l_compat_translate_ioctl(struct inode *inode, struct file *file, 1123int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
1119 int cmd, void *arg, v4l2_kioctl driver_ioctl); 1124 int cmd, void *arg, v4l2_kioctl driver_ioctl);
1120 1125
1126/* 32 Bits compatibility layer for 64 bits processors */
1127extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd,
1128 unsigned long arg);
1129
1130
1121#endif /* __KERNEL__ */ 1131#endif /* __KERNEL__ */
1122#endif /* __LINUX_VIDEODEV2_H */ 1132#endif /* __LINUX_VIDEODEV2_H */
1123 1133
diff --git a/include/linux/wavefront.h b/include/linux/wavefront.h
index 61bd0fd35240..51ab3c933acd 100644
--- a/include/linux/wavefront.h
+++ b/include/linux/wavefront.h
@@ -434,22 +434,22 @@ typedef struct wf_multisample {
434} wavefront_multisample; 434} wavefront_multisample;
435 435
436typedef struct wf_alias { 436typedef struct wf_alias {
437 INT16 OriginalSample __attribute__ ((packed)); 437 INT16 OriginalSample;
438 438
439 struct wf_sample_offset sampleStartOffset __attribute__ ((packed)); 439 struct wf_sample_offset sampleStartOffset;
440 struct wf_sample_offset loopStartOffset __attribute__ ((packed)); 440 struct wf_sample_offset loopStartOffset;
441 struct wf_sample_offset sampleEndOffset __attribute__ ((packed)); 441 struct wf_sample_offset sampleEndOffset;
442 struct wf_sample_offset loopEndOffset __attribute__ ((packed)); 442 struct wf_sample_offset loopEndOffset;
443 443
444 INT16 FrequencyBias __attribute__ ((packed)); 444 INT16 FrequencyBias;
445 445
446 UCHAR8 SampleResolution:2 __attribute__ ((packed)); 446 UCHAR8 SampleResolution:2;
447 UCHAR8 Unused1:1 __attribute__ ((packed)); 447 UCHAR8 Unused1:1;
448 UCHAR8 Loop:1 __attribute__ ((packed)); 448 UCHAR8 Loop:1;
449 UCHAR8 Bidirectional:1 __attribute__ ((packed)); 449 UCHAR8 Bidirectional:1;
450 UCHAR8 Unused2:1 __attribute__ ((packed)); 450 UCHAR8 Unused2:1;
451 UCHAR8 Reverse:1 __attribute__ ((packed)); 451 UCHAR8 Reverse:1;
452 UCHAR8 Unused3:1 __attribute__ ((packed)); 452 UCHAR8 Unused3:1;
453 453
454 /* This structure is meant to be padded only to 16 bits on their 454 /* This structure is meant to be padded only to 16 bits on their
455 original. Of course, whoever wrote their documentation didn't 455 original. Of course, whoever wrote their documentation didn't
@@ -460,8 +460,8 @@ typedef struct wf_alias {
460 standard 16->32 bit issues. 460 standard 16->32 bit issues.
461 */ 461 */
462 462
463 UCHAR8 sixteen_bit_padding __attribute__ ((packed)); 463 UCHAR8 sixteen_bit_padding;
464} wavefront_alias; 464} __attribute__((packed)) wavefront_alias;
465 465
466typedef struct wf_drum { 466typedef struct wf_drum {
467 UCHAR8 PatchNumber; 467 UCHAR8 PatchNumber;
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index ac39d04d027c..86b111300231 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -65,6 +65,7 @@ extern int FASTCALL(schedule_work(struct work_struct *work));
65extern int FASTCALL(schedule_delayed_work(struct work_struct *work, unsigned long delay)); 65extern int FASTCALL(schedule_delayed_work(struct work_struct *work, unsigned long delay));
66 66
67extern int schedule_delayed_work_on(int cpu, struct work_struct *work, unsigned long delay); 67extern int schedule_delayed_work_on(int cpu, struct work_struct *work, unsigned long delay);
68extern int schedule_on_each_cpu(void (*func)(void *info), void *info);
68extern void flush_scheduled_work(void); 69extern void flush_scheduled_work(void);
69extern int current_is_keventd(void); 70extern int current_is_keventd(void);
70extern int keventd_up(void); 71extern int keventd_up(void);
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index b096159086e8..beaef5c7a0ea 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -103,7 +103,9 @@ void balance_dirty_pages_ratelimited(struct address_space *mapping);
103int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0); 103int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0);
104int do_writepages(struct address_space *mapping, struct writeback_control *wbc); 104int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
105int sync_page_range(struct inode *inode, struct address_space *mapping, 105int sync_page_range(struct inode *inode, struct address_space *mapping,
106 loff_t pos, size_t count); 106 loff_t pos, loff_t count);
107int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
108 loff_t pos, loff_t count);
107 109
108/* pdflush.c */ 110/* pdflush.c */
109extern int nr_pdflush_threads; /* Global so it can be exported to sysctl 111extern int nr_pdflush_threads; /* Global so it can be exported to sysctl
diff --git a/include/media/audiochip.h b/include/media/audiochip.h
index b7d4b0930408..295d256ee811 100644
--- a/include/media/audiochip.h
+++ b/include/media/audiochip.h
@@ -23,11 +23,6 @@ enum audiochip {
23 23
24/* ---------------------------------------------------------------------- */ 24/* ---------------------------------------------------------------------- */
25 25
26/* v4l device was opened in Radio mode */
27#define AUDC_SET_RADIO _IO('m',2)
28/* select from TV,radio,extern,MUTE */
29#define AUDC_SET_INPUT _IOW('m',17,int)
30
31/* audio inputs */ 26/* audio inputs */
32#define AUDIO_TUNER 0x00 27#define AUDIO_TUNER 0x00
33#define AUDIO_RADIO 0x01 28#define AUDIO_RADIO 0x01
@@ -40,15 +35,4 @@ enum audiochip {
40#define AUDIO_MUTE 0x80 35#define AUDIO_MUTE 0x80
41#define AUDIO_UNMUTE 0x81 36#define AUDIO_UNMUTE 0x81
42 37
43/* all the stuff below is obsolete and just here for reference. I'll
44 * remove it once the driver is tested and works fine.
45 *
46 * Instead creating alot of tiny API's for all kinds of different
47 * chips, we'll just pass throuth the v4l ioctl structs (v4l2 not
48 * yet...). It is a bit less flexible, but most/all used i2c chips
49 * make sense in v4l context only. So I think that's acceptable...
50 */
51
52/* misc stuff to pass around config info to i2c chips */
53#define AUDC_CONFIG_PINNACLE _IOW('m',32,int)
54#endif /* AUDIOCHIP_H */ 38#endif /* AUDIOCHIP_H */
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h
index 16af9299315f..e5e749e984ee 100644
--- a/include/media/saa7146_vv.h
+++ b/include/media/saa7146_vv.h
@@ -178,6 +178,8 @@ struct saa7146_ext_vv
178 178
179 struct saa7146_extension_ioctls *ioctls; 179 struct saa7146_extension_ioctls *ioctls;
180 int (*ioctl)(struct saa7146_fh*, unsigned int cmd, void *arg); 180 int (*ioctl)(struct saa7146_fh*, unsigned int cmd, void *arg);
181
182 struct file_operations vbi_fops;
181}; 183};
182 184
183struct saa7146_use_ops { 185struct saa7146_use_ops {
diff --git a/include/media/tuner.h b/include/media/tuner.h
index b37cde606692..7674b121ce8b 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -82,9 +82,9 @@
82#define TUNER_PHILIPS_FM1236_MK3 43 82#define TUNER_PHILIPS_FM1236_MK3 43
83 83
84#define TUNER_PHILIPS_4IN1 44 /* ATI TV Wonder Pro - Conexant */ 84#define TUNER_PHILIPS_4IN1 44 /* ATI TV Wonder Pro - Conexant */
85/* Microtune mergeged with Temic 12/31/1999 partially financed by Alps - these may be similar to Temic */ 85/* Microtune merged with Temic 12/31/1999 partially financed by Alps - these may be similar to Temic */
86#define TUNER_MICROTUNE_4049FM5 45 86#define TUNER_MICROTUNE_4049FM5 45
87#define TUNER_MICROTUNE_4042_FI5 46 87#define TUNER_PANASONIC_VP27 46
88#define TUNER_LG_NTSC_TAPE 47 88#define TUNER_LG_NTSC_TAPE 47
89 89
90#define TUNER_TNF_8831BGFF 48 90#define TUNER_TNF_8831BGFF 48
@@ -102,7 +102,7 @@
102#define TUNER_YMEC_TVF_8531MF 58 102#define TUNER_YMEC_TVF_8531MF 58
103#define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */ 103#define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */
104 104
105#define TUNER_THOMSON_DTT7611 60 /* DViCO FusionHDTV 3 Gold-T */ 105#define TUNER_THOMSON_DTT761X 60 /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
106#define TUNER_TENA_9533_DI 61 106#define TUNER_TENA_9533_DI 61
107#define TUNER_TEA5767 62 /* Only FM Radio Tuner */ 107#define TUNER_TEA5767 62 /* Only FM Radio Tuner */
108#define TUNER_PHILIPS_FMD1216ME_MK3 63 108#define TUNER_PHILIPS_FMD1216ME_MK3 63
@@ -115,47 +115,26 @@
115#define TUNER_PHILIPS_TUV1236D 68 /* ATI HDTV Wonder */ 115#define TUNER_PHILIPS_TUV1236D 68 /* ATI HDTV Wonder */
116#define TUNER_TNF_5335MF 69 /* Sabrent Bt848 */ 116#define TUNER_TNF_5335MF 69 /* Sabrent Bt848 */
117 117
118#define NOTUNER 0
119#define PAL 1 /* PAL_BG */
120#define PAL_I 2
121#define NTSC 3
122#define SECAM 4
123#define ATSC 5
124#define RADIO 6
125
126#define NoTuner 0
127#define Philips 1
128#define TEMIC 2
129#define Sony 3
130#define Alps 4
131#define LGINNOTEK 5
132#define SHARP 6
133#define Samsung 7
134#define Microtune 8
135#define HITACHI 9
136#define Panasonic 10
137#define TCL 11
138#define THOMSON 12
139
140#define TUNER_SET_TYPE_ADDR _IOW('T',3,int)
141#define TUNER_SET_STANDBY _IOW('T',4,int)
142#define TDA9887_SET_CONFIG _IOW('t',5,int)
143
144/* tv card specific */ 118/* tv card specific */
145# define TDA9887_PRESENT (1<<0) 119#define TDA9887_PRESENT (1<<0)
146# define TDA9887_PORT1_INACTIVE (1<<1) 120#define TDA9887_PORT1_INACTIVE (1<<1)
147# define TDA9887_PORT2_INACTIVE (1<<2) 121#define TDA9887_PORT2_INACTIVE (1<<2)
148# define TDA9887_QSS (1<<3) 122#define TDA9887_QSS (1<<3)
149# define TDA9887_INTERCARRIER (1<<4) 123#define TDA9887_INTERCARRIER (1<<4)
150# define TDA9887_PORT1_ACTIVE (1<<5) 124#define TDA9887_PORT1_ACTIVE (1<<5)
151# define TDA9887_PORT2_ACTIVE (1<<6) 125#define TDA9887_PORT2_ACTIVE (1<<6)
152# define TDA9887_INTERCARRIER_NTSC (1<<7) 126#define TDA9887_INTERCARRIER_NTSC (1<<7)
127/* Tuner takeover point adjustment, in dB, -16 <= top <= 15 */
128#define TDA9887_TOP_MASK (0x3f << 8)
129#define TDA9887_TOP_SET (1 << 13)
130#define TDA9887_TOP(top) (TDA9887_TOP_SET | (((16 + (top)) & 0x1f) << 8))
131
153/* config options */ 132/* config options */
154# define TDA9887_DEEMPHASIS_MASK (3<<16) 133#define TDA9887_DEEMPHASIS_MASK (3<<16)
155# define TDA9887_DEEMPHASIS_NONE (1<<16) 134#define TDA9887_DEEMPHASIS_NONE (1<<16)
156# define TDA9887_DEEMPHASIS_50 (2<<16) 135#define TDA9887_DEEMPHASIS_50 (2<<16)
157# define TDA9887_DEEMPHASIS_75 (3<<16) 136#define TDA9887_DEEMPHASIS_75 (3<<16)
158# define TDA9887_AUTOMUTE (1<<18) 137#define TDA9887_AUTOMUTE (1<<18)
159 138
160#ifdef __KERNEL__ 139#ifdef __KERNEL__
161 140
@@ -167,10 +146,26 @@ enum tuner_mode {
167 T_STANDBY = 1 << 31 146 T_STANDBY = 1 << 31
168}; 147};
169 148
149/* Older boards only had a single tuner device. Nowadays multiple tuner
150 devices may be present on a single board. Using TUNER_SET_TYPE_ADDR
151 to pass the tuner_setup structure it is possible to setup each tuner
152 device in turn.
153
154 Since multiple devices may be present it is no longer sufficient to
155 send a command to a single i2c device. Instead you should broadcast
156 the command to all i2c devices.
157
158 By setting the mode_mask correctly you can select which commands are
159 accepted by a specific tuner device. For example, set mode_mask to
160 T_RADIO if the device is a radio-only tuner. That specific tuner will
161 only accept commands when the tuner is in radio mode and ignore them
162 when the tuner is set to TV mode.
163 */
164
170struct tuner_setup { 165struct tuner_setup {
171 unsigned short addr; 166 unsigned short addr; /* I2C address */
172 unsigned int type; 167 unsigned int type; /* Tuner type */
173 unsigned int mode_mask; 168 unsigned int mode_mask; /* Allowed tuner modes */
174}; 169};
175 170
176struct tuner { 171struct tuner {
@@ -207,7 +202,6 @@ struct tuner {
207 void (*standby)(struct i2c_client *c); 202 void (*standby)(struct i2c_client *c);
208}; 203};
209 204
210extern unsigned int tuner_debug;
211extern unsigned const int tuner_count; 205extern unsigned const int tuner_count;
212 206
213extern int microtune_init(struct i2c_client *c); 207extern int microtune_init(struct i2c_client *c);
@@ -219,15 +213,15 @@ extern int tea5767_autodetection(struct i2c_client *c);
219 213
220#define tuner_warn(fmt, arg...) do {\ 214#define tuner_warn(fmt, arg...) do {\
221 printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \ 215 printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \
222 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) 216 i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
223#define tuner_info(fmt, arg...) do {\ 217#define tuner_info(fmt, arg...) do {\
224 printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \ 218 printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \
225 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) 219 i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
226#define tuner_dbg(fmt, arg...) do {\ 220#define tuner_dbg(fmt, arg...) do {\
227 if (tuner_debug) \ 221 extern int debug; \
228 printk(KERN_DEBUG "%s %d-%04x: " fmt, \ 222 if (debug) \
229 t->i2c.driver->driver.name, \ 223 printk(KERN_DEBUG "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \
230 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) 224 i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
231 225
232#endif /* __KERNEL__ */ 226#endif /* __KERNEL__ */
233 227
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index d3fd48157eb8..3cc3132f391e 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -26,12 +26,57 @@
26#ifndef V4L2_COMMON_H_ 26#ifndef V4L2_COMMON_H_
27#define V4L2_COMMON_H_ 27#define V4L2_COMMON_H_
28 28
29/* VIDIOC_INT_AUDIO_CLOCK_FREQ */ 29/* v4l debugging and diagnostics */
30enum v4l2_audio_clock_freq { 30
31 V4L2_AUDCLK_32_KHZ = 32000, 31/* Common printk constucts for v4l-i2c drivers. These macros create a unique
32 V4L2_AUDCLK_441_KHZ = 44100, 32 prefix consisting of the driver name, the adapter number and the i2c
33 V4L2_AUDCLK_48_KHZ = 48000, 33 address. */
34}; 34#define v4l_printk(level, name, adapter, addr, fmt, arg...) \
35 printk(level "%s %d-%04x: " fmt, name, i2c_adapter_id(adapter), addr , ## arg)
36
37#define v4l_client_printk(level, client, fmt, arg...) \
38 v4l_printk(level, (client)->driver->driver.name, (client)->adapter, \
39 (client)->addr, fmt , ## arg)
40
41#define v4l_err(client, fmt, arg...) \
42 v4l_client_printk(KERN_ERR, client, fmt , ## arg)
43
44#define v4l_warn(client, fmt, arg...) \
45 v4l_client_printk(KERN_WARNING, client, fmt , ## arg)
46
47#define v4l_info(client, fmt, arg...) \
48 v4l_client_printk(KERN_INFO, client, fmt , ## arg)
49
50/* These three macros assume that the debug level is set with a module
51 parameter called 'debug'. */
52#define v4l_dbg(level, client, fmt, arg...) \
53 do { \
54 extern int debug; \
55 if (debug >= (level)) \
56 v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \
57 } while (0)
58
59/* Prints the ioctl in a human-readable format */
60extern void v4l_printk_ioctl(unsigned int cmd);
61
62/* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */
63#define v4l_print_ioctl(name, cmd) \
64 do { \
65 printk(KERN_DEBUG "%s: ", name); \
66 v4l_printk_ioctl(cmd); \
67 } while (0)
68
69/* Use this macro in I2C drivers where 'client' is the struct i2c_client
70 pointer */
71#define v4l_i2c_print_ioctl(client, cmd) \
72 do { \
73 v4l_client_printk(KERN_DEBUG, client, ""); \
74 v4l_printk_ioctl(cmd); \
75 } while (0)
76
77/* ------------------------------------------------------------------------- */
78
79/* Internal ioctls */
35 80
36/* VIDIOC_INT_G_REGISTER and VIDIOC_INT_S_REGISTER */ 81/* VIDIOC_INT_G_REGISTER and VIDIOC_INT_S_REGISTER */
37struct v4l2_register { 82struct v4l2_register {
@@ -70,6 +115,20 @@ enum v4l2_chip_ident {
70 V4L2_IDENT_CX25843 = 243, 115 V4L2_IDENT_CX25843 = 243,
71}; 116};
72 117
118/* audio ioctls */
119/* v4l device was opened in Radio mode */
120#define AUDC_SET_RADIO _IO('d',88)
121/* select from TV,radio,extern,MUTE */
122#define AUDC_SET_INPUT _IOW('d',89,int)
123
124/* tuner ioctls */
125/* Sets tuner type and its I2C addr */
126#define TUNER_SET_TYPE_ADDR _IOW('d',90,int)
127/* Puts tuner on powersaving state, disabling it, except for i2c */
128#define TUNER_SET_STANDBY _IOW('d',91,int)
129/* Sets tda9887 specific stuff, like port1, port2 and qss */
130#define TDA9887_SET_CONFIG _IOW('d',92,int)
131
73/* only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */ 132/* only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */
74#define VIDIOC_INT_S_REGISTER _IOR ('d', 100, struct v4l2_register) 133#define VIDIOC_INT_S_REGISTER _IOR ('d', 100, struct v4l2_register)
75#define VIDIOC_INT_G_REGISTER _IOWR('d', 101, struct v4l2_register) 134#define VIDIOC_INT_G_REGISTER _IOWR('d', 101, struct v4l2_register)
@@ -77,10 +136,12 @@ enum v4l2_chip_ident {
77/* Reset the I2C chip */ 136/* Reset the I2C chip */
78#define VIDIOC_INT_RESET _IO ('d', 102) 137#define VIDIOC_INT_RESET _IO ('d', 102)
79 138
80/* Set the frequency of the audio clock output. 139/* Set the frequency (in Hz) of the audio clock output.
81 Used to slave an audio processor to the video decoder, ensuring that audio 140 Used to slave an audio processor to the video decoder, ensuring that audio
82 and video remain synchronized. */ 141 and video remain synchronized.
83#define VIDIOC_INT_AUDIO_CLOCK_FREQ _IOR ('d', 103, enum v4l2_audio_clock_freq) 142 Usual values for the frequency are 48000, 44100 or 32000 Hz.
143 If the frequency is not supported, then -EINVAL is returned. */
144#define VIDIOC_INT_AUDIO_CLOCK_FREQ _IOW ('d', 103, u32)
84 145
85/* Video decoders that support sliced VBI need to implement this ioctl. 146/* Video decoders that support sliced VBI need to implement this ioctl.
86 Field p of the v4l2_sliced_vbi_line struct is set to the start of the VBI 147 Field p of the v4l2_sliced_vbi_line struct is set to the start of the VBI
@@ -107,4 +168,10 @@ enum v4l2_chip_ident {
107 be made. */ 168 be made. */
108#define VIDIOC_INT_G_CHIP_IDENT _IOR ('d', 107, enum v4l2_chip_ident *) 169#define VIDIOC_INT_G_CHIP_IDENT _IOR ('d', 107, enum v4l2_chip_ident *)
109 170
171/* Sets I2S speed in bps. This is used to provide a standard way to select I2S
172 clock used by driving digital audio streams at some board designs.
173 Usual values for the frequency are 1024000 and 2048000.
174 If the frequency is not supported, then -EINVAL is returned. */
175#define VIDIOC_INT_I2S_CLOCK_FREQ _IOW ('d', 108, u32)
176
110#endif /* V4L2_COMMON_H_ */ 177#endif /* V4L2_COMMON_H_ */
diff --git a/include/net/dn_dev.h b/include/net/dn_dev.h
index 86e8e86e624a..5a86e78081bf 100644
--- a/include/net/dn_dev.h
+++ b/include/net/dn_dev.h
@@ -88,8 +88,8 @@ struct dn_dev {
88 struct net_device *dev; 88 struct net_device *dev;
89 struct dn_dev_parms parms; 89 struct dn_dev_parms parms;
90 char use_long; 90 char use_long;
91 struct timer_list timer; 91 struct timer_list timer;
92 unsigned long t3; 92 unsigned long t3;
93 struct neigh_parms *neigh_parms; 93 struct neigh_parms *neigh_parms;
94 unsigned char addr[ETH_ALEN]; 94 unsigned char addr[ETH_ALEN];
95 struct neighbour *router; /* Default router on circuit */ 95 struct neighbour *router; /* Default router on circuit */
@@ -99,57 +99,57 @@ struct dn_dev {
99 99
100struct dn_short_packet 100struct dn_short_packet
101{ 101{
102 unsigned char msgflg __attribute__((packed)); 102 unsigned char msgflg;
103 unsigned short dstnode __attribute__((packed)); 103 unsigned short dstnode;
104 unsigned short srcnode __attribute__((packed)); 104 unsigned short srcnode;
105 unsigned char forward __attribute__((packed)); 105 unsigned char forward;
106}; 106} __attribute__((packed));
107 107
108struct dn_long_packet 108struct dn_long_packet
109{ 109{
110 unsigned char msgflg __attribute__((packed)); 110 unsigned char msgflg;
111 unsigned char d_area __attribute__((packed)); 111 unsigned char d_area;
112 unsigned char d_subarea __attribute__((packed)); 112 unsigned char d_subarea;
113 unsigned char d_id[6] __attribute__((packed)); 113 unsigned char d_id[6];
114 unsigned char s_area __attribute__((packed)); 114 unsigned char s_area;
115 unsigned char s_subarea __attribute__((packed)); 115 unsigned char s_subarea;
116 unsigned char s_id[6] __attribute__((packed)); 116 unsigned char s_id[6];
117 unsigned char nl2 __attribute__((packed)); 117 unsigned char nl2;
118 unsigned char visit_ct __attribute__((packed)); 118 unsigned char visit_ct;
119 unsigned char s_class __attribute__((packed)); 119 unsigned char s_class;
120 unsigned char pt __attribute__((packed)); 120 unsigned char pt;
121}; 121} __attribute__((packed));
122 122
123/*------------------------- DRP - Routing messages ---------------------*/ 123/*------------------------- DRP - Routing messages ---------------------*/
124 124
125struct endnode_hello_message 125struct endnode_hello_message
126{ 126{
127 unsigned char msgflg __attribute__((packed)); 127 unsigned char msgflg;
128 unsigned char tiver[3] __attribute__((packed)); 128 unsigned char tiver[3];
129 unsigned char id[6] __attribute__((packed)); 129 unsigned char id[6];
130 unsigned char iinfo __attribute__((packed)); 130 unsigned char iinfo;
131 unsigned short blksize __attribute__((packed)); 131 unsigned short blksize;
132 unsigned char area __attribute__((packed)); 132 unsigned char area;
133 unsigned char seed[8] __attribute__((packed)); 133 unsigned char seed[8];
134 unsigned char neighbor[6] __attribute__((packed)); 134 unsigned char neighbor[6];
135 unsigned short timer __attribute__((packed)); 135 unsigned short timer;
136 unsigned char mpd __attribute__((packed)); 136 unsigned char mpd;
137 unsigned char datalen __attribute__((packed)); 137 unsigned char datalen;
138 unsigned char data[2] __attribute__((packed)); 138 unsigned char data[2];
139}; 139} __attribute__((packed));
140 140
141struct rtnode_hello_message 141struct rtnode_hello_message
142{ 142{
143 unsigned char msgflg __attribute__((packed)); 143 unsigned char msgflg;
144 unsigned char tiver[3] __attribute__((packed)); 144 unsigned char tiver[3];
145 unsigned char id[6] __attribute__((packed)); 145 unsigned char id[6];
146 unsigned char iinfo __attribute__((packed)); 146 unsigned char iinfo;
147 unsigned short blksize __attribute__((packed)); 147 unsigned short blksize;
148 unsigned char priority __attribute__((packed)); 148 unsigned char priority;
149 unsigned char area __attribute__((packed)); 149 unsigned char area;
150 unsigned short timer __attribute__((packed)); 150 unsigned short timer;
151 unsigned char mpd __attribute__((packed)); 151 unsigned char mpd;
152}; 152} __attribute__((packed));
153 153
154 154
155extern void dn_dev_init(void); 155extern void dn_dev_init(void);
diff --git a/include/net/dn_nsp.h b/include/net/dn_nsp.h
index 1ba03be0af3a..e6182b86262b 100644
--- a/include/net/dn_nsp.h
+++ b/include/net/dn_nsp.h
@@ -72,78 +72,78 @@ extern struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int nobl
72 72
73struct nsp_data_seg_msg 73struct nsp_data_seg_msg
74{ 74{
75 unsigned char msgflg __attribute__((packed)); 75 unsigned char msgflg;
76 unsigned short dstaddr __attribute__((packed)); 76 unsigned short dstaddr;
77 unsigned short srcaddr __attribute__((packed)); 77 unsigned short srcaddr;
78}; 78} __attribute__((packed));
79 79
80struct nsp_data_opt_msg 80struct nsp_data_opt_msg
81{ 81{
82 unsigned short acknum __attribute__((packed)); 82 unsigned short acknum;
83 unsigned short segnum __attribute__((packed)); 83 unsigned short segnum;
84 unsigned short lsflgs __attribute__((packed)); 84 unsigned short lsflgs;
85}; 85} __attribute__((packed));
86 86
87struct nsp_data_opt_msg1 87struct nsp_data_opt_msg1
88{ 88{
89 unsigned short acknum __attribute__((packed)); 89 unsigned short acknum;
90 unsigned short segnum __attribute__((packed)); 90 unsigned short segnum;
91}; 91} __attribute__((packed));
92 92
93 93
94/* Acknowledgment Message (data/other data) */ 94/* Acknowledgment Message (data/other data) */
95struct nsp_data_ack_msg 95struct nsp_data_ack_msg
96{ 96{
97 unsigned char msgflg __attribute__((packed)); 97 unsigned char msgflg;
98 unsigned short dstaddr __attribute__((packed)); 98 unsigned short dstaddr;
99 unsigned short srcaddr __attribute__((packed)); 99 unsigned short srcaddr;
100 unsigned short acknum __attribute__((packed)); 100 unsigned short acknum;
101}; 101} __attribute__((packed));
102 102
103/* Connect Acknowledgment Message */ 103/* Connect Acknowledgment Message */
104struct nsp_conn_ack_msg 104struct nsp_conn_ack_msg
105{ 105{
106 unsigned char msgflg __attribute__((packed)); 106 unsigned char msgflg;
107 unsigned short dstaddr __attribute__((packed)); 107 unsigned short dstaddr;
108}; 108} __attribute__((packed));
109 109
110 110
111/* Connect Initiate/Retransmit Initiate/Connect Confirm */ 111/* Connect Initiate/Retransmit Initiate/Connect Confirm */
112struct nsp_conn_init_msg 112struct nsp_conn_init_msg
113{ 113{
114 unsigned char msgflg __attribute__((packed)); 114 unsigned char msgflg;
115#define NSP_CI 0x18 /* Connect Initiate */ 115#define NSP_CI 0x18 /* Connect Initiate */
116#define NSP_RCI 0x68 /* Retrans. Conn Init */ 116#define NSP_RCI 0x68 /* Retrans. Conn Init */
117 unsigned short dstaddr __attribute__((packed)); 117 unsigned short dstaddr;
118 unsigned short srcaddr __attribute__((packed)); 118 unsigned short srcaddr;
119 unsigned char services __attribute__((packed)); 119 unsigned char services;
120#define NSP_FC_NONE 0x00 /* Flow Control None */ 120#define NSP_FC_NONE 0x00 /* Flow Control None */
121#define NSP_FC_SRC 0x04 /* Seg Req. Count */ 121#define NSP_FC_SRC 0x04 /* Seg Req. Count */
122#define NSP_FC_SCMC 0x08 /* Sess. Control Mess */ 122#define NSP_FC_SCMC 0x08 /* Sess. Control Mess */
123#define NSP_FC_MASK 0x0c /* FC type mask */ 123#define NSP_FC_MASK 0x0c /* FC type mask */
124 unsigned char info __attribute__((packed)); 124 unsigned char info;
125 unsigned short segsize __attribute__((packed)); 125 unsigned short segsize;
126}; 126} __attribute__((packed));
127 127
128/* Disconnect Initiate/Disconnect Confirm */ 128/* Disconnect Initiate/Disconnect Confirm */
129struct nsp_disconn_init_msg 129struct nsp_disconn_init_msg
130{ 130{
131 unsigned char msgflg __attribute__((packed)); 131 unsigned char msgflg;
132 unsigned short dstaddr __attribute__((packed)); 132 unsigned short dstaddr;
133 unsigned short srcaddr __attribute__((packed)); 133 unsigned short srcaddr;
134 unsigned short reason __attribute__((packed)); 134 unsigned short reason;
135}; 135} __attribute__((packed));
136 136
137 137
138 138
139struct srcobj_fmt 139struct srcobj_fmt
140{ 140{
141 char format __attribute__((packed)); 141 char format;
142 unsigned char task __attribute__((packed)); 142 unsigned char task;
143 unsigned short grpcode __attribute__((packed)); 143 unsigned short grpcode;
144 unsigned short usrcode __attribute__((packed)); 144 unsigned short usrcode;
145 char dlen __attribute__((packed)); 145 char dlen;
146}; 146} __attribute__((packed));
147 147
148/* 148/*
149 * A collection of functions for manipulating the sequence 149 * A collection of functions for manipulating the sequence
diff --git a/include/net/dst.h b/include/net/dst.h
index bee8b84d329d..5161e89017f9 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -225,16 +225,7 @@ static inline void dst_set_expires(struct dst_entry *dst, int timeout)
225/* Output packet to network from transport. */ 225/* Output packet to network from transport. */
226static inline int dst_output(struct sk_buff *skb) 226static inline int dst_output(struct sk_buff *skb)
227{ 227{
228 int err; 228 return skb->dst->output(skb);
229
230 for (;;) {
231 err = skb->dst->output(skb);
232
233 if (likely(err == 0))
234 return err;
235 if (unlikely(err != NET_XMIT_BYPASS))
236 return err;
237 }
238} 229}
239 230
240/* Input packet from network to transport. */ 231/* Input packet from network to transport. */
diff --git a/include/net/ip.h b/include/net/ip.h
index 7bb5804847f2..8de0697b364c 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -37,11 +37,10 @@ struct inet_skb_parm
37 struct ip_options opt; /* Compiled IP options */ 37 struct ip_options opt; /* Compiled IP options */
38 unsigned char flags; 38 unsigned char flags;
39 39
40#define IPSKB_MASQUERADED 1 40#define IPSKB_FORWARDED 1
41#define IPSKB_TRANSLATED 2 41#define IPSKB_XFRM_TUNNEL_SIZE 2
42#define IPSKB_FORWARDED 4 42#define IPSKB_XFRM_TRANSFORMED 4
43#define IPSKB_XFRM_TUNNEL_SIZE 8 43#define IPSKB_FRAG_COMPLETE 8
44#define IPSKB_FRAG_COMPLETE 16
45}; 44};
46 45
47struct ipcm_cookie 46struct ipcm_cookie
@@ -95,7 +94,6 @@ extern int ip_local_deliver(struct sk_buff *skb);
95extern int ip_mr_input(struct sk_buff *skb); 94extern int ip_mr_input(struct sk_buff *skb);
96extern int ip_output(struct sk_buff *skb); 95extern int ip_output(struct sk_buff *skb);
97extern int ip_mc_output(struct sk_buff *skb); 96extern int ip_mc_output(struct sk_buff *skb);
98extern int ip_fragment(struct sk_buff *skb, int (*out)(struct sk_buff*));
99extern int ip_do_nat(struct sk_buff *skb); 97extern int ip_do_nat(struct sk_buff *skb);
100extern void ip_send_check(struct iphdr *ip); 98extern void ip_send_check(struct iphdr *ip);
101extern int ip_queue_xmit(struct sk_buff *skb, int ipfragok); 99extern int ip_queue_xmit(struct sk_buff *skb, int ipfragok);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 860bbac4c4ee..3b1d963d396c 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -418,6 +418,8 @@ extern int ipv6_rcv(struct sk_buff *skb,
418 struct packet_type *pt, 418 struct packet_type *pt,
419 struct net_device *orig_dev); 419 struct net_device *orig_dev);
420 420
421extern int ip6_rcv_finish(struct sk_buff *skb);
422
421/* 423/*
422 * upper-layer output functions 424 * upper-layer output functions
423 */ 425 */
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 63f7db99c2a6..6dc5970612d7 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -43,7 +43,7 @@ struct net_protocol {
43#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 43#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
44struct inet6_protocol 44struct inet6_protocol
45{ 45{
46 int (*handler)(struct sk_buff **skb, unsigned int *nhoffp); 46 int (*handler)(struct sk_buff **skb);
47 47
48 void (*err_handler)(struct sk_buff *skb, 48 void (*err_handler)(struct sk_buff *skb,
49 struct inet6_skb_parm *opt, 49 struct inet6_skb_parm *opt,
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 07d7b50cdd76..d09ca0e7d139 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -668,7 +668,7 @@ static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *s
668 return xfrm_policy_check(sk, dir, skb, AF_INET6); 668 return xfrm_policy_check(sk, dir, skb, AF_INET6);
669} 669}
670 670
671 671extern int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family);
672extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family); 672extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
673 673
674static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) 674static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
@@ -831,7 +831,7 @@ struct xfrm_tunnel {
831}; 831};
832 832
833struct xfrm6_tunnel { 833struct xfrm6_tunnel {
834 int (*handler)(struct sk_buff **pskb, unsigned int *nhoffp); 834 int (*handler)(struct sk_buff **pskb);
835 void (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt, 835 void (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
836 int type, int code, int offset, __u32 info); 836 int type, int code, int offset, __u32 info);
837}; 837};
@@ -866,10 +866,11 @@ extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
866extern int xfrm_init_state(struct xfrm_state *x); 866extern int xfrm_init_state(struct xfrm_state *x);
867extern int xfrm4_rcv(struct sk_buff *skb); 867extern int xfrm4_rcv(struct sk_buff *skb);
868extern int xfrm4_output(struct sk_buff *skb); 868extern int xfrm4_output(struct sk_buff *skb);
869extern int xfrm4_output_finish(struct sk_buff *skb);
869extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler); 870extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
870extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler); 871extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);
871extern int xfrm6_rcv_spi(struct sk_buff **pskb, unsigned int *nhoffp, u32 spi); 872extern int xfrm6_rcv_spi(struct sk_buff **pskb, u32 spi);
872extern int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp); 873extern int xfrm6_rcv(struct sk_buff **pskb);
873extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler); 874extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler);
874extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler); 875extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler);
875extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr); 876extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);
diff --git a/include/sound/wavefront.h b/include/sound/wavefront.h
index 9e572aed2435..15d82e594b56 100644
--- a/include/sound/wavefront.h
+++ b/include/sound/wavefront.h
@@ -454,22 +454,22 @@ typedef struct wf_multisample {
454} wavefront_multisample; 454} wavefront_multisample;
455 455
456typedef struct wf_alias { 456typedef struct wf_alias {
457 s16 OriginalSample __attribute__ ((packed)); 457 s16 OriginalSample;
458 458
459 struct wf_sample_offset sampleStartOffset __attribute__ ((packed)); 459 struct wf_sample_offset sampleStartOffset;
460 struct wf_sample_offset loopStartOffset __attribute__ ((packed)); 460 struct wf_sample_offset loopStartOffset;
461 struct wf_sample_offset sampleEndOffset __attribute__ ((packed)); 461 struct wf_sample_offset sampleEndOffset;
462 struct wf_sample_offset loopEndOffset __attribute__ ((packed)); 462 struct wf_sample_offset loopEndOffset;
463 463
464 s16 FrequencyBias __attribute__ ((packed)); 464 s16 FrequencyBias;
465 465
466 u8 SampleResolution:2 __attribute__ ((packed)); 466 u8 SampleResolution:2;
467 u8 Unused1:1 __attribute__ ((packed)); 467 u8 Unused1:1;
468 u8 Loop:1 __attribute__ ((packed)); 468 u8 Loop:1;
469 u8 Bidirectional:1 __attribute__ ((packed)); 469 u8 Bidirectional:1;
470 u8 Unused2:1 __attribute__ ((packed)); 470 u8 Unused2:1;
471 u8 Reverse:1 __attribute__ ((packed)); 471 u8 Reverse:1;
472 u8 Unused3:1 __attribute__ ((packed)); 472 u8 Unused3:1;
473 473
474 /* This structure is meant to be padded only to 16 bits on their 474 /* This structure is meant to be padded only to 16 bits on their
475 original. Of course, whoever wrote their documentation didn't 475 original. Of course, whoever wrote their documentation didn't
@@ -480,8 +480,8 @@ typedef struct wf_alias {
480 standard 16->32 bit issues. 480 standard 16->32 bit issues.
481 */ 481 */
482 482
483 u8 sixteen_bit_padding __attribute__ ((packed)); 483 u8 sixteen_bit_padding;
484} wavefront_alias; 484} __attribute__((packed)) wavefront_alias;
485 485
486typedef struct wf_drum { 486typedef struct wf_drum {
487 u8 PatchNumber; 487 u8 PatchNumber;
diff --git a/include/video/cyblafb.h b/include/video/cyblafb.h
index a9948232b131..717440575380 100644
--- a/include/video/cyblafb.h
+++ b/include/video/cyblafb.h
@@ -153,6 +153,10 @@
153#define GE04 (GEBase+0x04) // source 2, p 111 153#define GE04 (GEBase+0x04) // source 2, p 111
154#define GE08 (GEBase+0x08) // destination 1, p 111 154#define GE08 (GEBase+0x08) // destination 1, p 111
155#define GE0C (GEBase+0x0C) // destination 2, p 112 155#define GE0C (GEBase+0x0C) // destination 2, p 112
156#define GE10 (GEBase+0x10) // right view base & enable, p 112
157#define GE13 (GEBase+0x13) // left view base & enable, p 112
158#define GE18 (GEBase+0x18) // block write start address, p 112
159#define GE1C (GEBase+0x1C) // block write end address, p 112
156#define GE20 (GEBase+0x20) // engine status, p 113 160#define GE20 (GEBase+0x20) // engine status, p 113
157#define GE24 (GEBase+0x24) // reset all GE pointers 161#define GE24 (GEBase+0x24) // reset all GE pointers
158#define GE44 (GEBase+0x44) // command register, p 126 162#define GE44 (GEBase+0x44) // command register, p 126
diff --git a/init/Kconfig b/init/Kconfig
index ba42f3793a84..f8f6929d8f25 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -228,6 +228,25 @@ config CPUSETS
228 228
229source "usr/Kconfig" 229source "usr/Kconfig"
230 230
231config UID16
232 bool "Enable 16-bit UID system calls" if EMBEDDED
233 depends !ALPHA && !PPC && !PPC64 && !PARISC && !V850 && !ARCH_S390X
234 depends !X86_64 || IA32_EMULATION
235 depends !SPARC64 || SPARC32_COMPAT
236 default y
237 help
238 This enables the legacy 16-bit UID syscall wrappers.
239
240config VM86
241 depends X86
242 default y
243 bool "Enable VM86 support" if EMBEDDED
244 help
245 This option is required by programs like DOSEMU to run 16-bit legacy
246 code on X86 processors. It also may be needed by software like
247 XFree86 to initialize some video cards via BIOS. Disabling this
248 option saves about 6k.
249
231config CC_OPTIMIZE_FOR_SIZE 250config CC_OPTIMIZE_FOR_SIZE
232 bool "Optimize for size (Look out for broken compilers!)" 251 bool "Optimize for size (Look out for broken compilers!)"
233 default y 252 default y
@@ -309,6 +328,21 @@ config BUG
309 option for embedded systems with no facilities for reporting errors. 328 option for embedded systems with no facilities for reporting errors.
310 Just say Y. 329 Just say Y.
311 330
331config DOUBLEFAULT
332 depends X86
333 default y if X86
334 bool "Enable doublefault exception handler" if EMBEDDED
335 help
336 This option allows trapping of rare doublefault exceptions that
337 would otherwise cause a system to silently reboot. Disabling this
338 option saves about 4k.
339
340config ELF_CORE
341 default y
342 bool "Enable ELF core dumps" if EMBEDDED
343 help
344 Enable support for generating core dumps. Disabling saves about 4k.
345
312config BASE_FULL 346config BASE_FULL
313 default y 347 default y
314 bool "Enable full-sized data structures for core" if EMBEDDED 348 bool "Enable full-sized data structures for core" if EMBEDDED
@@ -380,6 +414,15 @@ config CC_ALIGN_JUMPS
380 no dummy operations need be executed. 414 no dummy operations need be executed.
381 Zero means use compiler's default. 415 Zero means use compiler's default.
382 416
417config SLAB
418 default y
419 bool "Use full SLAB allocator" if EMBEDDED
420 help
421 Disabling this replaces the advanced SLAB allocator and
422 kmalloc support with the drastically simpler SLOB allocator.
423 SLOB is more space efficient but does not scale well and is
424 more susceptible to fragmentation.
425
383endmenu # General setup 426endmenu # General setup
384 427
385config TINY_SHMEM 428config TINY_SHMEM
@@ -391,6 +434,10 @@ config BASE_SMALL
391 default 0 if BASE_FULL 434 default 0 if BASE_FULL
392 default 1 if !BASE_FULL 435 default 1 if !BASE_FULL
393 436
437config SLOB
438 default !SLAB
439 bool
440
394menu "Loadable module support" 441menu "Loadable module support"
395 442
396config MODULES 443config MODULES
diff --git a/init/main.c b/init/main.c
index 2ed3638deec7..8342c2890b16 100644
--- a/init/main.c
+++ b/init/main.c
@@ -58,11 +58,6 @@
58 * This is one of the first .c files built. Error out early 58 * This is one of the first .c files built. Error out early
59 * if we have compiler trouble.. 59 * if we have compiler trouble..
60 */ 60 */
61#if __GNUC__ == 2 && __GNUC_MINOR__ == 96
62#ifdef CONFIG_FRAME_POINTER
63#error This compiler cannot compile correctly with frame pointers enabled
64#endif
65#endif
66 61
67#ifdef CONFIG_X86_LOCAL_APIC 62#ifdef CONFIG_X86_LOCAL_APIC
68#include <asm/smp.h> 63#include <asm/smp.h>
@@ -74,7 +69,7 @@
74 * To avoid associated bogus bug reports, we flatly refuse to compile 69 * To avoid associated bogus bug reports, we flatly refuse to compile
75 * with a gcc that is known to be too old from the very beginning. 70 * with a gcc that is known to be too old from the very beginning.
76 */ 71 */
77#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95) 72#if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2)
78#error Sorry, your GCC is too old. It builds incorrect kernels. 73#error Sorry, your GCC is too old. It builds incorrect kernels.
79#endif 74#endif
80 75
@@ -512,6 +507,7 @@ asmlinkage void __init start_kernel(void)
512 } 507 }
513#endif 508#endif
514 vfs_caches_init_early(); 509 vfs_caches_init_early();
510 cpuset_init_early();
515 mem_init(); 511 mem_init();
516 kmem_cache_init(); 512 kmem_cache_init();
517 setup_per_cpu_pageset(); 513 setup_per_cpu_pageset();
diff --git a/ipc/shm.c b/ipc/shm.c
index 0ef4a1cf3e27..0b92e874fc06 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -34,8 +34,6 @@
34 34
35#include "util.h" 35#include "util.h"
36 36
37#define shm_flags shm_perm.mode
38
39static struct file_operations shm_file_operations; 37static struct file_operations shm_file_operations;
40static struct vm_operations_struct shm_vm_ops; 38static struct vm_operations_struct shm_vm_ops;
41 39
@@ -148,7 +146,7 @@ static void shm_close (struct vm_area_struct *shmd)
148 shp->shm_dtim = get_seconds(); 146 shp->shm_dtim = get_seconds();
149 shp->shm_nattch--; 147 shp->shm_nattch--;
150 if(shp->shm_nattch == 0 && 148 if(shp->shm_nattch == 0 &&
151 shp->shm_flags & SHM_DEST) 149 shp->shm_perm.mode & SHM_DEST)
152 shm_destroy (shp); 150 shm_destroy (shp);
153 else 151 else
154 shm_unlock(shp); 152 shm_unlock(shp);
@@ -205,7 +203,7 @@ static int newseg (key_t key, int shmflg, size_t size)
205 return -ENOMEM; 203 return -ENOMEM;
206 204
207 shp->shm_perm.key = key; 205 shp->shm_perm.key = key;
208 shp->shm_flags = (shmflg & S_IRWXUGO); 206 shp->shm_perm.mode = (shmflg & S_IRWXUGO);
209 shp->mlock_user = NULL; 207 shp->mlock_user = NULL;
210 208
211 shp->shm_perm.security = NULL; 209 shp->shm_perm.security = NULL;
@@ -345,7 +343,7 @@ static inline unsigned long copy_shmid_from_user(struct shm_setbuf *out, void __
345 343
346 out->uid = tbuf.shm_perm.uid; 344 out->uid = tbuf.shm_perm.uid;
347 out->gid = tbuf.shm_perm.gid; 345 out->gid = tbuf.shm_perm.gid;
348 out->mode = tbuf.shm_flags; 346 out->mode = tbuf.shm_perm.mode;
349 347
350 return 0; 348 return 0;
351 } 349 }
@@ -358,7 +356,7 @@ static inline unsigned long copy_shmid_from_user(struct shm_setbuf *out, void __
358 356
359 out->uid = tbuf_old.shm_perm.uid; 357 out->uid = tbuf_old.shm_perm.uid;
360 out->gid = tbuf_old.shm_perm.gid; 358 out->gid = tbuf_old.shm_perm.gid;
361 out->mode = tbuf_old.shm_flags; 359 out->mode = tbuf_old.shm_perm.mode;
362 360
363 return 0; 361 return 0;
364 } 362 }
@@ -560,13 +558,13 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
560 if (!is_file_hugepages(shp->shm_file)) { 558 if (!is_file_hugepages(shp->shm_file)) {
561 err = shmem_lock(shp->shm_file, 1, user); 559 err = shmem_lock(shp->shm_file, 1, user);
562 if (!err) { 560 if (!err) {
563 shp->shm_flags |= SHM_LOCKED; 561 shp->shm_perm.mode |= SHM_LOCKED;
564 shp->mlock_user = user; 562 shp->mlock_user = user;
565 } 563 }
566 } 564 }
567 } else if (!is_file_hugepages(shp->shm_file)) { 565 } else if (!is_file_hugepages(shp->shm_file)) {
568 shmem_lock(shp->shm_file, 0, shp->mlock_user); 566 shmem_lock(shp->shm_file, 0, shp->mlock_user);
569 shp->shm_flags &= ~SHM_LOCKED; 567 shp->shm_perm.mode &= ~SHM_LOCKED;
570 shp->mlock_user = NULL; 568 shp->mlock_user = NULL;
571 } 569 }
572 shm_unlock(shp); 570 shm_unlock(shp);
@@ -605,7 +603,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
605 goto out_unlock_up; 603 goto out_unlock_up;
606 604
607 if (shp->shm_nattch){ 605 if (shp->shm_nattch){
608 shp->shm_flags |= SHM_DEST; 606 shp->shm_perm.mode |= SHM_DEST;
609 /* Do not find it any more */ 607 /* Do not find it any more */
610 shp->shm_perm.key = IPC_PRIVATE; 608 shp->shm_perm.key = IPC_PRIVATE;
611 shm_unlock(shp); 609 shm_unlock(shp);
@@ -644,7 +642,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
644 642
645 shp->shm_perm.uid = setbuf.uid; 643 shp->shm_perm.uid = setbuf.uid;
646 shp->shm_perm.gid = setbuf.gid; 644 shp->shm_perm.gid = setbuf.gid;
647 shp->shm_flags = (shp->shm_flags & ~S_IRWXUGO) 645 shp->shm_perm.mode = (shp->shm_perm.mode & ~S_IRWXUGO)
648 | (setbuf.mode & S_IRWXUGO); 646 | (setbuf.mode & S_IRWXUGO);
649 shp->shm_ctim = get_seconds(); 647 shp->shm_ctim = get_seconds();
650 break; 648 break;
@@ -777,7 +775,7 @@ invalid:
777 BUG(); 775 BUG();
778 shp->shm_nattch--; 776 shp->shm_nattch--;
779 if(shp->shm_nattch == 0 && 777 if(shp->shm_nattch == 0 &&
780 shp->shm_flags & SHM_DEST) 778 shp->shm_perm.mode & SHM_DEST)
781 shm_destroy (shp); 779 shm_destroy (shp);
782 else 780 else
783 shm_unlock(shp); 781 shm_unlock(shp);
@@ -902,7 +900,7 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it)
902 return seq_printf(s, format, 900 return seq_printf(s, format,
903 shp->shm_perm.key, 901 shp->shm_perm.key,
904 shp->id, 902 shp->id,
905 shp->shm_flags, 903 shp->shm_perm.mode,
906 shp->shm_segsz, 904 shp->shm_segsz,
907 shp->shm_cprid, 905 shp->shm_cprid,
908 shp->shm_lprid, 906 shp->shm_lprid,
diff --git a/kernel/audit.c b/kernel/audit.c
index 32fa03ad1984..d13ab7d2d899 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -267,7 +267,7 @@ static int audit_set_failure(int state, uid_t loginuid)
267 return old; 267 return old;
268} 268}
269 269
270int kauditd_thread(void *dummy) 270static int kauditd_thread(void *dummy)
271{ 271{
272 struct sk_buff *skb; 272 struct sk_buff *skb;
273 273
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 7430640f9816..eab64e23bcae 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -39,6 +39,7 @@
39#include <linux/namei.h> 39#include <linux/namei.h>
40#include <linux/pagemap.h> 40#include <linux/pagemap.h>
41#include <linux/proc_fs.h> 41#include <linux/proc_fs.h>
42#include <linux/rcupdate.h>
42#include <linux/sched.h> 43#include <linux/sched.h>
43#include <linux/seq_file.h> 44#include <linux/seq_file.h>
44#include <linux/slab.h> 45#include <linux/slab.h>
@@ -54,7 +55,23 @@
54#include <asm/atomic.h> 55#include <asm/atomic.h>
55#include <asm/semaphore.h> 56#include <asm/semaphore.h>
56 57
57#define CPUSET_SUPER_MAGIC 0x27e0eb 58#define CPUSET_SUPER_MAGIC 0x27e0eb
59
60/*
61 * Tracks how many cpusets are currently defined in system.
62 * When there is only one cpuset (the root cpuset) we can
63 * short circuit some hooks.
64 */
65int number_of_cpusets __read_mostly;
66
67/* See "Frequency meter" comments, below. */
68
69struct fmeter {
70 int cnt; /* unprocessed events count */
71 int val; /* most recent output value */
72 time_t time; /* clock (secs) when val computed */
73 spinlock_t lock; /* guards read or write of above */
74};
58 75
59struct cpuset { 76struct cpuset {
60 unsigned long flags; /* "unsigned long" so bitops work */ 77 unsigned long flags; /* "unsigned long" so bitops work */
@@ -80,13 +97,16 @@ struct cpuset {
80 * Copy of global cpuset_mems_generation as of the most 97 * Copy of global cpuset_mems_generation as of the most
81 * recent time this cpuset changed its mems_allowed. 98 * recent time this cpuset changed its mems_allowed.
82 */ 99 */
83 int mems_generation; 100 int mems_generation;
101
102 struct fmeter fmeter; /* memory_pressure filter */
84}; 103};
85 104
86/* bits in struct cpuset flags field */ 105/* bits in struct cpuset flags field */
87typedef enum { 106typedef enum {
88 CS_CPU_EXCLUSIVE, 107 CS_CPU_EXCLUSIVE,
89 CS_MEM_EXCLUSIVE, 108 CS_MEM_EXCLUSIVE,
109 CS_MEMORY_MIGRATE,
90 CS_REMOVED, 110 CS_REMOVED,
91 CS_NOTIFY_ON_RELEASE 111 CS_NOTIFY_ON_RELEASE
92} cpuset_flagbits_t; 112} cpuset_flagbits_t;
@@ -112,6 +132,11 @@ static inline int notify_on_release(const struct cpuset *cs)
112 return !!test_bit(CS_NOTIFY_ON_RELEASE, &cs->flags); 132 return !!test_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
113} 133}
114 134
135static inline int is_memory_migrate(const struct cpuset *cs)
136{
137 return !!test_bit(CS_MEMORY_MIGRATE, &cs->flags);
138}
139
115/* 140/*
116 * Increment this atomic integer everytime any cpuset changes its 141 * Increment this atomic integer everytime any cpuset changes its
117 * mems_allowed value. Users of cpusets can track this generation 142 * mems_allowed value. Users of cpusets can track this generation
@@ -137,13 +162,10 @@ static struct cpuset top_cpuset = {
137 .count = ATOMIC_INIT(0), 162 .count = ATOMIC_INIT(0),
138 .sibling = LIST_HEAD_INIT(top_cpuset.sibling), 163 .sibling = LIST_HEAD_INIT(top_cpuset.sibling),
139 .children = LIST_HEAD_INIT(top_cpuset.children), 164 .children = LIST_HEAD_INIT(top_cpuset.children),
140 .parent = NULL,
141 .dentry = NULL,
142 .mems_generation = 0,
143}; 165};
144 166
145static struct vfsmount *cpuset_mount; 167static struct vfsmount *cpuset_mount;
146static struct super_block *cpuset_sb = NULL; 168static struct super_block *cpuset_sb;
147 169
148/* 170/*
149 * We have two global cpuset semaphores below. They can nest. 171 * We have two global cpuset semaphores below. They can nest.
@@ -227,6 +249,11 @@ static struct super_block *cpuset_sb = NULL;
227 * a tasks cpuset pointer we use task_lock(), which acts on a spinlock 249 * a tasks cpuset pointer we use task_lock(), which acts on a spinlock
228 * (task->alloc_lock) already in the task_struct routinely used for 250 * (task->alloc_lock) already in the task_struct routinely used for
229 * such matters. 251 * such matters.
252 *
253 * P.S. One more locking exception. RCU is used to guard the
254 * update of a tasks cpuset pointer by attach_task() and the
255 * access of task->cpuset->mems_generation via that pointer in
256 * the routine cpuset_update_task_memory_state().
230 */ 257 */
231 258
232static DECLARE_MUTEX(manage_sem); 259static DECLARE_MUTEX(manage_sem);
@@ -304,7 +331,7 @@ static void cpuset_d_remove_dir(struct dentry *dentry)
304 spin_lock(&dcache_lock); 331 spin_lock(&dcache_lock);
305 node = dentry->d_subdirs.next; 332 node = dentry->d_subdirs.next;
306 while (node != &dentry->d_subdirs) { 333 while (node != &dentry->d_subdirs) {
307 struct dentry *d = list_entry(node, struct dentry, d_child); 334 struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
308 list_del_init(node); 335 list_del_init(node);
309 if (d->d_inode) { 336 if (d->d_inode) {
310 d = dget_locked(d); 337 d = dget_locked(d);
@@ -316,7 +343,7 @@ static void cpuset_d_remove_dir(struct dentry *dentry)
316 } 343 }
317 node = dentry->d_subdirs.next; 344 node = dentry->d_subdirs.next;
318 } 345 }
319 list_del_init(&dentry->d_child); 346 list_del_init(&dentry->d_u.d_child);
320 spin_unlock(&dcache_lock); 347 spin_unlock(&dcache_lock);
321 remove_dir(dentry); 348 remove_dir(dentry);
322} 349}
@@ -570,20 +597,43 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
570 BUG_ON(!nodes_intersects(*pmask, node_online_map)); 597 BUG_ON(!nodes_intersects(*pmask, node_online_map));
571} 598}
572 599
573/* 600/**
574 * Refresh current tasks mems_allowed and mems_generation from current 601 * cpuset_update_task_memory_state - update task memory placement
575 * tasks cpuset.
576 * 602 *
577 * Call without callback_sem or task_lock() held. May be called with 603 * If the current tasks cpusets mems_allowed changed behind our
578 * or without manage_sem held. Will acquire task_lock() and might 604 * backs, update current->mems_allowed, mems_generation and task NUMA
579 * acquire callback_sem during call. 605 * mempolicy to the new value.
606 *
607 * Task mempolicy is updated by rebinding it relative to the
608 * current->cpuset if a task has its memory placement changed.
609 * Do not call this routine if in_interrupt().
580 * 610 *
581 * The task_lock() is required to dereference current->cpuset safely. 611 * Call without callback_sem or task_lock() held. May be called
582 * Without it, we could pick up the pointer value of current->cpuset 612 * with or without manage_sem held. Doesn't need task_lock to guard
583 * in one instruction, and then attach_task could give us a different 613 * against another task changing a non-NULL cpuset pointer to NULL,
584 * cpuset, and then the cpuset we had could be removed and freed, 614 * as that is only done by a task on itself, and if the current task
585 * and then on our next instruction, we could dereference a no longer 615 * is here, it is not simultaneously in the exit code NULL'ing its
586 * valid cpuset pointer to get its mems_generation field. 616 * cpuset pointer. This routine also might acquire callback_sem and
617 * current->mm->mmap_sem during call.
618 *
619 * Reading current->cpuset->mems_generation doesn't need task_lock
620 * to guard the current->cpuset derefence, because it is guarded
621 * from concurrent freeing of current->cpuset by attach_task(),
622 * using RCU.
623 *
624 * The rcu_dereference() is technically probably not needed,
625 * as I don't actually mind if I see a new cpuset pointer but
626 * an old value of mems_generation. However this really only
627 * matters on alpha systems using cpusets heavily. If I dropped
628 * that rcu_dereference(), it would save them a memory barrier.
629 * For all other arch's, rcu_dereference is a no-op anyway, and for
630 * alpha systems not using cpusets, another planned optimization,
631 * avoiding the rcu critical section for tasks in the root cpuset
632 * which is statically allocated, so can't vanish, will make this
633 * irrelevant. Better to use RCU as intended, than to engage in
634 * some cute trick to save a memory barrier that is impossible to
635 * test, for alpha systems using cpusets heavily, which might not
636 * even exist.
587 * 637 *
588 * This routine is needed to update the per-task mems_allowed data, 638 * This routine is needed to update the per-task mems_allowed data,
589 * within the tasks context, when it is trying to allocate memory 639 * within the tasks context, when it is trying to allocate memory
@@ -591,27 +641,31 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
591 * task has been modifying its cpuset. 641 * task has been modifying its cpuset.
592 */ 642 */
593 643
594static void refresh_mems(void) 644void cpuset_update_task_memory_state()
595{ 645{
596 int my_cpusets_mem_gen; 646 int my_cpusets_mem_gen;
647 struct task_struct *tsk = current;
648 struct cpuset *cs;
597 649
598 task_lock(current); 650 if (tsk->cpuset == &top_cpuset) {
599 my_cpusets_mem_gen = current->cpuset->mems_generation; 651 /* Don't need rcu for top_cpuset. It's never freed. */
600 task_unlock(current); 652 my_cpusets_mem_gen = top_cpuset.mems_generation;
601 653 } else {
602 if (current->cpuset_mems_generation != my_cpusets_mem_gen) { 654 rcu_read_lock();
603 struct cpuset *cs; 655 cs = rcu_dereference(tsk->cpuset);
604 nodemask_t oldmem = current->mems_allowed; 656 my_cpusets_mem_gen = cs->mems_generation;
657 rcu_read_unlock();
658 }
605 659
660 if (my_cpusets_mem_gen != tsk->cpuset_mems_generation) {
606 down(&callback_sem); 661 down(&callback_sem);
607 task_lock(current); 662 task_lock(tsk);
608 cs = current->cpuset; 663 cs = tsk->cpuset; /* Maybe changed when task not locked */
609 guarantee_online_mems(cs, &current->mems_allowed); 664 guarantee_online_mems(cs, &tsk->mems_allowed);
610 current->cpuset_mems_generation = cs->mems_generation; 665 tsk->cpuset_mems_generation = cs->mems_generation;
611 task_unlock(current); 666 task_unlock(tsk);
612 up(&callback_sem); 667 up(&callback_sem);
613 if (!nodes_equal(oldmem, current->mems_allowed)) 668 mpol_rebind_task(tsk, &tsk->mems_allowed);
614 numa_policy_rebind(&oldmem, &current->mems_allowed);
615 } 669 }
616} 670}
617 671
@@ -766,36 +820,150 @@ static int update_cpumask(struct cpuset *cs, char *buf)
766} 820}
767 821
768/* 822/*
823 * Handle user request to change the 'mems' memory placement
824 * of a cpuset. Needs to validate the request, update the
825 * cpusets mems_allowed and mems_generation, and for each
826 * task in the cpuset, rebind any vma mempolicies and if
827 * the cpuset is marked 'memory_migrate', migrate the tasks
828 * pages to the new memory.
829 *
769 * Call with manage_sem held. May take callback_sem during call. 830 * Call with manage_sem held. May take callback_sem during call.
831 * Will take tasklist_lock, scan tasklist for tasks in cpuset cs,
832 * lock each such tasks mm->mmap_sem, scan its vma's and rebind
833 * their mempolicies to the cpusets new mems_allowed.
770 */ 834 */
771 835
772static int update_nodemask(struct cpuset *cs, char *buf) 836static int update_nodemask(struct cpuset *cs, char *buf)
773{ 837{
774 struct cpuset trialcs; 838 struct cpuset trialcs;
839 nodemask_t oldmem;
840 struct task_struct *g, *p;
841 struct mm_struct **mmarray;
842 int i, n, ntasks;
843 int migrate;
844 int fudge;
775 int retval; 845 int retval;
776 846
777 trialcs = *cs; 847 trialcs = *cs;
778 retval = nodelist_parse(buf, trialcs.mems_allowed); 848 retval = nodelist_parse(buf, trialcs.mems_allowed);
779 if (retval < 0) 849 if (retval < 0)
780 return retval; 850 goto done;
781 nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, node_online_map); 851 nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, node_online_map);
782 if (nodes_empty(trialcs.mems_allowed)) 852 oldmem = cs->mems_allowed;
783 return -ENOSPC; 853 if (nodes_equal(oldmem, trialcs.mems_allowed)) {
854 retval = 0; /* Too easy - nothing to do */
855 goto done;
856 }
857 if (nodes_empty(trialcs.mems_allowed)) {
858 retval = -ENOSPC;
859 goto done;
860 }
784 retval = validate_change(cs, &trialcs); 861 retval = validate_change(cs, &trialcs);
785 if (retval == 0) { 862 if (retval < 0)
786 down(&callback_sem); 863 goto done;
787 cs->mems_allowed = trialcs.mems_allowed; 864
788 atomic_inc(&cpuset_mems_generation); 865 down(&callback_sem);
789 cs->mems_generation = atomic_read(&cpuset_mems_generation); 866 cs->mems_allowed = trialcs.mems_allowed;
790 up(&callback_sem); 867 atomic_inc(&cpuset_mems_generation);
868 cs->mems_generation = atomic_read(&cpuset_mems_generation);
869 up(&callback_sem);
870
871 set_cpuset_being_rebound(cs); /* causes mpol_copy() rebind */
872
873 fudge = 10; /* spare mmarray[] slots */
874 fudge += cpus_weight(cs->cpus_allowed); /* imagine one fork-bomb/cpu */
875 retval = -ENOMEM;
876
877 /*
878 * Allocate mmarray[] to hold mm reference for each task
879 * in cpuset cs. Can't kmalloc GFP_KERNEL while holding
880 * tasklist_lock. We could use GFP_ATOMIC, but with a
881 * few more lines of code, we can retry until we get a big
882 * enough mmarray[] w/o using GFP_ATOMIC.
883 */
884 while (1) {
885 ntasks = atomic_read(&cs->count); /* guess */
886 ntasks += fudge;
887 mmarray = kmalloc(ntasks * sizeof(*mmarray), GFP_KERNEL);
888 if (!mmarray)
889 goto done;
890 write_lock_irq(&tasklist_lock); /* block fork */
891 if (atomic_read(&cs->count) <= ntasks)
892 break; /* got enough */
893 write_unlock_irq(&tasklist_lock); /* try again */
894 kfree(mmarray);
791 } 895 }
896
897 n = 0;
898
899 /* Load up mmarray[] with mm reference for each task in cpuset. */
900 do_each_thread(g, p) {
901 struct mm_struct *mm;
902
903 if (n >= ntasks) {
904 printk(KERN_WARNING
905 "Cpuset mempolicy rebind incomplete.\n");
906 continue;
907 }
908 if (p->cpuset != cs)
909 continue;
910 mm = get_task_mm(p);
911 if (!mm)
912 continue;
913 mmarray[n++] = mm;
914 } while_each_thread(g, p);
915 write_unlock_irq(&tasklist_lock);
916
917 /*
918 * Now that we've dropped the tasklist spinlock, we can
919 * rebind the vma mempolicies of each mm in mmarray[] to their
920 * new cpuset, and release that mm. The mpol_rebind_mm()
921 * call takes mmap_sem, which we couldn't take while holding
922 * tasklist_lock. Forks can happen again now - the mpol_copy()
923 * cpuset_being_rebound check will catch such forks, and rebind
924 * their vma mempolicies too. Because we still hold the global
925 * cpuset manage_sem, we know that no other rebind effort will
926 * be contending for the global variable cpuset_being_rebound.
927 * It's ok if we rebind the same mm twice; mpol_rebind_mm()
928 * is idempotent. Also migrate pages in each mm to new nodes.
929 */
930 migrate = is_memory_migrate(cs);
931 for (i = 0; i < n; i++) {
932 struct mm_struct *mm = mmarray[i];
933
934 mpol_rebind_mm(mm, &cs->mems_allowed);
935 if (migrate) {
936 do_migrate_pages(mm, &oldmem, &cs->mems_allowed,
937 MPOL_MF_MOVE_ALL);
938 }
939 mmput(mm);
940 }
941
942 /* We're done rebinding vma's to this cpusets new mems_allowed. */
943 kfree(mmarray);
944 set_cpuset_being_rebound(NULL);
945 retval = 0;
946done:
792 return retval; 947 return retval;
793} 948}
794 949
795/* 950/*
951 * Call with manage_sem held.
952 */
953
954static int update_memory_pressure_enabled(struct cpuset *cs, char *buf)
955{
956 if (simple_strtoul(buf, NULL, 10) != 0)
957 cpuset_memory_pressure_enabled = 1;
958 else
959 cpuset_memory_pressure_enabled = 0;
960 return 0;
961}
962
963/*
796 * update_flag - read a 0 or a 1 in a file and update associated flag 964 * update_flag - read a 0 or a 1 in a file and update associated flag
797 * bit: the bit to update (CS_CPU_EXCLUSIVE, CS_MEM_EXCLUSIVE, 965 * bit: the bit to update (CS_CPU_EXCLUSIVE, CS_MEM_EXCLUSIVE,
798 * CS_NOTIFY_ON_RELEASE) 966 * CS_NOTIFY_ON_RELEASE, CS_MEMORY_MIGRATE)
799 * cs: the cpuset to update 967 * cs: the cpuset to update
800 * buf: the buffer where we read the 0 or 1 968 * buf: the buffer where we read the 0 or 1
801 * 969 *
@@ -834,6 +1002,104 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
834} 1002}
835 1003
836/* 1004/*
1005 * Frequency meter - How fast is some event occuring?
1006 *
1007 * These routines manage a digitally filtered, constant time based,
1008 * event frequency meter. There are four routines:
1009 * fmeter_init() - initialize a frequency meter.
1010 * fmeter_markevent() - called each time the event happens.
1011 * fmeter_getrate() - returns the recent rate of such events.
1012 * fmeter_update() - internal routine used to update fmeter.
1013 *
1014 * A common data structure is passed to each of these routines,
1015 * which is used to keep track of the state required to manage the
1016 * frequency meter and its digital filter.
1017 *
1018 * The filter works on the number of events marked per unit time.
1019 * The filter is single-pole low-pass recursive (IIR). The time unit
1020 * is 1 second. Arithmetic is done using 32-bit integers scaled to
1021 * simulate 3 decimal digits of precision (multiplied by 1000).
1022 *
1023 * With an FM_COEF of 933, and a time base of 1 second, the filter
1024 * has a half-life of 10 seconds, meaning that if the events quit
1025 * happening, then the rate returned from the fmeter_getrate()
1026 * will be cut in half each 10 seconds, until it converges to zero.
1027 *
1028 * It is not worth doing a real infinitely recursive filter. If more
1029 * than FM_MAXTICKS ticks have elapsed since the last filter event,
1030 * just compute FM_MAXTICKS ticks worth, by which point the level
1031 * will be stable.
1032 *
1033 * Limit the count of unprocessed events to FM_MAXCNT, so as to avoid
1034 * arithmetic overflow in the fmeter_update() routine.
1035 *
1036 * Given the simple 32 bit integer arithmetic used, this meter works
1037 * best for reporting rates between one per millisecond (msec) and
1038 * one per 32 (approx) seconds. At constant rates faster than one
1039 * per msec it maxes out at values just under 1,000,000. At constant
1040 * rates between one per msec, and one per second it will stabilize
1041 * to a value N*1000, where N is the rate of events per second.
1042 * At constant rates between one per second and one per 32 seconds,
1043 * it will be choppy, moving up on the seconds that have an event,
1044 * and then decaying until the next event. At rates slower than
1045 * about one in 32 seconds, it decays all the way back to zero between
1046 * each event.
1047 */
1048
1049#define FM_COEF 933 /* coefficient for half-life of 10 secs */
1050#define FM_MAXTICKS ((time_t)99) /* useless computing more ticks than this */
1051#define FM_MAXCNT 1000000 /* limit cnt to avoid overflow */
1052#define FM_SCALE 1000 /* faux fixed point scale */
1053
1054/* Initialize a frequency meter */
1055static void fmeter_init(struct fmeter *fmp)
1056{
1057 fmp->cnt = 0;
1058 fmp->val = 0;
1059 fmp->time = 0;
1060 spin_lock_init(&fmp->lock);
1061}
1062
1063/* Internal meter update - process cnt events and update value */
1064static void fmeter_update(struct fmeter *fmp)
1065{
1066 time_t now = get_seconds();
1067 time_t ticks = now - fmp->time;
1068
1069 if (ticks == 0)
1070 return;
1071
1072 ticks = min(FM_MAXTICKS, ticks);
1073 while (ticks-- > 0)
1074 fmp->val = (FM_COEF * fmp->val) / FM_SCALE;
1075 fmp->time = now;
1076
1077 fmp->val += ((FM_SCALE - FM_COEF) * fmp->cnt) / FM_SCALE;
1078 fmp->cnt = 0;
1079}
1080
1081/* Process any previous ticks, then bump cnt by one (times scale). */
1082static void fmeter_markevent(struct fmeter *fmp)
1083{
1084 spin_lock(&fmp->lock);
1085 fmeter_update(fmp);
1086 fmp->cnt = min(FM_MAXCNT, fmp->cnt + FM_SCALE);
1087 spin_unlock(&fmp->lock);
1088}
1089
1090/* Process any previous ticks, then return current value. */
1091static int fmeter_getrate(struct fmeter *fmp)
1092{
1093 int val;
1094
1095 spin_lock(&fmp->lock);
1096 fmeter_update(fmp);
1097 val = fmp->val;
1098 spin_unlock(&fmp->lock);
1099 return val;
1100}
1101
1102/*
837 * Attack task specified by pid in 'pidbuf' to cpuset 'cs', possibly 1103 * Attack task specified by pid in 'pidbuf' to cpuset 'cs', possibly
838 * writing the path of the old cpuset in 'ppathbuf' if it needs to be 1104 * writing the path of the old cpuset in 'ppathbuf' if it needs to be
839 * notified on release. 1105 * notified on release.
@@ -848,6 +1114,8 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
848 struct task_struct *tsk; 1114 struct task_struct *tsk;
849 struct cpuset *oldcs; 1115 struct cpuset *oldcs;
850 cpumask_t cpus; 1116 cpumask_t cpus;
1117 nodemask_t from, to;
1118 struct mm_struct *mm;
851 1119
852 if (sscanf(pidbuf, "%d", &pid) != 1) 1120 if (sscanf(pidbuf, "%d", &pid) != 1)
853 return -EIO; 1121 return -EIO;
@@ -887,14 +1155,27 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
887 return -ESRCH; 1155 return -ESRCH;
888 } 1156 }
889 atomic_inc(&cs->count); 1157 atomic_inc(&cs->count);
890 tsk->cpuset = cs; 1158 rcu_assign_pointer(tsk->cpuset, cs);
891 task_unlock(tsk); 1159 task_unlock(tsk);
892 1160
893 guarantee_online_cpus(cs, &cpus); 1161 guarantee_online_cpus(cs, &cpus);
894 set_cpus_allowed(tsk, cpus); 1162 set_cpus_allowed(tsk, cpus);
895 1163
1164 from = oldcs->mems_allowed;
1165 to = cs->mems_allowed;
1166
896 up(&callback_sem); 1167 up(&callback_sem);
1168
1169 mm = get_task_mm(tsk);
1170 if (mm) {
1171 mpol_rebind_mm(mm, &to);
1172 mmput(mm);
1173 }
1174
1175 if (is_memory_migrate(cs))
1176 do_migrate_pages(tsk->mm, &from, &to, MPOL_MF_MOVE_ALL);
897 put_task_struct(tsk); 1177 put_task_struct(tsk);
1178 synchronize_rcu();
898 if (atomic_dec_and_test(&oldcs->count)) 1179 if (atomic_dec_and_test(&oldcs->count))
899 check_for_release(oldcs, ppathbuf); 1180 check_for_release(oldcs, ppathbuf);
900 return 0; 1181 return 0;
@@ -905,11 +1186,14 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
905typedef enum { 1186typedef enum {
906 FILE_ROOT, 1187 FILE_ROOT,
907 FILE_DIR, 1188 FILE_DIR,
1189 FILE_MEMORY_MIGRATE,
908 FILE_CPULIST, 1190 FILE_CPULIST,
909 FILE_MEMLIST, 1191 FILE_MEMLIST,
910 FILE_CPU_EXCLUSIVE, 1192 FILE_CPU_EXCLUSIVE,
911 FILE_MEM_EXCLUSIVE, 1193 FILE_MEM_EXCLUSIVE,
912 FILE_NOTIFY_ON_RELEASE, 1194 FILE_NOTIFY_ON_RELEASE,
1195 FILE_MEMORY_PRESSURE_ENABLED,
1196 FILE_MEMORY_PRESSURE,
913 FILE_TASKLIST, 1197 FILE_TASKLIST,
914} cpuset_filetype_t; 1198} cpuset_filetype_t;
915 1199
@@ -960,6 +1244,15 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
960 case FILE_NOTIFY_ON_RELEASE: 1244 case FILE_NOTIFY_ON_RELEASE:
961 retval = update_flag(CS_NOTIFY_ON_RELEASE, cs, buffer); 1245 retval = update_flag(CS_NOTIFY_ON_RELEASE, cs, buffer);
962 break; 1246 break;
1247 case FILE_MEMORY_MIGRATE:
1248 retval = update_flag(CS_MEMORY_MIGRATE, cs, buffer);
1249 break;
1250 case FILE_MEMORY_PRESSURE_ENABLED:
1251 retval = update_memory_pressure_enabled(cs, buffer);
1252 break;
1253 case FILE_MEMORY_PRESSURE:
1254 retval = -EACCES;
1255 break;
963 case FILE_TASKLIST: 1256 case FILE_TASKLIST:
964 retval = attach_task(cs, buffer, &pathbuf); 1257 retval = attach_task(cs, buffer, &pathbuf);
965 break; 1258 break;
@@ -1060,6 +1353,15 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
1060 case FILE_NOTIFY_ON_RELEASE: 1353 case FILE_NOTIFY_ON_RELEASE:
1061 *s++ = notify_on_release(cs) ? '1' : '0'; 1354 *s++ = notify_on_release(cs) ? '1' : '0';
1062 break; 1355 break;
1356 case FILE_MEMORY_MIGRATE:
1357 *s++ = is_memory_migrate(cs) ? '1' : '0';
1358 break;
1359 case FILE_MEMORY_PRESSURE_ENABLED:
1360 *s++ = cpuset_memory_pressure_enabled ? '1' : '0';
1361 break;
1362 case FILE_MEMORY_PRESSURE:
1363 s += sprintf(s, "%d", fmeter_getrate(&cs->fmeter));
1364 break;
1063 default: 1365 default:
1064 retval = -EINVAL; 1366 retval = -EINVAL;
1065 goto out; 1367 goto out;
@@ -1178,7 +1480,7 @@ static int cpuset_create_file(struct dentry *dentry, int mode)
1178 1480
1179/* 1481/*
1180 * cpuset_create_dir - create a directory for an object. 1482 * cpuset_create_dir - create a directory for an object.
1181 * cs: the cpuset we create the directory for. 1483 * cs: the cpuset we create the directory for.
1182 * It must have a valid ->parent field 1484 * It must have a valid ->parent field
1183 * And we are going to fill its ->dentry field. 1485 * And we are going to fill its ->dentry field.
1184 * name: The name to give to the cpuset directory. Will be copied. 1486 * name: The name to give to the cpuset directory. Will be copied.
@@ -1408,6 +1710,21 @@ static struct cftype cft_notify_on_release = {
1408 .private = FILE_NOTIFY_ON_RELEASE, 1710 .private = FILE_NOTIFY_ON_RELEASE,
1409}; 1711};
1410 1712
1713static struct cftype cft_memory_migrate = {
1714 .name = "memory_migrate",
1715 .private = FILE_MEMORY_MIGRATE,
1716};
1717
1718static struct cftype cft_memory_pressure_enabled = {
1719 .name = "memory_pressure_enabled",
1720 .private = FILE_MEMORY_PRESSURE_ENABLED,
1721};
1722
1723static struct cftype cft_memory_pressure = {
1724 .name = "memory_pressure",
1725 .private = FILE_MEMORY_PRESSURE,
1726};
1727
1411static int cpuset_populate_dir(struct dentry *cs_dentry) 1728static int cpuset_populate_dir(struct dentry *cs_dentry)
1412{ 1729{
1413 int err; 1730 int err;
@@ -1422,6 +1739,10 @@ static int cpuset_populate_dir(struct dentry *cs_dentry)
1422 return err; 1739 return err;
1423 if ((err = cpuset_add_file(cs_dentry, &cft_notify_on_release)) < 0) 1740 if ((err = cpuset_add_file(cs_dentry, &cft_notify_on_release)) < 0)
1424 return err; 1741 return err;
1742 if ((err = cpuset_add_file(cs_dentry, &cft_memory_migrate)) < 0)
1743 return err;
1744 if ((err = cpuset_add_file(cs_dentry, &cft_memory_pressure)) < 0)
1745 return err;
1425 if ((err = cpuset_add_file(cs_dentry, &cft_tasks)) < 0) 1746 if ((err = cpuset_add_file(cs_dentry, &cft_tasks)) < 0)
1426 return err; 1747 return err;
1427 return 0; 1748 return 0;
@@ -1446,7 +1767,7 @@ static long cpuset_create(struct cpuset *parent, const char *name, int mode)
1446 return -ENOMEM; 1767 return -ENOMEM;
1447 1768
1448 down(&manage_sem); 1769 down(&manage_sem);
1449 refresh_mems(); 1770 cpuset_update_task_memory_state();
1450 cs->flags = 0; 1771 cs->flags = 0;
1451 if (notify_on_release(parent)) 1772 if (notify_on_release(parent))
1452 set_bit(CS_NOTIFY_ON_RELEASE, &cs->flags); 1773 set_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
@@ -1457,11 +1778,13 @@ static long cpuset_create(struct cpuset *parent, const char *name, int mode)
1457 INIT_LIST_HEAD(&cs->children); 1778 INIT_LIST_HEAD(&cs->children);
1458 atomic_inc(&cpuset_mems_generation); 1779 atomic_inc(&cpuset_mems_generation);
1459 cs->mems_generation = atomic_read(&cpuset_mems_generation); 1780 cs->mems_generation = atomic_read(&cpuset_mems_generation);
1781 fmeter_init(&cs->fmeter);
1460 1782
1461 cs->parent = parent; 1783 cs->parent = parent;
1462 1784
1463 down(&callback_sem); 1785 down(&callback_sem);
1464 list_add(&cs->sibling, &cs->parent->children); 1786 list_add(&cs->sibling, &cs->parent->children);
1787 number_of_cpusets++;
1465 up(&callback_sem); 1788 up(&callback_sem);
1466 1789
1467 err = cpuset_create_dir(cs, name, mode); 1790 err = cpuset_create_dir(cs, name, mode);
@@ -1503,7 +1826,7 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
1503 /* the vfs holds both inode->i_sem already */ 1826 /* the vfs holds both inode->i_sem already */
1504 1827
1505 down(&manage_sem); 1828 down(&manage_sem);
1506 refresh_mems(); 1829 cpuset_update_task_memory_state();
1507 if (atomic_read(&cs->count) > 0) { 1830 if (atomic_read(&cs->count) > 0) {
1508 up(&manage_sem); 1831 up(&manage_sem);
1509 return -EBUSY; 1832 return -EBUSY;
@@ -1524,6 +1847,7 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
1524 spin_unlock(&d->d_lock); 1847 spin_unlock(&d->d_lock);
1525 cpuset_d_remove_dir(d); 1848 cpuset_d_remove_dir(d);
1526 dput(d); 1849 dput(d);
1850 number_of_cpusets--;
1527 up(&callback_sem); 1851 up(&callback_sem);
1528 if (list_empty(&parent->children)) 1852 if (list_empty(&parent->children))
1529 check_for_release(parent, &pathbuf); 1853 check_for_release(parent, &pathbuf);
@@ -1532,6 +1856,21 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
1532 return 0; 1856 return 0;
1533} 1857}
1534 1858
1859/*
1860 * cpuset_init_early - just enough so that the calls to
1861 * cpuset_update_task_memory_state() in early init code
1862 * are harmless.
1863 */
1864
1865int __init cpuset_init_early(void)
1866{
1867 struct task_struct *tsk = current;
1868
1869 tsk->cpuset = &top_cpuset;
1870 tsk->cpuset->mems_generation = atomic_read(&cpuset_mems_generation);
1871 return 0;
1872}
1873
1535/** 1874/**
1536 * cpuset_init - initialize cpusets at system boot 1875 * cpuset_init - initialize cpusets at system boot
1537 * 1876 *
@@ -1546,6 +1885,7 @@ int __init cpuset_init(void)
1546 top_cpuset.cpus_allowed = CPU_MASK_ALL; 1885 top_cpuset.cpus_allowed = CPU_MASK_ALL;
1547 top_cpuset.mems_allowed = NODE_MASK_ALL; 1886 top_cpuset.mems_allowed = NODE_MASK_ALL;
1548 1887
1888 fmeter_init(&top_cpuset.fmeter);
1549 atomic_inc(&cpuset_mems_generation); 1889 atomic_inc(&cpuset_mems_generation);
1550 top_cpuset.mems_generation = atomic_read(&cpuset_mems_generation); 1890 top_cpuset.mems_generation = atomic_read(&cpuset_mems_generation);
1551 1891
@@ -1566,7 +1906,11 @@ int __init cpuset_init(void)
1566 root->d_inode->i_nlink++; 1906 root->d_inode->i_nlink++;
1567 top_cpuset.dentry = root; 1907 top_cpuset.dentry = root;
1568 root->d_inode->i_op = &cpuset_dir_inode_operations; 1908 root->d_inode->i_op = &cpuset_dir_inode_operations;
1909 number_of_cpusets = 1;
1569 err = cpuset_populate_dir(root); 1910 err = cpuset_populate_dir(root);
1911 /* memory_pressure_enabled is in root cpuset only */
1912 if (err == 0)
1913 err = cpuset_add_file(root, &cft_memory_pressure_enabled);
1570out: 1914out:
1571 return err; 1915 return err;
1572} 1916}
@@ -1632,15 +1976,13 @@ void cpuset_fork(struct task_struct *child)
1632 * 1976 *
1633 * We don't need to task_lock() this reference to tsk->cpuset, 1977 * We don't need to task_lock() this reference to tsk->cpuset,
1634 * because tsk is already marked PF_EXITING, so attach_task() won't 1978 * because tsk is already marked PF_EXITING, so attach_task() won't
1635 * mess with it. 1979 * mess with it, or task is a failed fork, never visible to attach_task.
1636 **/ 1980 **/
1637 1981
1638void cpuset_exit(struct task_struct *tsk) 1982void cpuset_exit(struct task_struct *tsk)
1639{ 1983{
1640 struct cpuset *cs; 1984 struct cpuset *cs;
1641 1985
1642 BUG_ON(!(tsk->flags & PF_EXITING));
1643
1644 cs = tsk->cpuset; 1986 cs = tsk->cpuset;
1645 tsk->cpuset = NULL; 1987 tsk->cpuset = NULL;
1646 1988
@@ -1667,14 +2009,14 @@ void cpuset_exit(struct task_struct *tsk)
1667 * tasks cpuset. 2009 * tasks cpuset.
1668 **/ 2010 **/
1669 2011
1670cpumask_t cpuset_cpus_allowed(const struct task_struct *tsk) 2012cpumask_t cpuset_cpus_allowed(struct task_struct *tsk)
1671{ 2013{
1672 cpumask_t mask; 2014 cpumask_t mask;
1673 2015
1674 down(&callback_sem); 2016 down(&callback_sem);
1675 task_lock((struct task_struct *)tsk); 2017 task_lock(tsk);
1676 guarantee_online_cpus(tsk->cpuset, &mask); 2018 guarantee_online_cpus(tsk->cpuset, &mask);
1677 task_unlock((struct task_struct *)tsk); 2019 task_unlock(tsk);
1678 up(&callback_sem); 2020 up(&callback_sem);
1679 2021
1680 return mask; 2022 return mask;
@@ -1686,43 +2028,26 @@ void cpuset_init_current_mems_allowed(void)
1686} 2028}
1687 2029
1688/** 2030/**
1689 * cpuset_update_current_mems_allowed - update mems parameters to new values 2031 * cpuset_mems_allowed - return mems_allowed mask from a tasks cpuset.
1690 * 2032 * @tsk: pointer to task_struct from which to obtain cpuset->mems_allowed.
1691 * If the current tasks cpusets mems_allowed changed behind our backs,
1692 * update current->mems_allowed and mems_generation to the new value.
1693 * Do not call this routine if in_interrupt().
1694 * 2033 *
1695 * Call without callback_sem or task_lock() held. May be called 2034 * Description: Returns the nodemask_t mems_allowed of the cpuset
1696 * with or without manage_sem held. Unless exiting, it will acquire 2035 * attached to the specified @tsk. Guaranteed to return some non-empty
1697 * task_lock(). Also might acquire callback_sem during call to 2036 * subset of node_online_map, even if this means going outside the
1698 * refresh_mems(). 2037 * tasks cpuset.
1699 */ 2038 **/
1700 2039
1701void cpuset_update_current_mems_allowed(void) 2040nodemask_t cpuset_mems_allowed(struct task_struct *tsk)
1702{ 2041{
1703 struct cpuset *cs; 2042 nodemask_t mask;
1704 int need_to_refresh = 0;
1705 2043
1706 task_lock(current); 2044 down(&callback_sem);
1707 cs = current->cpuset; 2045 task_lock(tsk);
1708 if (!cs) 2046 guarantee_online_mems(tsk->cpuset, &mask);
1709 goto done; 2047 task_unlock(tsk);
1710 if (current->cpuset_mems_generation != cs->mems_generation) 2048 up(&callback_sem);
1711 need_to_refresh = 1;
1712done:
1713 task_unlock(current);
1714 if (need_to_refresh)
1715 refresh_mems();
1716}
1717 2049
1718/** 2050 return mask;
1719 * cpuset_restrict_to_mems_allowed - limit nodes to current mems_allowed
1720 * @nodes: pointer to a node bitmap that is and-ed with mems_allowed
1721 */
1722void cpuset_restrict_to_mems_allowed(unsigned long *nodes)
1723{
1724 bitmap_and(nodes, nodes, nodes_addr(current->mems_allowed),
1725 MAX_NUMNODES);
1726} 2051}
1727 2052
1728/** 2053/**
@@ -1795,7 +2120,7 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
1795 * GFP_USER - only nodes in current tasks mems allowed ok. 2120 * GFP_USER - only nodes in current tasks mems allowed ok.
1796 **/ 2121 **/
1797 2122
1798int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask) 2123int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
1799{ 2124{
1800 int node; /* node that zone z is on */ 2125 int node; /* node that zone z is on */
1801 const struct cpuset *cs; /* current cpuset ancestors */ 2126 const struct cpuset *cs; /* current cpuset ancestors */
@@ -1867,6 +2192,42 @@ done:
1867} 2192}
1868 2193
1869/* 2194/*
2195 * Collection of memory_pressure is suppressed unless
2196 * this flag is enabled by writing "1" to the special
2197 * cpuset file 'memory_pressure_enabled' in the root cpuset.
2198 */
2199
2200int cpuset_memory_pressure_enabled __read_mostly;
2201
2202/**
2203 * cpuset_memory_pressure_bump - keep stats of per-cpuset reclaims.
2204 *
2205 * Keep a running average of the rate of synchronous (direct)
2206 * page reclaim efforts initiated by tasks in each cpuset.
2207 *
2208 * This represents the rate at which some task in the cpuset
2209 * ran low on memory on all nodes it was allowed to use, and
2210 * had to enter the kernels page reclaim code in an effort to
2211 * create more free memory by tossing clean pages or swapping
2212 * or writing dirty pages.
2213 *
2214 * Display to user space in the per-cpuset read-only file
2215 * "memory_pressure". Value displayed is an integer
2216 * representing the recent rate of entry into the synchronous
2217 * (direct) page reclaim by any task attached to the cpuset.
2218 **/
2219
2220void __cpuset_memory_pressure_bump(void)
2221{
2222 struct cpuset *cs;
2223
2224 task_lock(current);
2225 cs = current->cpuset;
2226 fmeter_markevent(&cs->fmeter);
2227 task_unlock(current);
2228}
2229
2230/*
1870 * proc_cpuset_show() 2231 * proc_cpuset_show()
1871 * - Print tasks cpuset path into seq_file. 2232 * - Print tasks cpuset path into seq_file.
1872 * - Used for /proc/<pid>/cpuset. 2233 * - Used for /proc/<pid>/cpuset.
diff --git a/kernel/crash_dump.c b/kernel/crash_dump.c
index 334c37f5218a..fccb27dbc623 100644
--- a/kernel/crash_dump.c
+++ b/kernel/crash_dump.c
@@ -14,10 +14,12 @@
14 14
15#include <asm/io.h> 15#include <asm/io.h>
16#include <asm/uaccess.h> 16#include <asm/uaccess.h>
17#include <asm/kexec.h>
17 18
18/* Stores the physical address of elf header of crash image. */ 19/* Stores the physical address of elf header of crash image. */
19unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; 20unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
20 21
22#ifndef HAVE_ARCH_COPY_OLDMEM_PAGE
21/** 23/**
22 * copy_oldmem_page - copy one page from "oldmem" 24 * copy_oldmem_page - copy one page from "oldmem"
23 * @pfn: page frame number to be copied 25 * @pfn: page frame number to be copied
@@ -59,3 +61,4 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
59 kfree(page); 61 kfree(page);
60 return csize; 62 return csize;
61} 63}
64#endif
diff --git a/kernel/exit.c b/kernel/exit.c
index ee515683b92d..caceabf3f230 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -72,7 +72,6 @@ repeat:
72 __ptrace_unlink(p); 72 __ptrace_unlink(p);
73 BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children)); 73 BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
74 __exit_signal(p); 74 __exit_signal(p);
75 __exit_sighand(p);
76 /* 75 /*
77 * Note that the fastpath in sys_times depends on __exit_signal having 76 * Note that the fastpath in sys_times depends on __exit_signal having
78 * updated the counters before a task is removed from the tasklist of 77 * updated the counters before a task is removed from the tasklist of
@@ -258,7 +257,7 @@ static inline void reparent_to_init(void)
258 257
259void __set_special_pids(pid_t session, pid_t pgrp) 258void __set_special_pids(pid_t session, pid_t pgrp)
260{ 259{
261 struct task_struct *curr = current; 260 struct task_struct *curr = current->group_leader;
262 261
263 if (curr->signal->session != session) { 262 if (curr->signal->session != session) {
264 detach_pid(curr, PIDTYPE_SID); 263 detach_pid(curr, PIDTYPE_SID);
@@ -926,7 +925,6 @@ do_group_exit(int exit_code)
926 /* Another thread got here before we took the lock. */ 925 /* Another thread got here before we took the lock. */
927 exit_code = sig->group_exit_code; 926 exit_code = sig->group_exit_code;
928 else { 927 else {
929 sig->flags = SIGNAL_GROUP_EXIT;
930 sig->group_exit_code = exit_code; 928 sig->group_exit_code = exit_code;
931 zap_other_threads(current); 929 zap_other_threads(current);
932 } 930 }
diff --git a/kernel/fork.c b/kernel/fork.c
index fb8572a42297..72e3252c6763 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -743,6 +743,14 @@ int unshare_files(void)
743 743
744EXPORT_SYMBOL(unshare_files); 744EXPORT_SYMBOL(unshare_files);
745 745
746void sighand_free_cb(struct rcu_head *rhp)
747{
748 struct sighand_struct *sp;
749
750 sp = container_of(rhp, struct sighand_struct, rcu);
751 kmem_cache_free(sighand_cachep, sp);
752}
753
746static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk) 754static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk)
747{ 755{
748 struct sighand_struct *sig; 756 struct sighand_struct *sig;
@@ -752,7 +760,7 @@ static inline int copy_sighand(unsigned long clone_flags, struct task_struct * t
752 return 0; 760 return 0;
753 } 761 }
754 sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL); 762 sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL);
755 tsk->sighand = sig; 763 rcu_assign_pointer(tsk->sighand, sig);
756 if (!sig) 764 if (!sig)
757 return -ENOMEM; 765 return -ENOMEM;
758 spin_lock_init(&sig->siglock); 766 spin_lock_init(&sig->siglock);
@@ -803,9 +811,6 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
803 sig->it_prof_expires = cputime_zero; 811 sig->it_prof_expires = cputime_zero;
804 sig->it_prof_incr = cputime_zero; 812 sig->it_prof_incr = cputime_zero;
805 813
806 sig->tty = current->signal->tty;
807 sig->pgrp = process_group(current);
808 sig->session = current->signal->session;
809 sig->leader = 0; /* session leadership doesn't inherit */ 814 sig->leader = 0; /* session leadership doesn't inherit */
810 sig->tty_old_pgrp = 0; 815 sig->tty_old_pgrp = 0;
811 816
@@ -964,12 +969,13 @@ static task_t *copy_process(unsigned long clone_flags,
964 p->io_context = NULL; 969 p->io_context = NULL;
965 p->io_wait = NULL; 970 p->io_wait = NULL;
966 p->audit_context = NULL; 971 p->audit_context = NULL;
972 cpuset_fork(p);
967#ifdef CONFIG_NUMA 973#ifdef CONFIG_NUMA
968 p->mempolicy = mpol_copy(p->mempolicy); 974 p->mempolicy = mpol_copy(p->mempolicy);
969 if (IS_ERR(p->mempolicy)) { 975 if (IS_ERR(p->mempolicy)) {
970 retval = PTR_ERR(p->mempolicy); 976 retval = PTR_ERR(p->mempolicy);
971 p->mempolicy = NULL; 977 p->mempolicy = NULL;
972 goto bad_fork_cleanup; 978 goto bad_fork_cleanup_cpuset;
973 } 979 }
974#endif 980#endif
975 981
@@ -1127,25 +1133,19 @@ static task_t *copy_process(unsigned long clone_flags,
1127 attach_pid(p, PIDTYPE_PID, p->pid); 1133 attach_pid(p, PIDTYPE_PID, p->pid);
1128 attach_pid(p, PIDTYPE_TGID, p->tgid); 1134 attach_pid(p, PIDTYPE_TGID, p->tgid);
1129 if (thread_group_leader(p)) { 1135 if (thread_group_leader(p)) {
1136 p->signal->tty = current->signal->tty;
1137 p->signal->pgrp = process_group(current);
1138 p->signal->session = current->signal->session;
1130 attach_pid(p, PIDTYPE_PGID, process_group(p)); 1139 attach_pid(p, PIDTYPE_PGID, process_group(p));
1131 attach_pid(p, PIDTYPE_SID, p->signal->session); 1140 attach_pid(p, PIDTYPE_SID, p->signal->session);
1132 if (p->pid) 1141 if (p->pid)
1133 __get_cpu_var(process_counts)++; 1142 __get_cpu_var(process_counts)++;
1134 } 1143 }
1135 1144
1136 if (!current->signal->tty && p->signal->tty)
1137 p->signal->tty = NULL;
1138
1139 nr_threads++; 1145 nr_threads++;
1140 total_forks++; 1146 total_forks++;
1141 write_unlock_irq(&tasklist_lock); 1147 write_unlock_irq(&tasklist_lock);
1142 proc_fork_connector(p); 1148 proc_fork_connector(p);
1143 cpuset_fork(p);
1144 retval = 0;
1145
1146fork_out:
1147 if (retval)
1148 return ERR_PTR(retval);
1149 return p; 1149 return p;
1150 1150
1151bad_fork_cleanup_namespace: 1151bad_fork_cleanup_namespace:
@@ -1172,7 +1172,9 @@ bad_fork_cleanup_security:
1172bad_fork_cleanup_policy: 1172bad_fork_cleanup_policy:
1173#ifdef CONFIG_NUMA 1173#ifdef CONFIG_NUMA
1174 mpol_free(p->mempolicy); 1174 mpol_free(p->mempolicy);
1175bad_fork_cleanup_cpuset:
1175#endif 1176#endif
1177 cpuset_exit(p);
1176bad_fork_cleanup: 1178bad_fork_cleanup:
1177 if (p->binfmt) 1179 if (p->binfmt)
1178 module_put(p->binfmt->module); 1180 module_put(p->binfmt->module);
@@ -1184,7 +1186,8 @@ bad_fork_cleanup_count:
1184 free_uid(p->user); 1186 free_uid(p->user);
1185bad_fork_free: 1187bad_fork_free:
1186 free_task(p); 1188 free_task(p);
1187 goto fork_out; 1189fork_out:
1190 return ERR_PTR(retval);
1188} 1191}
1189 1192
1190struct pt_regs * __devinit __attribute__((weak)) idle_regs(struct pt_regs *regs) 1193struct pt_regs * __devinit __attribute__((weak)) idle_regs(struct pt_regs *regs)
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 8a64a4844cde..d03b5eef8ce0 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -10,6 +10,8 @@
10#include <linux/proc_fs.h> 10#include <linux/proc_fs.h>
11#include <linux/interrupt.h> 11#include <linux/interrupt.h>
12 12
13#include "internals.h"
14
13static struct proc_dir_entry *root_irq_dir, *irq_dir[NR_IRQS]; 15static struct proc_dir_entry *root_irq_dir, *irq_dir[NR_IRQS];
14 16
15#ifdef CONFIG_SMP 17#ifdef CONFIG_SMP
diff --git a/kernel/module.c b/kernel/module.c
index 4b06bbad49c2..e4276046a1b6 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -496,15 +496,15 @@ static void module_unload_free(struct module *mod)
496} 496}
497 497
498#ifdef CONFIG_MODULE_FORCE_UNLOAD 498#ifdef CONFIG_MODULE_FORCE_UNLOAD
499static inline int try_force(unsigned int flags) 499static inline int try_force_unload(unsigned int flags)
500{ 500{
501 int ret = (flags & O_TRUNC); 501 int ret = (flags & O_TRUNC);
502 if (ret) 502 if (ret)
503 add_taint(TAINT_FORCED_MODULE); 503 add_taint(TAINT_FORCED_RMMOD);
504 return ret; 504 return ret;
505} 505}
506#else 506#else
507static inline int try_force(unsigned int flags) 507static inline int try_force_unload(unsigned int flags)
508{ 508{
509 return 0; 509 return 0;
510} 510}
@@ -524,7 +524,7 @@ static int __try_stop_module(void *_sref)
524 524
525 /* If it's not unused, quit unless we are told to block. */ 525 /* If it's not unused, quit unless we are told to block. */
526 if ((sref->flags & O_NONBLOCK) && module_refcount(sref->mod) != 0) { 526 if ((sref->flags & O_NONBLOCK) && module_refcount(sref->mod) != 0) {
527 if (!(*sref->forced = try_force(sref->flags))) 527 if (!(*sref->forced = try_force_unload(sref->flags)))
528 return -EWOULDBLOCK; 528 return -EWOULDBLOCK;
529 } 529 }
530 530
@@ -609,7 +609,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
609 /* If it has an init func, it must have an exit func to unload */ 609 /* If it has an init func, it must have an exit func to unload */
610 if ((mod->init != NULL && mod->exit == NULL) 610 if ((mod->init != NULL && mod->exit == NULL)
611 || mod->unsafe) { 611 || mod->unsafe) {
612 forced = try_force(flags); 612 forced = try_force_unload(flags);
613 if (!forced) { 613 if (!forced) {
614 /* This module can't be removed */ 614 /* This module can't be removed */
615 ret = -EBUSY; 615 ret = -EBUSY;
@@ -958,7 +958,6 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
958 unsigned long ret; 958 unsigned long ret;
959 const unsigned long *crc; 959 const unsigned long *crc;
960 960
961 spin_lock_irq(&modlist_lock);
962 ret = __find_symbol(name, &owner, &crc, mod->license_gplok); 961 ret = __find_symbol(name, &owner, &crc, mod->license_gplok);
963 if (ret) { 962 if (ret) {
964 /* use_module can fail due to OOM, or module unloading */ 963 /* use_module can fail due to OOM, or module unloading */
@@ -966,7 +965,6 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
966 !use_module(mod, owner)) 965 !use_module(mod, owner))
967 ret = 0; 966 ret = 0;
968 } 967 }
969 spin_unlock_irq(&modlist_lock);
970 return ret; 968 return ret;
971} 969}
972 970
@@ -1204,6 +1202,39 @@ void *__symbol_get(const char *symbol)
1204} 1202}
1205EXPORT_SYMBOL_GPL(__symbol_get); 1203EXPORT_SYMBOL_GPL(__symbol_get);
1206 1204
1205/*
1206 * Ensure that an exported symbol [global namespace] does not already exist
1207 * in the Kernel or in some other modules exported symbol table.
1208 */
1209static int verify_export_symbols(struct module *mod)
1210{
1211 const char *name = NULL;
1212 unsigned long i, ret = 0;
1213 struct module *owner;
1214 const unsigned long *crc;
1215
1216 for (i = 0; i < mod->num_syms; i++)
1217 if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) {
1218 name = mod->syms[i].name;
1219 ret = -ENOEXEC;
1220 goto dup;
1221 }
1222
1223 for (i = 0; i < mod->num_gpl_syms; i++)
1224 if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) {
1225 name = mod->gpl_syms[i].name;
1226 ret = -ENOEXEC;
1227 goto dup;
1228 }
1229
1230dup:
1231 if (ret)
1232 printk(KERN_ERR "%s: exports duplicate symbol %s (owned by %s)\n",
1233 mod->name, name, module_name(owner));
1234
1235 return ret;
1236}
1237
1207/* Change all symbols so that sh_value encodes the pointer directly. */ 1238/* Change all symbols so that sh_value encodes the pointer directly. */
1208static int simplify_symbols(Elf_Shdr *sechdrs, 1239static int simplify_symbols(Elf_Shdr *sechdrs,
1209 unsigned int symindex, 1240 unsigned int symindex,
@@ -1715,6 +1746,11 @@ static struct module *load_module(void __user *umod,
1715 /* Set up license info based on the info section */ 1746 /* Set up license info based on the info section */
1716 set_license(mod, get_modinfo(sechdrs, infoindex, "license")); 1747 set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
1717 1748
1749 if (strcmp(mod->name, "ndiswrapper") == 0)
1750 add_taint(TAINT_PROPRIETARY_MODULE);
1751 if (strcmp(mod->name, "driverloader") == 0)
1752 add_taint(TAINT_PROPRIETARY_MODULE);
1753
1718#ifdef CONFIG_MODULE_UNLOAD 1754#ifdef CONFIG_MODULE_UNLOAD
1719 /* Set up MODINFO_ATTR fields */ 1755 /* Set up MODINFO_ATTR fields */
1720 setup_modinfo(mod, sechdrs, infoindex); 1756 setup_modinfo(mod, sechdrs, infoindex);
@@ -1767,6 +1803,12 @@ static struct module *load_module(void __user *umod,
1767 goto cleanup; 1803 goto cleanup;
1768 } 1804 }
1769 1805
1806 /* Find duplicate symbols */
1807 err = verify_export_symbols(mod);
1808
1809 if (err < 0)
1810 goto cleanup;
1811
1770 /* Set up and sort exception table */ 1812 /* Set up and sort exception table */
1771 mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable); 1813 mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
1772 mod->extable = extable = (void *)sechdrs[exindex].sh_addr; 1814 mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
diff --git a/kernel/pid.c b/kernel/pid.c
index edba31c681ac..1acc07246991 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -136,7 +136,7 @@ struct pid * fastcall find_pid(enum pid_type type, int nr)
136 struct hlist_node *elem; 136 struct hlist_node *elem;
137 struct pid *pid; 137 struct pid *pid;
138 138
139 hlist_for_each_entry(pid, elem, 139 hlist_for_each_entry_rcu(pid, elem,
140 &pid_hash[type][pid_hashfn(nr)], pid_chain) { 140 &pid_hash[type][pid_hashfn(nr)], pid_chain) {
141 if (pid->nr == nr) 141 if (pid->nr == nr)
142 return pid; 142 return pid;
@@ -150,15 +150,15 @@ int fastcall attach_pid(task_t *task, enum pid_type type, int nr)
150 150
151 task_pid = &task->pids[type]; 151 task_pid = &task->pids[type];
152 pid = find_pid(type, nr); 152 pid = find_pid(type, nr);
153 task_pid->nr = nr;
153 if (pid == NULL) { 154 if (pid == NULL) {
154 hlist_add_head(&task_pid->pid_chain,
155 &pid_hash[type][pid_hashfn(nr)]);
156 INIT_LIST_HEAD(&task_pid->pid_list); 155 INIT_LIST_HEAD(&task_pid->pid_list);
156 hlist_add_head_rcu(&task_pid->pid_chain,
157 &pid_hash[type][pid_hashfn(nr)]);
157 } else { 158 } else {
158 INIT_HLIST_NODE(&task_pid->pid_chain); 159 INIT_HLIST_NODE(&task_pid->pid_chain);
159 list_add_tail(&task_pid->pid_list, &pid->pid_list); 160 list_add_tail_rcu(&task_pid->pid_list, &pid->pid_list);
160 } 161 }
161 task_pid->nr = nr;
162 162
163 return 0; 163 return 0;
164} 164}
@@ -170,20 +170,20 @@ static fastcall int __detach_pid(task_t *task, enum pid_type type)
170 170
171 pid = &task->pids[type]; 171 pid = &task->pids[type];
172 if (!hlist_unhashed(&pid->pid_chain)) { 172 if (!hlist_unhashed(&pid->pid_chain)) {
173 hlist_del(&pid->pid_chain);
174 173
175 if (list_empty(&pid->pid_list)) 174 if (list_empty(&pid->pid_list)) {
176 nr = pid->nr; 175 nr = pid->nr;
177 else { 176 hlist_del_rcu(&pid->pid_chain);
177 } else {
178 pid_next = list_entry(pid->pid_list.next, 178 pid_next = list_entry(pid->pid_list.next,
179 struct pid, pid_list); 179 struct pid, pid_list);
180 /* insert next pid from pid_list to hash */ 180 /* insert next pid from pid_list to hash */
181 hlist_add_head(&pid_next->pid_chain, 181 hlist_replace_rcu(&pid->pid_chain,
182 &pid_hash[type][pid_hashfn(pid_next->nr)]); 182 &pid_next->pid_chain);
183 } 183 }
184 } 184 }
185 185
186 list_del(&pid->pid_list); 186 list_del_rcu(&pid->pid_list);
187 pid->nr = 0; 187 pid->nr = 0;
188 188
189 return nr; 189 return nr;
diff --git a/kernel/printk.c b/kernel/printk.c
index 5287be83e3e7..2251be80cd22 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -569,7 +569,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
569 p[1] <= '7' && p[2] == '>') { 569 p[1] <= '7' && p[2] == '>') {
570 loglev_char = p[1]; 570 loglev_char = p[1];
571 p += 3; 571 p += 3;
572 printed_len += 3; 572 printed_len -= 3;
573 } else { 573 } else {
574 loglev_char = default_message_loglevel 574 loglev_char = default_message_loglevel
575 + '0'; 575 + '0';
@@ -584,7 +584,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
584 584
585 for (tp = tbuf; tp < tbuf + tlen; tp++) 585 for (tp = tbuf; tp < tbuf + tlen; tp++)
586 emit_log_char(*tp); 586 emit_log_char(*tp);
587 printed_len += tlen - 3; 587 printed_len += tlen;
588 } else { 588 } else {
589 if (p[0] != '<' || p[1] < '0' || 589 if (p[0] != '<' || p[1] < '0' ||
590 p[1] > '7' || p[2] != '>') { 590 p[1] > '7' || p[2] != '>') {
@@ -592,8 +592,8 @@ asmlinkage int vprintk(const char *fmt, va_list args)
592 emit_log_char(default_message_loglevel 592 emit_log_char(default_message_loglevel
593 + '0'); 593 + '0');
594 emit_log_char('>'); 594 emit_log_char('>');
595 printed_len += 3;
595 } 596 }
596 printed_len += 3;
597 } 597 }
598 log_level_unknown = 0; 598 log_level_unknown = 0;
599 if (!*p) 599 if (!*p)
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 656476eedb1b..cceaf09ac413 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -408,54 +408,62 @@ int ptrace_request(struct task_struct *child, long request,
408 return ret; 408 return ret;
409} 409}
410 410
411#ifndef __ARCH_SYS_PTRACE 411/**
412static int ptrace_get_task_struct(long request, long pid, 412 * ptrace_traceme -- helper for PTRACE_TRACEME
413 struct task_struct **childp) 413 *
414 * Performs checks and sets PT_PTRACED.
415 * Should be used by all ptrace implementations for PTRACE_TRACEME.
416 */
417int ptrace_traceme(void)
414{ 418{
415 struct task_struct *child;
416 int ret; 419 int ret;
417 420
418 /* 421 /*
419 * Callers use child == NULL as an indication to exit early even 422 * Are we already being traced?
420 * when the return value is 0, so make sure it is non-NULL here. 423 */
424 if (current->ptrace & PT_PTRACED)
425 return -EPERM;
426 ret = security_ptrace(current->parent, current);
427 if (ret)
428 return -EPERM;
429 /*
430 * Set the ptrace bit in the process ptrace flags.
421 */ 431 */
422 *childp = NULL; 432 current->ptrace |= PT_PTRACED;
433 return 0;
434}
423 435
424 if (request == PTRACE_TRACEME) { 436/**
425 /* 437 * ptrace_get_task_struct -- grab a task struct reference for ptrace
426 * Are we already being traced? 438 * @pid: process id to grab a task_struct reference of
427 */ 439 *
428 if (current->ptrace & PT_PTRACED) 440 * This function is a helper for ptrace implementations. It checks
429 return -EPERM; 441 * permissions and then grabs a task struct for use of the actual
430 ret = security_ptrace(current->parent, current); 442 * ptrace implementation.
431 if (ret) 443 *
432 return -EPERM; 444 * Returns the task_struct for @pid or an ERR_PTR() on failure.
433 /* 445 */
434 * Set the ptrace bit in the process ptrace flags. 446struct task_struct *ptrace_get_task_struct(pid_t pid)
435 */ 447{
436 current->ptrace |= PT_PTRACED; 448 struct task_struct *child;
437 return 0;
438 }
439 449
440 /* 450 /*
441 * You may not mess with init 451 * Tracing init is not allowed.
442 */ 452 */
443 if (pid == 1) 453 if (pid == 1)
444 return -EPERM; 454 return ERR_PTR(-EPERM);
445 455
446 ret = -ESRCH;
447 read_lock(&tasklist_lock); 456 read_lock(&tasklist_lock);
448 child = find_task_by_pid(pid); 457 child = find_task_by_pid(pid);
449 if (child) 458 if (child)
450 get_task_struct(child); 459 get_task_struct(child);
451 read_unlock(&tasklist_lock); 460 read_unlock(&tasklist_lock);
452 if (!child) 461 if (!child)
453 return -ESRCH; 462 return ERR_PTR(-ESRCH);
454 463 return child;
455 *childp = child;
456 return 0;
457} 464}
458 465
466#ifndef __ARCH_SYS_PTRACE
459asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 467asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
460{ 468{
461 struct task_struct *child; 469 struct task_struct *child;
@@ -465,9 +473,16 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
465 * This lock_kernel fixes a subtle race with suid exec 473 * This lock_kernel fixes a subtle race with suid exec
466 */ 474 */
467 lock_kernel(); 475 lock_kernel();
468 ret = ptrace_get_task_struct(request, pid, &child); 476 if (request == PTRACE_TRACEME) {
469 if (!child) 477 ret = ptrace_traceme();
470 goto out; 478 goto out;
479 }
480
481 child = ptrace_get_task_struct(pid);
482 if (IS_ERR(child)) {
483 ret = PTR_ERR(child);
484 goto out;
485 }
471 486
472 if (request == PTRACE_ATTACH) { 487 if (request == PTRACE_ATTACH) {
473 ret = ptrace_attach(child); 488 ret = ptrace_attach(child);
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 48d3bce465b8..ccc45d49ce71 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -35,6 +35,7 @@
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/spinlock.h> 36#include <linux/spinlock.h>
37#include <linux/smp.h> 37#include <linux/smp.h>
38#include <linux/rcupdate.h>
38#include <linux/interrupt.h> 39#include <linux/interrupt.h>
39#include <linux/sched.h> 40#include <linux/sched.h>
40#include <asm/atomic.h> 41#include <asm/atomic.h>
@@ -45,7 +46,6 @@
45#include <linux/percpu.h> 46#include <linux/percpu.h>
46#include <linux/notifier.h> 47#include <linux/notifier.h>
47#include <linux/rcupdate.h> 48#include <linux/rcupdate.h>
48#include <linux/rcuref.h>
49#include <linux/cpu.h> 49#include <linux/cpu.h>
50 50
51/* Definition for rcupdate control block. */ 51/* Definition for rcupdate control block. */
@@ -61,9 +61,9 @@ struct rcu_state {
61 /* for current batch to proceed. */ 61 /* for current batch to proceed. */
62}; 62};
63 63
64static struct rcu_state rcu_state ____cacheline_maxaligned_in_smp = 64static struct rcu_state rcu_state ____cacheline_internodealigned_in_smp =
65 {.lock = SPIN_LOCK_UNLOCKED, .cpumask = CPU_MASK_NONE }; 65 {.lock = SPIN_LOCK_UNLOCKED, .cpumask = CPU_MASK_NONE };
66static struct rcu_state rcu_bh_state ____cacheline_maxaligned_in_smp = 66static struct rcu_state rcu_bh_state ____cacheline_internodealigned_in_smp =
67 {.lock = SPIN_LOCK_UNLOCKED, .cpumask = CPU_MASK_NONE }; 67 {.lock = SPIN_LOCK_UNLOCKED, .cpumask = CPU_MASK_NONE };
68 68
69DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; 69DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };
@@ -73,19 +73,6 @@ DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
73static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL}; 73static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
74static int maxbatch = 10000; 74static int maxbatch = 10000;
75 75
76#ifndef __HAVE_ARCH_CMPXCHG
77/*
78 * We use an array of spinlocks for the rcurefs -- similar to ones in sparc
79 * 32 bit atomic_t implementations, and a hash function similar to that
80 * for our refcounting needs.
81 * Can't help multiprocessors which donot have cmpxchg :(
82 */
83
84spinlock_t __rcuref_hash[RCUREF_HASH_SIZE] = {
85 [0 ... (RCUREF_HASH_SIZE-1)] = SPIN_LOCK_UNLOCKED
86};
87#endif
88
89/** 76/**
90 * call_rcu - Queue an RCU callback for invocation after a grace period. 77 * call_rcu - Queue an RCU callback for invocation after a grace period.
91 * @head: structure to be used for queueing the RCU updates. 78 * @head: structure to be used for queueing the RCU updates.
@@ -442,6 +429,36 @@ static void rcu_process_callbacks(unsigned long unused)
442 &__get_cpu_var(rcu_bh_data)); 429 &__get_cpu_var(rcu_bh_data));
443} 430}
444 431
432static int __rcu_pending(struct rcu_ctrlblk *rcp, struct rcu_data *rdp)
433{
434 /* This cpu has pending rcu entries and the grace period
435 * for them has completed.
436 */
437 if (rdp->curlist && !rcu_batch_before(rcp->completed, rdp->batch))
438 return 1;
439
440 /* This cpu has no pending entries, but there are new entries */
441 if (!rdp->curlist && rdp->nxtlist)
442 return 1;
443
444 /* This cpu has finished callbacks to invoke */
445 if (rdp->donelist)
446 return 1;
447
448 /* The rcu core waits for a quiescent state from the cpu */
449 if (rdp->quiescbatch != rcp->cur || rdp->qs_pending)
450 return 1;
451
452 /* nothing to do */
453 return 0;
454}
455
456int rcu_pending(int cpu)
457{
458 return __rcu_pending(&rcu_ctrlblk, &per_cpu(rcu_data, cpu)) ||
459 __rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu));
460}
461
445void rcu_check_callbacks(int cpu, int user) 462void rcu_check_callbacks(int cpu, int user)
446{ 463{
447 if (user || 464 if (user ||
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 49fbbeff201c..773219907dd8 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -39,7 +39,6 @@
39#include <linux/moduleparam.h> 39#include <linux/moduleparam.h>
40#include <linux/percpu.h> 40#include <linux/percpu.h>
41#include <linux/notifier.h> 41#include <linux/notifier.h>
42#include <linux/rcuref.h>
43#include <linux/cpu.h> 42#include <linux/cpu.h>
44#include <linux/random.h> 43#include <linux/random.h>
45#include <linux/delay.h> 44#include <linux/delay.h>
@@ -49,9 +48,11 @@
49MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
50 49
51static int nreaders = -1; /* # reader threads, defaults to 4*ncpus */ 50static int nreaders = -1; /* # reader threads, defaults to 4*ncpus */
52static int stat_interval = 0; /* Interval between stats, in seconds. */ 51static int stat_interval; /* Interval between stats, in seconds. */
53 /* Defaults to "only at end of test". */ 52 /* Defaults to "only at end of test". */
54static int verbose = 0; /* Print more debug info. */ 53static int verbose; /* Print more debug info. */
54static int test_no_idle_hz; /* Test RCU's support for tickless idle CPUs. */
55static int shuffle_interval = 5; /* Interval between shuffles (in sec)*/
55 56
56MODULE_PARM(nreaders, "i"); 57MODULE_PARM(nreaders, "i");
57MODULE_PARM_DESC(nreaders, "Number of RCU reader threads"); 58MODULE_PARM_DESC(nreaders, "Number of RCU reader threads");
@@ -59,6 +60,10 @@ MODULE_PARM(stat_interval, "i");
59MODULE_PARM_DESC(stat_interval, "Number of seconds between stats printk()s"); 60MODULE_PARM_DESC(stat_interval, "Number of seconds between stats printk()s");
60MODULE_PARM(verbose, "i"); 61MODULE_PARM(verbose, "i");
61MODULE_PARM_DESC(verbose, "Enable verbose debugging printk()s"); 62MODULE_PARM_DESC(verbose, "Enable verbose debugging printk()s");
63MODULE_PARM(test_no_idle_hz, "i");
64MODULE_PARM_DESC(test_no_idle_hz, "Test support for tickless idle CPUs");
65MODULE_PARM(shuffle_interval, "i");
66MODULE_PARM_DESC(shuffle_interval, "Number of seconds between shuffles");
62#define TORTURE_FLAG "rcutorture: " 67#define TORTURE_FLAG "rcutorture: "
63#define PRINTK_STRING(s) \ 68#define PRINTK_STRING(s) \
64 do { printk(KERN_ALERT TORTURE_FLAG s "\n"); } while (0) 69 do { printk(KERN_ALERT TORTURE_FLAG s "\n"); } while (0)
@@ -73,6 +78,7 @@ static int nrealreaders;
73static struct task_struct *writer_task; 78static struct task_struct *writer_task;
74static struct task_struct **reader_tasks; 79static struct task_struct **reader_tasks;
75static struct task_struct *stats_task; 80static struct task_struct *stats_task;
81static struct task_struct *shuffler_task;
76 82
77#define RCU_TORTURE_PIPE_LEN 10 83#define RCU_TORTURE_PIPE_LEN 10
78 84
@@ -103,7 +109,7 @@ atomic_t n_rcu_torture_error;
103/* 109/*
104 * Allocate an element from the rcu_tortures pool. 110 * Allocate an element from the rcu_tortures pool.
105 */ 111 */
106struct rcu_torture * 112static struct rcu_torture *
107rcu_torture_alloc(void) 113rcu_torture_alloc(void)
108{ 114{
109 struct list_head *p; 115 struct list_head *p;
@@ -376,12 +382,77 @@ rcu_torture_stats(void *arg)
376 return 0; 382 return 0;
377} 383}
378 384
385static int rcu_idle_cpu; /* Force all torture tasks off this CPU */
386
387/* Shuffle tasks such that we allow @rcu_idle_cpu to become idle. A special case
388 * is when @rcu_idle_cpu = -1, when we allow the tasks to run on all CPUs.
389 */
390void rcu_torture_shuffle_tasks(void)
391{
392 cpumask_t tmp_mask = CPU_MASK_ALL;
393 int i;
394
395 lock_cpu_hotplug();
396
397 /* No point in shuffling if there is only one online CPU (ex: UP) */
398 if (num_online_cpus() == 1) {
399 unlock_cpu_hotplug();
400 return;
401 }
402
403 if (rcu_idle_cpu != -1)
404 cpu_clear(rcu_idle_cpu, tmp_mask);
405
406 set_cpus_allowed(current, tmp_mask);
407
408 if (reader_tasks != NULL) {
409 for (i = 0; i < nrealreaders; i++)
410 if (reader_tasks[i])
411 set_cpus_allowed(reader_tasks[i], tmp_mask);
412 }
413
414 if (writer_task)
415 set_cpus_allowed(writer_task, tmp_mask);
416
417 if (stats_task)
418 set_cpus_allowed(stats_task, tmp_mask);
419
420 if (rcu_idle_cpu == -1)
421 rcu_idle_cpu = num_online_cpus() - 1;
422 else
423 rcu_idle_cpu--;
424
425 unlock_cpu_hotplug();
426}
427
428/* Shuffle tasks across CPUs, with the intent of allowing each CPU in the
429 * system to become idle at a time and cut off its timer ticks. This is meant
430 * to test the support for such tickless idle CPU in RCU.
431 */
432static int
433rcu_torture_shuffle(void *arg)
434{
435 VERBOSE_PRINTK_STRING("rcu_torture_shuffle task started");
436 do {
437 schedule_timeout_interruptible(shuffle_interval * HZ);
438 rcu_torture_shuffle_tasks();
439 } while (!kthread_should_stop());
440 VERBOSE_PRINTK_STRING("rcu_torture_shuffle task stopping");
441 return 0;
442}
443
379static void 444static void
380rcu_torture_cleanup(void) 445rcu_torture_cleanup(void)
381{ 446{
382 int i; 447 int i;
383 448
384 fullstop = 1; 449 fullstop = 1;
450 if (shuffler_task != NULL) {
451 VERBOSE_PRINTK_STRING("Stopping rcu_torture_shuffle task");
452 kthread_stop(shuffler_task);
453 }
454 shuffler_task = NULL;
455
385 if (writer_task != NULL) { 456 if (writer_task != NULL) {
386 VERBOSE_PRINTK_STRING("Stopping rcu_torture_writer task"); 457 VERBOSE_PRINTK_STRING("Stopping rcu_torture_writer task");
387 kthread_stop(writer_task); 458 kthread_stop(writer_task);
@@ -430,9 +501,11 @@ rcu_torture_init(void)
430 nrealreaders = nreaders; 501 nrealreaders = nreaders;
431 else 502 else
432 nrealreaders = 2 * num_online_cpus(); 503 nrealreaders = 2 * num_online_cpus();
433 printk(KERN_ALERT TORTURE_FLAG 504 printk(KERN_ALERT TORTURE_FLAG "--- Start of test: nreaders=%d "
434 "--- Start of test: nreaders=%d stat_interval=%d verbose=%d\n", 505 "stat_interval=%d verbose=%d test_no_idle_hz=%d "
435 nrealreaders, stat_interval, verbose); 506 "shuffle_interval = %d\n",
507 nrealreaders, stat_interval, verbose, test_no_idle_hz,
508 shuffle_interval);
436 fullstop = 0; 509 fullstop = 0;
437 510
438 /* Set up the freelist. */ 511 /* Set up the freelist. */
@@ -502,6 +575,18 @@ rcu_torture_init(void)
502 goto unwind; 575 goto unwind;
503 } 576 }
504 } 577 }
578 if (test_no_idle_hz) {
579 rcu_idle_cpu = num_online_cpus() - 1;
580 /* Create the shuffler thread */
581 shuffler_task = kthread_run(rcu_torture_shuffle, NULL,
582 "rcu_torture_shuffle");
583 if (IS_ERR(shuffler_task)) {
584 firsterr = PTR_ERR(shuffler_task);
585 VERBOSE_PRINTK_ERRSTRING("Failed to create shuffler");
586 shuffler_task = NULL;
587 goto unwind;
588 }
589 }
505 return 0; 590 return 0;
506 591
507unwind: 592unwind:
diff --git a/kernel/sched.c b/kernel/sched.c
index 6f46c94cc29e..92733091154c 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -176,6 +176,13 @@ static unsigned int task_timeslice(task_t *p)
176#define task_hot(p, now, sd) ((long long) ((now) - (p)->last_ran) \ 176#define task_hot(p, now, sd) ((long long) ((now) - (p)->last_ran) \
177 < (long long) (sd)->cache_hot_time) 177 < (long long) (sd)->cache_hot_time)
178 178
179void __put_task_struct_cb(struct rcu_head *rhp)
180{
181 __put_task_struct(container_of(rhp, struct task_struct, rcu));
182}
183
184EXPORT_SYMBOL_GPL(__put_task_struct_cb);
185
179/* 186/*
180 * These are the runqueue data structures: 187 * These are the runqueue data structures:
181 */ 188 */
diff --git a/kernel/signal.c b/kernel/signal.c
index d7611f189ef7..08aa5b263f36 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -329,13 +329,20 @@ void __exit_sighand(struct task_struct *tsk)
329 /* Ok, we're done with the signal handlers */ 329 /* Ok, we're done with the signal handlers */
330 tsk->sighand = NULL; 330 tsk->sighand = NULL;
331 if (atomic_dec_and_test(&sighand->count)) 331 if (atomic_dec_and_test(&sighand->count))
332 kmem_cache_free(sighand_cachep, sighand); 332 sighand_free(sighand);
333} 333}
334 334
335void exit_sighand(struct task_struct *tsk) 335void exit_sighand(struct task_struct *tsk)
336{ 336{
337 write_lock_irq(&tasklist_lock); 337 write_lock_irq(&tasklist_lock);
338 __exit_sighand(tsk); 338 rcu_read_lock();
339 if (tsk->sighand != NULL) {
340 struct sighand_struct *sighand = rcu_dereference(tsk->sighand);
341 spin_lock(&sighand->siglock);
342 __exit_sighand(tsk);
343 spin_unlock(&sighand->siglock);
344 }
345 rcu_read_unlock();
339 write_unlock_irq(&tasklist_lock); 346 write_unlock_irq(&tasklist_lock);
340} 347}
341 348
@@ -345,19 +352,20 @@ void exit_sighand(struct task_struct *tsk)
345void __exit_signal(struct task_struct *tsk) 352void __exit_signal(struct task_struct *tsk)
346{ 353{
347 struct signal_struct * sig = tsk->signal; 354 struct signal_struct * sig = tsk->signal;
348 struct sighand_struct * sighand = tsk->sighand; 355 struct sighand_struct * sighand;
349 356
350 if (!sig) 357 if (!sig)
351 BUG(); 358 BUG();
352 if (!atomic_read(&sig->count)) 359 if (!atomic_read(&sig->count))
353 BUG(); 360 BUG();
361 rcu_read_lock();
362 sighand = rcu_dereference(tsk->sighand);
354 spin_lock(&sighand->siglock); 363 spin_lock(&sighand->siglock);
355 posix_cpu_timers_exit(tsk); 364 posix_cpu_timers_exit(tsk);
356 if (atomic_dec_and_test(&sig->count)) { 365 if (atomic_dec_and_test(&sig->count)) {
357 posix_cpu_timers_exit_group(tsk); 366 posix_cpu_timers_exit_group(tsk);
358 if (tsk == sig->curr_target)
359 sig->curr_target = next_thread(tsk);
360 tsk->signal = NULL; 367 tsk->signal = NULL;
368 __exit_sighand(tsk);
361 spin_unlock(&sighand->siglock); 369 spin_unlock(&sighand->siglock);
362 flush_sigqueue(&sig->shared_pending); 370 flush_sigqueue(&sig->shared_pending);
363 } else { 371 } else {
@@ -389,9 +397,11 @@ void __exit_signal(struct task_struct *tsk)
389 sig->nvcsw += tsk->nvcsw; 397 sig->nvcsw += tsk->nvcsw;
390 sig->nivcsw += tsk->nivcsw; 398 sig->nivcsw += tsk->nivcsw;
391 sig->sched_time += tsk->sched_time; 399 sig->sched_time += tsk->sched_time;
400 __exit_sighand(tsk);
392 spin_unlock(&sighand->siglock); 401 spin_unlock(&sighand->siglock);
393 sig = NULL; /* Marker for below. */ 402 sig = NULL; /* Marker for below. */
394 } 403 }
404 rcu_read_unlock();
395 clear_tsk_thread_flag(tsk,TIF_SIGPENDING); 405 clear_tsk_thread_flag(tsk,TIF_SIGPENDING);
396 flush_sigqueue(&tsk->pending); 406 flush_sigqueue(&tsk->pending);
397 if (sig) { 407 if (sig) {
@@ -613,6 +623,33 @@ void signal_wake_up(struct task_struct *t, int resume)
613 * Returns 1 if any signals were found. 623 * Returns 1 if any signals were found.
614 * 624 *
615 * All callers must be holding the siglock. 625 * All callers must be holding the siglock.
626 *
627 * This version takes a sigset mask and looks at all signals,
628 * not just those in the first mask word.
629 */
630static int rm_from_queue_full(sigset_t *mask, struct sigpending *s)
631{
632 struct sigqueue *q, *n;
633 sigset_t m;
634
635 sigandsets(&m, mask, &s->signal);
636 if (sigisemptyset(&m))
637 return 0;
638
639 signandsets(&s->signal, &s->signal, mask);
640 list_for_each_entry_safe(q, n, &s->list, list) {
641 if (sigismember(mask, q->info.si_signo)) {
642 list_del_init(&q->list);
643 __sigqueue_free(q);
644 }
645 }
646 return 1;
647}
648/*
649 * Remove signals in mask from the pending set and queue.
650 * Returns 1 if any signals were found.
651 *
652 * All callers must be holding the siglock.
616 */ 653 */
617static int rm_from_queue(unsigned long mask, struct sigpending *s) 654static int rm_from_queue(unsigned long mask, struct sigpending *s)
618{ 655{
@@ -1080,18 +1117,29 @@ void zap_other_threads(struct task_struct *p)
1080} 1117}
1081 1118
1082/* 1119/*
1083 * Must be called with the tasklist_lock held for reading! 1120 * Must be called under rcu_read_lock() or with tasklist_lock read-held.
1084 */ 1121 */
1085int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) 1122int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
1086{ 1123{
1087 unsigned long flags; 1124 unsigned long flags;
1125 struct sighand_struct *sp;
1088 int ret; 1126 int ret;
1089 1127
1128retry:
1090 ret = check_kill_permission(sig, info, p); 1129 ret = check_kill_permission(sig, info, p);
1091 if (!ret && sig && p->sighand) { 1130 if (!ret && sig && (sp = rcu_dereference(p->sighand))) {
1092 spin_lock_irqsave(&p->sighand->siglock, flags); 1131 spin_lock_irqsave(&sp->siglock, flags);
1132 if (p->sighand != sp) {
1133 spin_unlock_irqrestore(&sp->siglock, flags);
1134 goto retry;
1135 }
1136 if ((atomic_read(&sp->count) == 0) ||
1137 (atomic_read(&p->usage) == 0)) {
1138 spin_unlock_irqrestore(&sp->siglock, flags);
1139 return -ESRCH;
1140 }
1093 ret = __group_send_sig_info(sig, info, p); 1141 ret = __group_send_sig_info(sig, info, p);
1094 spin_unlock_irqrestore(&p->sighand->siglock, flags); 1142 spin_unlock_irqrestore(&sp->siglock, flags);
1095 } 1143 }
1096 1144
1097 return ret; 1145 return ret;
@@ -1136,14 +1184,21 @@ int
1136kill_proc_info(int sig, struct siginfo *info, pid_t pid) 1184kill_proc_info(int sig, struct siginfo *info, pid_t pid)
1137{ 1185{
1138 int error; 1186 int error;
1187 int acquired_tasklist_lock = 0;
1139 struct task_struct *p; 1188 struct task_struct *p;
1140 1189
1141 read_lock(&tasklist_lock); 1190 rcu_read_lock();
1191 if (unlikely(sig_kernel_stop(sig) || sig == SIGCONT)) {
1192 read_lock(&tasklist_lock);
1193 acquired_tasklist_lock = 1;
1194 }
1142 p = find_task_by_pid(pid); 1195 p = find_task_by_pid(pid);
1143 error = -ESRCH; 1196 error = -ESRCH;
1144 if (p) 1197 if (p)
1145 error = group_send_sig_info(sig, info, p); 1198 error = group_send_sig_info(sig, info, p);
1146 read_unlock(&tasklist_lock); 1199 if (unlikely(acquired_tasklist_lock))
1200 read_unlock(&tasklist_lock);
1201 rcu_read_unlock();
1147 return error; 1202 return error;
1148} 1203}
1149 1204
@@ -1163,8 +1218,7 @@ int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid,
1163 ret = -ESRCH; 1218 ret = -ESRCH;
1164 goto out_unlock; 1219 goto out_unlock;
1165 } 1220 }
1166 if ((!info || ((unsigned long)info != 1 && 1221 if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
1167 (unsigned long)info != 2 && SI_FROMUSER(info)))
1168 && (euid != p->suid) && (euid != p->uid) 1222 && (euid != p->suid) && (euid != p->uid)
1169 && (uid != p->suid) && (uid != p->uid)) { 1223 && (uid != p->suid) && (uid != p->uid)) {
1170 ret = -EPERM; 1224 ret = -EPERM;
@@ -1355,16 +1409,54 @@ send_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
1355{ 1409{
1356 unsigned long flags; 1410 unsigned long flags;
1357 int ret = 0; 1411 int ret = 0;
1412 struct sighand_struct *sh;
1358 1413
1359 BUG_ON(!(q->flags & SIGQUEUE_PREALLOC)); 1414 BUG_ON(!(q->flags & SIGQUEUE_PREALLOC));
1360 read_lock(&tasklist_lock); 1415
1416 /*
1417 * The rcu based delayed sighand destroy makes it possible to
1418 * run this without tasklist lock held. The task struct itself
1419 * cannot go away as create_timer did get_task_struct().
1420 *
1421 * We return -1, when the task is marked exiting, so
1422 * posix_timer_event can redirect it to the group leader
1423 */
1424 rcu_read_lock();
1361 1425
1362 if (unlikely(p->flags & PF_EXITING)) { 1426 if (unlikely(p->flags & PF_EXITING)) {
1363 ret = -1; 1427 ret = -1;
1364 goto out_err; 1428 goto out_err;
1365 } 1429 }
1366 1430
1367 spin_lock_irqsave(&p->sighand->siglock, flags); 1431retry:
1432 sh = rcu_dereference(p->sighand);
1433
1434 spin_lock_irqsave(&sh->siglock, flags);
1435 if (p->sighand != sh) {
1436 /* We raced with exec() in a multithreaded process... */
1437 spin_unlock_irqrestore(&sh->siglock, flags);
1438 goto retry;
1439 }
1440
1441 /*
1442 * We do the check here again to handle the following scenario:
1443 *
1444 * CPU 0 CPU 1
1445 * send_sigqueue
1446 * check PF_EXITING
1447 * interrupt exit code running
1448 * __exit_signal
1449 * lock sighand->siglock
1450 * unlock sighand->siglock
1451 * lock sh->siglock
1452 * add(tsk->pending) flush_sigqueue(tsk->pending)
1453 *
1454 */
1455
1456 if (unlikely(p->flags & PF_EXITING)) {
1457 ret = -1;
1458 goto out;
1459 }
1368 1460
1369 if (unlikely(!list_empty(&q->list))) { 1461 if (unlikely(!list_empty(&q->list))) {
1370 /* 1462 /*
@@ -1388,9 +1480,9 @@ send_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
1388 signal_wake_up(p, sig == SIGKILL); 1480 signal_wake_up(p, sig == SIGKILL);
1389 1481
1390out: 1482out:
1391 spin_unlock_irqrestore(&p->sighand->siglock, flags); 1483 spin_unlock_irqrestore(&sh->siglock, flags);
1392out_err: 1484out_err:
1393 read_unlock(&tasklist_lock); 1485 rcu_read_unlock();
1394 1486
1395 return ret; 1487 return ret;
1396} 1488}
@@ -1402,7 +1494,9 @@ send_group_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
1402 int ret = 0; 1494 int ret = 0;
1403 1495
1404 BUG_ON(!(q->flags & SIGQUEUE_PREALLOC)); 1496 BUG_ON(!(q->flags & SIGQUEUE_PREALLOC));
1497
1405 read_lock(&tasklist_lock); 1498 read_lock(&tasklist_lock);
1499 /* Since it_lock is held, p->sighand cannot be NULL. */
1406 spin_lock_irqsave(&p->sighand->siglock, flags); 1500 spin_lock_irqsave(&p->sighand->siglock, flags);
1407 handle_stop_signal(sig, p); 1501 handle_stop_signal(sig, p);
1408 1502
@@ -1436,7 +1530,7 @@ send_group_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
1436out: 1530out:
1437 spin_unlock_irqrestore(&p->sighand->siglock, flags); 1531 spin_unlock_irqrestore(&p->sighand->siglock, flags);
1438 read_unlock(&tasklist_lock); 1532 read_unlock(&tasklist_lock);
1439 return(ret); 1533 return ret;
1440} 1534}
1441 1535
1442/* 1536/*
@@ -2338,6 +2432,7 @@ int
2338do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact) 2432do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact)
2339{ 2433{
2340 struct k_sigaction *k; 2434 struct k_sigaction *k;
2435 sigset_t mask;
2341 2436
2342 if (!valid_signal(sig) || sig < 1 || (act && sig_kernel_only(sig))) 2437 if (!valid_signal(sig) || sig < 1 || (act && sig_kernel_only(sig)))
2343 return -EINVAL; 2438 return -EINVAL;
@@ -2385,9 +2480,11 @@ do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact)
2385 *k = *act; 2480 *k = *act;
2386 sigdelsetmask(&k->sa.sa_mask, 2481 sigdelsetmask(&k->sa.sa_mask,
2387 sigmask(SIGKILL) | sigmask(SIGSTOP)); 2482 sigmask(SIGKILL) | sigmask(SIGSTOP));
2388 rm_from_queue(sigmask(sig), &t->signal->shared_pending); 2483 sigemptyset(&mask);
2484 sigaddset(&mask, sig);
2485 rm_from_queue_full(&mask, &t->signal->shared_pending);
2389 do { 2486 do {
2390 rm_from_queue(sigmask(sig), &t->pending); 2487 rm_from_queue_full(&mask, &t->pending);
2391 recalc_sigpending_tsk(t); 2488 recalc_sigpending_tsk(t);
2392 t = next_thread(t); 2489 t = next_thread(t);
2393 } while (t != current); 2490 } while (t != current);
diff --git a/kernel/sys.c b/kernel/sys.c
index eecf84526afe..b6941e06d5d5 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -489,6 +489,12 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
489 magic2 != LINUX_REBOOT_MAGIC2C)) 489 magic2 != LINUX_REBOOT_MAGIC2C))
490 return -EINVAL; 490 return -EINVAL;
491 491
492 /* Instead of trying to make the power_off code look like
493 * halt when pm_power_off is not set do it the easy way.
494 */
495 if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
496 cmd = LINUX_REBOOT_CMD_HALT;
497
492 lock_kernel(); 498 lock_kernel();
493 switch (cmd) { 499 switch (cmd) {
494 case LINUX_REBOOT_CMD_RESTART: 500 case LINUX_REBOOT_CMD_RESTART:
@@ -1084,10 +1090,11 @@ asmlinkage long sys_times(struct tms __user * tbuf)
1084asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) 1090asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
1085{ 1091{
1086 struct task_struct *p; 1092 struct task_struct *p;
1093 struct task_struct *group_leader = current->group_leader;
1087 int err = -EINVAL; 1094 int err = -EINVAL;
1088 1095
1089 if (!pid) 1096 if (!pid)
1090 pid = current->pid; 1097 pid = group_leader->pid;
1091 if (!pgid) 1098 if (!pgid)
1092 pgid = pid; 1099 pgid = pid;
1093 if (pgid < 0) 1100 if (pgid < 0)
@@ -1107,16 +1114,16 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
1107 if (!thread_group_leader(p)) 1114 if (!thread_group_leader(p))
1108 goto out; 1115 goto out;
1109 1116
1110 if (p->parent == current || p->real_parent == current) { 1117 if (p->real_parent == group_leader) {
1111 err = -EPERM; 1118 err = -EPERM;
1112 if (p->signal->session != current->signal->session) 1119 if (p->signal->session != group_leader->signal->session)
1113 goto out; 1120 goto out;
1114 err = -EACCES; 1121 err = -EACCES;
1115 if (p->did_exec) 1122 if (p->did_exec)
1116 goto out; 1123 goto out;
1117 } else { 1124 } else {
1118 err = -ESRCH; 1125 err = -ESRCH;
1119 if (p != current) 1126 if (p != group_leader)
1120 goto out; 1127 goto out;
1121 } 1128 }
1122 1129
@@ -1128,7 +1135,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
1128 struct task_struct *p; 1135 struct task_struct *p;
1129 1136
1130 do_each_task_pid(pgid, PIDTYPE_PGID, p) { 1137 do_each_task_pid(pgid, PIDTYPE_PGID, p) {
1131 if (p->signal->session == current->signal->session) 1138 if (p->signal->session == group_leader->signal->session)
1132 goto ok_pgid; 1139 goto ok_pgid;
1133 } while_each_task_pid(pgid, PIDTYPE_PGID, p); 1140 } while_each_task_pid(pgid, PIDTYPE_PGID, p);
1134 goto out; 1141 goto out;
@@ -1208,24 +1215,22 @@ asmlinkage long sys_getsid(pid_t pid)
1208 1215
1209asmlinkage long sys_setsid(void) 1216asmlinkage long sys_setsid(void)
1210{ 1217{
1218 struct task_struct *group_leader = current->group_leader;
1211 struct pid *pid; 1219 struct pid *pid;
1212 int err = -EPERM; 1220 int err = -EPERM;
1213 1221
1214 if (!thread_group_leader(current))
1215 return -EINVAL;
1216
1217 down(&tty_sem); 1222 down(&tty_sem);
1218 write_lock_irq(&tasklist_lock); 1223 write_lock_irq(&tasklist_lock);
1219 1224
1220 pid = find_pid(PIDTYPE_PGID, current->pid); 1225 pid = find_pid(PIDTYPE_PGID, group_leader->pid);
1221 if (pid) 1226 if (pid)
1222 goto out; 1227 goto out;
1223 1228
1224 current->signal->leader = 1; 1229 group_leader->signal->leader = 1;
1225 __set_special_pids(current->pid, current->pid); 1230 __set_special_pids(group_leader->pid, group_leader->pid);
1226 current->signal->tty = NULL; 1231 group_leader->signal->tty = NULL;
1227 current->signal->tty_old_pgrp = 0; 1232 group_leader->signal->tty_old_pgrp = 0;
1228 err = process_group(current); 1233 err = process_group(group_leader);
1229out: 1234out:
1230 write_unlock_irq(&tasklist_lock); 1235 write_unlock_irq(&tasklist_lock);
1231 up(&tty_sem); 1236 up(&tty_sem);
@@ -1687,7 +1692,10 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1687 if (unlikely(!p->signal)) 1692 if (unlikely(!p->signal))
1688 return; 1693 return;
1689 1694
1695 utime = stime = cputime_zero;
1696
1690 switch (who) { 1697 switch (who) {
1698 case RUSAGE_BOTH:
1691 case RUSAGE_CHILDREN: 1699 case RUSAGE_CHILDREN:
1692 spin_lock_irqsave(&p->sighand->siglock, flags); 1700 spin_lock_irqsave(&p->sighand->siglock, flags);
1693 utime = p->signal->cutime; 1701 utime = p->signal->cutime;
@@ -1697,22 +1705,11 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1697 r->ru_minflt = p->signal->cmin_flt; 1705 r->ru_minflt = p->signal->cmin_flt;
1698 r->ru_majflt = p->signal->cmaj_flt; 1706 r->ru_majflt = p->signal->cmaj_flt;
1699 spin_unlock_irqrestore(&p->sighand->siglock, flags); 1707 spin_unlock_irqrestore(&p->sighand->siglock, flags);
1700 cputime_to_timeval(utime, &r->ru_utime); 1708
1701 cputime_to_timeval(stime, &r->ru_stime); 1709 if (who == RUSAGE_CHILDREN)
1702 break; 1710 break;
1711
1703 case RUSAGE_SELF: 1712 case RUSAGE_SELF:
1704 spin_lock_irqsave(&p->sighand->siglock, flags);
1705 utime = stime = cputime_zero;
1706 goto sum_group;
1707 case RUSAGE_BOTH:
1708 spin_lock_irqsave(&p->sighand->siglock, flags);
1709 utime = p->signal->cutime;
1710 stime = p->signal->cstime;
1711 r->ru_nvcsw = p->signal->cnvcsw;
1712 r->ru_nivcsw = p->signal->cnivcsw;
1713 r->ru_minflt = p->signal->cmin_flt;
1714 r->ru_majflt = p->signal->cmaj_flt;
1715 sum_group:
1716 utime = cputime_add(utime, p->signal->utime); 1713 utime = cputime_add(utime, p->signal->utime);
1717 stime = cputime_add(stime, p->signal->stime); 1714 stime = cputime_add(stime, p->signal->stime);
1718 r->ru_nvcsw += p->signal->nvcsw; 1715 r->ru_nvcsw += p->signal->nvcsw;
@@ -1729,13 +1726,14 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1729 r->ru_majflt += t->maj_flt; 1726 r->ru_majflt += t->maj_flt;
1730 t = next_thread(t); 1727 t = next_thread(t);
1731 } while (t != p); 1728 } while (t != p);
1732 spin_unlock_irqrestore(&p->sighand->siglock, flags);
1733 cputime_to_timeval(utime, &r->ru_utime);
1734 cputime_to_timeval(stime, &r->ru_stime);
1735 break; 1729 break;
1730
1736 default: 1731 default:
1737 BUG(); 1732 BUG();
1738 } 1733 }
1734
1735 cputime_to_timeval(utime, &r->ru_utime);
1736 cputime_to_timeval(stime, &r->ru_stime);
1739} 1737}
1740 1738
1741int getrusage(struct task_struct *p, int who, struct rusage __user *ru) 1739int getrusage(struct task_struct *p, int who, struct rusage __user *ru)
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 1ab2370e2efa..17313b99e53d 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -82,6 +82,28 @@ cond_syscall(compat_sys_socketcall);
82cond_syscall(sys_inotify_init); 82cond_syscall(sys_inotify_init);
83cond_syscall(sys_inotify_add_watch); 83cond_syscall(sys_inotify_add_watch);
84cond_syscall(sys_inotify_rm_watch); 84cond_syscall(sys_inotify_rm_watch);
85cond_syscall(sys_migrate_pages);
86cond_syscall(sys_chown16);
87cond_syscall(sys_fchown16);
88cond_syscall(sys_getegid16);
89cond_syscall(sys_geteuid16);
90cond_syscall(sys_getgid16);
91cond_syscall(sys_getgroups16);
92cond_syscall(sys_getresgid16);
93cond_syscall(sys_getresuid16);
94cond_syscall(sys_getuid16);
95cond_syscall(sys_lchown16);
96cond_syscall(sys_setfsgid16);
97cond_syscall(sys_setfsuid16);
98cond_syscall(sys_setgid16);
99cond_syscall(sys_setgroups16);
100cond_syscall(sys_setregid16);
101cond_syscall(sys_setresgid16);
102cond_syscall(sys_setresuid16);
103cond_syscall(sys_setreuid16);
104cond_syscall(sys_setuid16);
105cond_syscall(sys_vm86old);
106cond_syscall(sys_vm86);
85 107
86/* arch-specific weak syscall entries */ 108/* arch-specific weak syscall entries */
87cond_syscall(sys_pciconfig_read); 109cond_syscall(sys_pciconfig_read);
@@ -90,3 +112,5 @@ cond_syscall(sys_pciconfig_iobase);
90cond_syscall(sys32_ipc); 112cond_syscall(sys32_ipc);
91cond_syscall(sys32_sysctl); 113cond_syscall(sys32_sysctl);
92cond_syscall(ppc_rtas); 114cond_syscall(ppc_rtas);
115cond_syscall(sys_spu_run);
116cond_syscall(sys_spu_create);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index a85047bb5739..03b0598f2369 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -68,6 +68,8 @@ extern int min_free_kbytes;
68extern int printk_ratelimit_jiffies; 68extern int printk_ratelimit_jiffies;
69extern int printk_ratelimit_burst; 69extern int printk_ratelimit_burst;
70extern int pid_max_min, pid_max_max; 70extern int pid_max_min, pid_max_max;
71extern int sysctl_drop_caches;
72extern int percpu_pagelist_fraction;
71 73
72#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) 74#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
73int unknown_nmi_panic; 75int unknown_nmi_panic;
@@ -78,6 +80,7 @@ extern int proc_unknown_nmi_panic(ctl_table *, int, struct file *,
78/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ 80/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
79static int maxolduid = 65535; 81static int maxolduid = 65535;
80static int minolduid; 82static int minolduid;
83static int min_percpu_pagelist_fract = 8;
81 84
82static int ngroups_max = NGROUPS_MAX; 85static int ngroups_max = NGROUPS_MAX;
83 86
@@ -775,6 +778,15 @@ static ctl_table vm_table[] = {
775 .strategy = &sysctl_intvec, 778 .strategy = &sysctl_intvec,
776 }, 779 },
777 { 780 {
781 .ctl_name = VM_DROP_PAGECACHE,
782 .procname = "drop_caches",
783 .data = &sysctl_drop_caches,
784 .maxlen = sizeof(int),
785 .mode = 0644,
786 .proc_handler = drop_caches_sysctl_handler,
787 .strategy = &sysctl_intvec,
788 },
789 {
778 .ctl_name = VM_MIN_FREE_KBYTES, 790 .ctl_name = VM_MIN_FREE_KBYTES,
779 .procname = "min_free_kbytes", 791 .procname = "min_free_kbytes",
780 .data = &min_free_kbytes, 792 .data = &min_free_kbytes,
@@ -784,6 +796,16 @@ static ctl_table vm_table[] = {
784 .strategy = &sysctl_intvec, 796 .strategy = &sysctl_intvec,
785 .extra1 = &zero, 797 .extra1 = &zero,
786 }, 798 },
799 {
800 .ctl_name = VM_PERCPU_PAGELIST_FRACTION,
801 .procname = "percpu_pagelist_fraction",
802 .data = &percpu_pagelist_fraction,
803 .maxlen = sizeof(percpu_pagelist_fraction),
804 .mode = 0644,
805 .proc_handler = &percpu_pagelist_fraction_sysctl_handler,
806 .strategy = &sysctl_intvec,
807 .extra1 = &min_percpu_pagelist_fract,
808 },
787#ifdef CONFIG_MMU 809#ifdef CONFIG_MMU
788 { 810 {
789 .ctl_name = VM_MAX_MAP_COUNT, 811 .ctl_name = VM_MAX_MAP_COUNT,
diff --git a/kernel/timer.c b/kernel/timer.c
index fd74268d8663..074b4bd5cfd8 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -33,6 +33,7 @@
33#include <linux/posix-timers.h> 33#include <linux/posix-timers.h>
34#include <linux/cpu.h> 34#include <linux/cpu.h>
35#include <linux/syscalls.h> 35#include <linux/syscalls.h>
36#include <linux/delay.h>
36 37
37#include <asm/uaccess.h> 38#include <asm/uaccess.h>
38#include <asm/unistd.h> 39#include <asm/unistd.h>
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 2bd5aee1c736..82c4fa70595c 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -29,7 +29,8 @@
29#include <linux/kthread.h> 29#include <linux/kthread.h>
30 30
31/* 31/*
32 * The per-CPU workqueue (if single thread, we always use cpu 0's). 32 * The per-CPU workqueue (if single thread, we always use the first
33 * possible cpu).
33 * 34 *
34 * The sequence counters are for flush_scheduled_work(). It wants to wait 35 * The sequence counters are for flush_scheduled_work(). It wants to wait
35 * until until all currently-scheduled works are completed, but it doesn't 36 * until until all currently-scheduled works are completed, but it doesn't
@@ -69,6 +70,8 @@ struct workqueue_struct {
69static DEFINE_SPINLOCK(workqueue_lock); 70static DEFINE_SPINLOCK(workqueue_lock);
70static LIST_HEAD(workqueues); 71static LIST_HEAD(workqueues);
71 72
73static int singlethread_cpu;
74
72/* If it's single threaded, it isn't in the list of workqueues. */ 75/* If it's single threaded, it isn't in the list of workqueues. */
73static inline int is_single_threaded(struct workqueue_struct *wq) 76static inline int is_single_threaded(struct workqueue_struct *wq)
74{ 77{
@@ -102,7 +105,7 @@ int fastcall queue_work(struct workqueue_struct *wq, struct work_struct *work)
102 105
103 if (!test_and_set_bit(0, &work->pending)) { 106 if (!test_and_set_bit(0, &work->pending)) {
104 if (unlikely(is_single_threaded(wq))) 107 if (unlikely(is_single_threaded(wq)))
105 cpu = any_online_cpu(cpu_online_map); 108 cpu = singlethread_cpu;
106 BUG_ON(!list_empty(&work->entry)); 109 BUG_ON(!list_empty(&work->entry));
107 __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work); 110 __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
108 ret = 1; 111 ret = 1;
@@ -118,7 +121,7 @@ static void delayed_work_timer_fn(unsigned long __data)
118 int cpu = smp_processor_id(); 121 int cpu = smp_processor_id();
119 122
120 if (unlikely(is_single_threaded(wq))) 123 if (unlikely(is_single_threaded(wq)))
121 cpu = any_online_cpu(cpu_online_map); 124 cpu = singlethread_cpu;
122 125
123 __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work); 126 __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
124} 127}
@@ -267,7 +270,7 @@ void fastcall flush_workqueue(struct workqueue_struct *wq)
267 270
268 if (is_single_threaded(wq)) { 271 if (is_single_threaded(wq)) {
269 /* Always use first cpu's area. */ 272 /* Always use first cpu's area. */
270 flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, any_online_cpu(cpu_online_map))); 273 flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, singlethread_cpu));
271 } else { 274 } else {
272 int cpu; 275 int cpu;
273 276
@@ -315,12 +318,17 @@ struct workqueue_struct *__create_workqueue(const char *name,
315 return NULL; 318 return NULL;
316 319
317 wq->cpu_wq = alloc_percpu(struct cpu_workqueue_struct); 320 wq->cpu_wq = alloc_percpu(struct cpu_workqueue_struct);
321 if (!wq->cpu_wq) {
322 kfree(wq);
323 return NULL;
324 }
325
318 wq->name = name; 326 wq->name = name;
319 /* We don't need the distraction of CPUs appearing and vanishing. */ 327 /* We don't need the distraction of CPUs appearing and vanishing. */
320 lock_cpu_hotplug(); 328 lock_cpu_hotplug();
321 if (singlethread) { 329 if (singlethread) {
322 INIT_LIST_HEAD(&wq->list); 330 INIT_LIST_HEAD(&wq->list);
323 p = create_workqueue_thread(wq, any_online_cpu(cpu_online_map)); 331 p = create_workqueue_thread(wq, singlethread_cpu);
324 if (!p) 332 if (!p)
325 destroy = 1; 333 destroy = 1;
326 else 334 else
@@ -374,7 +382,7 @@ void destroy_workqueue(struct workqueue_struct *wq)
374 /* We don't need the distraction of CPUs appearing and vanishing. */ 382 /* We don't need the distraction of CPUs appearing and vanishing. */
375 lock_cpu_hotplug(); 383 lock_cpu_hotplug();
376 if (is_single_threaded(wq)) 384 if (is_single_threaded(wq))
377 cleanup_workqueue_thread(wq, any_online_cpu(cpu_online_map)); 385 cleanup_workqueue_thread(wq, singlethread_cpu);
378 else { 386 else {
379 for_each_online_cpu(cpu) 387 for_each_online_cpu(cpu)
380 cleanup_workqueue_thread(wq, cpu); 388 cleanup_workqueue_thread(wq, cpu);
@@ -419,6 +427,25 @@ int schedule_delayed_work_on(int cpu,
419 return ret; 427 return ret;
420} 428}
421 429
430int schedule_on_each_cpu(void (*func) (void *info), void *info)
431{
432 int cpu;
433 struct work_struct *work;
434
435 work = kmalloc(NR_CPUS * sizeof(struct work_struct), GFP_KERNEL);
436
437 if (!work)
438 return -ENOMEM;
439 for_each_online_cpu(cpu) {
440 INIT_WORK(work + cpu, func, info);
441 __queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu),
442 work + cpu);
443 }
444 flush_workqueue(keventd_wq);
445 kfree(work);
446 return 0;
447}
448
422void flush_scheduled_work(void) 449void flush_scheduled_work(void)
423{ 450{
424 flush_workqueue(keventd_wq); 451 flush_workqueue(keventd_wq);
@@ -543,6 +570,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
543 570
544void init_workqueues(void) 571void init_workqueues(void)
545{ 572{
573 singlethread_cpu = first_cpu(cpu_possible_map);
546 hotcpu_notifier(workqueue_cpu_callback, 0); 574 hotcpu_notifier(workqueue_cpu_callback, 0);
547 keventd_wq = create_workqueue("events"); 575 keventd_wq = create_workqueue("events");
548 BUG_ON(!keventd_wq); 576 BUG_ON(!keventd_wq);
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 80598cfd728c..c48260fb8fd9 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -79,7 +79,7 @@ config SCHEDSTATS
79 79
80config DEBUG_SLAB 80config DEBUG_SLAB
81 bool "Debug memory allocations" 81 bool "Debug memory allocations"
82 depends on DEBUG_KERNEL 82 depends on DEBUG_KERNEL && SLAB
83 help 83 help
84 Say Y here to have the kernel do limited verification on memory 84 Say Y here to have the kernel do limited verification on memory
85 allocation as well as poisoning memory on free to catch use of freed 85 allocation as well as poisoning memory on free to catch use of freed
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 23d3b1147fe9..48e708381d44 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -519,7 +519,7 @@ EXPORT_SYMBOL(bitmap_parselist);
519 * 519 *
520 * Map the bit at position @pos in @buf (of length @bits) to the 520 * Map the bit at position @pos in @buf (of length @bits) to the
521 * ordinal of which set bit it is. If it is not set or if @pos 521 * ordinal of which set bit it is. If it is not set or if @pos
522 * is not a valid bit position, map to zero (0). 522 * is not a valid bit position, map to -1.
523 * 523 *
524 * If for example, just bits 4 through 7 are set in @buf, then @pos 524 * If for example, just bits 4 through 7 are set in @buf, then @pos
525 * values 4 through 7 will get mapped to 0 through 3, respectively, 525 * values 4 through 7 will get mapped to 0 through 3, respectively,
@@ -531,18 +531,19 @@ EXPORT_SYMBOL(bitmap_parselist);
531 */ 531 */
532static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits) 532static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits)
533{ 533{
534 int ord = 0; 534 int i, ord;
535 535
536 if (pos >= 0 && pos < bits) { 536 if (pos < 0 || pos >= bits || !test_bit(pos, buf))
537 int i; 537 return -1;
538 538
539 for (i = find_first_bit(buf, bits); 539 i = find_first_bit(buf, bits);
540 i < pos; 540 ord = 0;
541 i = find_next_bit(buf, bits, i + 1)) 541 while (i < pos) {
542 ord++; 542 i = find_next_bit(buf, bits, i + 1);
543 if (i > pos) 543 ord++;
544 ord = 0;
545 } 544 }
545 BUG_ON(i != pos);
546
546 return ord; 547 return ord;
547} 548}
548 549
@@ -553,11 +554,12 @@ static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits)
553 * @bits: number of valid bit positions in @buf 554 * @bits: number of valid bit positions in @buf
554 * 555 *
555 * Map the ordinal offset of bit @ord in @buf to its position in @buf. 556 * Map the ordinal offset of bit @ord in @buf to its position in @buf.
556 * If @ord is not the ordinal offset of a set bit in @buf, map to zero (0). 557 * Value of @ord should be in range 0 <= @ord < weight(buf), else
558 * results are undefined.
557 * 559 *
558 * If for example, just bits 4 through 7 are set in @buf, then @ord 560 * If for example, just bits 4 through 7 are set in @buf, then @ord
559 * values 0 through 3 will get mapped to 4 through 7, respectively, 561 * values 0 through 3 will get mapped to 4 through 7, respectively,
560 * and all other @ord valuds will get mapped to 0. When @ord value 3 562 * and all other @ord values return undefined values. When @ord value 3
561 * gets mapped to (returns) @pos value 7 in this example, that means 563 * gets mapped to (returns) @pos value 7 in this example, that means
562 * that the 3rd set bit (starting with 0th) is at position 7 in @buf. 564 * that the 3rd set bit (starting with 0th) is at position 7 in @buf.
563 * 565 *
@@ -583,8 +585,8 @@ static int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits)
583 585
584/** 586/**
585 * bitmap_remap - Apply map defined by a pair of bitmaps to another bitmap 587 * bitmap_remap - Apply map defined by a pair of bitmaps to another bitmap
586 * @src: subset to be remapped
587 * @dst: remapped result 588 * @dst: remapped result
589 * @src: subset to be remapped
588 * @old: defines domain of map 590 * @old: defines domain of map
589 * @new: defines range of map 591 * @new: defines range of map
590 * @bits: number of bits in each of these bitmaps 592 * @bits: number of bits in each of these bitmaps
@@ -596,49 +598,42 @@ static int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits)
596 * weight of @old, map the position of the n-th set bit in @old to 598 * weight of @old, map the position of the n-th set bit in @old to
597 * the position of the m-th set bit in @new, where m == n % w. 599 * the position of the m-th set bit in @new, where m == n % w.
598 * 600 *
599 * If either of the @old and @new bitmaps are empty, or if@src and @dst 601 * If either of the @old and @new bitmaps are empty, or if @src and
600 * point to the same location, then this routine does nothing. 602 * @dst point to the same location, then this routine copies @src
603 * to @dst.
601 * 604 *
602 * The positions of unset bits in @old are mapped to the position of 605 * The positions of unset bits in @old are mapped to themselves
603 * the first set bit in @new. 606 * (the identify map).
604 * 607 *
605 * Apply the above specified mapping to @src, placing the result in 608 * Apply the above specified mapping to @src, placing the result in
606 * @dst, clearing any bits previously set in @dst. 609 * @dst, clearing any bits previously set in @dst.
607 * 610 *
608 * The resulting value of @dst will have either the same weight as
609 * @src, or less weight in the general case that the mapping wasn't
610 * injective due to the weight of @new being less than that of @old.
611 * The resulting value of @dst will never have greater weight than
612 * that of @src, except perhaps in the case that one of the above
613 * conditions was not met and this routine just returned.
614 *
615 * For example, lets say that @old has bits 4 through 7 set, and 611 * For example, lets say that @old has bits 4 through 7 set, and
616 * @new has bits 12 through 15 set. This defines the mapping of bit 612 * @new has bits 12 through 15 set. This defines the mapping of bit
617 * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other 613 * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
618 * bit positions to 12 (the first set bit in @new. So if say @src 614 * bit positions unchanged. So if say @src comes into this routine
619 * comes into this routine with bits 1, 5 and 7 set, then @dst should 615 * with bits 1, 5 and 7 set, then @dst should leave with bits 1,
620 * leave with bits 12, 13 and 15 set. 616 * 13 and 15 set.
621 */ 617 */
622void bitmap_remap(unsigned long *dst, const unsigned long *src, 618void bitmap_remap(unsigned long *dst, const unsigned long *src,
623 const unsigned long *old, const unsigned long *new, 619 const unsigned long *old, const unsigned long *new,
624 int bits) 620 int bits)
625{ 621{
626 int s; 622 int oldbit, w;
627 623
628 if (bitmap_weight(old, bits) == 0)
629 return;
630 if (bitmap_weight(new, bits) == 0)
631 return;
632 if (dst == src) /* following doesn't handle inplace remaps */ 624 if (dst == src) /* following doesn't handle inplace remaps */
633 return; 625 return;
634
635 bitmap_zero(dst, bits); 626 bitmap_zero(dst, bits);
636 for (s = find_first_bit(src, bits); 627
637 s < bits; 628 w = bitmap_weight(new, bits);
638 s = find_next_bit(src, bits, s + 1)) { 629 for (oldbit = find_first_bit(src, bits);
639 int x = bitmap_pos_to_ord(old, s, bits); 630 oldbit < bits;
640 int y = bitmap_ord_to_pos(new, x, bits); 631 oldbit = find_next_bit(src, bits, oldbit + 1)) {
641 set_bit(y, dst); 632 int n = bitmap_pos_to_ord(old, oldbit, bits);
633 if (n < 0 || w == 0)
634 set_bit(oldbit, dst); /* identity map */
635 else
636 set_bit(bitmap_ord_to_pos(new, n % w, bits), dst);
642 } 637 }
643} 638}
644EXPORT_SYMBOL(bitmap_remap); 639EXPORT_SYMBOL(bitmap_remap);
@@ -657,8 +652,8 @@ EXPORT_SYMBOL(bitmap_remap);
657 * weight of @old, map the position of the n-th set bit in @old to 652 * weight of @old, map the position of the n-th set bit in @old to
658 * the position of the m-th set bit in @new, where m == n % w. 653 * the position of the m-th set bit in @new, where m == n % w.
659 * 654 *
660 * The positions of unset bits in @old are mapped to the position of 655 * The positions of unset bits in @old are mapped to themselves
661 * the first set bit in @new. 656 * (the identify map).
662 * 657 *
663 * Apply the above specified mapping to bit position @oldbit, returning 658 * Apply the above specified mapping to bit position @oldbit, returning
664 * the new bit position. 659 * the new bit position.
@@ -666,14 +661,18 @@ EXPORT_SYMBOL(bitmap_remap);
666 * For example, lets say that @old has bits 4 through 7 set, and 661 * For example, lets say that @old has bits 4 through 7 set, and
667 * @new has bits 12 through 15 set. This defines the mapping of bit 662 * @new has bits 12 through 15 set. This defines the mapping of bit
668 * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other 663 * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
669 * bit positions to 12 (the first set bit in @new. So if say @oldbit 664 * bit positions unchanged. So if say @oldbit is 5, then this routine
670 * is 5, then this routine returns 13. 665 * returns 13.
671 */ 666 */
672int bitmap_bitremap(int oldbit, const unsigned long *old, 667int bitmap_bitremap(int oldbit, const unsigned long *old,
673 const unsigned long *new, int bits) 668 const unsigned long *new, int bits)
674{ 669{
675 int x = bitmap_pos_to_ord(old, oldbit, bits); 670 int w = bitmap_weight(new, bits);
676 return bitmap_ord_to_pos(new, x, bits); 671 int n = bitmap_pos_to_ord(old, oldbit, bits);
672 if (n < 0 || w == 0)
673 return oldbit;
674 else
675 return bitmap_ord_to_pos(new, n % w, bits);
677} 676}
678EXPORT_SYMBOL(bitmap_bitremap); 677EXPORT_SYMBOL(bitmap_bitremap);
679 678
diff --git a/lib/dec_and_lock.c b/lib/dec_and_lock.c
index 305a9663aee3..a65c31455541 100644
--- a/lib/dec_and_lock.c
+++ b/lib/dec_and_lock.c
@@ -1,47 +1,11 @@
1#include <linux/module.h> 1#include <linux/module.h>
2#include <linux/spinlock.h> 2#include <linux/spinlock.h>
3#include <asm/atomic.h> 3#include <asm/atomic.h>
4#include <asm/system.h>
5 4
6#ifdef __HAVE_ARCH_CMPXCHG
7/* 5/*
8 * This is an implementation of the notion of "decrement a 6 * This is an implementation of the notion of "decrement a
9 * reference count, and return locked if it decremented to zero". 7 * reference count, and return locked if it decremented to zero".
10 * 8 *
11 * This implementation can be used on any architecture that
12 * has a cmpxchg, and where atomic->value is an int holding
13 * the value of the atomic (i.e. the high bits aren't used
14 * for a lock or anything like that).
15 */
16int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
17{
18 int counter;
19 int newcount;
20
21 for (;;) {
22 counter = atomic_read(atomic);
23 newcount = counter - 1;
24 if (!newcount)
25 break; /* do it the slow way */
26
27 newcount = cmpxchg(&atomic->counter, counter, newcount);
28 if (newcount == counter)
29 return 0;
30 }
31
32 spin_lock(lock);
33 if (atomic_dec_and_test(atomic))
34 return 1;
35 spin_unlock(lock);
36 return 0;
37}
38#else
39/*
40 * This is an architecture-neutral, but slow,
41 * implementation of the notion of "decrement
42 * a reference count, and return locked if it
43 * decremented to zero".
44 *
45 * NOTE NOTE NOTE! This is _not_ equivalent to 9 * NOTE NOTE NOTE! This is _not_ equivalent to
46 * 10 *
47 * if (atomic_dec_and_test(&atomic)) { 11 * if (atomic_dec_and_test(&atomic)) {
@@ -52,21 +16,20 @@ int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
52 * 16 *
53 * because the spin-lock and the decrement must be 17 * because the spin-lock and the decrement must be
54 * "atomic". 18 * "atomic".
55 *
56 * This slow version gets the spinlock unconditionally,
57 * and releases it if it isn't needed. Architectures
58 * are encouraged to come up with better approaches,
59 * this is trivially done efficiently using a load-locked
60 * store-conditional approach, for example.
61 */ 19 */
62int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) 20int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
63{ 21{
22#ifdef CONFIG_SMP
23 /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */
24 if (atomic_add_unless(atomic, -1, 1))
25 return 0;
26#endif
27 /* Otherwise do it the slow way */
64 spin_lock(lock); 28 spin_lock(lock);
65 if (atomic_dec_and_test(atomic)) 29 if (atomic_dec_and_test(atomic))
66 return 1; 30 return 1;
67 spin_unlock(lock); 31 spin_unlock(lock);
68 return 0; 32 return 0;
69} 33}
70#endif
71 34
72EXPORT_SYMBOL(_atomic_dec_and_lock); 35EXPORT_SYMBOL(_atomic_dec_and_lock);
diff --git a/lib/find_next_bit.c b/lib/find_next_bit.c
index d08302d2a42c..c05b4b19cf6c 100644
--- a/lib/find_next_bit.c
+++ b/lib/find_next_bit.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/bitops.h> 12#include <linux/bitops.h>
13#include <linux/module.h>
13 14
14int find_next_bit(const unsigned long *addr, int size, int offset) 15int find_next_bit(const unsigned long *addr, int size, int offset)
15{ 16{
@@ -53,3 +54,5 @@ int find_next_bit(const unsigned long *addr, int size, int offset)
53 54
54 return offset; 55 return offset;
55} 56}
57
58EXPORT_SYMBOL(find_next_bit);
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 88511c3805ad..c0bd4a914803 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -137,18 +137,31 @@ out:
137 137
138static inline void tag_set(struct radix_tree_node *node, int tag, int offset) 138static inline void tag_set(struct radix_tree_node *node, int tag, int offset)
139{ 139{
140 if (!test_bit(offset, &node->tags[tag][0])) 140 __set_bit(offset, node->tags[tag]);
141 __set_bit(offset, &node->tags[tag][0]);
142} 141}
143 142
144static inline void tag_clear(struct radix_tree_node *node, int tag, int offset) 143static inline void tag_clear(struct radix_tree_node *node, int tag, int offset)
145{ 144{
146 __clear_bit(offset, &node->tags[tag][0]); 145 __clear_bit(offset, node->tags[tag]);
147} 146}
148 147
149static inline int tag_get(struct radix_tree_node *node, int tag, int offset) 148static inline int tag_get(struct radix_tree_node *node, int tag, int offset)
150{ 149{
151 return test_bit(offset, &node->tags[tag][0]); 150 return test_bit(offset, node->tags[tag]);
151}
152
153/*
154 * Returns 1 if any slot in the node has this tag set.
155 * Otherwise returns 0.
156 */
157static inline int any_tag_set(struct radix_tree_node *node, int tag)
158{
159 int idx;
160 for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) {
161 if (node->tags[tag][idx])
162 return 1;
163 }
164 return 0;
152} 165}
153 166
154/* 167/*
@@ -185,15 +198,9 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index)
185 * into the newly-pushed top-level node(s) 198 * into the newly-pushed top-level node(s)
186 */ 199 */
187 for (tag = 0; tag < RADIX_TREE_TAGS; tag++) { 200 for (tag = 0; tag < RADIX_TREE_TAGS; tag++) {
188 int idx;
189
190 tags[tag] = 0; 201 tags[tag] = 0;
191 for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) { 202 if (any_tag_set(root->rnode, tag))
192 if (root->rnode->tags[tag][idx]) { 203 tags[tag] = 1;
193 tags[tag] = 1;
194 break;
195 }
196 }
197 } 204 }
198 205
199 do { 206 do {
@@ -246,7 +253,7 @@ int radix_tree_insert(struct radix_tree_root *root,
246 shift = (height-1) * RADIX_TREE_MAP_SHIFT; 253 shift = (height-1) * RADIX_TREE_MAP_SHIFT;
247 254
248 offset = 0; /* uninitialised var warning */ 255 offset = 0; /* uninitialised var warning */
249 while (height > 0) { 256 do {
250 if (slot == NULL) { 257 if (slot == NULL) {
251 /* Have to add a child node. */ 258 /* Have to add a child node. */
252 if (!(slot = radix_tree_node_alloc(root))) 259 if (!(slot = radix_tree_node_alloc(root)))
@@ -264,18 +271,16 @@ int radix_tree_insert(struct radix_tree_root *root,
264 slot = node->slots[offset]; 271 slot = node->slots[offset];
265 shift -= RADIX_TREE_MAP_SHIFT; 272 shift -= RADIX_TREE_MAP_SHIFT;
266 height--; 273 height--;
267 } 274 } while (height > 0);
268 275
269 if (slot != NULL) 276 if (slot != NULL)
270 return -EEXIST; 277 return -EEXIST;
271 278
272 if (node) { 279 BUG_ON(!node);
273 node->count++; 280 node->count++;
274 node->slots[offset] = item; 281 node->slots[offset] = item;
275 BUG_ON(tag_get(node, 0, offset)); 282 BUG_ON(tag_get(node, 0, offset));
276 BUG_ON(tag_get(node, 1, offset)); 283 BUG_ON(tag_get(node, 1, offset));
277 } else
278 root->rnode = item;
279 284
280 return 0; 285 return 0;
281} 286}
@@ -367,7 +372,8 @@ void *radix_tree_tag_set(struct radix_tree_root *root,
367 int offset; 372 int offset;
368 373
369 offset = (index >> shift) & RADIX_TREE_MAP_MASK; 374 offset = (index >> shift) & RADIX_TREE_MAP_MASK;
370 tag_set(slot, tag, offset); 375 if (!tag_get(slot, tag, offset))
376 tag_set(slot, tag, offset);
371 slot = slot->slots[offset]; 377 slot = slot->slots[offset];
372 BUG_ON(slot == NULL); 378 BUG_ON(slot == NULL);
373 shift -= RADIX_TREE_MAP_SHIFT; 379 shift -= RADIX_TREE_MAP_SHIFT;
@@ -427,13 +433,11 @@ void *radix_tree_tag_clear(struct radix_tree_root *root,
427 goto out; 433 goto out;
428 434
429 do { 435 do {
430 int idx; 436 if (!tag_get(pathp->node, tag, pathp->offset))
431 437 goto out;
432 tag_clear(pathp->node, tag, pathp->offset); 438 tag_clear(pathp->node, tag, pathp->offset);
433 for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) { 439 if (any_tag_set(pathp->node, tag))
434 if (pathp->node->tags[tag][idx]) 440 goto out;
435 goto out;
436 }
437 pathp--; 441 pathp--;
438 } while (pathp->node); 442 } while (pathp->node);
439out: 443out:
@@ -674,6 +678,29 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,
674EXPORT_SYMBOL(radix_tree_gang_lookup_tag); 678EXPORT_SYMBOL(radix_tree_gang_lookup_tag);
675 679
676/** 680/**
681 * radix_tree_shrink - shrink height of a radix tree to minimal
682 * @root radix tree root
683 */
684static inline void radix_tree_shrink(struct radix_tree_root *root)
685{
686 /* try to shrink tree height */
687 while (root->height > 1 &&
688 root->rnode->count == 1 &&
689 root->rnode->slots[0]) {
690 struct radix_tree_node *to_free = root->rnode;
691
692 root->rnode = to_free->slots[0];
693 root->height--;
694 /* must only free zeroed nodes into the slab */
695 tag_clear(to_free, 0, 0);
696 tag_clear(to_free, 1, 0);
697 to_free->slots[0] = NULL;
698 to_free->count = 0;
699 radix_tree_node_free(to_free);
700 }
701}
702
703/**
677 * radix_tree_delete - delete an item from a radix tree 704 * radix_tree_delete - delete an item from a radix tree
678 * @root: radix tree root 705 * @root: radix tree root
679 * @index: index key 706 * @index: index key
@@ -691,6 +718,8 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
691 void *ret = NULL; 718 void *ret = NULL;
692 char tags[RADIX_TREE_TAGS]; 719 char tags[RADIX_TREE_TAGS];
693 int nr_cleared_tags; 720 int nr_cleared_tags;
721 int tag;
722 int offset;
694 723
695 height = root->height; 724 height = root->height;
696 if (index > radix_tree_maxindex(height)) 725 if (index > radix_tree_maxindex(height))
@@ -701,16 +730,14 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
701 slot = root->rnode; 730 slot = root->rnode;
702 731
703 for ( ; height > 0; height--) { 732 for ( ; height > 0; height--) {
704 int offset;
705
706 if (slot == NULL) 733 if (slot == NULL)
707 goto out; 734 goto out;
708 735
736 pathp++;
709 offset = (index >> shift) & RADIX_TREE_MAP_MASK; 737 offset = (index >> shift) & RADIX_TREE_MAP_MASK;
710 pathp[1].offset = offset; 738 pathp->offset = offset;
711 pathp[1].node = slot; 739 pathp->node = slot;
712 slot = slot->slots[offset]; 740 slot = slot->slots[offset];
713 pathp++;
714 shift -= RADIX_TREE_MAP_SHIFT; 741 shift -= RADIX_TREE_MAP_SHIFT;
715 } 742 }
716 743
@@ -723,35 +750,39 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
723 /* 750 /*
724 * Clear all tags associated with the just-deleted item 751 * Clear all tags associated with the just-deleted item
725 */ 752 */
726 memset(tags, 0, sizeof(tags)); 753 nr_cleared_tags = 0;
727 do { 754 for (tag = 0; tag < RADIX_TREE_TAGS; tag++) {
728 int tag; 755 if (tag_get(pathp->node, tag, pathp->offset)) {
756 tag_clear(pathp->node, tag, pathp->offset);
757 tags[tag] = 0;
758 nr_cleared_tags++;
759 } else
760 tags[tag] = 1;
761 }
729 762
730 nr_cleared_tags = RADIX_TREE_TAGS; 763 for (pathp--; nr_cleared_tags && pathp->node; pathp--) {
731 for (tag = 0; tag < RADIX_TREE_TAGS; tag++) { 764 for (tag = 0; tag < RADIX_TREE_TAGS; tag++) {
732 int idx;
733
734 if (tags[tag]) 765 if (tags[tag])
735 continue; 766 continue;
736 767
737 tag_clear(pathp->node, tag, pathp->offset); 768 tag_clear(pathp->node, tag, pathp->offset);
738 769 if (any_tag_set(pathp->node, tag)) {
739 for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) { 770 tags[tag] = 1;
740 if (pathp->node->tags[tag][idx]) { 771 nr_cleared_tags--;
741 tags[tag] = 1;
742 nr_cleared_tags--;
743 break;
744 }
745 } 772 }
746 } 773 }
747 pathp--; 774 }
748 } while (pathp->node && nr_cleared_tags);
749 775
750 /* Now free the nodes we do not need anymore */ 776 /* Now free the nodes we do not need anymore */
751 for (pathp = orig_pathp; pathp->node; pathp--) { 777 for (pathp = orig_pathp; pathp->node; pathp--) {
752 pathp->node->slots[pathp->offset] = NULL; 778 pathp->node->slots[pathp->offset] = NULL;
753 if (--pathp->node->count) 779 pathp->node->count--;
780
781 if (pathp->node->count) {
782 if (pathp->node == root->rnode)
783 radix_tree_shrink(root);
754 goto out; 784 goto out;
785 }
755 786
756 /* Node with zero slots in use so free it */ 787 /* Node with zero slots in use so free it */
757 radix_tree_node_free(pathp->node); 788 radix_tree_node_free(pathp->node);
@@ -770,15 +801,11 @@ EXPORT_SYMBOL(radix_tree_delete);
770 */ 801 */
771int radix_tree_tagged(struct radix_tree_root *root, int tag) 802int radix_tree_tagged(struct radix_tree_root *root, int tag)
772{ 803{
773 int idx; 804 struct radix_tree_node *rnode;
774 805 rnode = root->rnode;
775 if (!root->rnode) 806 if (!rnode)
776 return 0; 807 return 0;
777 for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) { 808 return any_tag_set(rnode, tag);
778 if (root->rnode->tags[tag][idx])
779 return 1;
780 }
781 return 0;
782} 809}
783EXPORT_SYMBOL(radix_tree_tagged); 810EXPORT_SYMBOL(radix_tree_tagged);
784 811
diff --git a/mm/Kconfig b/mm/Kconfig
index b3db11f137e0..a9cb80ae6409 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -132,3 +132,10 @@ config SPLIT_PTLOCK_CPUS
132 default "4096" if ARM && !CPU_CACHE_VIPT 132 default "4096" if ARM && !CPU_CACHE_VIPT
133 default "4096" if PARISC && !PA20 133 default "4096" if PARISC && !PA20
134 default "4" 134 default "4"
135
136#
137# support for page migration
138#
139config MIGRATION
140 def_bool y if NUMA || SPARSEMEM || DISCONTIGMEM
141 depends on SWAP
diff --git a/mm/Makefile b/mm/Makefile
index 2fa6d2ca9f28..9aa03fa1dcc3 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -9,8 +9,8 @@ mmu-$(CONFIG_MMU) := fremap.o highmem.o madvise.o memory.o mincore.o \
9 9
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 slab.o swap.o truncate.o vmscan.o \ 12 readahead.o swap.o truncate.o vmscan.o \
13 prio_tree.o $(mmu-y) 13 prio_tree.o util.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
@@ -18,5 +18,7 @@ obj-$(CONFIG_NUMA) += mempolicy.o
18obj-$(CONFIG_SPARSEMEM) += sparse.o 18obj-$(CONFIG_SPARSEMEM) += sparse.o
19obj-$(CONFIG_SHMEM) += shmem.o 19obj-$(CONFIG_SHMEM) += shmem.o
20obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o 20obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
21obj-$(CONFIG_SLOB) += slob.o
22obj-$(CONFIG_SLAB) += slab.o
21obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o 23obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
22obj-$(CONFIG_FS_XIP) += filemap_xip.o 24obj-$(CONFIG_FS_XIP) += filemap_xip.o
diff --git a/mm/fadvise.c b/mm/fadvise.c
index 5f19e87bc5af..d257c89e7704 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -37,6 +37,11 @@ asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
37 if (!file) 37 if (!file)
38 return -EBADF; 38 return -EBADF;
39 39
40 if (S_ISFIFO(file->f_dentry->d_inode->i_mode)) {
41 ret = -ESPIPE;
42 goto out;
43 }
44
40 mapping = file->f_mapping; 45 mapping = file->f_mapping;
41 if (!mapping || len < 0) { 46 if (!mapping || len < 0) {
42 ret = -EINVAL; 47 ret = -EINVAL;
diff --git a/mm/filemap.c b/mm/filemap.c
index 4ef24a397684..478f4c74cc31 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -280,7 +280,7 @@ static int wait_on_page_writeback_range(struct address_space *mapping,
280 * it is otherwise livelockable. 280 * it is otherwise livelockable.
281 */ 281 */
282int sync_page_range(struct inode *inode, struct address_space *mapping, 282int sync_page_range(struct inode *inode, struct address_space *mapping,
283 loff_t pos, size_t count) 283 loff_t pos, loff_t count)
284{ 284{
285 pgoff_t start = pos >> PAGE_CACHE_SHIFT; 285 pgoff_t start = pos >> PAGE_CACHE_SHIFT;
286 pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT; 286 pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
@@ -305,9 +305,8 @@ EXPORT_SYMBOL(sync_page_range);
305 * as it forces O_SYNC writers to different parts of the same file 305 * as it forces O_SYNC writers to different parts of the same file
306 * to be serialised right until io completion. 306 * to be serialised right until io completion.
307 */ 307 */
308static int sync_page_range_nolock(struct inode *inode, 308int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
309 struct address_space *mapping, 309 loff_t pos, loff_t count)
310 loff_t pos, size_t count)
311{ 310{
312 pgoff_t start = pos >> PAGE_CACHE_SHIFT; 311 pgoff_t start = pos >> PAGE_CACHE_SHIFT;
313 pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT; 312 pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
@@ -322,6 +321,7 @@ static int sync_page_range_nolock(struct inode *inode,
322 ret = wait_on_page_writeback_range(mapping, start, end); 321 ret = wait_on_page_writeback_range(mapping, start, end);
323 return ret; 322 return ret;
324} 323}
324EXPORT_SYMBOL(sync_page_range_nolock);
325 325
326/** 326/**
327 * filemap_fdatawait - walk the list of under-writeback pages of the given 327 * filemap_fdatawait - walk the list of under-writeback pages of the given
@@ -343,30 +343,44 @@ EXPORT_SYMBOL(filemap_fdatawait);
343 343
344int filemap_write_and_wait(struct address_space *mapping) 344int filemap_write_and_wait(struct address_space *mapping)
345{ 345{
346 int retval = 0; 346 int err = 0;
347 347
348 if (mapping->nrpages) { 348 if (mapping->nrpages) {
349 retval = filemap_fdatawrite(mapping); 349 err = filemap_fdatawrite(mapping);
350 if (retval == 0) 350 /*
351 retval = filemap_fdatawait(mapping); 351 * Even if the above returned error, the pages may be
352 * written partially (e.g. -ENOSPC), so we wait for it.
353 * But the -EIO is special case, it may indicate the worst
354 * thing (e.g. bug) happened, so we avoid waiting for it.
355 */
356 if (err != -EIO) {
357 int err2 = filemap_fdatawait(mapping);
358 if (!err)
359 err = err2;
360 }
352 } 361 }
353 return retval; 362 return err;
354} 363}
364EXPORT_SYMBOL(filemap_write_and_wait);
355 365
356int filemap_write_and_wait_range(struct address_space *mapping, 366int filemap_write_and_wait_range(struct address_space *mapping,
357 loff_t lstart, loff_t lend) 367 loff_t lstart, loff_t lend)
358{ 368{
359 int retval = 0; 369 int err = 0;
360 370
361 if (mapping->nrpages) { 371 if (mapping->nrpages) {
362 retval = __filemap_fdatawrite_range(mapping, lstart, lend, 372 err = __filemap_fdatawrite_range(mapping, lstart, lend,
363 WB_SYNC_ALL); 373 WB_SYNC_ALL);
364 if (retval == 0) 374 /* See comment of filemap_write_and_wait() */
365 retval = wait_on_page_writeback_range(mapping, 375 if (err != -EIO) {
366 lstart >> PAGE_CACHE_SHIFT, 376 int err2 = wait_on_page_writeback_range(mapping,
367 lend >> PAGE_CACHE_SHIFT); 377 lstart >> PAGE_CACHE_SHIFT,
378 lend >> PAGE_CACHE_SHIFT);
379 if (!err)
380 err = err2;
381 }
368 } 382 }
369 return retval; 383 return err;
370} 384}
371 385
372/* 386/*
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index f4c43d7980ba..b21d78c941b5 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -12,6 +12,7 @@
12#include <linux/nodemask.h> 12#include <linux/nodemask.h>
13#include <linux/pagemap.h> 13#include <linux/pagemap.h>
14#include <linux/mempolicy.h> 14#include <linux/mempolicy.h>
15#include <linux/cpuset.h>
15 16
16#include <asm/page.h> 17#include <asm/page.h>
17#include <asm/pgtable.h> 18#include <asm/pgtable.h>
@@ -48,7 +49,8 @@ static struct page *dequeue_huge_page(struct vm_area_struct *vma,
48 49
49 for (z = zonelist->zones; *z; z++) { 50 for (z = zonelist->zones; *z; z++) {
50 nid = (*z)->zone_pgdat->node_id; 51 nid = (*z)->zone_pgdat->node_id;
51 if (!list_empty(&hugepage_freelists[nid])) 52 if (cpuset_zone_allowed(*z, GFP_HIGHUSER) &&
53 !list_empty(&hugepage_freelists[nid]))
52 break; 54 break;
53 } 55 }
54 56
diff --git a/mm/memory.c b/mm/memory.c
index 7197f9bcd384..3944fec38012 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2267,6 +2267,8 @@ int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
2267 return handle_pte_fault(mm, vma, address, pte, pmd, write_access); 2267 return handle_pte_fault(mm, vma, address, pte, pmd, write_access);
2268} 2268}
2269 2269
2270EXPORT_SYMBOL_GPL(__handle_mm_fault);
2271
2270#ifndef __PAGETABLE_PUD_FOLDED 2272#ifndef __PAGETABLE_PUD_FOLDED
2271/* 2273/*
2272 * Allocate page upper directory. 2274 * Allocate page upper directory.
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 0f1d2b8a952b..1850d0aef4ac 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -83,9 +83,18 @@
83#include <linux/init.h> 83#include <linux/init.h>
84#include <linux/compat.h> 84#include <linux/compat.h>
85#include <linux/mempolicy.h> 85#include <linux/mempolicy.h>
86#include <linux/swap.h>
87#include <linux/seq_file.h>
88#include <linux/proc_fs.h>
89
86#include <asm/tlbflush.h> 90#include <asm/tlbflush.h>
87#include <asm/uaccess.h> 91#include <asm/uaccess.h>
88 92
93/* Internal flags */
94#define MPOL_MF_DISCONTIG_OK (MPOL_MF_INTERNAL << 0) /* Skip checks for continuous vmas */
95#define MPOL_MF_INVERT (MPOL_MF_INTERNAL << 1) /* Invert check for nodemask */
96#define MPOL_MF_STATS (MPOL_MF_INTERNAL << 2) /* Gather statistics */
97
89static kmem_cache_t *policy_cache; 98static kmem_cache_t *policy_cache;
90static kmem_cache_t *sn_cache; 99static kmem_cache_t *sn_cache;
91 100
@@ -171,12 +180,19 @@ static struct mempolicy *mpol_new(int mode, nodemask_t *nodes)
171 break; 180 break;
172 } 181 }
173 policy->policy = mode; 182 policy->policy = mode;
183 policy->cpuset_mems_allowed = cpuset_mems_allowed(current);
174 return policy; 184 return policy;
175} 185}
176 186
177/* Ensure all existing pages follow the policy. */ 187static void gather_stats(struct page *, void *);
188static void migrate_page_add(struct vm_area_struct *vma,
189 struct page *page, struct list_head *pagelist, unsigned long flags);
190
191/* Scan through pages checking if pages follow certain conditions. */
178static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd, 192static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
179 unsigned long addr, unsigned long end, nodemask_t *nodes) 193 unsigned long addr, unsigned long end,
194 const nodemask_t *nodes, unsigned long flags,
195 void *private)
180{ 196{
181 pte_t *orig_pte; 197 pte_t *orig_pte;
182 pte_t *pte; 198 pte_t *pte;
@@ -193,7 +209,17 @@ static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
193 if (!page) 209 if (!page)
194 continue; 210 continue;
195 nid = page_to_nid(page); 211 nid = page_to_nid(page);
196 if (!node_isset(nid, *nodes)) 212 if (node_isset(nid, *nodes) == !!(flags & MPOL_MF_INVERT))
213 continue;
214
215 if (flags & MPOL_MF_STATS)
216 gather_stats(page, private);
217 else if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) {
218 spin_unlock(ptl);
219 migrate_page_add(vma, page, private, flags);
220 spin_lock(ptl);
221 }
222 else
197 break; 223 break;
198 } while (pte++, addr += PAGE_SIZE, addr != end); 224 } while (pte++, addr += PAGE_SIZE, addr != end);
199 pte_unmap_unlock(orig_pte, ptl); 225 pte_unmap_unlock(orig_pte, ptl);
@@ -201,7 +227,9 @@ static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
201} 227}
202 228
203static inline int check_pmd_range(struct vm_area_struct *vma, pud_t *pud, 229static inline int check_pmd_range(struct vm_area_struct *vma, pud_t *pud,
204 unsigned long addr, unsigned long end, nodemask_t *nodes) 230 unsigned long addr, unsigned long end,
231 const nodemask_t *nodes, unsigned long flags,
232 void *private)
205{ 233{
206 pmd_t *pmd; 234 pmd_t *pmd;
207 unsigned long next; 235 unsigned long next;
@@ -211,14 +239,17 @@ static inline int check_pmd_range(struct vm_area_struct *vma, pud_t *pud,
211 next = pmd_addr_end(addr, end); 239 next = pmd_addr_end(addr, end);
212 if (pmd_none_or_clear_bad(pmd)) 240 if (pmd_none_or_clear_bad(pmd))
213 continue; 241 continue;
214 if (check_pte_range(vma, pmd, addr, next, nodes)) 242 if (check_pte_range(vma, pmd, addr, next, nodes,
243 flags, private))
215 return -EIO; 244 return -EIO;
216 } while (pmd++, addr = next, addr != end); 245 } while (pmd++, addr = next, addr != end);
217 return 0; 246 return 0;
218} 247}
219 248
220static inline int check_pud_range(struct vm_area_struct *vma, pgd_t *pgd, 249static inline int check_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
221 unsigned long addr, unsigned long end, nodemask_t *nodes) 250 unsigned long addr, unsigned long end,
251 const nodemask_t *nodes, unsigned long flags,
252 void *private)
222{ 253{
223 pud_t *pud; 254 pud_t *pud;
224 unsigned long next; 255 unsigned long next;
@@ -228,14 +259,17 @@ static inline int check_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
228 next = pud_addr_end(addr, end); 259 next = pud_addr_end(addr, end);
229 if (pud_none_or_clear_bad(pud)) 260 if (pud_none_or_clear_bad(pud))
230 continue; 261 continue;
231 if (check_pmd_range(vma, pud, addr, next, nodes)) 262 if (check_pmd_range(vma, pud, addr, next, nodes,
263 flags, private))
232 return -EIO; 264 return -EIO;
233 } while (pud++, addr = next, addr != end); 265 } while (pud++, addr = next, addr != end);
234 return 0; 266 return 0;
235} 267}
236 268
237static inline int check_pgd_range(struct vm_area_struct *vma, 269static inline int check_pgd_range(struct vm_area_struct *vma,
238 unsigned long addr, unsigned long end, nodemask_t *nodes) 270 unsigned long addr, unsigned long end,
271 const nodemask_t *nodes, unsigned long flags,
272 void *private)
239{ 273{
240 pgd_t *pgd; 274 pgd_t *pgd;
241 unsigned long next; 275 unsigned long next;
@@ -245,16 +279,30 @@ static inline int check_pgd_range(struct vm_area_struct *vma,
245 next = pgd_addr_end(addr, end); 279 next = pgd_addr_end(addr, end);
246 if (pgd_none_or_clear_bad(pgd)) 280 if (pgd_none_or_clear_bad(pgd))
247 continue; 281 continue;
248 if (check_pud_range(vma, pgd, addr, next, nodes)) 282 if (check_pud_range(vma, pgd, addr, next, nodes,
283 flags, private))
249 return -EIO; 284 return -EIO;
250 } while (pgd++, addr = next, addr != end); 285 } while (pgd++, addr = next, addr != end);
251 return 0; 286 return 0;
252} 287}
253 288
254/* Step 1: check the range */ 289/* Check if a vma is migratable */
290static inline int vma_migratable(struct vm_area_struct *vma)
291{
292 if (vma->vm_flags & (
293 VM_LOCKED|VM_IO|VM_HUGETLB|VM_PFNMAP))
294 return 0;
295 return 1;
296}
297
298/*
299 * Check if all pages in a range are on a set of nodes.
300 * If pagelist != NULL then isolate pages from the LRU and
301 * put them on the pagelist.
302 */
255static struct vm_area_struct * 303static struct vm_area_struct *
256check_range(struct mm_struct *mm, unsigned long start, unsigned long end, 304check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
257 nodemask_t *nodes, unsigned long flags) 305 const nodemask_t *nodes, unsigned long flags, void *private)
258{ 306{
259 int err; 307 int err;
260 struct vm_area_struct *first, *vma, *prev; 308 struct vm_area_struct *first, *vma, *prev;
@@ -264,17 +312,24 @@ check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
264 return ERR_PTR(-EFAULT); 312 return ERR_PTR(-EFAULT);
265 prev = NULL; 313 prev = NULL;
266 for (vma = first; vma && vma->vm_start < end; vma = vma->vm_next) { 314 for (vma = first; vma && vma->vm_start < end; vma = vma->vm_next) {
267 if (!vma->vm_next && vma->vm_end < end) 315 if (!(flags & MPOL_MF_DISCONTIG_OK)) {
268 return ERR_PTR(-EFAULT); 316 if (!vma->vm_next && vma->vm_end < end)
269 if (prev && prev->vm_end < vma->vm_start) 317 return ERR_PTR(-EFAULT);
270 return ERR_PTR(-EFAULT); 318 if (prev && prev->vm_end < vma->vm_start)
271 if ((flags & MPOL_MF_STRICT) && !is_vm_hugetlb_page(vma)) { 319 return ERR_PTR(-EFAULT);
320 }
321 if (!is_vm_hugetlb_page(vma) &&
322 ((flags & MPOL_MF_STRICT) ||
323 ((flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) &&
324 vma_migratable(vma)))) {
272 unsigned long endvma = vma->vm_end; 325 unsigned long endvma = vma->vm_end;
326
273 if (endvma > end) 327 if (endvma > end)
274 endvma = end; 328 endvma = end;
275 if (vma->vm_start > start) 329 if (vma->vm_start > start)
276 start = vma->vm_start; 330 start = vma->vm_start;
277 err = check_pgd_range(vma, start, endvma, nodes); 331 err = check_pgd_range(vma, start, endvma, nodes,
332 flags, private);
278 if (err) { 333 if (err) {
279 first = ERR_PTR(err); 334 first = ERR_PTR(err);
280 break; 335 break;
@@ -333,51 +388,10 @@ static int contextualize_policy(int mode, nodemask_t *nodes)
333 if (!nodes) 388 if (!nodes)
334 return 0; 389 return 0;
335 390
336 /* Update current mems_allowed */ 391 cpuset_update_task_memory_state();
337 cpuset_update_current_mems_allowed(); 392 if (!cpuset_nodes_subset_current_mems_allowed(*nodes))
338 /* Ignore nodes not set in current->mems_allowed */
339 cpuset_restrict_to_mems_allowed(nodes->bits);
340 return mpol_check_policy(mode, nodes);
341}
342
343long do_mbind(unsigned long start, unsigned long len,
344 unsigned long mode, nodemask_t *nmask, unsigned long flags)
345{
346 struct vm_area_struct *vma;
347 struct mm_struct *mm = current->mm;
348 struct mempolicy *new;
349 unsigned long end;
350 int err;
351
352 if ((flags & ~(unsigned long)(MPOL_MF_STRICT)) || mode > MPOL_MAX)
353 return -EINVAL;
354 if (start & ~PAGE_MASK)
355 return -EINVAL;
356 if (mode == MPOL_DEFAULT)
357 flags &= ~MPOL_MF_STRICT;
358 len = (len + PAGE_SIZE - 1) & PAGE_MASK;
359 end = start + len;
360 if (end < start)
361 return -EINVAL; 393 return -EINVAL;
362 if (end == start) 394 return mpol_check_policy(mode, nodes);
363 return 0;
364 if (mpol_check_policy(mode, nmask))
365 return -EINVAL;
366 new = mpol_new(mode, nmask);
367 if (IS_ERR(new))
368 return PTR_ERR(new);
369
370 PDprintk("mbind %lx-%lx mode:%ld nodes:%lx\n",start,start+len,
371 mode,nodes_addr(nodes)[0]);
372
373 down_write(&mm->mmap_sem);
374 vma = check_range(mm, start, end, nmask, flags);
375 err = PTR_ERR(vma);
376 if (!IS_ERR(vma))
377 err = mbind_range(vma, start, end, new);
378 up_write(&mm->mmap_sem);
379 mpol_free(new);
380 return err;
381} 395}
382 396
383/* Set the process memory policy */ 397/* Set the process memory policy */
@@ -448,7 +462,7 @@ long do_get_mempolicy(int *policy, nodemask_t *nmask,
448 struct vm_area_struct *vma = NULL; 462 struct vm_area_struct *vma = NULL;
449 struct mempolicy *pol = current->mempolicy; 463 struct mempolicy *pol = current->mempolicy;
450 464
451 cpuset_update_current_mems_allowed(); 465 cpuset_update_task_memory_state();
452 if (flags & ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR)) 466 if (flags & ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR))
453 return -EINVAL; 467 return -EINVAL;
454 if (flags & MPOL_F_ADDR) { 468 if (flags & MPOL_F_ADDR) {
@@ -500,11 +514,177 @@ long do_get_mempolicy(int *policy, nodemask_t *nmask,
500} 514}
501 515
502/* 516/*
517 * page migration
518 */
519
520/* Check if we are the only process mapping the page in question */
521static inline int single_mm_mapping(struct mm_struct *mm,
522 struct address_space *mapping)
523{
524 struct vm_area_struct *vma;
525 struct prio_tree_iter iter;
526 int rc = 1;
527
528 spin_lock(&mapping->i_mmap_lock);
529 vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, 0, ULONG_MAX)
530 if (mm != vma->vm_mm) {
531 rc = 0;
532 goto out;
533 }
534 list_for_each_entry(vma, &mapping->i_mmap_nonlinear, shared.vm_set.list)
535 if (mm != vma->vm_mm) {
536 rc = 0;
537 goto out;
538 }
539out:
540 spin_unlock(&mapping->i_mmap_lock);
541 return rc;
542}
543
544/*
545 * Add a page to be migrated to the pagelist
546 */
547static void migrate_page_add(struct vm_area_struct *vma,
548 struct page *page, struct list_head *pagelist, unsigned long flags)
549{
550 /*
551 * Avoid migrating a page that is shared by others and not writable.
552 */
553 if ((flags & MPOL_MF_MOVE_ALL) || !page->mapping || PageAnon(page) ||
554 mapping_writably_mapped(page->mapping) ||
555 single_mm_mapping(vma->vm_mm, page->mapping)) {
556 int rc = isolate_lru_page(page);
557
558 if (rc == 1)
559 list_add(&page->lru, pagelist);
560 /*
561 * If the isolate attempt was not successful then we just
562 * encountered an unswappable page. Something must be wrong.
563 */
564 WARN_ON(rc == 0);
565 }
566}
567
568static int swap_pages(struct list_head *pagelist)
569{
570 LIST_HEAD(moved);
571 LIST_HEAD(failed);
572 int n;
573
574 n = migrate_pages(pagelist, NULL, &moved, &failed);
575 putback_lru_pages(&failed);
576 putback_lru_pages(&moved);
577
578 return n;
579}
580
581/*
582 * For now migrate_pages simply swaps out the pages from nodes that are in
583 * the source set but not in the target set. In the future, we would
584 * want a function that moves pages between the two nodesets in such
585 * a way as to preserve the physical layout as much as possible.
586 *
587 * Returns the number of page that could not be moved.
588 */
589int do_migrate_pages(struct mm_struct *mm,
590 const nodemask_t *from_nodes, const nodemask_t *to_nodes, int flags)
591{
592 LIST_HEAD(pagelist);
593 int count = 0;
594 nodemask_t nodes;
595
596 nodes_andnot(nodes, *from_nodes, *to_nodes);
597
598 down_read(&mm->mmap_sem);
599 check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nodes,
600 flags | MPOL_MF_DISCONTIG_OK, &pagelist);
601
602 if (!list_empty(&pagelist)) {
603 count = swap_pages(&pagelist);
604 putback_lru_pages(&pagelist);
605 }
606
607 up_read(&mm->mmap_sem);
608 return count;
609}
610
611long do_mbind(unsigned long start, unsigned long len,
612 unsigned long mode, nodemask_t *nmask, unsigned long flags)
613{
614 struct vm_area_struct *vma;
615 struct mm_struct *mm = current->mm;
616 struct mempolicy *new;
617 unsigned long end;
618 int err;
619 LIST_HEAD(pagelist);
620
621 if ((flags & ~(unsigned long)(MPOL_MF_STRICT |
622 MPOL_MF_MOVE | MPOL_MF_MOVE_ALL))
623 || mode > MPOL_MAX)
624 return -EINVAL;
625 if ((flags & MPOL_MF_MOVE_ALL) && !capable(CAP_SYS_RESOURCE))
626 return -EPERM;
627
628 if (start & ~PAGE_MASK)
629 return -EINVAL;
630
631 if (mode == MPOL_DEFAULT)
632 flags &= ~MPOL_MF_STRICT;
633
634 len = (len + PAGE_SIZE - 1) & PAGE_MASK;
635 end = start + len;
636
637 if (end < start)
638 return -EINVAL;
639 if (end == start)
640 return 0;
641
642 if (mpol_check_policy(mode, nmask))
643 return -EINVAL;
644
645 new = mpol_new(mode, nmask);
646 if (IS_ERR(new))
647 return PTR_ERR(new);
648
649 /*
650 * If we are using the default policy then operation
651 * on discontinuous address spaces is okay after all
652 */
653 if (!new)
654 flags |= MPOL_MF_DISCONTIG_OK;
655
656 PDprintk("mbind %lx-%lx mode:%ld nodes:%lx\n",start,start+len,
657 mode,nodes_addr(nodes)[0]);
658
659 down_write(&mm->mmap_sem);
660 vma = check_range(mm, start, end, nmask,
661 flags | MPOL_MF_INVERT, &pagelist);
662
663 err = PTR_ERR(vma);
664 if (!IS_ERR(vma)) {
665 int nr_failed = 0;
666
667 err = mbind_range(vma, start, end, new);
668 if (!list_empty(&pagelist))
669 nr_failed = swap_pages(&pagelist);
670
671 if (!err && nr_failed && (flags & MPOL_MF_STRICT))
672 err = -EIO;
673 }
674 if (!list_empty(&pagelist))
675 putback_lru_pages(&pagelist);
676
677 up_write(&mm->mmap_sem);
678 mpol_free(new);
679 return err;
680}
681
682/*
503 * User space interface with variable sized bitmaps for nodelists. 683 * User space interface with variable sized bitmaps for nodelists.
504 */ 684 */
505 685
506/* Copy a node mask from user space. */ 686/* Copy a node mask from user space. */
507static int get_nodes(nodemask_t *nodes, unsigned long __user *nmask, 687static int get_nodes(nodemask_t *nodes, const unsigned long __user *nmask,
508 unsigned long maxnode) 688 unsigned long maxnode)
509{ 689{
510 unsigned long k; 690 unsigned long k;
@@ -593,6 +773,65 @@ asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
593 return do_set_mempolicy(mode, &nodes); 773 return do_set_mempolicy(mode, &nodes);
594} 774}
595 775
776asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
777 const unsigned long __user *old_nodes,
778 const unsigned long __user *new_nodes)
779{
780 struct mm_struct *mm;
781 struct task_struct *task;
782 nodemask_t old;
783 nodemask_t new;
784 nodemask_t task_nodes;
785 int err;
786
787 err = get_nodes(&old, old_nodes, maxnode);
788 if (err)
789 return err;
790
791 err = get_nodes(&new, new_nodes, maxnode);
792 if (err)
793 return err;
794
795 /* Find the mm_struct */
796 read_lock(&tasklist_lock);
797 task = pid ? find_task_by_pid(pid) : current;
798 if (!task) {
799 read_unlock(&tasklist_lock);
800 return -ESRCH;
801 }
802 mm = get_task_mm(task);
803 read_unlock(&tasklist_lock);
804
805 if (!mm)
806 return -EINVAL;
807
808 /*
809 * Check if this process has the right to modify the specified
810 * process. The right exists if the process has administrative
811 * capabilities, superuser priviledges or the same
812 * userid as the target process.
813 */
814 if ((current->euid != task->suid) && (current->euid != task->uid) &&
815 (current->uid != task->suid) && (current->uid != task->uid) &&
816 !capable(CAP_SYS_ADMIN)) {
817 err = -EPERM;
818 goto out;
819 }
820
821 task_nodes = cpuset_mems_allowed(task);
822 /* Is the user allowed to access the target nodes? */
823 if (!nodes_subset(new, task_nodes) && !capable(CAP_SYS_ADMIN)) {
824 err = -EPERM;
825 goto out;
826 }
827
828 err = do_migrate_pages(mm, &old, &new, MPOL_MF_MOVE);
829out:
830 mmput(mm);
831 return err;
832}
833
834
596/* Retrieve NUMA policy */ 835/* Retrieve NUMA policy */
597asmlinkage long sys_get_mempolicy(int __user *policy, 836asmlinkage long sys_get_mempolicy(int __user *policy,
598 unsigned long __user *nmask, 837 unsigned long __user *nmask,
@@ -699,8 +938,8 @@ asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len,
699#endif 938#endif
700 939
701/* Return effective policy for a VMA */ 940/* Return effective policy for a VMA */
702struct mempolicy * 941static struct mempolicy * get_vma_policy(struct task_struct *task,
703get_vma_policy(struct task_struct *task, struct vm_area_struct *vma, unsigned long addr) 942 struct vm_area_struct *vma, unsigned long addr)
704{ 943{
705 struct mempolicy *pol = task->mempolicy; 944 struct mempolicy *pol = task->mempolicy;
706 945
@@ -848,7 +1087,7 @@ alloc_page_vma(gfp_t gfp, struct vm_area_struct *vma, unsigned long addr)
848{ 1087{
849 struct mempolicy *pol = get_vma_policy(current, vma, addr); 1088 struct mempolicy *pol = get_vma_policy(current, vma, addr);
850 1089
851 cpuset_update_current_mems_allowed(); 1090 cpuset_update_task_memory_state();
852 1091
853 if (unlikely(pol->policy == MPOL_INTERLEAVE)) { 1092 if (unlikely(pol->policy == MPOL_INTERLEAVE)) {
854 unsigned nid; 1093 unsigned nid;
@@ -874,7 +1113,7 @@ alloc_page_vma(gfp_t gfp, struct vm_area_struct *vma, unsigned long addr)
874 * interrupt context and apply the current process NUMA policy. 1113 * interrupt context and apply the current process NUMA policy.
875 * Returns NULL when no page can be allocated. 1114 * Returns NULL when no page can be allocated.
876 * 1115 *
877 * Don't call cpuset_update_current_mems_allowed() unless 1116 * Don't call cpuset_update_task_memory_state() unless
878 * 1) it's ok to take cpuset_sem (can WAIT), and 1117 * 1) it's ok to take cpuset_sem (can WAIT), and
879 * 2) allocating for current task (not interrupt). 1118 * 2) allocating for current task (not interrupt).
880 */ 1119 */
@@ -883,7 +1122,7 @@ struct page *alloc_pages_current(gfp_t gfp, unsigned order)
883 struct mempolicy *pol = current->mempolicy; 1122 struct mempolicy *pol = current->mempolicy;
884 1123
885 if ((gfp & __GFP_WAIT) && !in_interrupt()) 1124 if ((gfp & __GFP_WAIT) && !in_interrupt())
886 cpuset_update_current_mems_allowed(); 1125 cpuset_update_task_memory_state();
887 if (!pol || in_interrupt()) 1126 if (!pol || in_interrupt())
888 pol = &default_policy; 1127 pol = &default_policy;
889 if (pol->policy == MPOL_INTERLEAVE) 1128 if (pol->policy == MPOL_INTERLEAVE)
@@ -892,6 +1131,15 @@ struct page *alloc_pages_current(gfp_t gfp, unsigned order)
892} 1131}
893EXPORT_SYMBOL(alloc_pages_current); 1132EXPORT_SYMBOL(alloc_pages_current);
894 1133
1134/*
1135 * If mpol_copy() sees current->cpuset == cpuset_being_rebound, then it
1136 * rebinds the mempolicy its copying by calling mpol_rebind_policy()
1137 * with the mems_allowed returned by cpuset_mems_allowed(). This
1138 * keeps mempolicies cpuset relative after its cpuset moves. See
1139 * further kernel/cpuset.c update_nodemask().
1140 */
1141void *cpuset_being_rebound;
1142
895/* Slow path of a mempolicy copy */ 1143/* Slow path of a mempolicy copy */
896struct mempolicy *__mpol_copy(struct mempolicy *old) 1144struct mempolicy *__mpol_copy(struct mempolicy *old)
897{ 1145{
@@ -899,6 +1147,10 @@ struct mempolicy *__mpol_copy(struct mempolicy *old)
899 1147
900 if (!new) 1148 if (!new)
901 return ERR_PTR(-ENOMEM); 1149 return ERR_PTR(-ENOMEM);
1150 if (current_cpuset_is_being_rebound()) {
1151 nodemask_t mems = cpuset_mems_allowed(current);
1152 mpol_rebind_policy(old, &mems);
1153 }
902 *new = *old; 1154 *new = *old;
903 atomic_set(&new->refcnt, 1); 1155 atomic_set(&new->refcnt, 1);
904 if (new->policy == MPOL_BIND) { 1156 if (new->policy == MPOL_BIND) {
@@ -1173,25 +1425,31 @@ void numa_default_policy(void)
1173} 1425}
1174 1426
1175/* Migrate a policy to a different set of nodes */ 1427/* Migrate a policy to a different set of nodes */
1176static void rebind_policy(struct mempolicy *pol, const nodemask_t *old, 1428void mpol_rebind_policy(struct mempolicy *pol, const nodemask_t *newmask)
1177 const nodemask_t *new)
1178{ 1429{
1430 nodemask_t *mpolmask;
1179 nodemask_t tmp; 1431 nodemask_t tmp;
1180 1432
1181 if (!pol) 1433 if (!pol)
1182 return; 1434 return;
1435 mpolmask = &pol->cpuset_mems_allowed;
1436 if (nodes_equal(*mpolmask, *newmask))
1437 return;
1183 1438
1184 switch (pol->policy) { 1439 switch (pol->policy) {
1185 case MPOL_DEFAULT: 1440 case MPOL_DEFAULT:
1186 break; 1441 break;
1187 case MPOL_INTERLEAVE: 1442 case MPOL_INTERLEAVE:
1188 nodes_remap(tmp, pol->v.nodes, *old, *new); 1443 nodes_remap(tmp, pol->v.nodes, *mpolmask, *newmask);
1189 pol->v.nodes = tmp; 1444 pol->v.nodes = tmp;
1190 current->il_next = node_remap(current->il_next, *old, *new); 1445 *mpolmask = *newmask;
1446 current->il_next = node_remap(current->il_next,
1447 *mpolmask, *newmask);
1191 break; 1448 break;
1192 case MPOL_PREFERRED: 1449 case MPOL_PREFERRED:
1193 pol->v.preferred_node = node_remap(pol->v.preferred_node, 1450 pol->v.preferred_node = node_remap(pol->v.preferred_node,
1194 *old, *new); 1451 *mpolmask, *newmask);
1452 *mpolmask = *newmask;
1195 break; 1453 break;
1196 case MPOL_BIND: { 1454 case MPOL_BIND: {
1197 nodemask_t nodes; 1455 nodemask_t nodes;
@@ -1201,7 +1459,7 @@ static void rebind_policy(struct mempolicy *pol, const nodemask_t *old,
1201 nodes_clear(nodes); 1459 nodes_clear(nodes);
1202 for (z = pol->v.zonelist->zones; *z; z++) 1460 for (z = pol->v.zonelist->zones; *z; z++)
1203 node_set((*z)->zone_pgdat->node_id, nodes); 1461 node_set((*z)->zone_pgdat->node_id, nodes);
1204 nodes_remap(tmp, nodes, *old, *new); 1462 nodes_remap(tmp, nodes, *mpolmask, *newmask);
1205 nodes = tmp; 1463 nodes = tmp;
1206 1464
1207 zonelist = bind_zonelist(&nodes); 1465 zonelist = bind_zonelist(&nodes);
@@ -1216,6 +1474,7 @@ static void rebind_policy(struct mempolicy *pol, const nodemask_t *old,
1216 kfree(pol->v.zonelist); 1474 kfree(pol->v.zonelist);
1217 pol->v.zonelist = zonelist; 1475 pol->v.zonelist = zonelist;
1218 } 1476 }
1477 *mpolmask = *newmask;
1219 break; 1478 break;
1220 } 1479 }
1221 default: 1480 default:
@@ -1225,12 +1484,156 @@ static void rebind_policy(struct mempolicy *pol, const nodemask_t *old,
1225} 1484}
1226 1485
1227/* 1486/*
1228 * Someone moved this task to different nodes. Fixup mempolicies. 1487 * Wrapper for mpol_rebind_policy() that just requires task
1488 * pointer, and updates task mempolicy.
1489 */
1490
1491void mpol_rebind_task(struct task_struct *tsk, const nodemask_t *new)
1492{
1493 mpol_rebind_policy(tsk->mempolicy, new);
1494}
1495
1496/*
1497 * Rebind each vma in mm to new nodemask.
1229 * 1498 *
1230 * TODO - fixup current->mm->vma and shmfs/tmpfs/hugetlbfs policies as well, 1499 * Call holding a reference to mm. Takes mm->mmap_sem during call.
1231 * once we have a cpuset mechanism to mark which cpuset subtree is migrating.
1232 */ 1500 */
1233void numa_policy_rebind(const nodemask_t *old, const nodemask_t *new) 1501
1502void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new)
1234{ 1503{
1235 rebind_policy(current->mempolicy, old, new); 1504 struct vm_area_struct *vma;
1505
1506 down_write(&mm->mmap_sem);
1507 for (vma = mm->mmap; vma; vma = vma->vm_next)
1508 mpol_rebind_policy(vma->vm_policy, new);
1509 up_write(&mm->mmap_sem);
1236} 1510}
1511
1512/*
1513 * Display pages allocated per node and memory policy via /proc.
1514 */
1515
1516static const char *policy_types[] = { "default", "prefer", "bind",
1517 "interleave" };
1518
1519/*
1520 * Convert a mempolicy into a string.
1521 * Returns the number of characters in buffer (if positive)
1522 * or an error (negative)
1523 */
1524static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol)
1525{
1526 char *p = buffer;
1527 int l;
1528 nodemask_t nodes;
1529 int mode = pol ? pol->policy : MPOL_DEFAULT;
1530
1531 switch (mode) {
1532 case MPOL_DEFAULT:
1533 nodes_clear(nodes);
1534 break;
1535
1536 case MPOL_PREFERRED:
1537 nodes_clear(nodes);
1538 node_set(pol->v.preferred_node, nodes);
1539 break;
1540
1541 case MPOL_BIND:
1542 get_zonemask(pol, &nodes);
1543 break;
1544
1545 case MPOL_INTERLEAVE:
1546 nodes = pol->v.nodes;
1547 break;
1548
1549 default:
1550 BUG();
1551 return -EFAULT;
1552 }
1553
1554 l = strlen(policy_types[mode]);
1555 if (buffer + maxlen < p + l + 1)
1556 return -ENOSPC;
1557
1558 strcpy(p, policy_types[mode]);
1559 p += l;
1560
1561 if (!nodes_empty(nodes)) {
1562 if (buffer + maxlen < p + 2)
1563 return -ENOSPC;
1564 *p++ = '=';
1565 p += nodelist_scnprintf(p, buffer + maxlen - p, nodes);
1566 }
1567 return p - buffer;
1568}
1569
1570struct numa_maps {
1571 unsigned long pages;
1572 unsigned long anon;
1573 unsigned long mapped;
1574 unsigned long mapcount_max;
1575 unsigned long node[MAX_NUMNODES];
1576};
1577
1578static void gather_stats(struct page *page, void *private)
1579{
1580 struct numa_maps *md = private;
1581 int count = page_mapcount(page);
1582
1583 if (count)
1584 md->mapped++;
1585
1586 if (count > md->mapcount_max)
1587 md->mapcount_max = count;
1588
1589 md->pages++;
1590
1591 if (PageAnon(page))
1592 md->anon++;
1593
1594 md->node[page_to_nid(page)]++;
1595 cond_resched();
1596}
1597
1598int show_numa_map(struct seq_file *m, void *v)
1599{
1600 struct task_struct *task = m->private;
1601 struct vm_area_struct *vma = v;
1602 struct numa_maps *md;
1603 int n;
1604 char buffer[50];
1605
1606 if (!vma->vm_mm)
1607 return 0;
1608
1609 md = kzalloc(sizeof(struct numa_maps), GFP_KERNEL);
1610 if (!md)
1611 return 0;
1612
1613 check_pgd_range(vma, vma->vm_start, vma->vm_end,
1614 &node_online_map, MPOL_MF_STATS, md);
1615
1616 if (md->pages) {
1617 mpol_to_str(buffer, sizeof(buffer),
1618 get_vma_policy(task, vma, vma->vm_start));
1619
1620 seq_printf(m, "%08lx %s pages=%lu mapped=%lu maxref=%lu",
1621 vma->vm_start, buffer, md->pages,
1622 md->mapped, md->mapcount_max);
1623
1624 if (md->anon)
1625 seq_printf(m," anon=%lu",md->anon);
1626
1627 for_each_online_node(n)
1628 if (md->node[n])
1629 seq_printf(m, " N%d=%lu", n, md->node[n]);
1630
1631 seq_putc(m, '\n');
1632 }
1633 kfree(md);
1634
1635 if (m->count < m->size)
1636 m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0;
1637 return 0;
1638}
1639
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index d348b9035955..4748b906aff2 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -298,7 +298,8 @@ retry:
298 298
299 /* 299 /*
300 * Give "p" a good chance of killing itself before we 300 * Give "p" a good chance of killing itself before we
301 * retry to allocate memory. 301 * retry to allocate memory unless "p" is current
302 */ 302 */
303 schedule_timeout_interruptible(1); 303 if (!test_thread_flag(TIF_MEMDIE))
304 schedule_timeout_interruptible(1);
304} 305}
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index fd47494cb989..e0e84924171b 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -53,6 +53,7 @@ struct pglist_data *pgdat_list __read_mostly;
53unsigned long totalram_pages __read_mostly; 53unsigned long totalram_pages __read_mostly;
54unsigned long totalhigh_pages __read_mostly; 54unsigned long totalhigh_pages __read_mostly;
55long nr_swap_pages; 55long nr_swap_pages;
56int percpu_pagelist_fraction;
56 57
57static void fastcall free_hot_cold_page(struct page *page, int cold); 58static void fastcall free_hot_cold_page(struct page *page, int cold);
58 59
@@ -307,7 +308,7 @@ static inline int page_is_buddy(struct page *page, int order)
307 * -- wli 308 * -- wli
308 */ 309 */
309 310
310static inline void __free_pages_bulk (struct page *page, 311static inline void __free_one_page(struct page *page,
311 struct zone *zone, unsigned int order) 312 struct zone *zone, unsigned int order)
312{ 313{
313 unsigned long page_idx; 314 unsigned long page_idx;
@@ -382,40 +383,42 @@ static inline int free_pages_check(struct page *page)
382 * And clear the zone's pages_scanned counter, to hold off the "all pages are 383 * And clear the zone's pages_scanned counter, to hold off the "all pages are
383 * pinned" detection logic. 384 * pinned" detection logic.
384 */ 385 */
385static int 386static void free_pages_bulk(struct zone *zone, int count,
386free_pages_bulk(struct zone *zone, int count, 387 struct list_head *list, int order)
387 struct list_head *list, unsigned int order)
388{ 388{
389 struct page *page = NULL;
390 int ret = 0;
391
392 spin_lock(&zone->lock); 389 spin_lock(&zone->lock);
393 zone->all_unreclaimable = 0; 390 zone->all_unreclaimable = 0;
394 zone->pages_scanned = 0; 391 zone->pages_scanned = 0;
395 while (!list_empty(list) && count--) { 392 while (count--) {
393 struct page *page;
394
395 BUG_ON(list_empty(list));
396 page = list_entry(list->prev, struct page, lru); 396 page = list_entry(list->prev, struct page, lru);
397 /* have to delete it as __free_pages_bulk list manipulates */ 397 /* have to delete it as __free_one_page list manipulates */
398 list_del(&page->lru); 398 list_del(&page->lru);
399 __free_pages_bulk(page, zone, order); 399 __free_one_page(page, zone, order);
400 ret++;
401 } 400 }
402 spin_unlock(&zone->lock); 401 spin_unlock(&zone->lock);
403 return ret;
404} 402}
405 403
406void __free_pages_ok(struct page *page, unsigned int order) 404static void free_one_page(struct zone *zone, struct page *page, int order)
407{ 405{
408 unsigned long flags;
409 LIST_HEAD(list); 406 LIST_HEAD(list);
407 list_add(&page->lru, &list);
408 free_pages_bulk(zone, 1, &list, order);
409}
410
411static void __free_pages_ok(struct page *page, unsigned int order)
412{
413 unsigned long flags;
410 int i; 414 int i;
411 int reserved = 0; 415 int reserved = 0;
412 416
413 arch_free_page(page, order); 417 arch_free_page(page, order);
414 418
415#ifndef CONFIG_MMU 419#ifndef CONFIG_MMU
416 if (order > 0) 420 for (i = 1 ; i < (1 << order) ; ++i)
417 for (i = 1 ; i < (1 << order) ; ++i) 421 __put_page(page + i);
418 __put_page(page + i);
419#endif 422#endif
420 423
421 for (i = 0 ; i < (1 << order) ; ++i) 424 for (i = 0 ; i < (1 << order) ; ++i)
@@ -423,11 +426,10 @@ void __free_pages_ok(struct page *page, unsigned int order)
423 if (reserved) 426 if (reserved)
424 return; 427 return;
425 428
426 list_add(&page->lru, &list); 429 kernel_map_pages(page, 1 << order, 0);
427 kernel_map_pages(page, 1<<order, 0);
428 local_irq_save(flags); 430 local_irq_save(flags);
429 __mod_page_state(pgfree, 1 << order); 431 __mod_page_state(pgfree, 1 << order);
430 free_pages_bulk(page_zone(page), 1, &list, order); 432 free_one_page(page_zone(page), page, order);
431 local_irq_restore(flags); 433 local_irq_restore(flags);
432} 434}
433 435
@@ -596,14 +598,13 @@ void drain_remote_pages(void)
596 if (zone->zone_pgdat->node_id == numa_node_id()) 598 if (zone->zone_pgdat->node_id == numa_node_id())
597 continue; 599 continue;
598 600
599 pset = zone->pageset[smp_processor_id()]; 601 pset = zone_pcp(zone, smp_processor_id());
600 for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) { 602 for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) {
601 struct per_cpu_pages *pcp; 603 struct per_cpu_pages *pcp;
602 604
603 pcp = &pset->pcp[i]; 605 pcp = &pset->pcp[i];
604 if (pcp->count) 606 free_pages_bulk(zone, pcp->count, &pcp->list, 0);
605 pcp->count -= free_pages_bulk(zone, pcp->count, 607 pcp->count = 0;
606 &pcp->list, 0);
607 } 608 }
608 } 609 }
609 local_irq_restore(flags); 610 local_irq_restore(flags);
@@ -626,8 +627,8 @@ static void __drain_pages(unsigned int cpu)
626 627
627 pcp = &pset->pcp[i]; 628 pcp = &pset->pcp[i];
628 local_irq_save(flags); 629 local_irq_save(flags);
629 pcp->count -= free_pages_bulk(zone, pcp->count, 630 free_pages_bulk(zone, pcp->count, &pcp->list, 0);
630 &pcp->list, 0); 631 pcp->count = 0;
631 local_irq_restore(flags); 632 local_irq_restore(flags);
632 } 633 }
633 } 634 }
@@ -718,8 +719,10 @@ static void fastcall free_hot_cold_page(struct page *page, int cold)
718 __inc_page_state(pgfree); 719 __inc_page_state(pgfree);
719 list_add(&page->lru, &pcp->list); 720 list_add(&page->lru, &pcp->list);
720 pcp->count++; 721 pcp->count++;
721 if (pcp->count >= pcp->high) 722 if (pcp->count >= pcp->high) {
722 pcp->count -= free_pages_bulk(zone, pcp->batch, &pcp->list, 0); 723 free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
724 pcp->count -= pcp->batch;
725 }
723 local_irq_restore(flags); 726 local_irq_restore(flags);
724 put_cpu(); 727 put_cpu();
725} 728}
@@ -758,7 +761,7 @@ static struct page *buffered_rmqueue(struct zonelist *zonelist,
758 761
759again: 762again:
760 cpu = get_cpu(); 763 cpu = get_cpu();
761 if (order == 0) { 764 if (likely(order == 0)) {
762 struct per_cpu_pages *pcp; 765 struct per_cpu_pages *pcp;
763 766
764 pcp = &zone_pcp(zone, cpu)->pcp[cold]; 767 pcp = &zone_pcp(zone, cpu)->pcp[cold];
@@ -973,6 +976,7 @@ rebalance:
973 cond_resched(); 976 cond_resched();
974 977
975 /* We now go into synchronous reclaim */ 978 /* We now go into synchronous reclaim */
979 cpuset_memory_pressure_bump();
976 p->flags |= PF_MEMALLOC; 980 p->flags |= PF_MEMALLOC;
977 reclaim_state.reclaimed_slab = 0; 981 reclaim_state.reclaimed_slab = 0;
978 p->reclaim_state = &reclaim_state; 982 p->reclaim_state = &reclaim_state;
@@ -1204,6 +1208,7 @@ static void __get_page_state(struct page_state *ret, int nr, cpumask_t *cpumask)
1204 int cpu = 0; 1208 int cpu = 0;
1205 1209
1206 memset(ret, 0, sizeof(*ret)); 1210 memset(ret, 0, sizeof(*ret));
1211 cpus_and(*cpumask, *cpumask, cpu_online_map);
1207 1212
1208 cpu = first_cpu(*cpumask); 1213 cpu = first_cpu(*cpumask);
1209 while (cpu < NR_CPUS) { 1214 while (cpu < NR_CPUS) {
@@ -1256,7 +1261,7 @@ unsigned long read_page_state_offset(unsigned long offset)
1256 unsigned long ret = 0; 1261 unsigned long ret = 0;
1257 int cpu; 1262 int cpu;
1258 1263
1259 for_each_cpu(cpu) { 1264 for_each_online_cpu(cpu) {
1260 unsigned long in; 1265 unsigned long in;
1261 1266
1262 in = (unsigned long)&per_cpu(page_states, cpu) + offset; 1267 in = (unsigned long)&per_cpu(page_states, cpu) + offset;
@@ -1830,6 +1835,24 @@ inline void setup_pageset(struct per_cpu_pageset *p, unsigned long batch)
1830 INIT_LIST_HEAD(&pcp->list); 1835 INIT_LIST_HEAD(&pcp->list);
1831} 1836}
1832 1837
1838/*
1839 * setup_pagelist_highmark() sets the high water mark for hot per_cpu_pagelist
1840 * to the value high for the pageset p.
1841 */
1842
1843static void setup_pagelist_highmark(struct per_cpu_pageset *p,
1844 unsigned long high)
1845{
1846 struct per_cpu_pages *pcp;
1847
1848 pcp = &p->pcp[0]; /* hot list */
1849 pcp->high = high;
1850 pcp->batch = max(1UL, high/4);
1851 if ((high/4) > (PAGE_SHIFT * 8))
1852 pcp->batch = PAGE_SHIFT * 8;
1853}
1854
1855
1833#ifdef CONFIG_NUMA 1856#ifdef CONFIG_NUMA
1834/* 1857/*
1835 * Boot pageset table. One per cpu which is going to be used for all 1858 * Boot pageset table. One per cpu which is going to be used for all
@@ -1861,12 +1884,16 @@ static int __devinit process_zones(int cpu)
1861 1884
1862 for_each_zone(zone) { 1885 for_each_zone(zone) {
1863 1886
1864 zone->pageset[cpu] = kmalloc_node(sizeof(struct per_cpu_pageset), 1887 zone_pcp(zone, cpu) = kmalloc_node(sizeof(struct per_cpu_pageset),
1865 GFP_KERNEL, cpu_to_node(cpu)); 1888 GFP_KERNEL, cpu_to_node(cpu));
1866 if (!zone->pageset[cpu]) 1889 if (!zone_pcp(zone, cpu))
1867 goto bad; 1890 goto bad;
1868 1891
1869 setup_pageset(zone->pageset[cpu], zone_batchsize(zone)); 1892 setup_pageset(zone_pcp(zone, cpu), zone_batchsize(zone));
1893
1894 if (percpu_pagelist_fraction)
1895 setup_pagelist_highmark(zone_pcp(zone, cpu),
1896 (zone->present_pages / percpu_pagelist_fraction));
1870 } 1897 }
1871 1898
1872 return 0; 1899 return 0;
@@ -1874,15 +1901,14 @@ bad:
1874 for_each_zone(dzone) { 1901 for_each_zone(dzone) {
1875 if (dzone == zone) 1902 if (dzone == zone)
1876 break; 1903 break;
1877 kfree(dzone->pageset[cpu]); 1904 kfree(zone_pcp(dzone, cpu));
1878 dzone->pageset[cpu] = NULL; 1905 zone_pcp(dzone, cpu) = NULL;
1879 } 1906 }
1880 return -ENOMEM; 1907 return -ENOMEM;
1881} 1908}
1882 1909
1883static inline void free_zone_pagesets(int cpu) 1910static inline void free_zone_pagesets(int cpu)
1884{ 1911{
1885#ifdef CONFIG_NUMA
1886 struct zone *zone; 1912 struct zone *zone;
1887 1913
1888 for_each_zone(zone) { 1914 for_each_zone(zone) {
@@ -1891,7 +1917,6 @@ static inline void free_zone_pagesets(int cpu)
1891 zone_pcp(zone, cpu) = NULL; 1917 zone_pcp(zone, cpu) = NULL;
1892 kfree(pset); 1918 kfree(pset);
1893 } 1919 }
1894#endif
1895} 1920}
1896 1921
1897static int __devinit pageset_cpuup_callback(struct notifier_block *nfb, 1922static int __devinit pageset_cpuup_callback(struct notifier_block *nfb,
@@ -1962,7 +1987,7 @@ static __devinit void zone_pcp_init(struct zone *zone)
1962 for (cpu = 0; cpu < NR_CPUS; cpu++) { 1987 for (cpu = 0; cpu < NR_CPUS; cpu++) {
1963#ifdef CONFIG_NUMA 1988#ifdef CONFIG_NUMA
1964 /* Early boot. Slab allocator not functional yet */ 1989 /* Early boot. Slab allocator not functional yet */
1965 zone->pageset[cpu] = &boot_pageset[cpu]; 1990 zone_pcp(zone, cpu) = &boot_pageset[cpu];
1966 setup_pageset(&boot_pageset[cpu],0); 1991 setup_pageset(&boot_pageset[cpu],0);
1967#else 1992#else
1968 setup_pageset(zone_pcp(zone,cpu), batch); 1993 setup_pageset(zone_pcp(zone,cpu), batch);
@@ -2205,7 +2230,7 @@ static int zoneinfo_show(struct seq_file *m, void *arg)
2205 seq_printf(m, 2230 seq_printf(m,
2206 ")" 2231 ")"
2207 "\n pagesets"); 2232 "\n pagesets");
2208 for (i = 0; i < ARRAY_SIZE(zone->pageset); i++) { 2233 for_each_online_cpu(i) {
2209 struct per_cpu_pageset *pageset; 2234 struct per_cpu_pageset *pageset;
2210 int j; 2235 int j;
2211 2236
@@ -2568,6 +2593,32 @@ int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write,
2568 return 0; 2593 return 0;
2569} 2594}
2570 2595
2596/*
2597 * percpu_pagelist_fraction - changes the pcp->high for each zone on each
2598 * cpu. It is the fraction of total pages in each zone that a hot per cpu pagelist
2599 * can have before it gets flushed back to buddy allocator.
2600 */
2601
2602int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write,
2603 struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
2604{
2605 struct zone *zone;
2606 unsigned int cpu;
2607 int ret;
2608
2609 ret = proc_dointvec_minmax(table, write, file, buffer, length, ppos);
2610 if (!write || (ret == -EINVAL))
2611 return ret;
2612 for_each_zone(zone) {
2613 for_each_online_cpu(cpu) {
2614 unsigned long high;
2615 high = zone->present_pages / percpu_pagelist_fraction;
2616 setup_pagelist_highmark(zone_pcp(zone, cpu), high);
2617 }
2618 }
2619 return 0;
2620}
2621
2571__initdata int hashdist = HASHDIST_DEFAULT; 2622__initdata int hashdist = HASHDIST_DEFAULT;
2572 2623
2573#ifdef CONFIG_NUMA 2624#ifdef CONFIG_NUMA
diff --git a/mm/pdflush.c b/mm/pdflush.c
index 52822c98c489..c4b6d0afd736 100644
--- a/mm/pdflush.c
+++ b/mm/pdflush.c
@@ -90,7 +90,7 @@ struct pdflush_work {
90 90
91static int __pdflush(struct pdflush_work *my_work) 91static int __pdflush(struct pdflush_work *my_work)
92{ 92{
93 current->flags |= PF_FLUSHER; 93 current->flags |= PF_FLUSHER | PF_SWAPWRITE;
94 my_work->fn = NULL; 94 my_work->fn = NULL;
95 my_work->who = current; 95 my_work->who = current;
96 INIT_LIST_HEAD(&my_work->list); 96 INIT_LIST_HEAD(&my_work->list);
diff --git a/mm/rmap.c b/mm/rmap.c
index 6f3f7db27128..66ec43053a4d 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -514,6 +514,13 @@ void page_add_file_rmap(struct page *page)
514void page_remove_rmap(struct page *page) 514void page_remove_rmap(struct page *page)
515{ 515{
516 if (atomic_add_negative(-1, &page->_mapcount)) { 516 if (atomic_add_negative(-1, &page->_mapcount)) {
517 if (page_mapcount(page) < 0) {
518 printk (KERN_EMERG "Eeek! page_mapcount(page) went negative! (%d)\n", page_mapcount(page));
519 printk (KERN_EMERG " page->flags = %lx\n", page->flags);
520 printk (KERN_EMERG " page->count = %x\n", page_count(page));
521 printk (KERN_EMERG " page->mapping = %p\n", page->mapping);
522 }
523
517 BUG_ON(page_mapcount(page) < 0); 524 BUG_ON(page_mapcount(page) < 0);
518 /* 525 /*
519 * It would be tidy to reset the PageAnon mapping here, 526 * It would be tidy to reset the PageAnon mapping here,
diff --git a/mm/slab.c b/mm/slab.c
index e5ec26e0c460..1c46c6383552 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -130,7 +130,6 @@
130#define FORCED_DEBUG 0 130#define FORCED_DEBUG 0
131#endif 131#endif
132 132
133
134/* Shouldn't this be in a header file somewhere? */ 133/* Shouldn't this be in a header file somewhere? */
135#define BYTES_PER_WORD sizeof(void *) 134#define BYTES_PER_WORD sizeof(void *)
136 135
@@ -217,12 +216,12 @@ static unsigned long offslab_limit;
217 * Slabs are chained into three list: fully used, partial, fully free slabs. 216 * Slabs are chained into three list: fully used, partial, fully free slabs.
218 */ 217 */
219struct slab { 218struct slab {
220 struct list_head list; 219 struct list_head list;
221 unsigned long colouroff; 220 unsigned long colouroff;
222 void *s_mem; /* including colour offset */ 221 void *s_mem; /* including colour offset */
223 unsigned int inuse; /* num of objs active in slab */ 222 unsigned int inuse; /* num of objs active in slab */
224 kmem_bufctl_t free; 223 kmem_bufctl_t free;
225 unsigned short nodeid; 224 unsigned short nodeid;
226}; 225};
227 226
228/* 227/*
@@ -242,9 +241,9 @@ struct slab {
242 * We assume struct slab_rcu can overlay struct slab when destroying. 241 * We assume struct slab_rcu can overlay struct slab when destroying.
243 */ 242 */
244struct slab_rcu { 243struct slab_rcu {
245 struct rcu_head head; 244 struct rcu_head head;
246 kmem_cache_t *cachep; 245 kmem_cache_t *cachep;
247 void *addr; 246 void *addr;
248}; 247};
249 248
250/* 249/*
@@ -279,23 +278,23 @@ struct array_cache {
279#define BOOT_CPUCACHE_ENTRIES 1 278#define BOOT_CPUCACHE_ENTRIES 1
280struct arraycache_init { 279struct arraycache_init {
281 struct array_cache cache; 280 struct array_cache cache;
282 void * entries[BOOT_CPUCACHE_ENTRIES]; 281 void *entries[BOOT_CPUCACHE_ENTRIES];
283}; 282};
284 283
285/* 284/*
286 * The slab lists for all objects. 285 * The slab lists for all objects.
287 */ 286 */
288struct kmem_list3 { 287struct kmem_list3 {
289 struct list_head slabs_partial; /* partial list first, better asm code */ 288 struct list_head slabs_partial; /* partial list first, better asm code */
290 struct list_head slabs_full; 289 struct list_head slabs_full;
291 struct list_head slabs_free; 290 struct list_head slabs_free;
292 unsigned long free_objects; 291 unsigned long free_objects;
293 unsigned long next_reap; 292 unsigned long next_reap;
294 int free_touched; 293 int free_touched;
295 unsigned int free_limit; 294 unsigned int free_limit;
296 spinlock_t list_lock; 295 spinlock_t list_lock;
297 struct array_cache *shared; /* shared per node */ 296 struct array_cache *shared; /* shared per node */
298 struct array_cache **alien; /* on other nodes */ 297 struct array_cache **alien; /* on other nodes */
299}; 298};
300 299
301/* 300/*
@@ -367,63 +366,63 @@ static inline void kmem_list3_init(struct kmem_list3 *parent)
367 * 366 *
368 * manages a cache. 367 * manages a cache.
369 */ 368 */
370 369
371struct kmem_cache { 370struct kmem_cache {
372/* 1) per-cpu data, touched during every alloc/free */ 371/* 1) per-cpu data, touched during every alloc/free */
373 struct array_cache *array[NR_CPUS]; 372 struct array_cache *array[NR_CPUS];
374 unsigned int batchcount; 373 unsigned int batchcount;
375 unsigned int limit; 374 unsigned int limit;
376 unsigned int shared; 375 unsigned int shared;
377 unsigned int objsize; 376 unsigned int objsize;
378/* 2) touched by every alloc & free from the backend */ 377/* 2) touched by every alloc & free from the backend */
379 struct kmem_list3 *nodelists[MAX_NUMNODES]; 378 struct kmem_list3 *nodelists[MAX_NUMNODES];
380 unsigned int flags; /* constant flags */ 379 unsigned int flags; /* constant flags */
381 unsigned int num; /* # of objs per slab */ 380 unsigned int num; /* # of objs per slab */
382 spinlock_t spinlock; 381 spinlock_t spinlock;
383 382
384/* 3) cache_grow/shrink */ 383/* 3) cache_grow/shrink */
385 /* order of pgs per slab (2^n) */ 384 /* order of pgs per slab (2^n) */
386 unsigned int gfporder; 385 unsigned int gfporder;
387 386
388 /* force GFP flags, e.g. GFP_DMA */ 387 /* force GFP flags, e.g. GFP_DMA */
389 gfp_t gfpflags; 388 gfp_t gfpflags;
390 389
391 size_t colour; /* cache colouring range */ 390 size_t colour; /* cache colouring range */
392 unsigned int colour_off; /* colour offset */ 391 unsigned int colour_off; /* colour offset */
393 unsigned int colour_next; /* cache colouring */ 392 unsigned int colour_next; /* cache colouring */
394 kmem_cache_t *slabp_cache; 393 kmem_cache_t *slabp_cache;
395 unsigned int slab_size; 394 unsigned int slab_size;
396 unsigned int dflags; /* dynamic flags */ 395 unsigned int dflags; /* dynamic flags */
397 396
398 /* constructor func */ 397 /* constructor func */
399 void (*ctor)(void *, kmem_cache_t *, unsigned long); 398 void (*ctor) (void *, kmem_cache_t *, unsigned long);
400 399
401 /* de-constructor func */ 400 /* de-constructor func */
402 void (*dtor)(void *, kmem_cache_t *, unsigned long); 401 void (*dtor) (void *, kmem_cache_t *, unsigned long);
403 402
404/* 4) cache creation/removal */ 403/* 4) cache creation/removal */
405 const char *name; 404 const char *name;
406 struct list_head next; 405 struct list_head next;
407 406
408/* 5) statistics */ 407/* 5) statistics */
409#if STATS 408#if STATS
410 unsigned long num_active; 409 unsigned long num_active;
411 unsigned long num_allocations; 410 unsigned long num_allocations;
412 unsigned long high_mark; 411 unsigned long high_mark;
413 unsigned long grown; 412 unsigned long grown;
414 unsigned long reaped; 413 unsigned long reaped;
415 unsigned long errors; 414 unsigned long errors;
416 unsigned long max_freeable; 415 unsigned long max_freeable;
417 unsigned long node_allocs; 416 unsigned long node_allocs;
418 unsigned long node_frees; 417 unsigned long node_frees;
419 atomic_t allochit; 418 atomic_t allochit;
420 atomic_t allocmiss; 419 atomic_t allocmiss;
421 atomic_t freehit; 420 atomic_t freehit;
422 atomic_t freemiss; 421 atomic_t freemiss;
423#endif 422#endif
424#if DEBUG 423#if DEBUG
425 int dbghead; 424 int dbghead;
426 int reallen; 425 int reallen;
427#endif 426#endif
428}; 427};
429 428
@@ -523,14 +522,15 @@ static unsigned long *dbg_redzone2(kmem_cache_t *cachep, void *objp)
523{ 522{
524 BUG_ON(!(cachep->flags & SLAB_RED_ZONE)); 523 BUG_ON(!(cachep->flags & SLAB_RED_ZONE));
525 if (cachep->flags & SLAB_STORE_USER) 524 if (cachep->flags & SLAB_STORE_USER)
526 return (unsigned long*) (objp+cachep->objsize-2*BYTES_PER_WORD); 525 return (unsigned long *)(objp + cachep->objsize -
527 return (unsigned long*) (objp+cachep->objsize-BYTES_PER_WORD); 526 2 * BYTES_PER_WORD);
527 return (unsigned long *)(objp + cachep->objsize - BYTES_PER_WORD);
528} 528}
529 529
530static void **dbg_userword(kmem_cache_t *cachep, void *objp) 530static void **dbg_userword(kmem_cache_t *cachep, void *objp)
531{ 531{
532 BUG_ON(!(cachep->flags & SLAB_STORE_USER)); 532 BUG_ON(!(cachep->flags & SLAB_STORE_USER));
533 return (void**)(objp+cachep->objsize-BYTES_PER_WORD); 533 return (void **)(objp + cachep->objsize - BYTES_PER_WORD);
534} 534}
535 535
536#else 536#else
@@ -607,31 +607,31 @@ struct cache_names {
607static struct cache_names __initdata cache_names[] = { 607static struct cache_names __initdata cache_names[] = {
608#define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" }, 608#define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
609#include <linux/kmalloc_sizes.h> 609#include <linux/kmalloc_sizes.h>
610 { NULL, } 610 {NULL,}
611#undef CACHE 611#undef CACHE
612}; 612};
613 613
614static struct arraycache_init initarray_cache __initdata = 614static struct arraycache_init initarray_cache __initdata =
615 { { 0, BOOT_CPUCACHE_ENTRIES, 1, 0} }; 615 { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
616static struct arraycache_init initarray_generic = 616static struct arraycache_init initarray_generic =
617 { { 0, BOOT_CPUCACHE_ENTRIES, 1, 0} }; 617 { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
618 618
619/* internal cache of cache description objs */ 619/* internal cache of cache description objs */
620static kmem_cache_t cache_cache = { 620static kmem_cache_t cache_cache = {
621 .batchcount = 1, 621 .batchcount = 1,
622 .limit = BOOT_CPUCACHE_ENTRIES, 622 .limit = BOOT_CPUCACHE_ENTRIES,
623 .shared = 1, 623 .shared = 1,
624 .objsize = sizeof(kmem_cache_t), 624 .objsize = sizeof(kmem_cache_t),
625 .flags = SLAB_NO_REAP, 625 .flags = SLAB_NO_REAP,
626 .spinlock = SPIN_LOCK_UNLOCKED, 626 .spinlock = SPIN_LOCK_UNLOCKED,
627 .name = "kmem_cache", 627 .name = "kmem_cache",
628#if DEBUG 628#if DEBUG
629 .reallen = sizeof(kmem_cache_t), 629 .reallen = sizeof(kmem_cache_t),
630#endif 630#endif
631}; 631};
632 632
633/* Guard access to the cache-chain. */ 633/* Guard access to the cache-chain. */
634static struct semaphore cache_chain_sem; 634static struct semaphore cache_chain_sem;
635static struct list_head cache_chain; 635static struct list_head cache_chain;
636 636
637/* 637/*
@@ -655,9 +655,9 @@ static enum {
655 655
656static DEFINE_PER_CPU(struct work_struct, reap_work); 656static DEFINE_PER_CPU(struct work_struct, reap_work);
657 657
658static void free_block(kmem_cache_t* cachep, void** objpp, int len, int node); 658static void free_block(kmem_cache_t *cachep, void **objpp, int len, int node);
659static void enable_cpucache (kmem_cache_t *cachep); 659static void enable_cpucache(kmem_cache_t *cachep);
660static void cache_reap (void *unused); 660static void cache_reap(void *unused);
661static int __node_shrink(kmem_cache_t *cachep, int node); 661static int __node_shrink(kmem_cache_t *cachep, int node);
662 662
663static inline struct array_cache *ac_data(kmem_cache_t *cachep) 663static inline struct array_cache *ac_data(kmem_cache_t *cachep)
@@ -671,9 +671,9 @@ static inline kmem_cache_t *__find_general_cachep(size_t size, gfp_t gfpflags)
671 671
672#if DEBUG 672#if DEBUG
673 /* This happens if someone tries to call 673 /* This happens if someone tries to call
674 * kmem_cache_create(), or __kmalloc(), before 674 * kmem_cache_create(), or __kmalloc(), before
675 * the generic caches are initialized. 675 * the generic caches are initialized.
676 */ 676 */
677 BUG_ON(malloc_sizes[INDEX_AC].cs_cachep == NULL); 677 BUG_ON(malloc_sizes[INDEX_AC].cs_cachep == NULL);
678#endif 678#endif
679 while (size > csizep->cs_size) 679 while (size > csizep->cs_size)
@@ -697,10 +697,10 @@ EXPORT_SYMBOL(kmem_find_general_cachep);
697 697
698/* Cal the num objs, wastage, and bytes left over for a given slab size. */ 698/* Cal the num objs, wastage, and bytes left over for a given slab size. */
699static void cache_estimate(unsigned long gfporder, size_t size, size_t align, 699static void cache_estimate(unsigned long gfporder, size_t size, size_t align,
700 int flags, size_t *left_over, unsigned int *num) 700 int flags, size_t *left_over, unsigned int *num)
701{ 701{
702 int i; 702 int i;
703 size_t wastage = PAGE_SIZE<<gfporder; 703 size_t wastage = PAGE_SIZE << gfporder;
704 size_t extra = 0; 704 size_t extra = 0;
705 size_t base = 0; 705 size_t base = 0;
706 706
@@ -709,7 +709,7 @@ static void cache_estimate(unsigned long gfporder, size_t size, size_t align,
709 extra = sizeof(kmem_bufctl_t); 709 extra = sizeof(kmem_bufctl_t);
710 } 710 }
711 i = 0; 711 i = 0;
712 while (i*size + ALIGN(base+i*extra, align) <= wastage) 712 while (i * size + ALIGN(base + i * extra, align) <= wastage)
713 i++; 713 i++;
714 if (i > 0) 714 if (i > 0)
715 i--; 715 i--;
@@ -718,8 +718,8 @@ static void cache_estimate(unsigned long gfporder, size_t size, size_t align,
718 i = SLAB_LIMIT; 718 i = SLAB_LIMIT;
719 719
720 *num = i; 720 *num = i;
721 wastage -= i*size; 721 wastage -= i * size;
722 wastage -= ALIGN(base+i*extra, align); 722 wastage -= ALIGN(base + i * extra, align);
723 *left_over = wastage; 723 *left_over = wastage;
724} 724}
725 725
@@ -728,7 +728,7 @@ static void cache_estimate(unsigned long gfporder, size_t size, size_t align,
728static void __slab_error(const char *function, kmem_cache_t *cachep, char *msg) 728static void __slab_error(const char *function, kmem_cache_t *cachep, char *msg)
729{ 729{
730 printk(KERN_ERR "slab error in %s(): cache `%s': %s\n", 730 printk(KERN_ERR "slab error in %s(): cache `%s': %s\n",
731 function, cachep->name, msg); 731 function, cachep->name, msg);
732 dump_stack(); 732 dump_stack();
733} 733}
734 734
@@ -755,9 +755,9 @@ static void __devinit start_cpu_timer(int cpu)
755} 755}
756 756
757static struct array_cache *alloc_arraycache(int node, int entries, 757static struct array_cache *alloc_arraycache(int node, int entries,
758 int batchcount) 758 int batchcount)
759{ 759{
760 int memsize = sizeof(void*)*entries+sizeof(struct array_cache); 760 int memsize = sizeof(void *) * entries + sizeof(struct array_cache);
761 struct array_cache *nc = NULL; 761 struct array_cache *nc = NULL;
762 762
763 nc = kmalloc_node(memsize, GFP_KERNEL, node); 763 nc = kmalloc_node(memsize, GFP_KERNEL, node);
@@ -775,7 +775,7 @@ static struct array_cache *alloc_arraycache(int node, int entries,
775static inline struct array_cache **alloc_alien_cache(int node, int limit) 775static inline struct array_cache **alloc_alien_cache(int node, int limit)
776{ 776{
777 struct array_cache **ac_ptr; 777 struct array_cache **ac_ptr;
778 int memsize = sizeof(void*)*MAX_NUMNODES; 778 int memsize = sizeof(void *) * MAX_NUMNODES;
779 int i; 779 int i;
780 780
781 if (limit > 1) 781 if (limit > 1)
@@ -789,7 +789,7 @@ static inline struct array_cache **alloc_alien_cache(int node, int limit)
789 } 789 }
790 ac_ptr[i] = alloc_arraycache(node, limit, 0xbaadf00d); 790 ac_ptr[i] = alloc_arraycache(node, limit, 0xbaadf00d);
791 if (!ac_ptr[i]) { 791 if (!ac_ptr[i]) {
792 for (i--; i <=0; i--) 792 for (i--; i <= 0; i--)
793 kfree(ac_ptr[i]); 793 kfree(ac_ptr[i]);
794 kfree(ac_ptr); 794 kfree(ac_ptr);
795 return NULL; 795 return NULL;
@@ -807,12 +807,13 @@ static inline void free_alien_cache(struct array_cache **ac_ptr)
807 return; 807 return;
808 808
809 for_each_node(i) 809 for_each_node(i)
810 kfree(ac_ptr[i]); 810 kfree(ac_ptr[i]);
811 811
812 kfree(ac_ptr); 812 kfree(ac_ptr);
813} 813}
814 814
815static inline void __drain_alien_cache(kmem_cache_t *cachep, struct array_cache *ac, int node) 815static inline void __drain_alien_cache(kmem_cache_t *cachep,
816 struct array_cache *ac, int node)
816{ 817{
817 struct kmem_list3 *rl3 = cachep->nodelists[node]; 818 struct kmem_list3 *rl3 = cachep->nodelists[node];
818 819
@@ -826,7 +827,7 @@ static inline void __drain_alien_cache(kmem_cache_t *cachep, struct array_cache
826 827
827static void drain_alien_cache(kmem_cache_t *cachep, struct kmem_list3 *l3) 828static void drain_alien_cache(kmem_cache_t *cachep, struct kmem_list3 *l3)
828{ 829{
829 int i=0; 830 int i = 0;
830 struct array_cache *ac; 831 struct array_cache *ac;
831 unsigned long flags; 832 unsigned long flags;
832 833
@@ -846,14 +847,13 @@ static void drain_alien_cache(kmem_cache_t *cachep, struct kmem_list3 *l3)
846#endif 847#endif
847 848
848static int __devinit cpuup_callback(struct notifier_block *nfb, 849static int __devinit cpuup_callback(struct notifier_block *nfb,
849 unsigned long action, void *hcpu) 850 unsigned long action, void *hcpu)
850{ 851{
851 long cpu = (long)hcpu; 852 long cpu = (long)hcpu;
852 kmem_cache_t* cachep; 853 kmem_cache_t *cachep;
853 struct kmem_list3 *l3 = NULL; 854 struct kmem_list3 *l3 = NULL;
854 int node = cpu_to_node(cpu); 855 int node = cpu_to_node(cpu);
855 int memsize = sizeof(struct kmem_list3); 856 int memsize = sizeof(struct kmem_list3);
856 struct array_cache *nc = NULL;
857 857
858 switch (action) { 858 switch (action) {
859 case CPU_UP_PREPARE: 859 case CPU_UP_PREPARE:
@@ -871,27 +871,29 @@ static int __devinit cpuup_callback(struct notifier_block *nfb,
871 */ 871 */
872 if (!cachep->nodelists[node]) { 872 if (!cachep->nodelists[node]) {
873 if (!(l3 = kmalloc_node(memsize, 873 if (!(l3 = kmalloc_node(memsize,
874 GFP_KERNEL, node))) 874 GFP_KERNEL, node)))
875 goto bad; 875 goto bad;
876 kmem_list3_init(l3); 876 kmem_list3_init(l3);
877 l3->next_reap = jiffies + REAPTIMEOUT_LIST3 + 877 l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
878 ((unsigned long)cachep)%REAPTIMEOUT_LIST3; 878 ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
879 879
880 cachep->nodelists[node] = l3; 880 cachep->nodelists[node] = l3;
881 } 881 }
882 882
883 spin_lock_irq(&cachep->nodelists[node]->list_lock); 883 spin_lock_irq(&cachep->nodelists[node]->list_lock);
884 cachep->nodelists[node]->free_limit = 884 cachep->nodelists[node]->free_limit =
885 (1 + nr_cpus_node(node)) * 885 (1 + nr_cpus_node(node)) *
886 cachep->batchcount + cachep->num; 886 cachep->batchcount + cachep->num;
887 spin_unlock_irq(&cachep->nodelists[node]->list_lock); 887 spin_unlock_irq(&cachep->nodelists[node]->list_lock);
888 } 888 }
889 889
890 /* Now we can go ahead with allocating the shared array's 890 /* Now we can go ahead with allocating the shared array's
891 & array cache's */ 891 & array cache's */
892 list_for_each_entry(cachep, &cache_chain, next) { 892 list_for_each_entry(cachep, &cache_chain, next) {
893 struct array_cache *nc;
894
893 nc = alloc_arraycache(node, cachep->limit, 895 nc = alloc_arraycache(node, cachep->limit,
894 cachep->batchcount); 896 cachep->batchcount);
895 if (!nc) 897 if (!nc)
896 goto bad; 898 goto bad;
897 cachep->array[cpu] = nc; 899 cachep->array[cpu] = nc;
@@ -900,12 +902,13 @@ static int __devinit cpuup_callback(struct notifier_block *nfb,
900 BUG_ON(!l3); 902 BUG_ON(!l3);
901 if (!l3->shared) { 903 if (!l3->shared) {
902 if (!(nc = alloc_arraycache(node, 904 if (!(nc = alloc_arraycache(node,
903 cachep->shared*cachep->batchcount, 905 cachep->shared *
904 0xbaadf00d))) 906 cachep->batchcount,
905 goto bad; 907 0xbaadf00d)))
908 goto bad;
906 909
907 /* we are serialised from CPU_DEAD or 910 /* we are serialised from CPU_DEAD or
908 CPU_UP_CANCELLED by the cpucontrol lock */ 911 CPU_UP_CANCELLED by the cpucontrol lock */
909 l3->shared = nc; 912 l3->shared = nc;
910 } 913 }
911 } 914 }
@@ -942,13 +945,13 @@ static int __devinit cpuup_callback(struct notifier_block *nfb,
942 free_block(cachep, nc->entry, nc->avail, node); 945 free_block(cachep, nc->entry, nc->avail, node);
943 946
944 if (!cpus_empty(mask)) { 947 if (!cpus_empty(mask)) {
945 spin_unlock(&l3->list_lock); 948 spin_unlock(&l3->list_lock);
946 goto unlock_cache; 949 goto unlock_cache;
947 } 950 }
948 951
949 if (l3->shared) { 952 if (l3->shared) {
950 free_block(cachep, l3->shared->entry, 953 free_block(cachep, l3->shared->entry,
951 l3->shared->avail, node); 954 l3->shared->avail, node);
952 kfree(l3->shared); 955 kfree(l3->shared);
953 l3->shared = NULL; 956 l3->shared = NULL;
954 } 957 }
@@ -966,7 +969,7 @@ static int __devinit cpuup_callback(struct notifier_block *nfb,
966 } else { 969 } else {
967 spin_unlock(&l3->list_lock); 970 spin_unlock(&l3->list_lock);
968 } 971 }
969unlock_cache: 972 unlock_cache:
970 spin_unlock_irq(&cachep->spinlock); 973 spin_unlock_irq(&cachep->spinlock);
971 kfree(nc); 974 kfree(nc);
972 } 975 }
@@ -975,7 +978,7 @@ unlock_cache:
975#endif 978#endif
976 } 979 }
977 return NOTIFY_OK; 980 return NOTIFY_OK;
978bad: 981 bad:
979 up(&cache_chain_sem); 982 up(&cache_chain_sem);
980 return NOTIFY_BAD; 983 return NOTIFY_BAD;
981} 984}
@@ -985,8 +988,7 @@ static struct notifier_block cpucache_notifier = { &cpuup_callback, NULL, 0 };
985/* 988/*
986 * swap the static kmem_list3 with kmalloced memory 989 * swap the static kmem_list3 with kmalloced memory
987 */ 990 */
988static void init_list(kmem_cache_t *cachep, struct kmem_list3 *list, 991static void init_list(kmem_cache_t *cachep, struct kmem_list3 *list, int nodeid)
989 int nodeid)
990{ 992{
991 struct kmem_list3 *ptr; 993 struct kmem_list3 *ptr;
992 994
@@ -1055,14 +1057,14 @@ void __init kmem_cache_init(void)
1055 cache_cache.objsize = ALIGN(cache_cache.objsize, cache_line_size()); 1057 cache_cache.objsize = ALIGN(cache_cache.objsize, cache_line_size());
1056 1058
1057 cache_estimate(0, cache_cache.objsize, cache_line_size(), 0, 1059 cache_estimate(0, cache_cache.objsize, cache_line_size(), 0,
1058 &left_over, &cache_cache.num); 1060 &left_over, &cache_cache.num);
1059 if (!cache_cache.num) 1061 if (!cache_cache.num)
1060 BUG(); 1062 BUG();
1061 1063
1062 cache_cache.colour = left_over/cache_cache.colour_off; 1064 cache_cache.colour = left_over / cache_cache.colour_off;
1063 cache_cache.colour_next = 0; 1065 cache_cache.colour_next = 0;
1064 cache_cache.slab_size = ALIGN(cache_cache.num*sizeof(kmem_bufctl_t) + 1066 cache_cache.slab_size = ALIGN(cache_cache.num * sizeof(kmem_bufctl_t) +
1065 sizeof(struct slab), cache_line_size()); 1067 sizeof(struct slab), cache_line_size());
1066 1068
1067 /* 2+3) create the kmalloc caches */ 1069 /* 2+3) create the kmalloc caches */
1068 sizes = malloc_sizes; 1070 sizes = malloc_sizes;
@@ -1074,14 +1076,18 @@ void __init kmem_cache_init(void)
1074 */ 1076 */
1075 1077
1076 sizes[INDEX_AC].cs_cachep = kmem_cache_create(names[INDEX_AC].name, 1078 sizes[INDEX_AC].cs_cachep = kmem_cache_create(names[INDEX_AC].name,
1077 sizes[INDEX_AC].cs_size, ARCH_KMALLOC_MINALIGN, 1079 sizes[INDEX_AC].cs_size,
1078 (ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL); 1080 ARCH_KMALLOC_MINALIGN,
1081 (ARCH_KMALLOC_FLAGS |
1082 SLAB_PANIC), NULL, NULL);
1079 1083
1080 if (INDEX_AC != INDEX_L3) 1084 if (INDEX_AC != INDEX_L3)
1081 sizes[INDEX_L3].cs_cachep = 1085 sizes[INDEX_L3].cs_cachep =
1082 kmem_cache_create(names[INDEX_L3].name, 1086 kmem_cache_create(names[INDEX_L3].name,
1083 sizes[INDEX_L3].cs_size, ARCH_KMALLOC_MINALIGN, 1087 sizes[INDEX_L3].cs_size,
1084 (ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL); 1088 ARCH_KMALLOC_MINALIGN,
1089 (ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL,
1090 NULL);
1085 1091
1086 while (sizes->cs_size != ULONG_MAX) { 1092 while (sizes->cs_size != ULONG_MAX) {
1087 /* 1093 /*
@@ -1091,35 +1097,41 @@ void __init kmem_cache_init(void)
1091 * Note for systems short on memory removing the alignment will 1097 * Note for systems short on memory removing the alignment will
1092 * allow tighter packing of the smaller caches. 1098 * allow tighter packing of the smaller caches.
1093 */ 1099 */
1094 if(!sizes->cs_cachep) 1100 if (!sizes->cs_cachep)
1095 sizes->cs_cachep = kmem_cache_create(names->name, 1101 sizes->cs_cachep = kmem_cache_create(names->name,
1096 sizes->cs_size, ARCH_KMALLOC_MINALIGN, 1102 sizes->cs_size,
1097 (ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL); 1103 ARCH_KMALLOC_MINALIGN,
1104 (ARCH_KMALLOC_FLAGS
1105 | SLAB_PANIC),
1106 NULL, NULL);
1098 1107
1099 /* Inc off-slab bufctl limit until the ceiling is hit. */ 1108 /* Inc off-slab bufctl limit until the ceiling is hit. */
1100 if (!(OFF_SLAB(sizes->cs_cachep))) { 1109 if (!(OFF_SLAB(sizes->cs_cachep))) {
1101 offslab_limit = sizes->cs_size-sizeof(struct slab); 1110 offslab_limit = sizes->cs_size - sizeof(struct slab);
1102 offslab_limit /= sizeof(kmem_bufctl_t); 1111 offslab_limit /= sizeof(kmem_bufctl_t);
1103 } 1112 }
1104 1113
1105 sizes->cs_dmacachep = kmem_cache_create(names->name_dma, 1114 sizes->cs_dmacachep = kmem_cache_create(names->name_dma,
1106 sizes->cs_size, ARCH_KMALLOC_MINALIGN, 1115 sizes->cs_size,
1107 (ARCH_KMALLOC_FLAGS | SLAB_CACHE_DMA | SLAB_PANIC), 1116 ARCH_KMALLOC_MINALIGN,
1108 NULL, NULL); 1117 (ARCH_KMALLOC_FLAGS |
1118 SLAB_CACHE_DMA |
1119 SLAB_PANIC), NULL,
1120 NULL);
1109 1121
1110 sizes++; 1122 sizes++;
1111 names++; 1123 names++;
1112 } 1124 }
1113 /* 4) Replace the bootstrap head arrays */ 1125 /* 4) Replace the bootstrap head arrays */
1114 { 1126 {
1115 void * ptr; 1127 void *ptr;
1116 1128
1117 ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL); 1129 ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL);
1118 1130
1119 local_irq_disable(); 1131 local_irq_disable();
1120 BUG_ON(ac_data(&cache_cache) != &initarray_cache.cache); 1132 BUG_ON(ac_data(&cache_cache) != &initarray_cache.cache);
1121 memcpy(ptr, ac_data(&cache_cache), 1133 memcpy(ptr, ac_data(&cache_cache),
1122 sizeof(struct arraycache_init)); 1134 sizeof(struct arraycache_init));
1123 cache_cache.array[smp_processor_id()] = ptr; 1135 cache_cache.array[smp_processor_id()] = ptr;
1124 local_irq_enable(); 1136 local_irq_enable();
1125 1137
@@ -1127,11 +1139,11 @@ void __init kmem_cache_init(void)
1127 1139
1128 local_irq_disable(); 1140 local_irq_disable();
1129 BUG_ON(ac_data(malloc_sizes[INDEX_AC].cs_cachep) 1141 BUG_ON(ac_data(malloc_sizes[INDEX_AC].cs_cachep)
1130 != &initarray_generic.cache); 1142 != &initarray_generic.cache);
1131 memcpy(ptr, ac_data(malloc_sizes[INDEX_AC].cs_cachep), 1143 memcpy(ptr, ac_data(malloc_sizes[INDEX_AC].cs_cachep),
1132 sizeof(struct arraycache_init)); 1144 sizeof(struct arraycache_init));
1133 malloc_sizes[INDEX_AC].cs_cachep->array[smp_processor_id()] = 1145 malloc_sizes[INDEX_AC].cs_cachep->array[smp_processor_id()] =
1134 ptr; 1146 ptr;
1135 local_irq_enable(); 1147 local_irq_enable();
1136 } 1148 }
1137 /* 5) Replace the bootstrap kmem_list3's */ 1149 /* 5) Replace the bootstrap kmem_list3's */
@@ -1139,16 +1151,16 @@ void __init kmem_cache_init(void)
1139 int node; 1151 int node;
1140 /* Replace the static kmem_list3 structures for the boot cpu */ 1152 /* Replace the static kmem_list3 structures for the boot cpu */
1141 init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], 1153 init_list(&cache_cache, &initkmem_list3[CACHE_CACHE],
1142 numa_node_id()); 1154 numa_node_id());
1143 1155
1144 for_each_online_node(node) { 1156 for_each_online_node(node) {
1145 init_list(malloc_sizes[INDEX_AC].cs_cachep, 1157 init_list(malloc_sizes[INDEX_AC].cs_cachep,
1146 &initkmem_list3[SIZE_AC+node], node); 1158 &initkmem_list3[SIZE_AC + node], node);
1147 1159
1148 if (INDEX_AC != INDEX_L3) { 1160 if (INDEX_AC != INDEX_L3) {
1149 init_list(malloc_sizes[INDEX_L3].cs_cachep, 1161 init_list(malloc_sizes[INDEX_L3].cs_cachep,
1150 &initkmem_list3[SIZE_L3+node], 1162 &initkmem_list3[SIZE_L3 + node],
1151 node); 1163 node);
1152 } 1164 }
1153 } 1165 }
1154 } 1166 }
@@ -1158,7 +1170,7 @@ void __init kmem_cache_init(void)
1158 kmem_cache_t *cachep; 1170 kmem_cache_t *cachep;
1159 down(&cache_chain_sem); 1171 down(&cache_chain_sem);
1160 list_for_each_entry(cachep, &cache_chain, next) 1172 list_for_each_entry(cachep, &cache_chain, next)
1161 enable_cpucache(cachep); 1173 enable_cpucache(cachep);
1162 up(&cache_chain_sem); 1174 up(&cache_chain_sem);
1163 } 1175 }
1164 1176
@@ -1184,7 +1196,7 @@ static int __init cpucache_init(void)
1184 * pages to gfp. 1196 * pages to gfp.
1185 */ 1197 */
1186 for_each_online_cpu(cpu) 1198 for_each_online_cpu(cpu)
1187 start_cpu_timer(cpu); 1199 start_cpu_timer(cpu);
1188 1200
1189 return 0; 1201 return 0;
1190} 1202}
@@ -1226,7 +1238,7 @@ static void *kmem_getpages(kmem_cache_t *cachep, gfp_t flags, int nodeid)
1226 */ 1238 */
1227static void kmem_freepages(kmem_cache_t *cachep, void *addr) 1239static void kmem_freepages(kmem_cache_t *cachep, void *addr)
1228{ 1240{
1229 unsigned long i = (1<<cachep->gfporder); 1241 unsigned long i = (1 << cachep->gfporder);
1230 struct page *page = virt_to_page(addr); 1242 struct page *page = virt_to_page(addr);
1231 const unsigned long nr_freed = i; 1243 const unsigned long nr_freed = i;
1232 1244
@@ -1239,13 +1251,13 @@ static void kmem_freepages(kmem_cache_t *cachep, void *addr)
1239 if (current->reclaim_state) 1251 if (current->reclaim_state)
1240 current->reclaim_state->reclaimed_slab += nr_freed; 1252 current->reclaim_state->reclaimed_slab += nr_freed;
1241 free_pages((unsigned long)addr, cachep->gfporder); 1253 free_pages((unsigned long)addr, cachep->gfporder);
1242 if (cachep->flags & SLAB_RECLAIM_ACCOUNT) 1254 if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
1243 atomic_sub(1<<cachep->gfporder, &slab_reclaim_pages); 1255 atomic_sub(1 << cachep->gfporder, &slab_reclaim_pages);
1244} 1256}
1245 1257
1246static void kmem_rcu_free(struct rcu_head *head) 1258static void kmem_rcu_free(struct rcu_head *head)
1247{ 1259{
1248 struct slab_rcu *slab_rcu = (struct slab_rcu *) head; 1260 struct slab_rcu *slab_rcu = (struct slab_rcu *)head;
1249 kmem_cache_t *cachep = slab_rcu->cachep; 1261 kmem_cache_t *cachep = slab_rcu->cachep;
1250 1262
1251 kmem_freepages(cachep, slab_rcu->addr); 1263 kmem_freepages(cachep, slab_rcu->addr);
@@ -1257,19 +1269,19 @@ static void kmem_rcu_free(struct rcu_head *head)
1257 1269
1258#ifdef CONFIG_DEBUG_PAGEALLOC 1270#ifdef CONFIG_DEBUG_PAGEALLOC
1259static void store_stackinfo(kmem_cache_t *cachep, unsigned long *addr, 1271static void store_stackinfo(kmem_cache_t *cachep, unsigned long *addr,
1260 unsigned long caller) 1272 unsigned long caller)
1261{ 1273{
1262 int size = obj_reallen(cachep); 1274 int size = obj_reallen(cachep);
1263 1275
1264 addr = (unsigned long *)&((char*)addr)[obj_dbghead(cachep)]; 1276 addr = (unsigned long *)&((char *)addr)[obj_dbghead(cachep)];
1265 1277
1266 if (size < 5*sizeof(unsigned long)) 1278 if (size < 5 * sizeof(unsigned long))
1267 return; 1279 return;
1268 1280
1269 *addr++=0x12345678; 1281 *addr++ = 0x12345678;
1270 *addr++=caller; 1282 *addr++ = caller;
1271 *addr++=smp_processor_id(); 1283 *addr++ = smp_processor_id();
1272 size -= 3*sizeof(unsigned long); 1284 size -= 3 * sizeof(unsigned long);
1273 { 1285 {
1274 unsigned long *sptr = &caller; 1286 unsigned long *sptr = &caller;
1275 unsigned long svalue; 1287 unsigned long svalue;
@@ -1277,7 +1289,7 @@ static void store_stackinfo(kmem_cache_t *cachep, unsigned long *addr,
1277 while (!kstack_end(sptr)) { 1289 while (!kstack_end(sptr)) {
1278 svalue = *sptr++; 1290 svalue = *sptr++;
1279 if (kernel_text_address(svalue)) { 1291 if (kernel_text_address(svalue)) {
1280 *addr++=svalue; 1292 *addr++ = svalue;
1281 size -= sizeof(unsigned long); 1293 size -= sizeof(unsigned long);
1282 if (size <= sizeof(unsigned long)) 1294 if (size <= sizeof(unsigned long))
1283 break; 1295 break;
@@ -1285,25 +1297,25 @@ static void store_stackinfo(kmem_cache_t *cachep, unsigned long *addr,
1285 } 1297 }
1286 1298
1287 } 1299 }
1288 *addr++=0x87654321; 1300 *addr++ = 0x87654321;
1289} 1301}
1290#endif 1302#endif
1291 1303
1292static void poison_obj(kmem_cache_t *cachep, void *addr, unsigned char val) 1304static void poison_obj(kmem_cache_t *cachep, void *addr, unsigned char val)
1293{ 1305{
1294 int size = obj_reallen(cachep); 1306 int size = obj_reallen(cachep);
1295 addr = &((char*)addr)[obj_dbghead(cachep)]; 1307 addr = &((char *)addr)[obj_dbghead(cachep)];
1296 1308
1297 memset(addr, val, size); 1309 memset(addr, val, size);
1298 *(unsigned char *)(addr+size-1) = POISON_END; 1310 *(unsigned char *)(addr + size - 1) = POISON_END;
1299} 1311}
1300 1312
1301static void dump_line(char *data, int offset, int limit) 1313static void dump_line(char *data, int offset, int limit)
1302{ 1314{
1303 int i; 1315 int i;
1304 printk(KERN_ERR "%03x:", offset); 1316 printk(KERN_ERR "%03x:", offset);
1305 for (i=0;i<limit;i++) { 1317 for (i = 0; i < limit; i++) {
1306 printk(" %02x", (unsigned char)data[offset+i]); 1318 printk(" %02x", (unsigned char)data[offset + i]);
1307 } 1319 }
1308 printk("\n"); 1320 printk("\n");
1309} 1321}
@@ -1318,24 +1330,24 @@ static void print_objinfo(kmem_cache_t *cachep, void *objp, int lines)
1318 1330
1319 if (cachep->flags & SLAB_RED_ZONE) { 1331 if (cachep->flags & SLAB_RED_ZONE) {
1320 printk(KERN_ERR "Redzone: 0x%lx/0x%lx.\n", 1332 printk(KERN_ERR "Redzone: 0x%lx/0x%lx.\n",
1321 *dbg_redzone1(cachep, objp), 1333 *dbg_redzone1(cachep, objp),
1322 *dbg_redzone2(cachep, objp)); 1334 *dbg_redzone2(cachep, objp));
1323 } 1335 }
1324 1336
1325 if (cachep->flags & SLAB_STORE_USER) { 1337 if (cachep->flags & SLAB_STORE_USER) {
1326 printk(KERN_ERR "Last user: [<%p>]", 1338 printk(KERN_ERR "Last user: [<%p>]",
1327 *dbg_userword(cachep, objp)); 1339 *dbg_userword(cachep, objp));
1328 print_symbol("(%s)", 1340 print_symbol("(%s)",
1329 (unsigned long)*dbg_userword(cachep, objp)); 1341 (unsigned long)*dbg_userword(cachep, objp));
1330 printk("\n"); 1342 printk("\n");
1331 } 1343 }
1332 realobj = (char*)objp+obj_dbghead(cachep); 1344 realobj = (char *)objp + obj_dbghead(cachep);
1333 size = obj_reallen(cachep); 1345 size = obj_reallen(cachep);
1334 for (i=0; i<size && lines;i+=16, lines--) { 1346 for (i = 0; i < size && lines; i += 16, lines--) {
1335 int limit; 1347 int limit;
1336 limit = 16; 1348 limit = 16;
1337 if (i+limit > size) 1349 if (i + limit > size)
1338 limit = size-i; 1350 limit = size - i;
1339 dump_line(realobj, i, limit); 1351 dump_line(realobj, i, limit);
1340 } 1352 }
1341} 1353}
@@ -1346,27 +1358,28 @@ static void check_poison_obj(kmem_cache_t *cachep, void *objp)
1346 int size, i; 1358 int size, i;
1347 int lines = 0; 1359 int lines = 0;
1348 1360
1349 realobj = (char*)objp+obj_dbghead(cachep); 1361 realobj = (char *)objp + obj_dbghead(cachep);
1350 size = obj_reallen(cachep); 1362 size = obj_reallen(cachep);
1351 1363
1352 for (i=0;i<size;i++) { 1364 for (i = 0; i < size; i++) {
1353 char exp = POISON_FREE; 1365 char exp = POISON_FREE;
1354 if (i == size-1) 1366 if (i == size - 1)
1355 exp = POISON_END; 1367 exp = POISON_END;
1356 if (realobj[i] != exp) { 1368 if (realobj[i] != exp) {
1357 int limit; 1369 int limit;
1358 /* Mismatch ! */ 1370 /* Mismatch ! */
1359 /* Print header */ 1371 /* Print header */
1360 if (lines == 0) { 1372 if (lines == 0) {
1361 printk(KERN_ERR "Slab corruption: start=%p, len=%d\n", 1373 printk(KERN_ERR
1362 realobj, size); 1374 "Slab corruption: start=%p, len=%d\n",
1375 realobj, size);
1363 print_objinfo(cachep, objp, 0); 1376 print_objinfo(cachep, objp, 0);
1364 } 1377 }
1365 /* Hexdump the affected line */ 1378 /* Hexdump the affected line */
1366 i = (i/16)*16; 1379 i = (i / 16) * 16;
1367 limit = 16; 1380 limit = 16;
1368 if (i+limit > size) 1381 if (i + limit > size)
1369 limit = size-i; 1382 limit = size - i;
1370 dump_line(realobj, i, limit); 1383 dump_line(realobj, i, limit);
1371 i += 16; 1384 i += 16;
1372 lines++; 1385 lines++;
@@ -1382,19 +1395,19 @@ static void check_poison_obj(kmem_cache_t *cachep, void *objp)
1382 struct slab *slabp = page_get_slab(virt_to_page(objp)); 1395 struct slab *slabp = page_get_slab(virt_to_page(objp));
1383 int objnr; 1396 int objnr;
1384 1397
1385 objnr = (objp-slabp->s_mem)/cachep->objsize; 1398 objnr = (objp - slabp->s_mem) / cachep->objsize;
1386 if (objnr) { 1399 if (objnr) {
1387 objp = slabp->s_mem+(objnr-1)*cachep->objsize; 1400 objp = slabp->s_mem + (objnr - 1) * cachep->objsize;
1388 realobj = (char*)objp+obj_dbghead(cachep); 1401 realobj = (char *)objp + obj_dbghead(cachep);
1389 printk(KERN_ERR "Prev obj: start=%p, len=%d\n", 1402 printk(KERN_ERR "Prev obj: start=%p, len=%d\n",
1390 realobj, size); 1403 realobj, size);
1391 print_objinfo(cachep, objp, 2); 1404 print_objinfo(cachep, objp, 2);
1392 } 1405 }
1393 if (objnr+1 < cachep->num) { 1406 if (objnr + 1 < cachep->num) {
1394 objp = slabp->s_mem+(objnr+1)*cachep->objsize; 1407 objp = slabp->s_mem + (objnr + 1) * cachep->objsize;
1395 realobj = (char*)objp+obj_dbghead(cachep); 1408 realobj = (char *)objp + obj_dbghead(cachep);
1396 printk(KERN_ERR "Next obj: start=%p, len=%d\n", 1409 printk(KERN_ERR "Next obj: start=%p, len=%d\n",
1397 realobj, size); 1410 realobj, size);
1398 print_objinfo(cachep, objp, 2); 1411 print_objinfo(cachep, objp, 2);
1399 } 1412 }
1400 } 1413 }
@@ -1405,7 +1418,7 @@ static void check_poison_obj(kmem_cache_t *cachep, void *objp)
1405 * Before calling the slab must have been unlinked from the cache. 1418 * Before calling the slab must have been unlinked from the cache.
1406 * The cache-lock is not held/needed. 1419 * The cache-lock is not held/needed.
1407 */ 1420 */
1408static void slab_destroy (kmem_cache_t *cachep, struct slab *slabp) 1421static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp)
1409{ 1422{
1410 void *addr = slabp->s_mem - slabp->colouroff; 1423 void *addr = slabp->s_mem - slabp->colouroff;
1411 1424
@@ -1416,8 +1429,11 @@ static void slab_destroy (kmem_cache_t *cachep, struct slab *slabp)
1416 1429
1417 if (cachep->flags & SLAB_POISON) { 1430 if (cachep->flags & SLAB_POISON) {
1418#ifdef CONFIG_DEBUG_PAGEALLOC 1431#ifdef CONFIG_DEBUG_PAGEALLOC
1419 if ((cachep->objsize%PAGE_SIZE)==0 && OFF_SLAB(cachep)) 1432 if ((cachep->objsize % PAGE_SIZE) == 0
1420 kernel_map_pages(virt_to_page(objp), cachep->objsize/PAGE_SIZE,1); 1433 && OFF_SLAB(cachep))
1434 kernel_map_pages(virt_to_page(objp),
1435 cachep->objsize / PAGE_SIZE,
1436 1);
1421 else 1437 else
1422 check_poison_obj(cachep, objp); 1438 check_poison_obj(cachep, objp);
1423#else 1439#else
@@ -1427,20 +1443,20 @@ static void slab_destroy (kmem_cache_t *cachep, struct slab *slabp)
1427 if (cachep->flags & SLAB_RED_ZONE) { 1443 if (cachep->flags & SLAB_RED_ZONE) {
1428 if (*dbg_redzone1(cachep, objp) != RED_INACTIVE) 1444 if (*dbg_redzone1(cachep, objp) != RED_INACTIVE)
1429 slab_error(cachep, "start of a freed object " 1445 slab_error(cachep, "start of a freed object "
1430 "was overwritten"); 1446 "was overwritten");
1431 if (*dbg_redzone2(cachep, objp) != RED_INACTIVE) 1447 if (*dbg_redzone2(cachep, objp) != RED_INACTIVE)
1432 slab_error(cachep, "end of a freed object " 1448 slab_error(cachep, "end of a freed object "
1433 "was overwritten"); 1449 "was overwritten");
1434 } 1450 }
1435 if (cachep->dtor && !(cachep->flags & SLAB_POISON)) 1451 if (cachep->dtor && !(cachep->flags & SLAB_POISON))
1436 (cachep->dtor)(objp+obj_dbghead(cachep), cachep, 0); 1452 (cachep->dtor) (objp + obj_dbghead(cachep), cachep, 0);
1437 } 1453 }
1438#else 1454#else
1439 if (cachep->dtor) { 1455 if (cachep->dtor) {
1440 int i; 1456 int i;
1441 for (i = 0; i < cachep->num; i++) { 1457 for (i = 0; i < cachep->num; i++) {
1442 void* objp = slabp->s_mem+cachep->objsize*i; 1458 void *objp = slabp->s_mem + cachep->objsize * i;
1443 (cachep->dtor)(objp, cachep, 0); 1459 (cachep->dtor) (objp, cachep, 0);
1444 } 1460 }
1445 } 1461 }
1446#endif 1462#endif
@@ -1448,7 +1464,7 @@ static void slab_destroy (kmem_cache_t *cachep, struct slab *slabp)
1448 if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU)) { 1464 if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU)) {
1449 struct slab_rcu *slab_rcu; 1465 struct slab_rcu *slab_rcu;
1450 1466
1451 slab_rcu = (struct slab_rcu *) slabp; 1467 slab_rcu = (struct slab_rcu *)slabp;
1452 slab_rcu->cachep = cachep; 1468 slab_rcu->cachep = cachep;
1453 slab_rcu->addr = addr; 1469 slab_rcu->addr = addr;
1454 call_rcu(&slab_rcu->head, kmem_rcu_free); 1470 call_rcu(&slab_rcu->head, kmem_rcu_free);
@@ -1466,11 +1482,58 @@ static inline void set_up_list3s(kmem_cache_t *cachep, int index)
1466 int node; 1482 int node;
1467 1483
1468 for_each_online_node(node) { 1484 for_each_online_node(node) {
1469 cachep->nodelists[node] = &initkmem_list3[index+node]; 1485 cachep->nodelists[node] = &initkmem_list3[index + node];
1470 cachep->nodelists[node]->next_reap = jiffies + 1486 cachep->nodelists[node]->next_reap = jiffies +
1471 REAPTIMEOUT_LIST3 + 1487 REAPTIMEOUT_LIST3 +
1472 ((unsigned long)cachep)%REAPTIMEOUT_LIST3; 1488 ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
1489 }
1490}
1491
1492/**
1493 * calculate_slab_order - calculate size (page order) of slabs and the number
1494 * of objects per slab.
1495 *
1496 * This could be made much more intelligent. For now, try to avoid using
1497 * high order pages for slabs. When the gfp() functions are more friendly
1498 * towards high-order requests, this should be changed.
1499 */
1500static inline size_t calculate_slab_order(kmem_cache_t *cachep, size_t size,
1501 size_t align, gfp_t flags)
1502{
1503 size_t left_over = 0;
1504
1505 for (;; cachep->gfporder++) {
1506 unsigned int num;
1507 size_t remainder;
1508
1509 if (cachep->gfporder > MAX_GFP_ORDER) {
1510 cachep->num = 0;
1511 break;
1512 }
1513
1514 cache_estimate(cachep->gfporder, size, align, flags,
1515 &remainder, &num);
1516 if (!num)
1517 continue;
1518 /* More than offslab_limit objects will cause problems */
1519 if (flags & CFLGS_OFF_SLAB && cachep->num > offslab_limit)
1520 break;
1521
1522 cachep->num = num;
1523 left_over = remainder;
1524
1525 /*
1526 * Large number of objects is good, but very large slabs are
1527 * currently bad for the gfp()s.
1528 */
1529 if (cachep->gfporder >= slab_break_gfp_order)
1530 break;
1531
1532 if ((left_over * 8) <= (PAGE_SIZE << cachep->gfporder))
1533 /* Acceptable internal fragmentation */
1534 break;
1473 } 1535 }
1536 return left_over;
1474} 1537}
1475 1538
1476/** 1539/**
@@ -1519,14 +1582,13 @@ kmem_cache_create (const char *name, size_t size, size_t align,
1519 * Sanity checks... these are all serious usage bugs. 1582 * Sanity checks... these are all serious usage bugs.
1520 */ 1583 */
1521 if ((!name) || 1584 if ((!name) ||
1522 in_interrupt() || 1585 in_interrupt() ||
1523 (size < BYTES_PER_WORD) || 1586 (size < BYTES_PER_WORD) ||
1524 (size > (1<<MAX_OBJ_ORDER)*PAGE_SIZE) || 1587 (size > (1 << MAX_OBJ_ORDER) * PAGE_SIZE) || (dtor && !ctor)) {
1525 (dtor && !ctor)) { 1588 printk(KERN_ERR "%s: Early error in slab %s\n",
1526 printk(KERN_ERR "%s: Early error in slab %s\n", 1589 __FUNCTION__, name);
1527 __FUNCTION__, name); 1590 BUG();
1528 BUG(); 1591 }
1529 }
1530 1592
1531 down(&cache_chain_sem); 1593 down(&cache_chain_sem);
1532 1594
@@ -1546,11 +1608,11 @@ kmem_cache_create (const char *name, size_t size, size_t align,
1546 set_fs(old_fs); 1608 set_fs(old_fs);
1547 if (res) { 1609 if (res) {
1548 printk("SLAB: cache with size %d has lost its name\n", 1610 printk("SLAB: cache with size %d has lost its name\n",
1549 pc->objsize); 1611 pc->objsize);
1550 continue; 1612 continue;
1551 } 1613 }
1552 1614
1553 if (!strcmp(pc->name,name)) { 1615 if (!strcmp(pc->name, name)) {
1554 printk("kmem_cache_create: duplicate cache %s\n", name); 1616 printk("kmem_cache_create: duplicate cache %s\n", name);
1555 dump_stack(); 1617 dump_stack();
1556 goto oops; 1618 goto oops;
@@ -1562,10 +1624,9 @@ kmem_cache_create (const char *name, size_t size, size_t align,
1562 if ((flags & SLAB_DEBUG_INITIAL) && !ctor) { 1624 if ((flags & SLAB_DEBUG_INITIAL) && !ctor) {
1563 /* No constructor, but inital state check requested */ 1625 /* No constructor, but inital state check requested */
1564 printk(KERN_ERR "%s: No con, but init state check " 1626 printk(KERN_ERR "%s: No con, but init state check "
1565 "requested - %s\n", __FUNCTION__, name); 1627 "requested - %s\n", __FUNCTION__, name);
1566 flags &= ~SLAB_DEBUG_INITIAL; 1628 flags &= ~SLAB_DEBUG_INITIAL;
1567 } 1629 }
1568
1569#if FORCED_DEBUG 1630#if FORCED_DEBUG
1570 /* 1631 /*
1571 * Enable redzoning and last user accounting, except for caches with 1632 * Enable redzoning and last user accounting, except for caches with
@@ -1573,8 +1634,9 @@ kmem_cache_create (const char *name, size_t size, size_t align,
1573 * above the next power of two: caches with object sizes just above a 1634 * above the next power of two: caches with object sizes just above a
1574 * power of two have a significant amount of internal fragmentation. 1635 * power of two have a significant amount of internal fragmentation.
1575 */ 1636 */
1576 if ((size < 4096 || fls(size-1) == fls(size-1+3*BYTES_PER_WORD))) 1637 if ((size < 4096
1577 flags |= SLAB_RED_ZONE|SLAB_STORE_USER; 1638 || fls(size - 1) == fls(size - 1 + 3 * BYTES_PER_WORD)))
1639 flags |= SLAB_RED_ZONE | SLAB_STORE_USER;
1578 if (!(flags & SLAB_DESTROY_BY_RCU)) 1640 if (!(flags & SLAB_DESTROY_BY_RCU))
1579 flags |= SLAB_POISON; 1641 flags |= SLAB_POISON;
1580#endif 1642#endif
@@ -1595,9 +1657,9 @@ kmem_cache_create (const char *name, size_t size, size_t align,
1595 * unaligned accesses for some archs when redzoning is used, and makes 1657 * unaligned accesses for some archs when redzoning is used, and makes
1596 * sure any on-slab bufctl's are also correctly aligned. 1658 * sure any on-slab bufctl's are also correctly aligned.
1597 */ 1659 */
1598 if (size & (BYTES_PER_WORD-1)) { 1660 if (size & (BYTES_PER_WORD - 1)) {
1599 size += (BYTES_PER_WORD-1); 1661 size += (BYTES_PER_WORD - 1);
1600 size &= ~(BYTES_PER_WORD-1); 1662 size &= ~(BYTES_PER_WORD - 1);
1601 } 1663 }
1602 1664
1603 /* calculate out the final buffer alignment: */ 1665 /* calculate out the final buffer alignment: */
@@ -1608,7 +1670,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
1608 * objects into one cacheline. 1670 * objects into one cacheline.
1609 */ 1671 */
1610 ralign = cache_line_size(); 1672 ralign = cache_line_size();
1611 while (size <= ralign/2) 1673 while (size <= ralign / 2)
1612 ralign /= 2; 1674 ralign /= 2;
1613 } else { 1675 } else {
1614 ralign = BYTES_PER_WORD; 1676 ralign = BYTES_PER_WORD;
@@ -1617,13 +1679,13 @@ kmem_cache_create (const char *name, size_t size, size_t align,
1617 if (ralign < ARCH_SLAB_MINALIGN) { 1679 if (ralign < ARCH_SLAB_MINALIGN) {
1618 ralign = ARCH_SLAB_MINALIGN; 1680 ralign = ARCH_SLAB_MINALIGN;
1619 if (ralign > BYTES_PER_WORD) 1681 if (ralign > BYTES_PER_WORD)
1620 flags &= ~(SLAB_RED_ZONE|SLAB_STORE_USER); 1682 flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER);
1621 } 1683 }
1622 /* 3) caller mandated alignment: disables debug if necessary */ 1684 /* 3) caller mandated alignment: disables debug if necessary */
1623 if (ralign < align) { 1685 if (ralign < align) {
1624 ralign = align; 1686 ralign = align;
1625 if (ralign > BYTES_PER_WORD) 1687 if (ralign > BYTES_PER_WORD)
1626 flags &= ~(SLAB_RED_ZONE|SLAB_STORE_USER); 1688 flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER);
1627 } 1689 }
1628 /* 4) Store it. Note that the debug code below can reduce 1690 /* 4) Store it. Note that the debug code below can reduce
1629 * the alignment to BYTES_PER_WORD. 1691 * the alignment to BYTES_PER_WORD.
@@ -1645,7 +1707,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
1645 1707
1646 /* add space for red zone words */ 1708 /* add space for red zone words */
1647 cachep->dbghead += BYTES_PER_WORD; 1709 cachep->dbghead += BYTES_PER_WORD;
1648 size += 2*BYTES_PER_WORD; 1710 size += 2 * BYTES_PER_WORD;
1649 } 1711 }
1650 if (flags & SLAB_STORE_USER) { 1712 if (flags & SLAB_STORE_USER) {
1651 /* user store requires word alignment and 1713 /* user store requires word alignment and
@@ -1656,7 +1718,8 @@ kmem_cache_create (const char *name, size_t size, size_t align,
1656 size += BYTES_PER_WORD; 1718 size += BYTES_PER_WORD;
1657 } 1719 }
1658#if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC) 1720#if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC)
1659 if (size >= malloc_sizes[INDEX_L3+1].cs_size && cachep->reallen > cache_line_size() && size < PAGE_SIZE) { 1721 if (size >= malloc_sizes[INDEX_L3 + 1].cs_size
1722 && cachep->reallen > cache_line_size() && size < PAGE_SIZE) {
1660 cachep->dbghead += PAGE_SIZE - size; 1723 cachep->dbghead += PAGE_SIZE - size;
1661 size = PAGE_SIZE; 1724 size = PAGE_SIZE;
1662 } 1725 }
@@ -1664,7 +1727,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
1664#endif 1727#endif
1665 1728
1666 /* Determine if the slab management is 'on' or 'off' slab. */ 1729 /* Determine if the slab management is 'on' or 'off' slab. */
1667 if (size >= (PAGE_SIZE>>3)) 1730 if (size >= (PAGE_SIZE >> 3))
1668 /* 1731 /*
1669 * Size is large, assume best to place the slab management obj 1732 * Size is large, assume best to place the slab management obj
1670 * off-slab (should allow better packing of objs). 1733 * off-slab (should allow better packing of objs).
@@ -1681,47 +1744,9 @@ kmem_cache_create (const char *name, size_t size, size_t align,
1681 */ 1744 */
1682 cachep->gfporder = 0; 1745 cachep->gfporder = 0;
1683 cache_estimate(cachep->gfporder, size, align, flags, 1746 cache_estimate(cachep->gfporder, size, align, flags,
1684 &left_over, &cachep->num); 1747 &left_over, &cachep->num);
1685 } else { 1748 } else
1686 /* 1749 left_over = calculate_slab_order(cachep, size, align, flags);
1687 * Calculate size (in pages) of slabs, and the num of objs per
1688 * slab. This could be made much more intelligent. For now,
1689 * try to avoid using high page-orders for slabs. When the
1690 * gfp() funcs are more friendly towards high-order requests,
1691 * this should be changed.
1692 */
1693 do {
1694 unsigned int break_flag = 0;
1695cal_wastage:
1696 cache_estimate(cachep->gfporder, size, align, flags,
1697 &left_over, &cachep->num);
1698 if (break_flag)
1699 break;
1700 if (cachep->gfporder >= MAX_GFP_ORDER)
1701 break;
1702 if (!cachep->num)
1703 goto next;
1704 if (flags & CFLGS_OFF_SLAB &&
1705 cachep->num > offslab_limit) {
1706 /* This num of objs will cause problems. */
1707 cachep->gfporder--;
1708 break_flag++;
1709 goto cal_wastage;
1710 }
1711
1712 /*
1713 * Large num of objs is good, but v. large slabs are
1714 * currently bad for the gfp()s.
1715 */
1716 if (cachep->gfporder >= slab_break_gfp_order)
1717 break;
1718
1719 if ((left_over*8) <= (PAGE_SIZE<<cachep->gfporder))
1720 break; /* Acceptable internal fragmentation. */
1721next:
1722 cachep->gfporder++;
1723 } while (1);
1724 }
1725 1750
1726 if (!cachep->num) { 1751 if (!cachep->num) {
1727 printk("kmem_cache_create: couldn't create cache %s.\n", name); 1752 printk("kmem_cache_create: couldn't create cache %s.\n", name);
@@ -1729,8 +1754,8 @@ next:
1729 cachep = NULL; 1754 cachep = NULL;
1730 goto oops; 1755 goto oops;
1731 } 1756 }
1732 slab_size = ALIGN(cachep->num*sizeof(kmem_bufctl_t) 1757 slab_size = ALIGN(cachep->num * sizeof(kmem_bufctl_t)
1733 + sizeof(struct slab), align); 1758 + sizeof(struct slab), align);
1734 1759
1735 /* 1760 /*
1736 * If the slab has been placed off-slab, and we have enough space then 1761 * If the slab has been placed off-slab, and we have enough space then
@@ -1743,14 +1768,15 @@ next:
1743 1768
1744 if (flags & CFLGS_OFF_SLAB) { 1769 if (flags & CFLGS_OFF_SLAB) {
1745 /* really off slab. No need for manual alignment */ 1770 /* really off slab. No need for manual alignment */
1746 slab_size = cachep->num*sizeof(kmem_bufctl_t)+sizeof(struct slab); 1771 slab_size =
1772 cachep->num * sizeof(kmem_bufctl_t) + sizeof(struct slab);
1747 } 1773 }
1748 1774
1749 cachep->colour_off = cache_line_size(); 1775 cachep->colour_off = cache_line_size();
1750 /* Offset must be a multiple of the alignment. */ 1776 /* Offset must be a multiple of the alignment. */
1751 if (cachep->colour_off < align) 1777 if (cachep->colour_off < align)
1752 cachep->colour_off = align; 1778 cachep->colour_off = align;
1753 cachep->colour = left_over/cachep->colour_off; 1779 cachep->colour = left_over / cachep->colour_off;
1754 cachep->slab_size = slab_size; 1780 cachep->slab_size = slab_size;
1755 cachep->flags = flags; 1781 cachep->flags = flags;
1756 cachep->gfpflags = 0; 1782 cachep->gfpflags = 0;
@@ -1777,7 +1803,7 @@ next:
1777 * the creation of further caches will BUG(). 1803 * the creation of further caches will BUG().
1778 */ 1804 */
1779 cachep->array[smp_processor_id()] = 1805 cachep->array[smp_processor_id()] =
1780 &initarray_generic.cache; 1806 &initarray_generic.cache;
1781 1807
1782 /* If the cache that's used by 1808 /* If the cache that's used by
1783 * kmalloc(sizeof(kmem_list3)) is the first cache, 1809 * kmalloc(sizeof(kmem_list3)) is the first cache,
@@ -1791,8 +1817,7 @@ next:
1791 g_cpucache_up = PARTIAL_AC; 1817 g_cpucache_up = PARTIAL_AC;
1792 } else { 1818 } else {
1793 cachep->array[smp_processor_id()] = 1819 cachep->array[smp_processor_id()] =
1794 kmalloc(sizeof(struct arraycache_init), 1820 kmalloc(sizeof(struct arraycache_init), GFP_KERNEL);
1795 GFP_KERNEL);
1796 1821
1797 if (g_cpucache_up == PARTIAL_AC) { 1822 if (g_cpucache_up == PARTIAL_AC) {
1798 set_up_list3s(cachep, SIZE_L3); 1823 set_up_list3s(cachep, SIZE_L3);
@@ -1802,16 +1827,18 @@ next:
1802 for_each_online_node(node) { 1827 for_each_online_node(node) {
1803 1828
1804 cachep->nodelists[node] = 1829 cachep->nodelists[node] =
1805 kmalloc_node(sizeof(struct kmem_list3), 1830 kmalloc_node(sizeof
1806 GFP_KERNEL, node); 1831 (struct kmem_list3),
1832 GFP_KERNEL, node);
1807 BUG_ON(!cachep->nodelists[node]); 1833 BUG_ON(!cachep->nodelists[node]);
1808 kmem_list3_init(cachep->nodelists[node]); 1834 kmem_list3_init(cachep->
1835 nodelists[node]);
1809 } 1836 }
1810 } 1837 }
1811 } 1838 }
1812 cachep->nodelists[numa_node_id()]->next_reap = 1839 cachep->nodelists[numa_node_id()]->next_reap =
1813 jiffies + REAPTIMEOUT_LIST3 + 1840 jiffies + REAPTIMEOUT_LIST3 +
1814 ((unsigned long)cachep)%REAPTIMEOUT_LIST3; 1841 ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
1815 1842
1816 BUG_ON(!ac_data(cachep)); 1843 BUG_ON(!ac_data(cachep));
1817 ac_data(cachep)->avail = 0; 1844 ac_data(cachep)->avail = 0;
@@ -1820,15 +1847,15 @@ next:
1820 ac_data(cachep)->touched = 0; 1847 ac_data(cachep)->touched = 0;
1821 cachep->batchcount = 1; 1848 cachep->batchcount = 1;
1822 cachep->limit = BOOT_CPUCACHE_ENTRIES; 1849 cachep->limit = BOOT_CPUCACHE_ENTRIES;
1823 } 1850 }
1824 1851
1825 /* cache setup completed, link it into the list */ 1852 /* cache setup completed, link it into the list */
1826 list_add(&cachep->next, &cache_chain); 1853 list_add(&cachep->next, &cache_chain);
1827 unlock_cpu_hotplug(); 1854 unlock_cpu_hotplug();
1828oops: 1855 oops:
1829 if (!cachep && (flags & SLAB_PANIC)) 1856 if (!cachep && (flags & SLAB_PANIC))
1830 panic("kmem_cache_create(): failed to create slab `%s'\n", 1857 panic("kmem_cache_create(): failed to create slab `%s'\n",
1831 name); 1858 name);
1832 up(&cache_chain_sem); 1859 up(&cache_chain_sem);
1833 return cachep; 1860 return cachep;
1834} 1861}
@@ -1871,7 +1898,7 @@ static inline void check_spinlock_acquired_node(kmem_cache_t *cachep, int node)
1871/* 1898/*
1872 * Waits for all CPUs to execute func(). 1899 * Waits for all CPUs to execute func().
1873 */ 1900 */
1874static void smp_call_function_all_cpus(void (*func) (void *arg), void *arg) 1901static void smp_call_function_all_cpus(void (*func)(void *arg), void *arg)
1875{ 1902{
1876 check_irq_on(); 1903 check_irq_on();
1877 preempt_disable(); 1904 preempt_disable();
@@ -1886,12 +1913,12 @@ static void smp_call_function_all_cpus(void (*func) (void *arg), void *arg)
1886 preempt_enable(); 1913 preempt_enable();
1887} 1914}
1888 1915
1889static void drain_array_locked(kmem_cache_t* cachep, 1916static void drain_array_locked(kmem_cache_t *cachep, struct array_cache *ac,
1890 struct array_cache *ac, int force, int node); 1917 int force, int node);
1891 1918
1892static void do_drain(void *arg) 1919static void do_drain(void *arg)
1893{ 1920{
1894 kmem_cache_t *cachep = (kmem_cache_t*)arg; 1921 kmem_cache_t *cachep = (kmem_cache_t *) arg;
1895 struct array_cache *ac; 1922 struct array_cache *ac;
1896 int node = numa_node_id(); 1923 int node = numa_node_id();
1897 1924
@@ -1911,7 +1938,7 @@ static void drain_cpu_caches(kmem_cache_t *cachep)
1911 smp_call_function_all_cpus(do_drain, cachep); 1938 smp_call_function_all_cpus(do_drain, cachep);
1912 check_irq_on(); 1939 check_irq_on();
1913 spin_lock_irq(&cachep->spinlock); 1940 spin_lock_irq(&cachep->spinlock);
1914 for_each_online_node(node) { 1941 for_each_online_node(node) {
1915 l3 = cachep->nodelists[node]; 1942 l3 = cachep->nodelists[node];
1916 if (l3) { 1943 if (l3) {
1917 spin_lock(&l3->list_lock); 1944 spin_lock(&l3->list_lock);
@@ -1949,8 +1976,7 @@ static int __node_shrink(kmem_cache_t *cachep, int node)
1949 slab_destroy(cachep, slabp); 1976 slab_destroy(cachep, slabp);
1950 spin_lock_irq(&l3->list_lock); 1977 spin_lock_irq(&l3->list_lock);
1951 } 1978 }
1952 ret = !list_empty(&l3->slabs_full) || 1979 ret = !list_empty(&l3->slabs_full) || !list_empty(&l3->slabs_partial);
1953 !list_empty(&l3->slabs_partial);
1954 return ret; 1980 return ret;
1955} 1981}
1956 1982
@@ -2006,7 +2032,7 @@ EXPORT_SYMBOL(kmem_cache_shrink);
2006 * The caller must guarantee that noone will allocate memory from the cache 2032 * The caller must guarantee that noone will allocate memory from the cache
2007 * during the kmem_cache_destroy(). 2033 * during the kmem_cache_destroy().
2008 */ 2034 */
2009int kmem_cache_destroy(kmem_cache_t * cachep) 2035int kmem_cache_destroy(kmem_cache_t *cachep)
2010{ 2036{
2011 int i; 2037 int i;
2012 struct kmem_list3 *l3; 2038 struct kmem_list3 *l3;
@@ -2028,7 +2054,7 @@ int kmem_cache_destroy(kmem_cache_t * cachep)
2028 if (__cache_shrink(cachep)) { 2054 if (__cache_shrink(cachep)) {
2029 slab_error(cachep, "Can't free all objects"); 2055 slab_error(cachep, "Can't free all objects");
2030 down(&cache_chain_sem); 2056 down(&cache_chain_sem);
2031 list_add(&cachep->next,&cache_chain); 2057 list_add(&cachep->next, &cache_chain);
2032 up(&cache_chain_sem); 2058 up(&cache_chain_sem);
2033 unlock_cpu_hotplug(); 2059 unlock_cpu_hotplug();
2034 return 1; 2060 return 1;
@@ -2038,7 +2064,7 @@ int kmem_cache_destroy(kmem_cache_t * cachep)
2038 synchronize_rcu(); 2064 synchronize_rcu();
2039 2065
2040 for_each_online_cpu(i) 2066 for_each_online_cpu(i)
2041 kfree(cachep->array[i]); 2067 kfree(cachep->array[i]);
2042 2068
2043 /* NUMA: free the list3 structures */ 2069 /* NUMA: free the list3 structures */
2044 for_each_online_node(i) { 2070 for_each_online_node(i) {
@@ -2057,39 +2083,39 @@ int kmem_cache_destroy(kmem_cache_t * cachep)
2057EXPORT_SYMBOL(kmem_cache_destroy); 2083EXPORT_SYMBOL(kmem_cache_destroy);
2058 2084
2059/* Get the memory for a slab management obj. */ 2085/* Get the memory for a slab management obj. */
2060static struct slab* alloc_slabmgmt(kmem_cache_t *cachep, void *objp, 2086static struct slab *alloc_slabmgmt(kmem_cache_t *cachep, void *objp,
2061 int colour_off, gfp_t local_flags) 2087 int colour_off, gfp_t local_flags)
2062{ 2088{
2063 struct slab *slabp; 2089 struct slab *slabp;
2064 2090
2065 if (OFF_SLAB(cachep)) { 2091 if (OFF_SLAB(cachep)) {
2066 /* Slab management obj is off-slab. */ 2092 /* Slab management obj is off-slab. */
2067 slabp = kmem_cache_alloc(cachep->slabp_cache, local_flags); 2093 slabp = kmem_cache_alloc(cachep->slabp_cache, local_flags);
2068 if (!slabp) 2094 if (!slabp)
2069 return NULL; 2095 return NULL;
2070 } else { 2096 } else {
2071 slabp = objp+colour_off; 2097 slabp = objp + colour_off;
2072 colour_off += cachep->slab_size; 2098 colour_off += cachep->slab_size;
2073 } 2099 }
2074 slabp->inuse = 0; 2100 slabp->inuse = 0;
2075 slabp->colouroff = colour_off; 2101 slabp->colouroff = colour_off;
2076 slabp->s_mem = objp+colour_off; 2102 slabp->s_mem = objp + colour_off;
2077 2103
2078 return slabp; 2104 return slabp;
2079} 2105}
2080 2106
2081static inline kmem_bufctl_t *slab_bufctl(struct slab *slabp) 2107static inline kmem_bufctl_t *slab_bufctl(struct slab *slabp)
2082{ 2108{
2083 return (kmem_bufctl_t *)(slabp+1); 2109 return (kmem_bufctl_t *) (slabp + 1);
2084} 2110}
2085 2111
2086static void cache_init_objs(kmem_cache_t *cachep, 2112static void cache_init_objs(kmem_cache_t *cachep,
2087 struct slab *slabp, unsigned long ctor_flags) 2113 struct slab *slabp, unsigned long ctor_flags)
2088{ 2114{
2089 int i; 2115 int i;
2090 2116
2091 for (i = 0; i < cachep->num; i++) { 2117 for (i = 0; i < cachep->num; i++) {
2092 void *objp = slabp->s_mem+cachep->objsize*i; 2118 void *objp = slabp->s_mem + cachep->objsize * i;
2093#if DEBUG 2119#if DEBUG
2094 /* need to poison the objs? */ 2120 /* need to poison the objs? */
2095 if (cachep->flags & SLAB_POISON) 2121 if (cachep->flags & SLAB_POISON)
@@ -2107,25 +2133,28 @@ static void cache_init_objs(kmem_cache_t *cachep,
2107 * Otherwise, deadlock. They must also be threaded. 2133 * Otherwise, deadlock. They must also be threaded.
2108 */ 2134 */
2109 if (cachep->ctor && !(cachep->flags & SLAB_POISON)) 2135 if (cachep->ctor && !(cachep->flags & SLAB_POISON))
2110 cachep->ctor(objp+obj_dbghead(cachep), cachep, ctor_flags); 2136 cachep->ctor(objp + obj_dbghead(cachep), cachep,
2137 ctor_flags);
2111 2138
2112 if (cachep->flags & SLAB_RED_ZONE) { 2139 if (cachep->flags & SLAB_RED_ZONE) {
2113 if (*dbg_redzone2(cachep, objp) != RED_INACTIVE) 2140 if (*dbg_redzone2(cachep, objp) != RED_INACTIVE)
2114 slab_error(cachep, "constructor overwrote the" 2141 slab_error(cachep, "constructor overwrote the"
2115 " end of an object"); 2142 " end of an object");
2116 if (*dbg_redzone1(cachep, objp) != RED_INACTIVE) 2143 if (*dbg_redzone1(cachep, objp) != RED_INACTIVE)
2117 slab_error(cachep, "constructor overwrote the" 2144 slab_error(cachep, "constructor overwrote the"
2118 " start of an object"); 2145 " start of an object");
2119 } 2146 }
2120 if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep) && cachep->flags & SLAB_POISON) 2147 if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep)
2121 kernel_map_pages(virt_to_page(objp), cachep->objsize/PAGE_SIZE, 0); 2148 && cachep->flags & SLAB_POISON)
2149 kernel_map_pages(virt_to_page(objp),
2150 cachep->objsize / PAGE_SIZE, 0);
2122#else 2151#else
2123 if (cachep->ctor) 2152 if (cachep->ctor)
2124 cachep->ctor(objp, cachep, ctor_flags); 2153 cachep->ctor(objp, cachep, ctor_flags);
2125#endif 2154#endif
2126 slab_bufctl(slabp)[i] = i+1; 2155 slab_bufctl(slabp)[i] = i + 1;
2127 } 2156 }
2128 slab_bufctl(slabp)[i-1] = BUFCTL_END; 2157 slab_bufctl(slabp)[i - 1] = BUFCTL_END;
2129 slabp->free = 0; 2158 slabp->free = 0;
2130} 2159}
2131 2160
@@ -2161,17 +2190,17 @@ static void set_slab_attr(kmem_cache_t *cachep, struct slab *slabp, void *objp)
2161 */ 2190 */
2162static int cache_grow(kmem_cache_t *cachep, gfp_t flags, int nodeid) 2191static int cache_grow(kmem_cache_t *cachep, gfp_t flags, int nodeid)
2163{ 2192{
2164 struct slab *slabp; 2193 struct slab *slabp;
2165 void *objp; 2194 void *objp;
2166 size_t offset; 2195 size_t offset;
2167 gfp_t local_flags; 2196 gfp_t local_flags;
2168 unsigned long ctor_flags; 2197 unsigned long ctor_flags;
2169 struct kmem_list3 *l3; 2198 struct kmem_list3 *l3;
2170 2199
2171 /* Be lazy and only check for valid flags here, 2200 /* Be lazy and only check for valid flags here,
2172 * keeping it out of the critical path in kmem_cache_alloc(). 2201 * keeping it out of the critical path in kmem_cache_alloc().
2173 */ 2202 */
2174 if (flags & ~(SLAB_DMA|SLAB_LEVEL_MASK|SLAB_NO_GROW)) 2203 if (flags & ~(SLAB_DMA | SLAB_LEVEL_MASK | SLAB_NO_GROW))
2175 BUG(); 2204 BUG();
2176 if (flags & SLAB_NO_GROW) 2205 if (flags & SLAB_NO_GROW)
2177 return 0; 2206 return 0;
@@ -2237,9 +2266,9 @@ static int cache_grow(kmem_cache_t *cachep, gfp_t flags, int nodeid)
2237 l3->free_objects += cachep->num; 2266 l3->free_objects += cachep->num;
2238 spin_unlock(&l3->list_lock); 2267 spin_unlock(&l3->list_lock);
2239 return 1; 2268 return 1;
2240opps1: 2269 opps1:
2241 kmem_freepages(cachep, objp); 2270 kmem_freepages(cachep, objp);
2242failed: 2271 failed:
2243 if (local_flags & __GFP_WAIT) 2272 if (local_flags & __GFP_WAIT)
2244 local_irq_disable(); 2273 local_irq_disable();
2245 return 0; 2274 return 0;
@@ -2259,18 +2288,19 @@ static void kfree_debugcheck(const void *objp)
2259 2288
2260 if (!virt_addr_valid(objp)) { 2289 if (!virt_addr_valid(objp)) {
2261 printk(KERN_ERR "kfree_debugcheck: out of range ptr %lxh.\n", 2290 printk(KERN_ERR "kfree_debugcheck: out of range ptr %lxh.\n",
2262 (unsigned long)objp); 2291 (unsigned long)objp);
2263 BUG(); 2292 BUG();
2264 } 2293 }
2265 page = virt_to_page(objp); 2294 page = virt_to_page(objp);
2266 if (!PageSlab(page)) { 2295 if (!PageSlab(page)) {
2267 printk(KERN_ERR "kfree_debugcheck: bad ptr %lxh.\n", (unsigned long)objp); 2296 printk(KERN_ERR "kfree_debugcheck: bad ptr %lxh.\n",
2297 (unsigned long)objp);
2268 BUG(); 2298 BUG();
2269 } 2299 }
2270} 2300}
2271 2301
2272static void *cache_free_debugcheck(kmem_cache_t *cachep, void *objp, 2302static void *cache_free_debugcheck(kmem_cache_t *cachep, void *objp,
2273 void *caller) 2303 void *caller)
2274{ 2304{
2275 struct page *page; 2305 struct page *page;
2276 unsigned int objnr; 2306 unsigned int objnr;
@@ -2281,20 +2311,26 @@ static void *cache_free_debugcheck(kmem_cache_t *cachep, void *objp,
2281 page = virt_to_page(objp); 2311 page = virt_to_page(objp);
2282 2312
2283 if (page_get_cache(page) != cachep) { 2313 if (page_get_cache(page) != cachep) {
2284 printk(KERN_ERR "mismatch in kmem_cache_free: expected cache %p, got %p\n", 2314 printk(KERN_ERR
2285 page_get_cache(page),cachep); 2315 "mismatch in kmem_cache_free: expected cache %p, got %p\n",
2316 page_get_cache(page), cachep);
2286 printk(KERN_ERR "%p is %s.\n", cachep, cachep->name); 2317 printk(KERN_ERR "%p is %s.\n", cachep, cachep->name);
2287 printk(KERN_ERR "%p is %s.\n", page_get_cache(page), page_get_cache(page)->name); 2318 printk(KERN_ERR "%p is %s.\n", page_get_cache(page),
2319 page_get_cache(page)->name);
2288 WARN_ON(1); 2320 WARN_ON(1);
2289 } 2321 }
2290 slabp = page_get_slab(page); 2322 slabp = page_get_slab(page);
2291 2323
2292 if (cachep->flags & SLAB_RED_ZONE) { 2324 if (cachep->flags & SLAB_RED_ZONE) {
2293 if (*dbg_redzone1(cachep, objp) != RED_ACTIVE || *dbg_redzone2(cachep, objp) != RED_ACTIVE) { 2325 if (*dbg_redzone1(cachep, objp) != RED_ACTIVE
2294 slab_error(cachep, "double free, or memory outside" 2326 || *dbg_redzone2(cachep, objp) != RED_ACTIVE) {
2295 " object was overwritten"); 2327 slab_error(cachep,
2296 printk(KERN_ERR "%p: redzone 1: 0x%lx, redzone 2: 0x%lx.\n", 2328 "double free, or memory outside"
2297 objp, *dbg_redzone1(cachep, objp), *dbg_redzone2(cachep, objp)); 2329 " object was overwritten");
2330 printk(KERN_ERR
2331 "%p: redzone 1: 0x%lx, redzone 2: 0x%lx.\n",
2332 objp, *dbg_redzone1(cachep, objp),
2333 *dbg_redzone2(cachep, objp));
2298 } 2334 }
2299 *dbg_redzone1(cachep, objp) = RED_INACTIVE; 2335 *dbg_redzone1(cachep, objp) = RED_INACTIVE;
2300 *dbg_redzone2(cachep, objp) = RED_INACTIVE; 2336 *dbg_redzone2(cachep, objp) = RED_INACTIVE;
@@ -2302,30 +2338,31 @@ static void *cache_free_debugcheck(kmem_cache_t *cachep, void *objp,
2302 if (cachep->flags & SLAB_STORE_USER) 2338 if (cachep->flags & SLAB_STORE_USER)
2303 *dbg_userword(cachep, objp) = caller; 2339 *dbg_userword(cachep, objp) = caller;
2304 2340
2305 objnr = (objp-slabp->s_mem)/cachep->objsize; 2341 objnr = (objp - slabp->s_mem) / cachep->objsize;
2306 2342
2307 BUG_ON(objnr >= cachep->num); 2343 BUG_ON(objnr >= cachep->num);
2308 BUG_ON(objp != slabp->s_mem + objnr*cachep->objsize); 2344 BUG_ON(objp != slabp->s_mem + objnr * cachep->objsize);
2309 2345
2310 if (cachep->flags & SLAB_DEBUG_INITIAL) { 2346 if (cachep->flags & SLAB_DEBUG_INITIAL) {
2311 /* Need to call the slab's constructor so the 2347 /* Need to call the slab's constructor so the
2312 * caller can perform a verify of its state (debugging). 2348 * caller can perform a verify of its state (debugging).
2313 * Called without the cache-lock held. 2349 * Called without the cache-lock held.
2314 */ 2350 */
2315 cachep->ctor(objp+obj_dbghead(cachep), 2351 cachep->ctor(objp + obj_dbghead(cachep),
2316 cachep, SLAB_CTOR_CONSTRUCTOR|SLAB_CTOR_VERIFY); 2352 cachep, SLAB_CTOR_CONSTRUCTOR | SLAB_CTOR_VERIFY);
2317 } 2353 }
2318 if (cachep->flags & SLAB_POISON && cachep->dtor) { 2354 if (cachep->flags & SLAB_POISON && cachep->dtor) {
2319 /* we want to cache poison the object, 2355 /* we want to cache poison the object,
2320 * call the destruction callback 2356 * call the destruction callback
2321 */ 2357 */
2322 cachep->dtor(objp+obj_dbghead(cachep), cachep, 0); 2358 cachep->dtor(objp + obj_dbghead(cachep), cachep, 0);
2323 } 2359 }
2324 if (cachep->flags & SLAB_POISON) { 2360 if (cachep->flags & SLAB_POISON) {
2325#ifdef CONFIG_DEBUG_PAGEALLOC 2361#ifdef CONFIG_DEBUG_PAGEALLOC
2326 if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep)) { 2362 if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep)) {
2327 store_stackinfo(cachep, objp, (unsigned long)caller); 2363 store_stackinfo(cachep, objp, (unsigned long)caller);
2328 kernel_map_pages(virt_to_page(objp), cachep->objsize/PAGE_SIZE, 0); 2364 kernel_map_pages(virt_to_page(objp),
2365 cachep->objsize / PAGE_SIZE, 0);
2329 } else { 2366 } else {
2330 poison_obj(cachep, objp, POISON_FREE); 2367 poison_obj(cachep, objp, POISON_FREE);
2331 } 2368 }
@@ -2340,7 +2377,7 @@ static void check_slabp(kmem_cache_t *cachep, struct slab *slabp)
2340{ 2377{
2341 kmem_bufctl_t i; 2378 kmem_bufctl_t i;
2342 int entries = 0; 2379 int entries = 0;
2343 2380
2344 /* Check slab's freelist to see if this obj is there. */ 2381 /* Check slab's freelist to see if this obj is there. */
2345 for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { 2382 for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
2346 entries++; 2383 entries++;
@@ -2348,13 +2385,16 @@ static void check_slabp(kmem_cache_t *cachep, struct slab *slabp)
2348 goto bad; 2385 goto bad;
2349 } 2386 }
2350 if (entries != cachep->num - slabp->inuse) { 2387 if (entries != cachep->num - slabp->inuse) {
2351bad: 2388 bad:
2352 printk(KERN_ERR "slab: Internal list corruption detected in cache '%s'(%d), slabp %p(%d). Hexdump:\n", 2389 printk(KERN_ERR
2353 cachep->name, cachep->num, slabp, slabp->inuse); 2390 "slab: Internal list corruption detected in cache '%s'(%d), slabp %p(%d). Hexdump:\n",
2354 for (i=0;i<sizeof(slabp)+cachep->num*sizeof(kmem_bufctl_t);i++) { 2391 cachep->name, cachep->num, slabp, slabp->inuse);
2355 if ((i%16)==0) 2392 for (i = 0;
2393 i < sizeof(slabp) + cachep->num * sizeof(kmem_bufctl_t);
2394 i++) {
2395 if ((i % 16) == 0)
2356 printk("\n%03x:", i); 2396 printk("\n%03x:", i);
2357 printk(" %02x", ((unsigned char*)slabp)[i]); 2397 printk(" %02x", ((unsigned char *)slabp)[i]);
2358 } 2398 }
2359 printk("\n"); 2399 printk("\n");
2360 BUG(); 2400 BUG();
@@ -2374,7 +2414,7 @@ static void *cache_alloc_refill(kmem_cache_t *cachep, gfp_t flags)
2374 2414
2375 check_irq_off(); 2415 check_irq_off();
2376 ac = ac_data(cachep); 2416 ac = ac_data(cachep);
2377retry: 2417 retry:
2378 batchcount = ac->batchcount; 2418 batchcount = ac->batchcount;
2379 if (!ac->touched && batchcount > BATCHREFILL_LIMIT) { 2419 if (!ac->touched && batchcount > BATCHREFILL_LIMIT) {
2380 /* if there was little recent activity on this 2420 /* if there was little recent activity on this
@@ -2396,8 +2436,8 @@ retry:
2396 shared_array->avail -= batchcount; 2436 shared_array->avail -= batchcount;
2397 ac->avail = batchcount; 2437 ac->avail = batchcount;
2398 memcpy(ac->entry, 2438 memcpy(ac->entry,
2399 &(shared_array->entry[shared_array->avail]), 2439 &(shared_array->entry[shared_array->avail]),
2400 sizeof(void*)*batchcount); 2440 sizeof(void *) * batchcount);
2401 shared_array->touched = 1; 2441 shared_array->touched = 1;
2402 goto alloc_done; 2442 goto alloc_done;
2403 } 2443 }
@@ -2425,7 +2465,7 @@ retry:
2425 2465
2426 /* get obj pointer */ 2466 /* get obj pointer */
2427 ac->entry[ac->avail++] = slabp->s_mem + 2467 ac->entry[ac->avail++] = slabp->s_mem +
2428 slabp->free*cachep->objsize; 2468 slabp->free * cachep->objsize;
2429 2469
2430 slabp->inuse++; 2470 slabp->inuse++;
2431 next = slab_bufctl(slabp)[slabp->free]; 2471 next = slab_bufctl(slabp)[slabp->free];
@@ -2433,7 +2473,7 @@ retry:
2433 slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE; 2473 slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
2434 WARN_ON(numa_node_id() != slabp->nodeid); 2474 WARN_ON(numa_node_id() != slabp->nodeid);
2435#endif 2475#endif
2436 slabp->free = next; 2476 slabp->free = next;
2437 } 2477 }
2438 check_slabp(cachep, slabp); 2478 check_slabp(cachep, slabp);
2439 2479
@@ -2445,9 +2485,9 @@ retry:
2445 list_add(&slabp->list, &l3->slabs_partial); 2485 list_add(&slabp->list, &l3->slabs_partial);
2446 } 2486 }
2447 2487
2448must_grow: 2488 must_grow:
2449 l3->free_objects -= ac->avail; 2489 l3->free_objects -= ac->avail;
2450alloc_done: 2490 alloc_done:
2451 spin_unlock(&l3->list_lock); 2491 spin_unlock(&l3->list_lock);
2452 2492
2453 if (unlikely(!ac->avail)) { 2493 if (unlikely(!ac->avail)) {
@@ -2459,7 +2499,7 @@ alloc_done:
2459 if (!x && ac->avail == 0) // no objects in sight? abort 2499 if (!x && ac->avail == 0) // no objects in sight? abort
2460 return NULL; 2500 return NULL;
2461 2501
2462 if (!ac->avail) // objects refilled by interrupt? 2502 if (!ac->avail) // objects refilled by interrupt?
2463 goto retry; 2503 goto retry;
2464 } 2504 }
2465 ac->touched = 1; 2505 ac->touched = 1;
@@ -2476,16 +2516,16 @@ cache_alloc_debugcheck_before(kmem_cache_t *cachep, gfp_t flags)
2476} 2516}
2477 2517
2478#if DEBUG 2518#if DEBUG
2479static void * 2519static void *cache_alloc_debugcheck_after(kmem_cache_t *cachep, gfp_t flags,
2480cache_alloc_debugcheck_after(kmem_cache_t *cachep, 2520 void *objp, void *caller)
2481 gfp_t flags, void *objp, void *caller)
2482{ 2521{
2483 if (!objp) 2522 if (!objp)
2484 return objp; 2523 return objp;
2485 if (cachep->flags & SLAB_POISON) { 2524 if (cachep->flags & SLAB_POISON) {
2486#ifdef CONFIG_DEBUG_PAGEALLOC 2525#ifdef CONFIG_DEBUG_PAGEALLOC
2487 if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep)) 2526 if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep))
2488 kernel_map_pages(virt_to_page(objp), cachep->objsize/PAGE_SIZE, 1); 2527 kernel_map_pages(virt_to_page(objp),
2528 cachep->objsize / PAGE_SIZE, 1);
2489 else 2529 else
2490 check_poison_obj(cachep, objp); 2530 check_poison_obj(cachep, objp);
2491#else 2531#else
@@ -2497,24 +2537,28 @@ cache_alloc_debugcheck_after(kmem_cache_t *cachep,
2497 *dbg_userword(cachep, objp) = caller; 2537 *dbg_userword(cachep, objp) = caller;
2498 2538
2499 if (cachep->flags & SLAB_RED_ZONE) { 2539 if (cachep->flags & SLAB_RED_ZONE) {
2500 if (*dbg_redzone1(cachep, objp) != RED_INACTIVE || *dbg_redzone2(cachep, objp) != RED_INACTIVE) { 2540 if (*dbg_redzone1(cachep, objp) != RED_INACTIVE
2501 slab_error(cachep, "double free, or memory outside" 2541 || *dbg_redzone2(cachep, objp) != RED_INACTIVE) {
2502 " object was overwritten"); 2542 slab_error(cachep,
2503 printk(KERN_ERR "%p: redzone 1: 0x%lx, redzone 2: 0x%lx.\n", 2543 "double free, or memory outside"
2504 objp, *dbg_redzone1(cachep, objp), *dbg_redzone2(cachep, objp)); 2544 " object was overwritten");
2545 printk(KERN_ERR
2546 "%p: redzone 1: 0x%lx, redzone 2: 0x%lx.\n",
2547 objp, *dbg_redzone1(cachep, objp),
2548 *dbg_redzone2(cachep, objp));
2505 } 2549 }
2506 *dbg_redzone1(cachep, objp) = RED_ACTIVE; 2550 *dbg_redzone1(cachep, objp) = RED_ACTIVE;
2507 *dbg_redzone2(cachep, objp) = RED_ACTIVE; 2551 *dbg_redzone2(cachep, objp) = RED_ACTIVE;
2508 } 2552 }
2509 objp += obj_dbghead(cachep); 2553 objp += obj_dbghead(cachep);
2510 if (cachep->ctor && cachep->flags & SLAB_POISON) { 2554 if (cachep->ctor && cachep->flags & SLAB_POISON) {
2511 unsigned long ctor_flags = SLAB_CTOR_CONSTRUCTOR; 2555 unsigned long ctor_flags = SLAB_CTOR_CONSTRUCTOR;
2512 2556
2513 if (!(flags & __GFP_WAIT)) 2557 if (!(flags & __GFP_WAIT))
2514 ctor_flags |= SLAB_CTOR_ATOMIC; 2558 ctor_flags |= SLAB_CTOR_ATOMIC;
2515 2559
2516 cachep->ctor(objp, cachep, ctor_flags); 2560 cachep->ctor(objp, cachep, ctor_flags);
2517 } 2561 }
2518 return objp; 2562 return objp;
2519} 2563}
2520#else 2564#else
@@ -2523,7 +2567,7 @@ cache_alloc_debugcheck_after(kmem_cache_t *cachep,
2523 2567
2524static inline void *____cache_alloc(kmem_cache_t *cachep, gfp_t flags) 2568static inline void *____cache_alloc(kmem_cache_t *cachep, gfp_t flags)
2525{ 2569{
2526 void* objp; 2570 void *objp;
2527 struct array_cache *ac; 2571 struct array_cache *ac;
2528 2572
2529 check_irq_off(); 2573 check_irq_off();
@@ -2542,7 +2586,7 @@ static inline void *____cache_alloc(kmem_cache_t *cachep, gfp_t flags)
2542static inline void *__cache_alloc(kmem_cache_t *cachep, gfp_t flags) 2586static inline void *__cache_alloc(kmem_cache_t *cachep, gfp_t flags)
2543{ 2587{
2544 unsigned long save_flags; 2588 unsigned long save_flags;
2545 void* objp; 2589 void *objp;
2546 2590
2547 cache_alloc_debugcheck_before(cachep, flags); 2591 cache_alloc_debugcheck_before(cachep, flags);
2548 2592
@@ -2550,7 +2594,7 @@ static inline void *__cache_alloc(kmem_cache_t *cachep, gfp_t flags)
2550 objp = ____cache_alloc(cachep, flags); 2594 objp = ____cache_alloc(cachep, flags);
2551 local_irq_restore(save_flags); 2595 local_irq_restore(save_flags);
2552 objp = cache_alloc_debugcheck_after(cachep, flags, objp, 2596 objp = cache_alloc_debugcheck_after(cachep, flags, objp,
2553 __builtin_return_address(0)); 2597 __builtin_return_address(0));
2554 prefetchw(objp); 2598 prefetchw(objp);
2555 return objp; 2599 return objp;
2556} 2600}
@@ -2562,74 +2606,75 @@ static inline void *__cache_alloc(kmem_cache_t *cachep, gfp_t flags)
2562static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid) 2606static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid)
2563{ 2607{
2564 struct list_head *entry; 2608 struct list_head *entry;
2565 struct slab *slabp; 2609 struct slab *slabp;
2566 struct kmem_list3 *l3; 2610 struct kmem_list3 *l3;
2567 void *obj; 2611 void *obj;
2568 kmem_bufctl_t next; 2612 kmem_bufctl_t next;
2569 int x; 2613 int x;
2570 2614
2571 l3 = cachep->nodelists[nodeid]; 2615 l3 = cachep->nodelists[nodeid];
2572 BUG_ON(!l3); 2616 BUG_ON(!l3);
2573 2617
2574retry: 2618 retry:
2575 spin_lock(&l3->list_lock); 2619 spin_lock(&l3->list_lock);
2576 entry = l3->slabs_partial.next; 2620 entry = l3->slabs_partial.next;
2577 if (entry == &l3->slabs_partial) { 2621 if (entry == &l3->slabs_partial) {
2578 l3->free_touched = 1; 2622 l3->free_touched = 1;
2579 entry = l3->slabs_free.next; 2623 entry = l3->slabs_free.next;
2580 if (entry == &l3->slabs_free) 2624 if (entry == &l3->slabs_free)
2581 goto must_grow; 2625 goto must_grow;
2582 } 2626 }
2583 2627
2584 slabp = list_entry(entry, struct slab, list); 2628 slabp = list_entry(entry, struct slab, list);
2585 check_spinlock_acquired_node(cachep, nodeid); 2629 check_spinlock_acquired_node(cachep, nodeid);
2586 check_slabp(cachep, slabp); 2630 check_slabp(cachep, slabp);
2587 2631
2588 STATS_INC_NODEALLOCS(cachep); 2632 STATS_INC_NODEALLOCS(cachep);
2589 STATS_INC_ACTIVE(cachep); 2633 STATS_INC_ACTIVE(cachep);
2590 STATS_SET_HIGH(cachep); 2634 STATS_SET_HIGH(cachep);
2591 2635
2592 BUG_ON(slabp->inuse == cachep->num); 2636 BUG_ON(slabp->inuse == cachep->num);
2593 2637
2594 /* get obj pointer */ 2638 /* get obj pointer */
2595 obj = slabp->s_mem + slabp->free*cachep->objsize; 2639 obj = slabp->s_mem + slabp->free * cachep->objsize;
2596 slabp->inuse++; 2640 slabp->inuse++;
2597 next = slab_bufctl(slabp)[slabp->free]; 2641 next = slab_bufctl(slabp)[slabp->free];
2598#if DEBUG 2642#if DEBUG
2599 slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE; 2643 slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
2600#endif 2644#endif
2601 slabp->free = next; 2645 slabp->free = next;
2602 check_slabp(cachep, slabp); 2646 check_slabp(cachep, slabp);
2603 l3->free_objects--; 2647 l3->free_objects--;
2604 /* move slabp to correct slabp list: */ 2648 /* move slabp to correct slabp list: */
2605 list_del(&slabp->list); 2649 list_del(&slabp->list);
2606 2650
2607 if (slabp->free == BUFCTL_END) { 2651 if (slabp->free == BUFCTL_END) {
2608 list_add(&slabp->list, &l3->slabs_full); 2652 list_add(&slabp->list, &l3->slabs_full);
2609 } else { 2653 } else {
2610 list_add(&slabp->list, &l3->slabs_partial); 2654 list_add(&slabp->list, &l3->slabs_partial);
2611 } 2655 }
2612 2656
2613 spin_unlock(&l3->list_lock); 2657 spin_unlock(&l3->list_lock);
2614 goto done; 2658 goto done;
2615 2659
2616must_grow: 2660 must_grow:
2617 spin_unlock(&l3->list_lock); 2661 spin_unlock(&l3->list_lock);
2618 x = cache_grow(cachep, flags, nodeid); 2662 x = cache_grow(cachep, flags, nodeid);
2619 2663
2620 if (!x) 2664 if (!x)
2621 return NULL; 2665 return NULL;
2622 2666
2623 goto retry; 2667 goto retry;
2624done: 2668 done:
2625 return obj; 2669 return obj;
2626} 2670}
2627#endif 2671#endif
2628 2672
2629/* 2673/*
2630 * Caller needs to acquire correct kmem_list's list_lock 2674 * Caller needs to acquire correct kmem_list's list_lock
2631 */ 2675 */
2632static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects, int node) 2676static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects,
2677 int node)
2633{ 2678{
2634 int i; 2679 int i;
2635 struct kmem_list3 *l3; 2680 struct kmem_list3 *l3;
@@ -2652,7 +2697,7 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects, int n
2652 2697
2653 if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) { 2698 if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
2654 printk(KERN_ERR "slab: double free detected in cache " 2699 printk(KERN_ERR "slab: double free detected in cache "
2655 "'%s', objp %p\n", cachep->name, objp); 2700 "'%s', objp %p\n", cachep->name, objp);
2656 BUG(); 2701 BUG();
2657 } 2702 }
2658#endif 2703#endif
@@ -2696,20 +2741,19 @@ static void cache_flusharray(kmem_cache_t *cachep, struct array_cache *ac)
2696 spin_lock(&l3->list_lock); 2741 spin_lock(&l3->list_lock);
2697 if (l3->shared) { 2742 if (l3->shared) {
2698 struct array_cache *shared_array = l3->shared; 2743 struct array_cache *shared_array = l3->shared;
2699 int max = shared_array->limit-shared_array->avail; 2744 int max = shared_array->limit - shared_array->avail;
2700 if (max) { 2745 if (max) {
2701 if (batchcount > max) 2746 if (batchcount > max)
2702 batchcount = max; 2747 batchcount = max;
2703 memcpy(&(shared_array->entry[shared_array->avail]), 2748 memcpy(&(shared_array->entry[shared_array->avail]),
2704 ac->entry, 2749 ac->entry, sizeof(void *) * batchcount);
2705 sizeof(void*)*batchcount);
2706 shared_array->avail += batchcount; 2750 shared_array->avail += batchcount;
2707 goto free_done; 2751 goto free_done;
2708 } 2752 }
2709 } 2753 }
2710 2754
2711 free_block(cachep, ac->entry, batchcount, node); 2755 free_block(cachep, ac->entry, batchcount, node);
2712free_done: 2756 free_done:
2713#if STATS 2757#if STATS
2714 { 2758 {
2715 int i = 0; 2759 int i = 0;
@@ -2731,10 +2775,9 @@ free_done:
2731 spin_unlock(&l3->list_lock); 2775 spin_unlock(&l3->list_lock);
2732 ac->avail -= batchcount; 2776 ac->avail -= batchcount;
2733 memmove(ac->entry, &(ac->entry[batchcount]), 2777 memmove(ac->entry, &(ac->entry[batchcount]),
2734 sizeof(void*)*ac->avail); 2778 sizeof(void *) * ac->avail);
2735} 2779}
2736 2780
2737
2738/* 2781/*
2739 * __cache_free 2782 * __cache_free
2740 * Release an obj back to its cache. If the obj has a constructed 2783 * Release an obj back to its cache. If the obj has a constructed
@@ -2759,7 +2802,8 @@ static inline void __cache_free(kmem_cache_t *cachep, void *objp)
2759 if (unlikely(slabp->nodeid != numa_node_id())) { 2802 if (unlikely(slabp->nodeid != numa_node_id())) {
2760 struct array_cache *alien = NULL; 2803 struct array_cache *alien = NULL;
2761 int nodeid = slabp->nodeid; 2804 int nodeid = slabp->nodeid;
2762 struct kmem_list3 *l3 = cachep->nodelists[numa_node_id()]; 2805 struct kmem_list3 *l3 =
2806 cachep->nodelists[numa_node_id()];
2763 2807
2764 STATS_INC_NODEFREES(cachep); 2808 STATS_INC_NODEFREES(cachep);
2765 if (l3->alien && l3->alien[nodeid]) { 2809 if (l3->alien && l3->alien[nodeid]) {
@@ -2767,15 +2811,15 @@ static inline void __cache_free(kmem_cache_t *cachep, void *objp)
2767 spin_lock(&alien->lock); 2811 spin_lock(&alien->lock);
2768 if (unlikely(alien->avail == alien->limit)) 2812 if (unlikely(alien->avail == alien->limit))
2769 __drain_alien_cache(cachep, 2813 __drain_alien_cache(cachep,
2770 alien, nodeid); 2814 alien, nodeid);
2771 alien->entry[alien->avail++] = objp; 2815 alien->entry[alien->avail++] = objp;
2772 spin_unlock(&alien->lock); 2816 spin_unlock(&alien->lock);
2773 } else { 2817 } else {
2774 spin_lock(&(cachep->nodelists[nodeid])-> 2818 spin_lock(&(cachep->nodelists[nodeid])->
2775 list_lock); 2819 list_lock);
2776 free_block(cachep, &objp, 1, nodeid); 2820 free_block(cachep, &objp, 1, nodeid);
2777 spin_unlock(&(cachep->nodelists[nodeid])-> 2821 spin_unlock(&(cachep->nodelists[nodeid])->
2778 list_lock); 2822 list_lock);
2779 } 2823 }
2780 return; 2824 return;
2781 } 2825 }
@@ -2822,9 +2866,9 @@ EXPORT_SYMBOL(kmem_cache_alloc);
2822 */ 2866 */
2823int fastcall kmem_ptr_validate(kmem_cache_t *cachep, void *ptr) 2867int fastcall kmem_ptr_validate(kmem_cache_t *cachep, void *ptr)
2824{ 2868{
2825 unsigned long addr = (unsigned long) ptr; 2869 unsigned long addr = (unsigned long)ptr;
2826 unsigned long min_addr = PAGE_OFFSET; 2870 unsigned long min_addr = PAGE_OFFSET;
2827 unsigned long align_mask = BYTES_PER_WORD-1; 2871 unsigned long align_mask = BYTES_PER_WORD - 1;
2828 unsigned long size = cachep->objsize; 2872 unsigned long size = cachep->objsize;
2829 struct page *page; 2873 struct page *page;
2830 2874
@@ -2844,7 +2888,7 @@ int fastcall kmem_ptr_validate(kmem_cache_t *cachep, void *ptr)
2844 if (unlikely(page_get_cache(page) != cachep)) 2888 if (unlikely(page_get_cache(page) != cachep))
2845 goto out; 2889 goto out;
2846 return 1; 2890 return 1;
2847out: 2891 out:
2848 return 0; 2892 return 0;
2849} 2893}
2850 2894
@@ -2871,8 +2915,10 @@ void *kmem_cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid)
2871 2915
2872 if (unlikely(!cachep->nodelists[nodeid])) { 2916 if (unlikely(!cachep->nodelists[nodeid])) {
2873 /* Fall back to __cache_alloc if we run into trouble */ 2917 /* Fall back to __cache_alloc if we run into trouble */
2874 printk(KERN_WARNING "slab: not allocating in inactive node %d for cache %s\n", nodeid, cachep->name); 2918 printk(KERN_WARNING
2875 return __cache_alloc(cachep,flags); 2919 "slab: not allocating in inactive node %d for cache %s\n",
2920 nodeid, cachep->name);
2921 return __cache_alloc(cachep, flags);
2876 } 2922 }
2877 2923
2878 cache_alloc_debugcheck_before(cachep, flags); 2924 cache_alloc_debugcheck_before(cachep, flags);
@@ -2882,7 +2928,9 @@ void *kmem_cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid)
2882 else 2928 else
2883 ptr = __cache_alloc_node(cachep, flags, nodeid); 2929 ptr = __cache_alloc_node(cachep, flags, nodeid);
2884 local_irq_restore(save_flags); 2930 local_irq_restore(save_flags);
2885 ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, __builtin_return_address(0)); 2931 ptr =
2932 cache_alloc_debugcheck_after(cachep, flags, ptr,
2933 __builtin_return_address(0));
2886 2934
2887 return ptr; 2935 return ptr;
2888} 2936}
@@ -2944,12 +2992,11 @@ EXPORT_SYMBOL(__kmalloc);
2944 * Objects should be dereferenced using the per_cpu_ptr macro only. 2992 * Objects should be dereferenced using the per_cpu_ptr macro only.
2945 * 2993 *
2946 * @size: how many bytes of memory are required. 2994 * @size: how many bytes of memory are required.
2947 * @align: the alignment, which can't be greater than SMP_CACHE_BYTES.
2948 */ 2995 */
2949void *__alloc_percpu(size_t size, size_t align) 2996void *__alloc_percpu(size_t size)
2950{ 2997{
2951 int i; 2998 int i;
2952 struct percpu_data *pdata = kmalloc(sizeof (*pdata), GFP_KERNEL); 2999 struct percpu_data *pdata = kmalloc(sizeof(*pdata), GFP_KERNEL);
2953 3000
2954 if (!pdata) 3001 if (!pdata)
2955 return NULL; 3002 return NULL;
@@ -2973,9 +3020,9 @@ void *__alloc_percpu(size_t size, size_t align)
2973 } 3020 }
2974 3021
2975 /* Catch derefs w/o wrappers */ 3022 /* Catch derefs w/o wrappers */
2976 return (void *) (~(unsigned long) pdata); 3023 return (void *)(~(unsigned long)pdata);
2977 3024
2978unwind_oom: 3025 unwind_oom:
2979 while (--i >= 0) { 3026 while (--i >= 0) {
2980 if (!cpu_possible(i)) 3027 if (!cpu_possible(i))
2981 continue; 3028 continue;
@@ -3006,20 +3053,6 @@ void kmem_cache_free(kmem_cache_t *cachep, void *objp)
3006EXPORT_SYMBOL(kmem_cache_free); 3053EXPORT_SYMBOL(kmem_cache_free);
3007 3054
3008/** 3055/**
3009 * kzalloc - allocate memory. The memory is set to zero.
3010 * @size: how many bytes of memory are required.
3011 * @flags: the type of memory to allocate.
3012 */
3013void *kzalloc(size_t size, gfp_t flags)
3014{
3015 void *ret = kmalloc(size, flags);
3016 if (ret)
3017 memset(ret, 0, size);
3018 return ret;
3019}
3020EXPORT_SYMBOL(kzalloc);
3021
3022/**
3023 * kfree - free previously allocated memory 3056 * kfree - free previously allocated memory
3024 * @objp: pointer returned by kmalloc. 3057 * @objp: pointer returned by kmalloc.
3025 * 3058 *
@@ -3038,7 +3071,7 @@ void kfree(const void *objp)
3038 local_irq_save(flags); 3071 local_irq_save(flags);
3039 kfree_debugcheck(objp); 3072 kfree_debugcheck(objp);
3040 c = page_get_cache(virt_to_page(objp)); 3073 c = page_get_cache(virt_to_page(objp));
3041 __cache_free(c, (void*)objp); 3074 __cache_free(c, (void *)objp);
3042 local_irq_restore(flags); 3075 local_irq_restore(flags);
3043} 3076}
3044EXPORT_SYMBOL(kfree); 3077EXPORT_SYMBOL(kfree);
@@ -3051,17 +3084,16 @@ EXPORT_SYMBOL(kfree);
3051 * Don't free memory not originally allocated by alloc_percpu() 3084 * Don't free memory not originally allocated by alloc_percpu()
3052 * The complemented objp is to check for that. 3085 * The complemented objp is to check for that.
3053 */ 3086 */
3054void 3087void free_percpu(const void *objp)
3055free_percpu(const void *objp)
3056{ 3088{
3057 int i; 3089 int i;
3058 struct percpu_data *p = (struct percpu_data *) (~(unsigned long) objp); 3090 struct percpu_data *p = (struct percpu_data *)(~(unsigned long)objp);
3059 3091
3060 /* 3092 /*
3061 * We allocate for all cpus so we cannot use for online cpu here. 3093 * We allocate for all cpus so we cannot use for online cpu here.
3062 */ 3094 */
3063 for_each_cpu(i) 3095 for_each_cpu(i)
3064 kfree(p->ptrs[i]); 3096 kfree(p->ptrs[i]);
3065 kfree(p); 3097 kfree(p);
3066} 3098}
3067EXPORT_SYMBOL(free_percpu); 3099EXPORT_SYMBOL(free_percpu);
@@ -3095,44 +3127,44 @@ static int alloc_kmemlist(kmem_cache_t *cachep)
3095 if (!(new_alien = alloc_alien_cache(node, cachep->limit))) 3127 if (!(new_alien = alloc_alien_cache(node, cachep->limit)))
3096 goto fail; 3128 goto fail;
3097#endif 3129#endif
3098 if (!(new = alloc_arraycache(node, (cachep->shared* 3130 if (!(new = alloc_arraycache(node, (cachep->shared *
3099 cachep->batchcount), 0xbaadf00d))) 3131 cachep->batchcount),
3132 0xbaadf00d)))
3100 goto fail; 3133 goto fail;
3101 if ((l3 = cachep->nodelists[node])) { 3134 if ((l3 = cachep->nodelists[node])) {
3102 3135
3103 spin_lock_irq(&l3->list_lock); 3136 spin_lock_irq(&l3->list_lock);
3104 3137
3105 if ((nc = cachep->nodelists[node]->shared)) 3138 if ((nc = cachep->nodelists[node]->shared))
3106 free_block(cachep, nc->entry, 3139 free_block(cachep, nc->entry, nc->avail, node);
3107 nc->avail, node);
3108 3140
3109 l3->shared = new; 3141 l3->shared = new;
3110 if (!cachep->nodelists[node]->alien) { 3142 if (!cachep->nodelists[node]->alien) {
3111 l3->alien = new_alien; 3143 l3->alien = new_alien;
3112 new_alien = NULL; 3144 new_alien = NULL;
3113 } 3145 }
3114 l3->free_limit = (1 + nr_cpus_node(node))* 3146 l3->free_limit = (1 + nr_cpus_node(node)) *
3115 cachep->batchcount + cachep->num; 3147 cachep->batchcount + cachep->num;
3116 spin_unlock_irq(&l3->list_lock); 3148 spin_unlock_irq(&l3->list_lock);
3117 kfree(nc); 3149 kfree(nc);
3118 free_alien_cache(new_alien); 3150 free_alien_cache(new_alien);
3119 continue; 3151 continue;
3120 } 3152 }
3121 if (!(l3 = kmalloc_node(sizeof(struct kmem_list3), 3153 if (!(l3 = kmalloc_node(sizeof(struct kmem_list3),
3122 GFP_KERNEL, node))) 3154 GFP_KERNEL, node)))
3123 goto fail; 3155 goto fail;
3124 3156
3125 kmem_list3_init(l3); 3157 kmem_list3_init(l3);
3126 l3->next_reap = jiffies + REAPTIMEOUT_LIST3 + 3158 l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
3127 ((unsigned long)cachep)%REAPTIMEOUT_LIST3; 3159 ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
3128 l3->shared = new; 3160 l3->shared = new;
3129 l3->alien = new_alien; 3161 l3->alien = new_alien;
3130 l3->free_limit = (1 + nr_cpus_node(node))* 3162 l3->free_limit = (1 + nr_cpus_node(node)) *
3131 cachep->batchcount + cachep->num; 3163 cachep->batchcount + cachep->num;
3132 cachep->nodelists[node] = l3; 3164 cachep->nodelists[node] = l3;
3133 } 3165 }
3134 return err; 3166 return err;
3135fail: 3167 fail:
3136 err = -ENOMEM; 3168 err = -ENOMEM;
3137 return err; 3169 return err;
3138} 3170}
@@ -3154,18 +3186,19 @@ static void do_ccupdate_local(void *info)
3154 new->new[smp_processor_id()] = old; 3186 new->new[smp_processor_id()] = old;
3155} 3187}
3156 3188
3157
3158static int do_tune_cpucache(kmem_cache_t *cachep, int limit, int batchcount, 3189static int do_tune_cpucache(kmem_cache_t *cachep, int limit, int batchcount,
3159 int shared) 3190 int shared)
3160{ 3191{
3161 struct ccupdate_struct new; 3192 struct ccupdate_struct new;
3162 int i, err; 3193 int i, err;
3163 3194
3164 memset(&new.new,0,sizeof(new.new)); 3195 memset(&new.new, 0, sizeof(new.new));
3165 for_each_online_cpu(i) { 3196 for_each_online_cpu(i) {
3166 new.new[i] = alloc_arraycache(cpu_to_node(i), limit, batchcount); 3197 new.new[i] =
3198 alloc_arraycache(cpu_to_node(i), limit, batchcount);
3167 if (!new.new[i]) { 3199 if (!new.new[i]) {
3168 for (i--; i >= 0; i--) kfree(new.new[i]); 3200 for (i--; i >= 0; i--)
3201 kfree(new.new[i]);
3169 return -ENOMEM; 3202 return -ENOMEM;
3170 } 3203 }
3171 } 3204 }
@@ -3193,13 +3226,12 @@ static int do_tune_cpucache(kmem_cache_t *cachep, int limit, int batchcount,
3193 err = alloc_kmemlist(cachep); 3226 err = alloc_kmemlist(cachep);
3194 if (err) { 3227 if (err) {
3195 printk(KERN_ERR "alloc_kmemlist failed for %s, error %d.\n", 3228 printk(KERN_ERR "alloc_kmemlist failed for %s, error %d.\n",
3196 cachep->name, -err); 3229 cachep->name, -err);
3197 BUG(); 3230 BUG();
3198 } 3231 }
3199 return 0; 3232 return 0;
3200} 3233}
3201 3234
3202
3203static void enable_cpucache(kmem_cache_t *cachep) 3235static void enable_cpucache(kmem_cache_t *cachep)
3204{ 3236{
3205 int err; 3237 int err;
@@ -3246,14 +3278,14 @@ static void enable_cpucache(kmem_cache_t *cachep)
3246 if (limit > 32) 3278 if (limit > 32)
3247 limit = 32; 3279 limit = 32;
3248#endif 3280#endif
3249 err = do_tune_cpucache(cachep, limit, (limit+1)/2, shared); 3281 err = do_tune_cpucache(cachep, limit, (limit + 1) / 2, shared);
3250 if (err) 3282 if (err)
3251 printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n", 3283 printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n",
3252 cachep->name, -err); 3284 cachep->name, -err);
3253} 3285}
3254 3286
3255static void drain_array_locked(kmem_cache_t *cachep, 3287static void drain_array_locked(kmem_cache_t *cachep, struct array_cache *ac,
3256 struct array_cache *ac, int force, int node) 3288 int force, int node)
3257{ 3289{
3258 int tofree; 3290 int tofree;
3259 3291
@@ -3261,14 +3293,14 @@ static void drain_array_locked(kmem_cache_t *cachep,
3261 if (ac->touched && !force) { 3293 if (ac->touched && !force) {
3262 ac->touched = 0; 3294 ac->touched = 0;
3263 } else if (ac->avail) { 3295 } else if (ac->avail) {
3264 tofree = force ? ac->avail : (ac->limit+4)/5; 3296 tofree = force ? ac->avail : (ac->limit + 4) / 5;
3265 if (tofree > ac->avail) { 3297 if (tofree > ac->avail) {
3266 tofree = (ac->avail+1)/2; 3298 tofree = (ac->avail + 1) / 2;
3267 } 3299 }
3268 free_block(cachep, ac->entry, tofree, node); 3300 free_block(cachep, ac->entry, tofree, node);
3269 ac->avail -= tofree; 3301 ac->avail -= tofree;
3270 memmove(ac->entry, &(ac->entry[tofree]), 3302 memmove(ac->entry, &(ac->entry[tofree]),
3271 sizeof(void*)*ac->avail); 3303 sizeof(void *) * ac->avail);
3272 } 3304 }
3273} 3305}
3274 3306
@@ -3291,13 +3323,14 @@ static void cache_reap(void *unused)
3291 3323
3292 if (down_trylock(&cache_chain_sem)) { 3324 if (down_trylock(&cache_chain_sem)) {
3293 /* Give up. Setup the next iteration. */ 3325 /* Give up. Setup the next iteration. */
3294 schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC); 3326 schedule_delayed_work(&__get_cpu_var(reap_work),
3327 REAPTIMEOUT_CPUC);
3295 return; 3328 return;
3296 } 3329 }
3297 3330
3298 list_for_each(walk, &cache_chain) { 3331 list_for_each(walk, &cache_chain) {
3299 kmem_cache_t *searchp; 3332 kmem_cache_t *searchp;
3300 struct list_head* p; 3333 struct list_head *p;
3301 int tofree; 3334 int tofree;
3302 struct slab *slabp; 3335 struct slab *slabp;
3303 3336
@@ -3314,7 +3347,7 @@ static void cache_reap(void *unused)
3314 spin_lock_irq(&l3->list_lock); 3347 spin_lock_irq(&l3->list_lock);
3315 3348
3316 drain_array_locked(searchp, ac_data(searchp), 0, 3349 drain_array_locked(searchp, ac_data(searchp), 0,
3317 numa_node_id()); 3350 numa_node_id());
3318 3351
3319 if (time_after(l3->next_reap, jiffies)) 3352 if (time_after(l3->next_reap, jiffies))
3320 goto next_unlock; 3353 goto next_unlock;
@@ -3323,14 +3356,16 @@ static void cache_reap(void *unused)
3323 3356
3324 if (l3->shared) 3357 if (l3->shared)
3325 drain_array_locked(searchp, l3->shared, 0, 3358 drain_array_locked(searchp, l3->shared, 0,
3326 numa_node_id()); 3359 numa_node_id());
3327 3360
3328 if (l3->free_touched) { 3361 if (l3->free_touched) {
3329 l3->free_touched = 0; 3362 l3->free_touched = 0;
3330 goto next_unlock; 3363 goto next_unlock;
3331 } 3364 }
3332 3365
3333 tofree = (l3->free_limit+5*searchp->num-1)/(5*searchp->num); 3366 tofree =
3367 (l3->free_limit + 5 * searchp->num -
3368 1) / (5 * searchp->num);
3334 do { 3369 do {
3335 p = l3->slabs_free.next; 3370 p = l3->slabs_free.next;
3336 if (p == &(l3->slabs_free)) 3371 if (p == &(l3->slabs_free))
@@ -3350,10 +3385,10 @@ static void cache_reap(void *unused)
3350 spin_unlock_irq(&l3->list_lock); 3385 spin_unlock_irq(&l3->list_lock);
3351 slab_destroy(searchp, slabp); 3386 slab_destroy(searchp, slabp);
3352 spin_lock_irq(&l3->list_lock); 3387 spin_lock_irq(&l3->list_lock);
3353 } while(--tofree > 0); 3388 } while (--tofree > 0);
3354next_unlock: 3389 next_unlock:
3355 spin_unlock_irq(&l3->list_lock); 3390 spin_unlock_irq(&l3->list_lock);
3356next: 3391 next:
3357 cond_resched(); 3392 cond_resched();
3358 } 3393 }
3359 check_irq_on(); 3394 check_irq_on();
@@ -3365,32 +3400,37 @@ next:
3365 3400
3366#ifdef CONFIG_PROC_FS 3401#ifdef CONFIG_PROC_FS
3367 3402
3368static void *s_start(struct seq_file *m, loff_t *pos) 3403static void print_slabinfo_header(struct seq_file *m)
3369{ 3404{
3370 loff_t n = *pos; 3405 /*
3371 struct list_head *p; 3406 * Output format version, so at least we can change it
3372 3407 * without _too_ many complaints.
3373 down(&cache_chain_sem); 3408 */
3374 if (!n) {
3375 /*
3376 * Output format version, so at least we can change it
3377 * without _too_ many complaints.
3378 */
3379#if STATS 3409#if STATS
3380 seq_puts(m, "slabinfo - version: 2.1 (statistics)\n"); 3410 seq_puts(m, "slabinfo - version: 2.1 (statistics)\n");
3381#else 3411#else
3382 seq_puts(m, "slabinfo - version: 2.1\n"); 3412 seq_puts(m, "slabinfo - version: 2.1\n");
3383#endif 3413#endif
3384 seq_puts(m, "# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab>"); 3414 seq_puts(m, "# name <active_objs> <num_objs> <objsize> "
3385 seq_puts(m, " : tunables <limit> <batchcount> <sharedfactor>"); 3415 "<objperslab> <pagesperslab>");
3386 seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>"); 3416 seq_puts(m, " : tunables <limit> <batchcount> <sharedfactor>");
3417 seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>");
3387#if STATS 3418#if STATS
3388 seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped>" 3419 seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped> "
3389 " <error> <maxfreeable> <nodeallocs> <remotefrees>"); 3420 "<error> <maxfreeable> <nodeallocs> <remotefrees>");
3390 seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>"); 3421 seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>");
3391#endif 3422#endif
3392 seq_putc(m, '\n'); 3423 seq_putc(m, '\n');
3393 } 3424}
3425
3426static void *s_start(struct seq_file *m, loff_t *pos)
3427{
3428 loff_t n = *pos;
3429 struct list_head *p;
3430
3431 down(&cache_chain_sem);
3432 if (!n)
3433 print_slabinfo_header(m);
3394 p = cache_chain.next; 3434 p = cache_chain.next;
3395 while (n--) { 3435 while (n--) {
3396 p = p->next; 3436 p = p->next;
@@ -3405,7 +3445,7 @@ static void *s_next(struct seq_file *m, void *p, loff_t *pos)
3405 kmem_cache_t *cachep = p; 3445 kmem_cache_t *cachep = p;
3406 ++*pos; 3446 ++*pos;
3407 return cachep->next.next == &cache_chain ? NULL 3447 return cachep->next.next == &cache_chain ? NULL
3408 : list_entry(cachep->next.next, kmem_cache_t, next); 3448 : list_entry(cachep->next.next, kmem_cache_t, next);
3409} 3449}
3410 3450
3411static void s_stop(struct seq_file *m, void *p) 3451static void s_stop(struct seq_file *m, void *p)
@@ -3417,11 +3457,11 @@ static int s_show(struct seq_file *m, void *p)
3417{ 3457{
3418 kmem_cache_t *cachep = p; 3458 kmem_cache_t *cachep = p;
3419 struct list_head *q; 3459 struct list_head *q;
3420 struct slab *slabp; 3460 struct slab *slabp;
3421 unsigned long active_objs; 3461 unsigned long active_objs;
3422 unsigned long num_objs; 3462 unsigned long num_objs;
3423 unsigned long active_slabs = 0; 3463 unsigned long active_slabs = 0;
3424 unsigned long num_slabs, free_objects = 0, shared_avail = 0; 3464 unsigned long num_slabs, free_objects = 0, shared_avail = 0;
3425 const char *name; 3465 const char *name;
3426 char *error = NULL; 3466 char *error = NULL;
3427 int node; 3467 int node;
@@ -3438,14 +3478,14 @@ static int s_show(struct seq_file *m, void *p)
3438 3478
3439 spin_lock(&l3->list_lock); 3479 spin_lock(&l3->list_lock);
3440 3480
3441 list_for_each(q,&l3->slabs_full) { 3481 list_for_each(q, &l3->slabs_full) {
3442 slabp = list_entry(q, struct slab, list); 3482 slabp = list_entry(q, struct slab, list);
3443 if (slabp->inuse != cachep->num && !error) 3483 if (slabp->inuse != cachep->num && !error)
3444 error = "slabs_full accounting error"; 3484 error = "slabs_full accounting error";
3445 active_objs += cachep->num; 3485 active_objs += cachep->num;
3446 active_slabs++; 3486 active_slabs++;
3447 } 3487 }
3448 list_for_each(q,&l3->slabs_partial) { 3488 list_for_each(q, &l3->slabs_partial) {
3449 slabp = list_entry(q, struct slab, list); 3489 slabp = list_entry(q, struct slab, list);
3450 if (slabp->inuse == cachep->num && !error) 3490 if (slabp->inuse == cachep->num && !error)
3451 error = "slabs_partial inuse accounting error"; 3491 error = "slabs_partial inuse accounting error";
@@ -3454,7 +3494,7 @@ static int s_show(struct seq_file *m, void *p)
3454 active_objs += slabp->inuse; 3494 active_objs += slabp->inuse;
3455 active_slabs++; 3495 active_slabs++;
3456 } 3496 }
3457 list_for_each(q,&l3->slabs_free) { 3497 list_for_each(q, &l3->slabs_free) {
3458 slabp = list_entry(q, struct slab, list); 3498 slabp = list_entry(q, struct slab, list);
3459 if (slabp->inuse && !error) 3499 if (slabp->inuse && !error)
3460 error = "slabs_free/inuse accounting error"; 3500 error = "slabs_free/inuse accounting error";
@@ -3465,25 +3505,24 @@ static int s_show(struct seq_file *m, void *p)
3465 3505
3466 spin_unlock(&l3->list_lock); 3506 spin_unlock(&l3->list_lock);
3467 } 3507 }
3468 num_slabs+=active_slabs; 3508 num_slabs += active_slabs;
3469 num_objs = num_slabs*cachep->num; 3509 num_objs = num_slabs * cachep->num;
3470 if (num_objs - active_objs != free_objects && !error) 3510 if (num_objs - active_objs != free_objects && !error)
3471 error = "free_objects accounting error"; 3511 error = "free_objects accounting error";
3472 3512
3473 name = cachep->name; 3513 name = cachep->name;
3474 if (error) 3514 if (error)
3475 printk(KERN_ERR "slab: cache %s error: %s\n", name, error); 3515 printk(KERN_ERR "slab: cache %s error: %s\n", name, error);
3476 3516
3477 seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d", 3517 seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d",
3478 name, active_objs, num_objs, cachep->objsize, 3518 name, active_objs, num_objs, cachep->objsize,
3479 cachep->num, (1<<cachep->gfporder)); 3519 cachep->num, (1 << cachep->gfporder));
3480 seq_printf(m, " : tunables %4u %4u %4u", 3520 seq_printf(m, " : tunables %4u %4u %4u",
3481 cachep->limit, cachep->batchcount, 3521 cachep->limit, cachep->batchcount, cachep->shared);
3482 cachep->shared);
3483 seq_printf(m, " : slabdata %6lu %6lu %6lu", 3522 seq_printf(m, " : slabdata %6lu %6lu %6lu",
3484 active_slabs, num_slabs, shared_avail); 3523 active_slabs, num_slabs, shared_avail);
3485#if STATS 3524#if STATS
3486 { /* list3 stats */ 3525 { /* list3 stats */
3487 unsigned long high = cachep->high_mark; 3526 unsigned long high = cachep->high_mark;
3488 unsigned long allocs = cachep->num_allocations; 3527 unsigned long allocs = cachep->num_allocations;
3489 unsigned long grown = cachep->grown; 3528 unsigned long grown = cachep->grown;
@@ -3494,9 +3533,7 @@ static int s_show(struct seq_file *m, void *p)
3494 unsigned long node_frees = cachep->node_frees; 3533 unsigned long node_frees = cachep->node_frees;
3495 3534
3496 seq_printf(m, " : globalstat %7lu %6lu %5lu %4lu \ 3535 seq_printf(m, " : globalstat %7lu %6lu %5lu %4lu \
3497 %4lu %4lu %4lu %4lu", 3536 %4lu %4lu %4lu %4lu", allocs, high, grown, reaped, errors, max_freeable, node_allocs, node_frees);
3498 allocs, high, grown, reaped, errors,
3499 max_freeable, node_allocs, node_frees);
3500 } 3537 }
3501 /* cpu stats */ 3538 /* cpu stats */
3502 { 3539 {
@@ -3506,7 +3543,7 @@ static int s_show(struct seq_file *m, void *p)
3506 unsigned long freemiss = atomic_read(&cachep->freemiss); 3543 unsigned long freemiss = atomic_read(&cachep->freemiss);
3507 3544
3508 seq_printf(m, " : cpustat %6lu %6lu %6lu %6lu", 3545 seq_printf(m, " : cpustat %6lu %6lu %6lu %6lu",
3509 allochit, allocmiss, freehit, freemiss); 3546 allochit, allocmiss, freehit, freemiss);
3510 } 3547 }
3511#endif 3548#endif
3512 seq_putc(m, '\n'); 3549 seq_putc(m, '\n');
@@ -3529,10 +3566,10 @@ static int s_show(struct seq_file *m, void *p)
3529 */ 3566 */
3530 3567
3531struct seq_operations slabinfo_op = { 3568struct seq_operations slabinfo_op = {
3532 .start = s_start, 3569 .start = s_start,
3533 .next = s_next, 3570 .next = s_next,
3534 .stop = s_stop, 3571 .stop = s_stop,
3535 .show = s_show, 3572 .show = s_show,
3536}; 3573};
3537 3574
3538#define MAX_SLABINFO_WRITE 128 3575#define MAX_SLABINFO_WRITE 128
@@ -3543,18 +3580,18 @@ struct seq_operations slabinfo_op = {
3543 * @count: data length 3580 * @count: data length
3544 * @ppos: unused 3581 * @ppos: unused
3545 */ 3582 */
3546ssize_t slabinfo_write(struct file *file, const char __user *buffer, 3583ssize_t slabinfo_write(struct file *file, const char __user * buffer,
3547 size_t count, loff_t *ppos) 3584 size_t count, loff_t *ppos)
3548{ 3585{
3549 char kbuf[MAX_SLABINFO_WRITE+1], *tmp; 3586 char kbuf[MAX_SLABINFO_WRITE + 1], *tmp;
3550 int limit, batchcount, shared, res; 3587 int limit, batchcount, shared, res;
3551 struct list_head *p; 3588 struct list_head *p;
3552 3589
3553 if (count > MAX_SLABINFO_WRITE) 3590 if (count > MAX_SLABINFO_WRITE)
3554 return -EINVAL; 3591 return -EINVAL;
3555 if (copy_from_user(&kbuf, buffer, count)) 3592 if (copy_from_user(&kbuf, buffer, count))
3556 return -EFAULT; 3593 return -EFAULT;
3557 kbuf[MAX_SLABINFO_WRITE] = '\0'; 3594 kbuf[MAX_SLABINFO_WRITE] = '\0';
3558 3595
3559 tmp = strchr(kbuf, ' '); 3596 tmp = strchr(kbuf, ' ');
3560 if (!tmp) 3597 if (!tmp)
@@ -3567,18 +3604,17 @@ ssize_t slabinfo_write(struct file *file, const char __user *buffer,
3567 /* Find the cache in the chain of caches. */ 3604 /* Find the cache in the chain of caches. */
3568 down(&cache_chain_sem); 3605 down(&cache_chain_sem);
3569 res = -EINVAL; 3606 res = -EINVAL;
3570 list_for_each(p,&cache_chain) { 3607 list_for_each(p, &cache_chain) {
3571 kmem_cache_t *cachep = list_entry(p, kmem_cache_t, next); 3608 kmem_cache_t *cachep = list_entry(p, kmem_cache_t, next);
3572 3609
3573 if (!strcmp(cachep->name, kbuf)) { 3610 if (!strcmp(cachep->name, kbuf)) {
3574 if (limit < 1 || 3611 if (limit < 1 ||
3575 batchcount < 1 || 3612 batchcount < 1 ||
3576 batchcount > limit || 3613 batchcount > limit || shared < 0) {
3577 shared < 0) {
3578 res = 0; 3614 res = 0;
3579 } else { 3615 } else {
3580 res = do_tune_cpucache(cachep, limit, 3616 res = do_tune_cpucache(cachep, limit,
3581 batchcount, shared); 3617 batchcount, shared);
3582 } 3618 }
3583 break; 3619 break;
3584 } 3620 }
@@ -3609,26 +3645,3 @@ unsigned int ksize(const void *objp)
3609 3645
3610 return obj_reallen(page_get_cache(virt_to_page(objp))); 3646 return obj_reallen(page_get_cache(virt_to_page(objp)));
3611} 3647}
3612
3613
3614/*
3615 * kstrdup - allocate space for and copy an existing string
3616 *
3617 * @s: the string to duplicate
3618 * @gfp: the GFP mask used in the kmalloc() call when allocating memory
3619 */
3620char *kstrdup(const char *s, gfp_t gfp)
3621{
3622 size_t len;
3623 char *buf;
3624
3625 if (!s)
3626 return NULL;
3627
3628 len = strlen(s) + 1;
3629 buf = kmalloc(len, gfp);
3630 if (buf)
3631 memcpy(buf, s, len);
3632 return buf;
3633}
3634EXPORT_SYMBOL(kstrdup);
diff --git a/mm/slob.c b/mm/slob.c
new file mode 100644
index 000000000000..1c240c4b71d9
--- /dev/null
+++ b/mm/slob.c
@@ -0,0 +1,385 @@
1/*
2 * SLOB Allocator: Simple List Of Blocks
3 *
4 * Matt Mackall <mpm@selenic.com> 12/30/03
5 *
6 * How SLOB works:
7 *
8 * The core of SLOB is a traditional K&R style heap allocator, with
9 * support for returning aligned objects. The granularity of this
10 * allocator is 8 bytes on x86, though it's perhaps possible to reduce
11 * this to 4 if it's deemed worth the effort. The slob heap is a
12 * singly-linked list of pages from __get_free_page, grown on demand
13 * and allocation from the heap is currently first-fit.
14 *
15 * Above this is an implementation of kmalloc/kfree. Blocks returned
16 * from kmalloc are 8-byte aligned and prepended with a 8-byte header.
17 * If kmalloc is asked for objects of PAGE_SIZE or larger, it calls
18 * __get_free_pages directly so that it can return page-aligned blocks
19 * and keeps a linked list of such pages and their orders. These
20 * objects are detected in kfree() by their page alignment.
21 *
22 * SLAB is emulated on top of SLOB by simply calling constructors and
23 * destructors for every SLAB allocation. Objects are returned with
24 * the 8-byte alignment unless the SLAB_MUST_HWCACHE_ALIGN flag is
25 * set, in which case the low-level allocator will fragment blocks to
26 * create the proper alignment. Again, objects of page-size or greater
27 * are allocated by calling __get_free_pages. As SLAB objects know
28 * their size, no separate size bookkeeping is necessary and there is
29 * essentially no allocation space overhead.
30 */
31
32#include <linux/config.h>
33#include <linux/slab.h>
34#include <linux/mm.h>
35#include <linux/cache.h>
36#include <linux/init.h>
37#include <linux/module.h>
38#include <linux/timer.h>
39
40struct slob_block {
41 int units;
42 struct slob_block *next;
43};
44typedef struct slob_block slob_t;
45
46#define SLOB_UNIT sizeof(slob_t)
47#define SLOB_UNITS(size) (((size) + SLOB_UNIT - 1)/SLOB_UNIT)
48#define SLOB_ALIGN L1_CACHE_BYTES
49
50struct bigblock {
51 int order;
52 void *pages;
53 struct bigblock *next;
54};
55typedef struct bigblock bigblock_t;
56
57static slob_t arena = { .next = &arena, .units = 1 };
58static slob_t *slobfree = &arena;
59static bigblock_t *bigblocks;
60static DEFINE_SPINLOCK(slob_lock);
61static DEFINE_SPINLOCK(block_lock);
62
63static void slob_free(void *b, int size);
64
65static void *slob_alloc(size_t size, gfp_t gfp, int align)
66{
67 slob_t *prev, *cur, *aligned = 0;
68 int delta = 0, units = SLOB_UNITS(size);
69 unsigned long flags;
70
71 spin_lock_irqsave(&slob_lock, flags);
72 prev = slobfree;
73 for (cur = prev->next; ; prev = cur, cur = cur->next) {
74 if (align) {
75 aligned = (slob_t *)ALIGN((unsigned long)cur, align);
76 delta = aligned - cur;
77 }
78 if (cur->units >= units + delta) { /* room enough? */
79 if (delta) { /* need to fragment head to align? */
80 aligned->units = cur->units - delta;
81 aligned->next = cur->next;
82 cur->next = aligned;
83 cur->units = delta;
84 prev = cur;
85 cur = aligned;
86 }
87
88 if (cur->units == units) /* exact fit? */
89 prev->next = cur->next; /* unlink */
90 else { /* fragment */
91 prev->next = cur + units;
92 prev->next->units = cur->units - units;
93 prev->next->next = cur->next;
94 cur->units = units;
95 }
96
97 slobfree = prev;
98 spin_unlock_irqrestore(&slob_lock, flags);
99 return cur;
100 }
101 if (cur == slobfree) {
102 spin_unlock_irqrestore(&slob_lock, flags);
103
104 if (size == PAGE_SIZE) /* trying to shrink arena? */
105 return 0;
106
107 cur = (slob_t *)__get_free_page(gfp);
108 if (!cur)
109 return 0;
110
111 slob_free(cur, PAGE_SIZE);
112 spin_lock_irqsave(&slob_lock, flags);
113 cur = slobfree;
114 }
115 }
116}
117
118static void slob_free(void *block, int size)
119{
120 slob_t *cur, *b = (slob_t *)block;
121 unsigned long flags;
122
123 if (!block)
124 return;
125
126 if (size)
127 b->units = SLOB_UNITS(size);
128
129 /* Find reinsertion point */
130 spin_lock_irqsave(&slob_lock, flags);
131 for (cur = slobfree; !(b > cur && b < cur->next); cur = cur->next)
132 if (cur >= cur->next && (b > cur || b < cur->next))
133 break;
134
135 if (b + b->units == cur->next) {
136 b->units += cur->next->units;
137 b->next = cur->next->next;
138 } else
139 b->next = cur->next;
140
141 if (cur + cur->units == b) {
142 cur->units += b->units;
143 cur->next = b->next;
144 } else
145 cur->next = b;
146
147 slobfree = cur;
148
149 spin_unlock_irqrestore(&slob_lock, flags);
150}
151
152static int FASTCALL(find_order(int size));
153static int fastcall find_order(int size)
154{
155 int order = 0;
156 for ( ; size > 4096 ; size >>=1)
157 order++;
158 return order;
159}
160
161void *kmalloc(size_t size, gfp_t gfp)
162{
163 slob_t *m;
164 bigblock_t *bb;
165 unsigned long flags;
166
167 if (size < PAGE_SIZE - SLOB_UNIT) {
168 m = slob_alloc(size + SLOB_UNIT, gfp, 0);
169 return m ? (void *)(m + 1) : 0;
170 }
171
172 bb = slob_alloc(sizeof(bigblock_t), gfp, 0);
173 if (!bb)
174 return 0;
175
176 bb->order = find_order(size);
177 bb->pages = (void *)__get_free_pages(gfp, bb->order);
178
179 if (bb->pages) {
180 spin_lock_irqsave(&block_lock, flags);
181 bb->next = bigblocks;
182 bigblocks = bb;
183 spin_unlock_irqrestore(&block_lock, flags);
184 return bb->pages;
185 }
186
187 slob_free(bb, sizeof(bigblock_t));
188 return 0;
189}
190
191EXPORT_SYMBOL(kmalloc);
192
193void kfree(const void *block)
194{
195 bigblock_t *bb, **last = &bigblocks;
196 unsigned long flags;
197
198 if (!block)
199 return;
200
201 if (!((unsigned long)block & (PAGE_SIZE-1))) {
202 /* might be on the big block list */
203 spin_lock_irqsave(&block_lock, flags);
204 for (bb = bigblocks; bb; last = &bb->next, bb = bb->next) {
205 if (bb->pages == block) {
206 *last = bb->next;
207 spin_unlock_irqrestore(&block_lock, flags);
208 free_pages((unsigned long)block, bb->order);
209 slob_free(bb, sizeof(bigblock_t));
210 return;
211 }
212 }
213 spin_unlock_irqrestore(&block_lock, flags);
214 }
215
216 slob_free((slob_t *)block - 1, 0);
217 return;
218}
219
220EXPORT_SYMBOL(kfree);
221
222unsigned int ksize(const void *block)
223{
224 bigblock_t *bb;
225 unsigned long flags;
226
227 if (!block)
228 return 0;
229
230 if (!((unsigned long)block & (PAGE_SIZE-1))) {
231 spin_lock_irqsave(&block_lock, flags);
232 for (bb = bigblocks; bb; bb = bb->next)
233 if (bb->pages == block) {
234 spin_unlock_irqrestore(&slob_lock, flags);
235 return PAGE_SIZE << bb->order;
236 }
237 spin_unlock_irqrestore(&block_lock, flags);
238 }
239
240 return ((slob_t *)block - 1)->units * SLOB_UNIT;
241}
242
243struct kmem_cache {
244 unsigned int size, align;
245 const char *name;
246 void (*ctor)(void *, struct kmem_cache *, unsigned long);
247 void (*dtor)(void *, struct kmem_cache *, unsigned long);
248};
249
250struct kmem_cache *kmem_cache_create(const char *name, size_t size,
251 size_t align, unsigned long flags,
252 void (*ctor)(void*, struct kmem_cache *, unsigned long),
253 void (*dtor)(void*, struct kmem_cache *, unsigned long))
254{
255 struct kmem_cache *c;
256
257 c = slob_alloc(sizeof(struct kmem_cache), flags, 0);
258
259 if (c) {
260 c->name = name;
261 c->size = size;
262 c->ctor = ctor;
263 c->dtor = dtor;
264 /* ignore alignment unless it's forced */
265 c->align = (flags & SLAB_MUST_HWCACHE_ALIGN) ? SLOB_ALIGN : 0;
266 if (c->align < align)
267 c->align = align;
268 }
269
270 return c;
271}
272EXPORT_SYMBOL(kmem_cache_create);
273
274int kmem_cache_destroy(struct kmem_cache *c)
275{
276 slob_free(c, sizeof(struct kmem_cache));
277 return 0;
278}
279EXPORT_SYMBOL(kmem_cache_destroy);
280
281void *kmem_cache_alloc(struct kmem_cache *c, gfp_t flags)
282{
283 void *b;
284
285 if (c->size < PAGE_SIZE)
286 b = slob_alloc(c->size, flags, c->align);
287 else
288 b = (void *)__get_free_pages(flags, find_order(c->size));
289
290 if (c->ctor)
291 c->ctor(b, c, SLAB_CTOR_CONSTRUCTOR);
292
293 return b;
294}
295EXPORT_SYMBOL(kmem_cache_alloc);
296
297void kmem_cache_free(struct kmem_cache *c, void *b)
298{
299 if (c->dtor)
300 c->dtor(b, c, 0);
301
302 if (c->size < PAGE_SIZE)
303 slob_free(b, c->size);
304 else
305 free_pages((unsigned long)b, find_order(c->size));
306}
307EXPORT_SYMBOL(kmem_cache_free);
308
309unsigned int kmem_cache_size(struct kmem_cache *c)
310{
311 return c->size;
312}
313EXPORT_SYMBOL(kmem_cache_size);
314
315const char *kmem_cache_name(struct kmem_cache *c)
316{
317 return c->name;
318}
319EXPORT_SYMBOL(kmem_cache_name);
320
321static struct timer_list slob_timer = TIMER_INITIALIZER(
322 (void (*)(unsigned long))kmem_cache_init, 0, 0);
323
324void kmem_cache_init(void)
325{
326 void *p = slob_alloc(PAGE_SIZE, 0, PAGE_SIZE-1);
327
328 if (p)
329 free_page((unsigned long)p);
330
331 mod_timer(&slob_timer, jiffies + HZ);
332}
333
334atomic_t slab_reclaim_pages = ATOMIC_INIT(0);
335EXPORT_SYMBOL(slab_reclaim_pages);
336
337#ifdef CONFIG_SMP
338
339void *__alloc_percpu(size_t size, size_t align)
340{
341 int i;
342 struct percpu_data *pdata = kmalloc(sizeof (*pdata), GFP_KERNEL);
343
344 if (!pdata)
345 return NULL;
346
347 for (i = 0; i < NR_CPUS; i++) {
348 if (!cpu_possible(i))
349 continue;
350 pdata->ptrs[i] = kmalloc(size, GFP_KERNEL);
351 if (!pdata->ptrs[i])
352 goto unwind_oom;
353 memset(pdata->ptrs[i], 0, size);
354 }
355
356 /* Catch derefs w/o wrappers */
357 return (void *) (~(unsigned long) pdata);
358
359unwind_oom:
360 while (--i >= 0) {
361 if (!cpu_possible(i))
362 continue;
363 kfree(pdata->ptrs[i]);
364 }
365 kfree(pdata);
366 return NULL;
367}
368EXPORT_SYMBOL(__alloc_percpu);
369
370void
371free_percpu(const void *objp)
372{
373 int i;
374 struct percpu_data *p = (struct percpu_data *) (~(unsigned long) objp);
375
376 for (i = 0; i < NR_CPUS; i++) {
377 if (!cpu_possible(i))
378 continue;
379 kfree(p->ptrs[i]);
380 }
381 kfree(p);
382}
383EXPORT_SYMBOL(free_percpu);
384
385#endif
diff --git a/mm/sparse.c b/mm/sparse.c
index 72079b538e2d..0a51f36ba3a1 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -18,10 +18,10 @@
18 */ 18 */
19#ifdef CONFIG_SPARSEMEM_EXTREME 19#ifdef CONFIG_SPARSEMEM_EXTREME
20struct mem_section *mem_section[NR_SECTION_ROOTS] 20struct mem_section *mem_section[NR_SECTION_ROOTS]
21 ____cacheline_maxaligned_in_smp; 21 ____cacheline_internodealigned_in_smp;
22#else 22#else
23struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT] 23struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT]
24 ____cacheline_maxaligned_in_smp; 24 ____cacheline_internodealigned_in_smp;
25#endif 25#endif
26EXPORT_SYMBOL(mem_section); 26EXPORT_SYMBOL(mem_section);
27 27
diff --git a/mm/swap_state.c b/mm/swap_state.c
index fc2aecb70a95..7b09ac503fec 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -141,7 +141,7 @@ void __delete_from_swap_cache(struct page *page)
141 * Allocate swap space for the page and add the page to the 141 * Allocate swap space for the page and add the page to the
142 * swap cache. Caller needs to hold the page lock. 142 * swap cache. Caller needs to hold the page lock.
143 */ 143 */
144int add_to_swap(struct page * page) 144int add_to_swap(struct page * page, gfp_t gfp_mask)
145{ 145{
146 swp_entry_t entry; 146 swp_entry_t entry;
147 int err; 147 int err;
@@ -166,7 +166,7 @@ int add_to_swap(struct page * page)
166 * Add it to the swap cache and mark it dirty 166 * Add it to the swap cache and mark it dirty
167 */ 167 */
168 err = __add_to_swap_cache(page, entry, 168 err = __add_to_swap_cache(page, entry,
169 GFP_ATOMIC|__GFP_NOMEMALLOC|__GFP_NOWARN); 169 gfp_mask|__GFP_NOMEMALLOC|__GFP_NOWARN);
170 170
171 switch (err) { 171 switch (err) {
172 case 0: /* Success */ 172 case 0: /* Success */
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 6da4b28b896b..80f948a2028b 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1493,7 +1493,7 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
1493 goto bad_swap; 1493 goto bad_swap;
1494 if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES) 1494 if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES)
1495 goto bad_swap; 1495 goto bad_swap;
1496 1496
1497 /* OK, set up the swap map and apply the bad block list */ 1497 /* OK, set up the swap map and apply the bad block list */
1498 if (!(p->swap_map = vmalloc(maxpages * sizeof(short)))) { 1498 if (!(p->swap_map = vmalloc(maxpages * sizeof(short)))) {
1499 error = -ENOMEM; 1499 error = -ENOMEM;
@@ -1502,17 +1502,17 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
1502 1502
1503 error = 0; 1503 error = 0;
1504 memset(p->swap_map, 0, maxpages * sizeof(short)); 1504 memset(p->swap_map, 0, maxpages * sizeof(short));
1505 for (i=0; i<swap_header->info.nr_badpages; i++) { 1505 for (i = 0; i < swap_header->info.nr_badpages; i++) {
1506 int page = swap_header->info.badpages[i]; 1506 int page_nr = swap_header->info.badpages[i];
1507 if (page <= 0 || page >= swap_header->info.last_page) 1507 if (page_nr <= 0 || page_nr >= swap_header->info.last_page)
1508 error = -EINVAL; 1508 error = -EINVAL;
1509 else 1509 else
1510 p->swap_map[page] = SWAP_MAP_BAD; 1510 p->swap_map[page_nr] = SWAP_MAP_BAD;
1511 } 1511 }
1512 nr_good_pages = swap_header->info.last_page - 1512 nr_good_pages = swap_header->info.last_page -
1513 swap_header->info.nr_badpages - 1513 swap_header->info.nr_badpages -
1514 1 /* header page */; 1514 1 /* header page */;
1515 if (error) 1515 if (error)
1516 goto bad_swap; 1516 goto bad_swap;
1517 } 1517 }
1518 1518
diff --git a/mm/truncate.c b/mm/truncate.c
index 7dee32745901..b1a463d0fe71 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -249,7 +249,6 @@ unlock:
249 break; 249 break;
250 } 250 }
251 pagevec_release(&pvec); 251 pagevec_release(&pvec);
252 cond_resched();
253 } 252 }
254 return ret; 253 return ret;
255} 254}
diff --git a/mm/util.c b/mm/util.c
new file mode 100644
index 000000000000..5f4bb59da63c
--- /dev/null
+++ b/mm/util.c
@@ -0,0 +1,39 @@
1#include <linux/slab.h>
2#include <linux/string.h>
3#include <linux/module.h>
4
5/**
6 * kzalloc - allocate memory. The memory is set to zero.
7 * @size: how many bytes of memory are required.
8 * @flags: the type of memory to allocate.
9 */
10void *kzalloc(size_t size, gfp_t flags)
11{
12 void *ret = kmalloc(size, flags);
13 if (ret)
14 memset(ret, 0, size);
15 return ret;
16}
17EXPORT_SYMBOL(kzalloc);
18
19/*
20 * kstrdup - allocate space for and copy an existing string
21 *
22 * @s: the string to duplicate
23 * @gfp: the GFP mask used in the kmalloc() call when allocating memory
24 */
25char *kstrdup(const char *s, gfp_t gfp)
26{
27 size_t len;
28 char *buf;
29
30 if (!s)
31 return NULL;
32
33 len = strlen(s) + 1;
34 buf = kmalloc(len, gfp);
35 if (buf)
36 memcpy(buf, s, len);
37 return buf;
38}
39EXPORT_SYMBOL(kstrdup);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index be8235fb1939..bf903b2d198f 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -180,8 +180,7 @@ EXPORT_SYMBOL(remove_shrinker);
180 * 180 *
181 * Returns the number of slab objects which we shrunk. 181 * Returns the number of slab objects which we shrunk.
182 */ 182 */
183static int shrink_slab(unsigned long scanned, gfp_t gfp_mask, 183int shrink_slab(unsigned long scanned, gfp_t gfp_mask, unsigned long lru_pages)
184 unsigned long lru_pages)
185{ 184{
186 struct shrinker *shrinker; 185 struct shrinker *shrinker;
187 int ret = 0; 186 int ret = 0;
@@ -269,9 +268,7 @@ static inline int is_page_cache_freeable(struct page *page)
269 268
270static int may_write_to_queue(struct backing_dev_info *bdi) 269static int may_write_to_queue(struct backing_dev_info *bdi)
271{ 270{
272 if (current_is_kswapd()) 271 if (current->flags & PF_SWAPWRITE)
273 return 1;
274 if (current_is_pdflush()) /* This is unlikely, but why not... */
275 return 1; 272 return 1;
276 if (!bdi_write_congested(bdi)) 273 if (!bdi_write_congested(bdi))
277 return 1; 274 return 1;
@@ -376,6 +373,43 @@ static pageout_t pageout(struct page *page, struct address_space *mapping)
376 return PAGE_CLEAN; 373 return PAGE_CLEAN;
377} 374}
378 375
376static int remove_mapping(struct address_space *mapping, struct page *page)
377{
378 if (!mapping)
379 return 0; /* truncate got there first */
380
381 write_lock_irq(&mapping->tree_lock);
382
383 /*
384 * The non-racy check for busy page. It is critical to check
385 * PageDirty _after_ making sure that the page is freeable and
386 * not in use by anybody. (pagecache + us == 2)
387 */
388 if (unlikely(page_count(page) != 2))
389 goto cannot_free;
390 smp_rmb();
391 if (unlikely(PageDirty(page)))
392 goto cannot_free;
393
394 if (PageSwapCache(page)) {
395 swp_entry_t swap = { .val = page_private(page) };
396 __delete_from_swap_cache(page);
397 write_unlock_irq(&mapping->tree_lock);
398 swap_free(swap);
399 __put_page(page); /* The pagecache ref */
400 return 1;
401 }
402
403 __remove_from_page_cache(page);
404 write_unlock_irq(&mapping->tree_lock);
405 __put_page(page);
406 return 1;
407
408cannot_free:
409 write_unlock_irq(&mapping->tree_lock);
410 return 0;
411}
412
379/* 413/*
380 * shrink_list adds the number of reclaimed pages to sc->nr_reclaimed 414 * shrink_list adds the number of reclaimed pages to sc->nr_reclaimed
381 */ 415 */
@@ -424,7 +458,7 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc)
424 * Try to allocate it some swap space here. 458 * Try to allocate it some swap space here.
425 */ 459 */
426 if (PageAnon(page) && !PageSwapCache(page)) { 460 if (PageAnon(page) && !PageSwapCache(page)) {
427 if (!add_to_swap(page)) 461 if (!add_to_swap(page, GFP_ATOMIC))
428 goto activate_locked; 462 goto activate_locked;
429 } 463 }
430#endif /* CONFIG_SWAP */ 464#endif /* CONFIG_SWAP */
@@ -507,36 +541,8 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc)
507 goto free_it; 541 goto free_it;
508 } 542 }
509 543
510 if (!mapping) 544 if (!remove_mapping(mapping, page))
511 goto keep_locked; /* truncate got there first */ 545 goto keep_locked;
512
513 write_lock_irq(&mapping->tree_lock);
514
515 /*
516 * The non-racy check for busy page. It is critical to check
517 * PageDirty _after_ making sure that the page is freeable and
518 * not in use by anybody. (pagecache + us == 2)
519 */
520 if (unlikely(page_count(page) != 2))
521 goto cannot_free;
522 smp_rmb();
523 if (unlikely(PageDirty(page)))
524 goto cannot_free;
525
526#ifdef CONFIG_SWAP
527 if (PageSwapCache(page)) {
528 swp_entry_t swap = { .val = page_private(page) };
529 __delete_from_swap_cache(page);
530 write_unlock_irq(&mapping->tree_lock);
531 swap_free(swap);
532 __put_page(page); /* The pagecache ref */
533 goto free_it;
534 }
535#endif /* CONFIG_SWAP */
536
537 __remove_from_page_cache(page);
538 write_unlock_irq(&mapping->tree_lock);
539 __put_page(page);
540 546
541free_it: 547free_it:
542 unlock_page(page); 548 unlock_page(page);
@@ -545,10 +551,6 @@ free_it:
545 __pagevec_release_nonlru(&freed_pvec); 551 __pagevec_release_nonlru(&freed_pvec);
546 continue; 552 continue;
547 553
548cannot_free:
549 write_unlock_irq(&mapping->tree_lock);
550 goto keep_locked;
551
552activate_locked: 554activate_locked:
553 SetPageActive(page); 555 SetPageActive(page);
554 pgactivate++; 556 pgactivate++;
@@ -566,6 +568,241 @@ keep:
566 return reclaimed; 568 return reclaimed;
567} 569}
568 570
571#ifdef CONFIG_MIGRATION
572static inline void move_to_lru(struct page *page)
573{
574 list_del(&page->lru);
575 if (PageActive(page)) {
576 /*
577 * lru_cache_add_active checks that
578 * the PG_active bit is off.
579 */
580 ClearPageActive(page);
581 lru_cache_add_active(page);
582 } else {
583 lru_cache_add(page);
584 }
585 put_page(page);
586}
587
588/*
589 * Add isolated pages on the list back to the LRU
590 *
591 * returns the number of pages put back.
592 */
593int putback_lru_pages(struct list_head *l)
594{
595 struct page *page;
596 struct page *page2;
597 int count = 0;
598
599 list_for_each_entry_safe(page, page2, l, lru) {
600 move_to_lru(page);
601 count++;
602 }
603 return count;
604}
605
606/*
607 * swapout a single page
608 * page is locked upon entry, unlocked on exit
609 */
610static int swap_page(struct page *page)
611{
612 struct address_space *mapping = page_mapping(page);
613
614 if (page_mapped(page) && mapping)
615 if (try_to_unmap(page) != SWAP_SUCCESS)
616 goto unlock_retry;
617
618 if (PageDirty(page)) {
619 /* Page is dirty, try to write it out here */
620 switch(pageout(page, mapping)) {
621 case PAGE_KEEP:
622 case PAGE_ACTIVATE:
623 goto unlock_retry;
624
625 case PAGE_SUCCESS:
626 goto retry;
627
628 case PAGE_CLEAN:
629 ; /* try to free the page below */
630 }
631 }
632
633 if (PagePrivate(page)) {
634 if (!try_to_release_page(page, GFP_KERNEL) ||
635 (!mapping && page_count(page) == 1))
636 goto unlock_retry;
637 }
638
639 if (remove_mapping(mapping, page)) {
640 /* Success */
641 unlock_page(page);
642 return 0;
643 }
644
645unlock_retry:
646 unlock_page(page);
647
648retry:
649 return -EAGAIN;
650}
651/*
652 * migrate_pages
653 *
654 * Two lists are passed to this function. The first list
655 * contains the pages isolated from the LRU to be migrated.
656 * The second list contains new pages that the pages isolated
657 * can be moved to. If the second list is NULL then all
658 * pages are swapped out.
659 *
660 * The function returns after 10 attempts or if no pages
661 * are movable anymore because t has become empty
662 * or no retryable pages exist anymore.
663 *
664 * SIMPLIFIED VERSION: This implementation of migrate_pages
665 * is only swapping out pages and never touches the second
666 * list. The direct migration patchset
667 * extends this function to avoid the use of swap.
668 *
669 * Return: Number of pages not migrated when "to" ran empty.
670 */
671int migrate_pages(struct list_head *from, struct list_head *to,
672 struct list_head *moved, struct list_head *failed)
673{
674 int retry;
675 int nr_failed = 0;
676 int pass = 0;
677 struct page *page;
678 struct page *page2;
679 int swapwrite = current->flags & PF_SWAPWRITE;
680 int rc;
681
682 if (!swapwrite)
683 current->flags |= PF_SWAPWRITE;
684
685redo:
686 retry = 0;
687
688 list_for_each_entry_safe(page, page2, from, lru) {
689 cond_resched();
690
691 rc = 0;
692 if (page_count(page) == 1)
693 /* page was freed from under us. So we are done. */
694 goto next;
695
696 /*
697 * Skip locked pages during the first two passes to give the
698 * functions holding the lock time to release the page. Later we
699 * use lock_page() to have a higher chance of acquiring the
700 * lock.
701 */
702 rc = -EAGAIN;
703 if (pass > 2)
704 lock_page(page);
705 else
706 if (TestSetPageLocked(page))
707 goto next;
708
709 /*
710 * Only wait on writeback if we have already done a pass where
711 * we we may have triggered writeouts for lots of pages.
712 */
713 if (pass > 0) {
714 wait_on_page_writeback(page);
715 } else {
716 if (PageWriteback(page))
717 goto unlock_page;
718 }
719
720 /*
721 * Anonymous pages must have swap cache references otherwise
722 * the information contained in the page maps cannot be
723 * preserved.
724 */
725 if (PageAnon(page) && !PageSwapCache(page)) {
726 if (!add_to_swap(page, GFP_KERNEL)) {
727 rc = -ENOMEM;
728 goto unlock_page;
729 }
730 }
731
732 /*
733 * Page is properly locked and writeback is complete.
734 * Try to migrate the page.
735 */
736 rc = swap_page(page);
737 goto next;
738
739unlock_page:
740 unlock_page(page);
741
742next:
743 if (rc == -EAGAIN) {
744 retry++;
745 } else if (rc) {
746 /* Permanent failure */
747 list_move(&page->lru, failed);
748 nr_failed++;
749 } else {
750 /* Success */
751 list_move(&page->lru, moved);
752 }
753 }
754 if (retry && pass++ < 10)
755 goto redo;
756
757 if (!swapwrite)
758 current->flags &= ~PF_SWAPWRITE;
759
760 return nr_failed + retry;
761}
762
763static void lru_add_drain_per_cpu(void *dummy)
764{
765 lru_add_drain();
766}
767
768/*
769 * Isolate one page from the LRU lists and put it on the
770 * indicated list. Do necessary cache draining if the
771 * page is not on the LRU lists yet.
772 *
773 * Result:
774 * 0 = page not on LRU list
775 * 1 = page removed from LRU list and added to the specified list.
776 * -ENOENT = page is being freed elsewhere.
777 */
778int isolate_lru_page(struct page *page)
779{
780 int rc = 0;
781 struct zone *zone = page_zone(page);
782
783redo:
784 spin_lock_irq(&zone->lru_lock);
785 rc = __isolate_lru_page(page);
786 if (rc == 1) {
787 if (PageActive(page))
788 del_page_from_active_list(zone, page);
789 else
790 del_page_from_inactive_list(zone, page);
791 }
792 spin_unlock_irq(&zone->lru_lock);
793 if (rc == 0) {
794 /*
795 * Maybe this page is still waiting for a cpu to drain it
796 * from one of the lru lists?
797 */
798 rc = schedule_on_each_cpu(lru_add_drain_per_cpu, NULL);
799 if (rc == 0 && PageLRU(page))
800 goto redo;
801 }
802 return rc;
803}
804#endif
805
569/* 806/*
570 * zone->lru_lock is heavily contended. Some of the functions that 807 * zone->lru_lock is heavily contended. Some of the functions that
571 * shrink the lists perform better by taking out a batch of pages 808 * shrink the lists perform better by taking out a batch of pages
@@ -594,20 +831,18 @@ static int isolate_lru_pages(int nr_to_scan, struct list_head *src,
594 page = lru_to_page(src); 831 page = lru_to_page(src);
595 prefetchw_prev_lru_page(page, src, flags); 832 prefetchw_prev_lru_page(page, src, flags);
596 833
597 if (!TestClearPageLRU(page)) 834 switch (__isolate_lru_page(page)) {
598 BUG(); 835 case 1:
599 list_del(&page->lru); 836 /* Succeeded to isolate page */
600 if (get_page_testone(page)) { 837 list_move(&page->lru, dst);
601 /*
602 * It is being freed elsewhere
603 */
604 __put_page(page);
605 SetPageLRU(page);
606 list_add(&page->lru, src);
607 continue;
608 } else {
609 list_add(&page->lru, dst);
610 nr_taken++; 838 nr_taken++;
839 break;
840 case -ENOENT:
841 /* Not possible to isolate */
842 list_move(&page->lru, src);
843 break;
844 default:
845 BUG();
611 } 846 }
612 } 847 }
613 848
@@ -1226,7 +1461,7 @@ static int kswapd(void *p)
1226 * us from recursively trying to free more memory as we're 1461 * us from recursively trying to free more memory as we're
1227 * trying to free the first piece of memory in the first place). 1462 * trying to free the first piece of memory in the first place).
1228 */ 1463 */
1229 tsk->flags |= PF_MEMALLOC|PF_KSWAPD; 1464 tsk->flags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD;
1230 1465
1231 order = 0; 1466 order = 0;
1232 for ( ; ; ) { 1467 for ( ; ; ) {
diff --git a/net/802/Makefile b/net/802/Makefile
index 01861929591a..977704a54f68 100644
--- a/net/802/Makefile
+++ b/net/802/Makefile
@@ -2,8 +2,6 @@
2# Makefile for the Linux 802.x protocol layers. 2# Makefile for the Linux 802.x protocol layers.
3# 3#
4 4
5obj-y := p8023.o
6
7# Check the p8022 selections against net/core/Makefile. 5# Check the p8022 selections against net/core/Makefile.
8obj-$(CONFIG_SYSCTL) += sysctl_net_802.o 6obj-$(CONFIG_SYSCTL) += sysctl_net_802.o
9obj-$(CONFIG_LLC) += p8022.o psnap.o 7obj-$(CONFIG_LLC) += p8022.o psnap.o
@@ -11,5 +9,5 @@ obj-$(CONFIG_TR) += p8022.o psnap.o tr.o sysctl_net_802.o
11obj-$(CONFIG_NET_FC) += fc.o 9obj-$(CONFIG_NET_FC) += fc.o
12obj-$(CONFIG_FDDI) += fddi.o 10obj-$(CONFIG_FDDI) += fddi.o
13obj-$(CONFIG_HIPPI) += hippi.o 11obj-$(CONFIG_HIPPI) += hippi.o
14obj-$(CONFIG_IPX) += p8022.o psnap.o 12obj-$(CONFIG_IPX) += p8022.o psnap.o p8023.o
15obj-$(CONFIG_ATALK) += p8022.o psnap.o 13obj-$(CONFIG_ATALK) += p8022.o psnap.o
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 3f244670764a..00f983226672 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -986,6 +986,7 @@ int dccp_v4_rcv(struct sk_buff *skb)
986 986
987 if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) 987 if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
988 goto discard_and_relse; 988 goto discard_and_relse;
989 nf_reset(skb);
989 990
990 return sk_receive_skb(sk, skb); 991 return sk_receive_skb(sk, skb);
991 992
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index c609dc78f487..df074259f9c3 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -27,6 +27,7 @@
27#include <net/ipv6.h> 27#include <net/ipv6.h>
28#include <net/protocol.h> 28#include <net/protocol.h>
29#include <net/transp_v6.h> 29#include <net/transp_v6.h>
30#include <net/ip6_checksum.h>
30#include <net/xfrm.h> 31#include <net/xfrm.h>
31 32
32#include "dccp.h" 33#include "dccp.h"
@@ -1028,7 +1029,7 @@ discard:
1028 return 0; 1029 return 0;
1029} 1030}
1030 1031
1031static int dccp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) 1032static int dccp_v6_rcv(struct sk_buff **pskb)
1032{ 1033{
1033 const struct dccp_hdr *dh; 1034 const struct dccp_hdr *dh;
1034 struct sk_buff *skb = *pskb; 1035 struct sk_buff *skb = *pskb;
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 073aebdf0f67..f8dca31be5dd 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -75,22 +75,14 @@ static void prism2_wep_deinit(void *priv)
75 kfree(priv); 75 kfree(priv);
76} 76}
77 77
78/* Perform WEP encryption on given skb that has at least 4 bytes of headroom 78/* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */
79 * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted, 79static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len, void *priv)
80 * so the payload length increases with 8 bytes.
81 *
82 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
83 */
84static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
85{ 80{
86 struct prism2_wep_data *wep = priv; 81 struct prism2_wep_data *wep = priv;
87 u32 crc, klen, len; 82 u32 klen, len;
88 u8 key[WEP_KEY_LEN + 3]; 83 u8 *pos;
89 u8 *pos, *icv; 84
90 struct scatterlist sg; 85 if (skb_headroom(skb) < 4 || skb->len < hdr_len)
91
92 if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
93 skb->len < hdr_len)
94 return -1; 86 return -1;
95 87
96 len = skb->len - hdr_len; 88 len = skb->len - hdr_len;
@@ -112,15 +104,47 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
112 } 104 }
113 105
114 /* Prepend 24-bit IV to RC4 key and TX frame */ 106 /* Prepend 24-bit IV to RC4 key and TX frame */
115 *pos++ = key[0] = (wep->iv >> 16) & 0xff; 107 *pos++ = (wep->iv >> 16) & 0xff;
116 *pos++ = key[1] = (wep->iv >> 8) & 0xff; 108 *pos++ = (wep->iv >> 8) & 0xff;
117 *pos++ = key[2] = wep->iv & 0xff; 109 *pos++ = wep->iv & 0xff;
118 *pos++ = wep->key_idx << 6; 110 *pos++ = wep->key_idx << 6;
119 111
112 return 0;
113}
114
115/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
116 * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
117 * so the payload length increases with 8 bytes.
118 *
119 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
120 */
121static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
122{
123 struct prism2_wep_data *wep = priv;
124 u32 crc, klen, len;
125 u8 *pos, *icv;
126 struct scatterlist sg;
127 u8 key[WEP_KEY_LEN + 3];
128
129 /* other checks are in prism2_wep_build_iv */
130 if (skb_tailroom(skb) < 4)
131 return -1;
132
133 /* add the IV to the frame */
134 if (prism2_wep_build_iv(skb, hdr_len, priv))
135 return -1;
136
137 /* Copy the IV into the first 3 bytes of the key */
138 memcpy(key, skb->data + hdr_len, 3);
139
120 /* Copy rest of the WEP key (the secret part) */ 140 /* Copy rest of the WEP key (the secret part) */
121 memcpy(key + 3, wep->key, wep->key_len); 141 memcpy(key + 3, wep->key, wep->key_len);
142
143 len = skb->len - hdr_len - 4;
144 pos = skb->data + hdr_len + 4;
145 klen = 3 + wep->key_len;
122 146
123 /* Append little-endian CRC32 and encrypt it to produce ICV */ 147 /* Append little-endian CRC32 over only the data and encrypt it to produce ICV */
124 crc = ~crc32_le(~0, pos, len); 148 crc = ~crc32_le(~0, pos, len);
125 icv = skb_put(skb, 4); 149 icv = skb_put(skb, 4);
126 icv[0] = crc; 150 icv[0] = crc;
@@ -231,6 +255,7 @@ static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
231 .name = "WEP", 255 .name = "WEP",
232 .init = prism2_wep_init, 256 .init = prism2_wep_init,
233 .deinit = prism2_wep_deinit, 257 .deinit = prism2_wep_deinit,
258 .build_iv = prism2_wep_build_iv,
234 .encrypt_mpdu = prism2_wep_encrypt, 259 .encrypt_mpdu = prism2_wep_encrypt,
235 .decrypt_mpdu = prism2_wep_decrypt, 260 .decrypt_mpdu = prism2_wep_decrypt,
236 .encrypt_msdu = NULL, 261 .encrypt_msdu = NULL,
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index 445f206e65e0..e5b33c8d5dbc 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -288,7 +288,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
288 /* Determine total amount of storage required for TXB packets */ 288 /* Determine total amount of storage required for TXB packets */
289 bytes = skb->len + SNAP_SIZE + sizeof(u16); 289 bytes = skb->len + SNAP_SIZE + sizeof(u16);
290 290
291 if (host_encrypt) 291 if (host_encrypt || host_build_iv)
292 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | 292 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
293 IEEE80211_FCTL_PROTECTED; 293 IEEE80211_FCTL_PROTECTED;
294 else 294 else
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 181755f2aa8b..406d5b964905 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -284,7 +284,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
284 }; 284 };
285 int i, key, key_provided, len; 285 int i, key, key_provided, len;
286 struct ieee80211_crypt_data **crypt; 286 struct ieee80211_crypt_data **crypt;
287 int host_crypto = ieee->host_encrypt || ieee->host_decrypt; 287 int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv;
288 288
289 IEEE80211_DEBUG_WX("SET_ENCODE\n"); 289 IEEE80211_DEBUG_WX("SET_ENCODE\n");
290 290
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 912c42f57c79..de16e944777f 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -832,6 +832,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
832 skb->h.raw = skb->nh.raw; 832 skb->h.raw = skb->nh.raw;
833 skb->nh.raw = skb_push(skb, gre_hlen); 833 skb->nh.raw = skb_push(skb, gre_hlen);
834 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 834 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
835 IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED);
835 dst_release(skb->dst); 836 dst_release(skb->dst);
836 skb->dst = &rt->u.dst; 837 skb->dst = &rt->u.dst;
837 838
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index e45846ae570b..18d7fad474d7 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -185,7 +185,6 @@ int ip_call_ra_chain(struct sk_buff *skb)
185 raw_rcv(last, skb2); 185 raw_rcv(last, skb2);
186 } 186 }
187 last = sk; 187 last = sk;
188 nf_reset(skb);
189 } 188 }
190 } 189 }
191 190
@@ -204,10 +203,6 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb)
204 203
205 __skb_pull(skb, ihl); 204 __skb_pull(skb, ihl);
206 205
207 /* Free reference early: we don't need it any more, and it may
208 hold ip_conntrack module loaded indefinitely. */
209 nf_reset(skb);
210
211 /* Point into the IP datagram, just past the header. */ 206 /* Point into the IP datagram, just past the header. */
212 skb->h.raw = skb->data; 207 skb->h.raw = skb->data;
213 208
@@ -232,10 +227,12 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb)
232 if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) { 227 if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) {
233 int ret; 228 int ret;
234 229
235 if (!ipprot->no_policy && 230 if (!ipprot->no_policy) {
236 !xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { 231 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
237 kfree_skb(skb); 232 kfree_skb(skb);
238 goto out; 233 goto out;
234 }
235 nf_reset(skb);
239 } 236 }
240 ret = ipprot->handler(skb); 237 ret = ipprot->handler(skb);
241 if (ret < 0) { 238 if (ret < 0) {
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 8b1c9bd0091e..c2169b47ddfd 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -85,6 +85,8 @@
85 85
86int sysctl_ip_default_ttl = IPDEFTTL; 86int sysctl_ip_default_ttl = IPDEFTTL;
87 87
88static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*));
89
88/* Generate a checksum for an outgoing IP datagram. */ 90/* Generate a checksum for an outgoing IP datagram. */
89__inline__ void ip_send_check(struct iphdr *iph) 91__inline__ void ip_send_check(struct iphdr *iph)
90{ 92{
@@ -202,6 +204,11 @@ static inline int ip_finish_output2(struct sk_buff *skb)
202 204
203static inline int ip_finish_output(struct sk_buff *skb) 205static inline int ip_finish_output(struct sk_buff *skb)
204{ 206{
207#if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
208 /* Policy lookup after SNAT yielded a new policy */
209 if (skb->dst->xfrm != NULL)
210 return xfrm4_output_finish(skb);
211#endif
205 if (skb->len > dst_mtu(skb->dst) && 212 if (skb->len > dst_mtu(skb->dst) &&
206 !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) 213 !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
207 return ip_fragment(skb, ip_finish_output2); 214 return ip_fragment(skb, ip_finish_output2);
@@ -409,7 +416,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
409 * single device frame, and queue such a frame for sending. 416 * single device frame, and queue such a frame for sending.
410 */ 417 */
411 418
412int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) 419static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
413{ 420{
414 struct iphdr *iph; 421 struct iphdr *iph;
415 int raw = 0; 422 int raw = 0;
@@ -1391,7 +1398,6 @@ void __init ip_init(void)
1391#endif 1398#endif
1392} 1399}
1393 1400
1394EXPORT_SYMBOL(ip_fragment);
1395EXPORT_SYMBOL(ip_generic_getfrag); 1401EXPORT_SYMBOL(ip_generic_getfrag);
1396EXPORT_SYMBOL(ip_queue_xmit); 1402EXPORT_SYMBOL(ip_queue_xmit);
1397EXPORT_SYMBOL(ip_send_check); 1403EXPORT_SYMBOL(ip_send_check);
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 35571cff81c6..bbd85f5ec985 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -621,6 +621,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
621 skb->h.raw = skb->nh.raw; 621 skb->h.raw = skb->nh.raw;
622 skb->nh.raw = skb_push(skb, sizeof(struct iphdr)); 622 skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
623 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 623 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
624 IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED);
624 dst_release(skb->dst); 625 dst_release(skb->dst);
625 skb->dst = &rt->u.dst; 626 skb->dst = &rt->u.dst;
626 627
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index ae0779d82c5d..3321092b0914 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -7,11 +7,13 @@
7#include <linux/netfilter.h> 7#include <linux/netfilter.h>
8#include <linux/netfilter_ipv4.h> 8#include <linux/netfilter_ipv4.h>
9 9
10#include <linux/ip.h>
10#include <linux/tcp.h> 11#include <linux/tcp.h>
11#include <linux/udp.h> 12#include <linux/udp.h>
12#include <linux/icmp.h> 13#include <linux/icmp.h>
13#include <net/route.h> 14#include <net/route.h>
14#include <linux/ip.h> 15#include <net/xfrm.h>
16#include <net/ip.h>
15 17
16/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */ 18/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
17int ip_route_me_harder(struct sk_buff **pskb) 19int ip_route_me_harder(struct sk_buff **pskb)
@@ -33,7 +35,6 @@ int ip_route_me_harder(struct sk_buff **pskb)
33#ifdef CONFIG_IP_ROUTE_FWMARK 35#ifdef CONFIG_IP_ROUTE_FWMARK
34 fl.nl_u.ip4_u.fwmark = (*pskb)->nfmark; 36 fl.nl_u.ip4_u.fwmark = (*pskb)->nfmark;
35#endif 37#endif
36 fl.proto = iph->protocol;
37 if (ip_route_output_key(&rt, &fl) != 0) 38 if (ip_route_output_key(&rt, &fl) != 0)
38 return -1; 39 return -1;
39 40
@@ -60,6 +61,13 @@ int ip_route_me_harder(struct sk_buff **pskb)
60 if ((*pskb)->dst->error) 61 if ((*pskb)->dst->error)
61 return -1; 62 return -1;
62 63
64#ifdef CONFIG_XFRM
65 if (!(IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED) &&
66 xfrm_decode_session(*pskb, &fl, AF_INET) == 0)
67 if (xfrm_lookup(&(*pskb)->dst, &fl, (*pskb)->sk, 0))
68 return -1;
69#endif
70
63 /* Change in oif may mean change in hh_len. */ 71 /* Change in oif may mean change in hh_len. */
64 hh_len = (*pskb)->dst->dev->hard_header_len; 72 hh_len = (*pskb)->dst->dev->hard_header_len;
65 if (skb_headroom(*pskb) < hh_len) { 73 if (skb_headroom(*pskb) < hh_len) {
@@ -78,6 +86,9 @@ int ip_route_me_harder(struct sk_buff **pskb)
78} 86}
79EXPORT_SYMBOL(ip_route_me_harder); 87EXPORT_SYMBOL(ip_route_me_harder);
80 88
89void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
90EXPORT_SYMBOL(ip_nat_decode_session);
91
81/* 92/*
82 * Extra routing may needed on local out, as the QUEUE target never 93 * Extra routing may needed on local out, as the QUEUE target never
83 * returns control to the table. 94 * returns control to the table.
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 88a60650e6b8..a9893ec03e02 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -487,6 +487,16 @@ config IP_NF_MATCH_STRING
487 487
488 To compile it as a module, choose M here. If unsure, say N. 488 To compile it as a module, choose M here. If unsure, say N.
489 489
490config IP_NF_MATCH_POLICY
491 tristate "IPsec policy match support"
492 depends on IP_NF_IPTABLES && XFRM
493 help
494 Policy matching allows you to match packets based on the
495 IPsec policy that was used during decapsulation/will
496 be used during encapsulation.
497
498 To compile it as a module, choose M here. If unsure, say N.
499
490# `filter', generic and specific targets 500# `filter', generic and specific targets
491config IP_NF_FILTER 501config IP_NF_FILTER
492 tristate "Packet filtering" 502 tristate "Packet filtering"
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index d0a447e520a2..549b01a648b3 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -72,6 +72,7 @@ obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
72obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o 72obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
73obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o 73obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
74obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o 74obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
75obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o
75obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o 76obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o
76obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o 77obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
77 78
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
index 977fb59d4563..0b25050981a1 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
@@ -16,6 +16,7 @@
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/sched.h> 17#include <linux/sched.h>
18#include <linux/timer.h> 18#include <linux/timer.h>
19#include <linux/interrupt.h>
19#include <linux/netfilter.h> 20#include <linux/netfilter.h>
20#include <linux/module.h> 21#include <linux/module.h>
21#include <linux/in.h> 22#include <linux/in.h>
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index f04111f74e09..8b8a1f00bbf4 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -55,6 +55,44 @@
55 : ((hooknum) == NF_IP_LOCAL_IN ? "LOCAL_IN" \ 55 : ((hooknum) == NF_IP_LOCAL_IN ? "LOCAL_IN" \
56 : "*ERROR*"))) 56 : "*ERROR*")))
57 57
58#ifdef CONFIG_XFRM
59static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
60{
61 struct ip_conntrack *ct;
62 struct ip_conntrack_tuple *t;
63 enum ip_conntrack_info ctinfo;
64 enum ip_conntrack_dir dir;
65 unsigned long statusbit;
66
67 ct = ip_conntrack_get(skb, &ctinfo);
68 if (ct == NULL)
69 return;
70 dir = CTINFO2DIR(ctinfo);
71 t = &ct->tuplehash[dir].tuple;
72
73 if (dir == IP_CT_DIR_ORIGINAL)
74 statusbit = IPS_DST_NAT;
75 else
76 statusbit = IPS_SRC_NAT;
77
78 if (ct->status & statusbit) {
79 fl->fl4_dst = t->dst.ip;
80 if (t->dst.protonum == IPPROTO_TCP ||
81 t->dst.protonum == IPPROTO_UDP)
82 fl->fl_ip_dport = t->dst.u.tcp.port;
83 }
84
85 statusbit ^= IPS_NAT_MASK;
86
87 if (ct->status & statusbit) {
88 fl->fl4_src = t->src.ip;
89 if (t->dst.protonum == IPPROTO_TCP ||
90 t->dst.protonum == IPPROTO_UDP)
91 fl->fl_ip_sport = t->src.u.tcp.port;
92 }
93}
94#endif
95
58static unsigned int 96static unsigned int
59ip_nat_fn(unsigned int hooknum, 97ip_nat_fn(unsigned int hooknum,
60 struct sk_buff **pskb, 98 struct sk_buff **pskb,
@@ -162,18 +200,20 @@ ip_nat_in(unsigned int hooknum,
162 const struct net_device *out, 200 const struct net_device *out,
163 int (*okfn)(struct sk_buff *)) 201 int (*okfn)(struct sk_buff *))
164{ 202{
165 u_int32_t saddr, daddr; 203 struct ip_conntrack *ct;
204 enum ip_conntrack_info ctinfo;
166 unsigned int ret; 205 unsigned int ret;
167 206
168 saddr = (*pskb)->nh.iph->saddr;
169 daddr = (*pskb)->nh.iph->daddr;
170
171 ret = ip_nat_fn(hooknum, pskb, in, out, okfn); 207 ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
172 if (ret != NF_DROP && ret != NF_STOLEN 208 if (ret != NF_DROP && ret != NF_STOLEN
173 && ((*pskb)->nh.iph->saddr != saddr 209 && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
174 || (*pskb)->nh.iph->daddr != daddr)) { 210 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
175 dst_release((*pskb)->dst); 211
176 (*pskb)->dst = NULL; 212 if (ct->tuplehash[dir].tuple.src.ip !=
213 ct->tuplehash[!dir].tuple.dst.ip) {
214 dst_release((*pskb)->dst);
215 (*pskb)->dst = NULL;
216 }
177 } 217 }
178 return ret; 218 return ret;
179} 219}
@@ -185,12 +225,30 @@ ip_nat_out(unsigned int hooknum,
185 const struct net_device *out, 225 const struct net_device *out,
186 int (*okfn)(struct sk_buff *)) 226 int (*okfn)(struct sk_buff *))
187{ 227{
228 struct ip_conntrack *ct;
229 enum ip_conntrack_info ctinfo;
230 unsigned int ret;
231
188 /* root is playing with raw sockets. */ 232 /* root is playing with raw sockets. */
189 if ((*pskb)->len < sizeof(struct iphdr) 233 if ((*pskb)->len < sizeof(struct iphdr)
190 || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) 234 || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
191 return NF_ACCEPT; 235 return NF_ACCEPT;
192 236
193 return ip_nat_fn(hooknum, pskb, in, out, okfn); 237 ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
238 if (ret != NF_DROP && ret != NF_STOLEN
239 && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
240 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
241
242 if (ct->tuplehash[dir].tuple.src.ip !=
243 ct->tuplehash[!dir].tuple.dst.ip
244#ifdef CONFIG_XFRM
245 || ct->tuplehash[dir].tuple.src.u.all !=
246 ct->tuplehash[!dir].tuple.dst.u.all
247#endif
248 )
249 return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
250 }
251 return ret;
194} 252}
195 253
196static unsigned int 254static unsigned int
@@ -200,7 +258,8 @@ ip_nat_local_fn(unsigned int hooknum,
200 const struct net_device *out, 258 const struct net_device *out,
201 int (*okfn)(struct sk_buff *)) 259 int (*okfn)(struct sk_buff *))
202{ 260{
203 u_int32_t saddr, daddr; 261 struct ip_conntrack *ct;
262 enum ip_conntrack_info ctinfo;
204 unsigned int ret; 263 unsigned int ret;
205 264
206 /* root is playing with raw sockets. */ 265 /* root is playing with raw sockets. */
@@ -208,14 +267,20 @@ ip_nat_local_fn(unsigned int hooknum,
208 || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) 267 || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
209 return NF_ACCEPT; 268 return NF_ACCEPT;
210 269
211 saddr = (*pskb)->nh.iph->saddr;
212 daddr = (*pskb)->nh.iph->daddr;
213
214 ret = ip_nat_fn(hooknum, pskb, in, out, okfn); 270 ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
215 if (ret != NF_DROP && ret != NF_STOLEN 271 if (ret != NF_DROP && ret != NF_STOLEN
216 && ((*pskb)->nh.iph->saddr != saddr 272 && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
217 || (*pskb)->nh.iph->daddr != daddr)) 273 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
218 return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP; 274
275 if (ct->tuplehash[dir].tuple.dst.ip !=
276 ct->tuplehash[!dir].tuple.src.ip
277#ifdef CONFIG_XFRM
278 || ct->tuplehash[dir].tuple.dst.u.all !=
279 ct->tuplehash[dir].tuple.src.u.all
280#endif
281 )
282 return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
283 }
219 return ret; 284 return ret;
220} 285}
221 286
@@ -303,10 +368,14 @@ static int init_or_cleanup(int init)
303 368
304 if (!init) goto cleanup; 369 if (!init) goto cleanup;
305 370
371#ifdef CONFIG_XFRM
372 BUG_ON(ip_nat_decode_session != NULL);
373 ip_nat_decode_session = nat_decode_session;
374#endif
306 ret = ip_nat_rule_init(); 375 ret = ip_nat_rule_init();
307 if (ret < 0) { 376 if (ret < 0) {
308 printk("ip_nat_init: can't setup rules.\n"); 377 printk("ip_nat_init: can't setup rules.\n");
309 goto cleanup_nothing; 378 goto cleanup_decode_session;
310 } 379 }
311 ret = nf_register_hook(&ip_nat_in_ops); 380 ret = nf_register_hook(&ip_nat_in_ops);
312 if (ret < 0) { 381 if (ret < 0) {
@@ -354,7 +423,11 @@ static int init_or_cleanup(int init)
354 nf_unregister_hook(&ip_nat_in_ops); 423 nf_unregister_hook(&ip_nat_in_ops);
355 cleanup_rule_init: 424 cleanup_rule_init:
356 ip_nat_rule_cleanup(); 425 ip_nat_rule_cleanup();
357 cleanup_nothing: 426 cleanup_decode_session:
427#ifdef CONFIG_XFRM
428 ip_nat_decode_session = NULL;
429 synchronize_net();
430#endif
358 return ret; 431 return ret;
359} 432}
360 433
diff --git a/net/ipv4/netfilter/ipt_policy.c b/net/ipv4/netfilter/ipt_policy.c
new file mode 100644
index 000000000000..709debcc69c9
--- /dev/null
+++ b/net/ipv4/netfilter/ipt_policy.c
@@ -0,0 +1,170 @@
1/* IP tables module for matching IPsec policy
2 *
3 * Copyright (c) 2004,2005 Patrick McHardy, <kaber@trash.net>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/kernel.h>
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/skbuff.h>
14#include <linux/init.h>
15#include <net/xfrm.h>
16
17#include <linux/netfilter_ipv4.h>
18#include <linux/netfilter_ipv4/ip_tables.h>
19#include <linux/netfilter_ipv4/ipt_policy.h>
20
21MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
22MODULE_DESCRIPTION("IPtables IPsec policy matching module");
23MODULE_LICENSE("GPL");
24
25
26static inline int
27match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
28{
29#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x))
30
31 return MATCH(saddr, x->props.saddr.a4 & e->smask) &&
32 MATCH(daddr, x->id.daddr.a4 & e->dmask) &&
33 MATCH(proto, x->id.proto) &&
34 MATCH(mode, x->props.mode) &&
35 MATCH(spi, x->id.spi) &&
36 MATCH(reqid, x->props.reqid);
37}
38
39static int
40match_policy_in(const struct sk_buff *skb, const struct ipt_policy_info *info)
41{
42 const struct ipt_policy_elem *e;
43 struct sec_path *sp = skb->sp;
44 int strict = info->flags & IPT_POLICY_MATCH_STRICT;
45 int i, pos;
46
47 if (sp == NULL)
48 return -1;
49 if (strict && info->len != sp->len)
50 return 0;
51
52 for (i = sp->len - 1; i >= 0; i--) {
53 pos = strict ? i - sp->len + 1 : 0;
54 if (pos >= info->len)
55 return 0;
56 e = &info->pol[pos];
57
58 if (match_xfrm_state(sp->x[i].xvec, e)) {
59 if (!strict)
60 return 1;
61 } else if (strict)
62 return 0;
63 }
64
65 return strict ? 1 : 0;
66}
67
68static int
69match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info)
70{
71 const struct ipt_policy_elem *e;
72 struct dst_entry *dst = skb->dst;
73 int strict = info->flags & IPT_POLICY_MATCH_STRICT;
74 int i, pos;
75
76 if (dst->xfrm == NULL)
77 return -1;
78
79 for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
80 pos = strict ? i : 0;
81 if (pos >= info->len)
82 return 0;
83 e = &info->pol[pos];
84
85 if (match_xfrm_state(dst->xfrm, e)) {
86 if (!strict)
87 return 1;
88 } else if (strict)
89 return 0;
90 }
91
92 return strict ? 1 : 0;
93}
94
95static int match(const struct sk_buff *skb,
96 const struct net_device *in,
97 const struct net_device *out,
98 const void *matchinfo, int offset, int *hotdrop)
99{
100 const struct ipt_policy_info *info = matchinfo;
101 int ret;
102
103 if (info->flags & IPT_POLICY_MATCH_IN)
104 ret = match_policy_in(skb, info);
105 else
106 ret = match_policy_out(skb, info);
107
108 if (ret < 0)
109 ret = info->flags & IPT_POLICY_MATCH_NONE ? 1 : 0;
110 else if (info->flags & IPT_POLICY_MATCH_NONE)
111 ret = 0;
112
113 return ret;
114}
115
116static int checkentry(const char *tablename, const struct ipt_ip *ip,
117 void *matchinfo, unsigned int matchsize,
118 unsigned int hook_mask)
119{
120 struct ipt_policy_info *info = matchinfo;
121
122 if (matchsize != IPT_ALIGN(sizeof(*info))) {
123 printk(KERN_ERR "ipt_policy: matchsize %u != %zu\n",
124 matchsize, IPT_ALIGN(sizeof(*info)));
125 return 0;
126 }
127 if (!(info->flags & (IPT_POLICY_MATCH_IN|IPT_POLICY_MATCH_OUT))) {
128 printk(KERN_ERR "ipt_policy: neither incoming nor "
129 "outgoing policy selected\n");
130 return 0;
131 }
132 if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
133 && info->flags & IPT_POLICY_MATCH_OUT) {
134 printk(KERN_ERR "ipt_policy: output policy not valid in "
135 "PRE_ROUTING and INPUT\n");
136 return 0;
137 }
138 if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
139 && info->flags & IPT_POLICY_MATCH_IN) {
140 printk(KERN_ERR "ipt_policy: input policy not valid in "
141 "POST_ROUTING and OUTPUT\n");
142 return 0;
143 }
144 if (info->len > IPT_POLICY_MAX_ELEM) {
145 printk(KERN_ERR "ipt_policy: too many policy elements\n");
146 return 0;
147 }
148
149 return 1;
150}
151
152static struct ipt_match policy_match = {
153 .name = "policy",
154 .match = match,
155 .checkentry = checkentry,
156 .me = THIS_MODULE,
157};
158
159static int __init init(void)
160{
161 return ipt_register_match(&policy_match);
162}
163
164static void __exit fini(void)
165{
166 ipt_unregister_match(&policy_match);
167}
168
169module_init(init);
170module_exit(fini);
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 4b0d7e4d6269..165a4d81efa4 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -255,6 +255,7 @@ int raw_rcv(struct sock *sk, struct sk_buff *skb)
255 kfree_skb(skb); 255 kfree_skb(skb);
256 return NET_RX_DROP; 256 return NET_RX_DROP;
257 } 257 }
258 nf_reset(skb);
258 259
259 skb_push(skb, skb->data - skb->nh.raw); 260 skb_push(skb, skb->data - skb->nh.raw);
260 261
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index e9f83e5b28ce..6ea353907af5 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1080,6 +1080,7 @@ process:
1080 1080
1081 if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) 1081 if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
1082 goto discard_and_relse; 1082 goto discard_and_relse;
1083 nf_reset(skb);
1083 1084
1084 if (sk_filter(sk, skb, 0)) 1085 if (sk_filter(sk, skb, 0))
1085 goto discard_and_relse; 1086 goto discard_and_relse;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 223abaa72bc5..00840474a449 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -989,6 +989,7 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
989 kfree_skb(skb); 989 kfree_skb(skb);
990 return -1; 990 return -1;
991 } 991 }
992 nf_reset(skb);
992 993
993 if (up->encap_type) { 994 if (up->encap_type) {
994 /* 995 /*
@@ -1149,6 +1150,7 @@ int udp_rcv(struct sk_buff *skb)
1149 1150
1150 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) 1151 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
1151 goto drop; 1152 goto drop;
1153 nf_reset(skb);
1152 1154
1153 /* No socket. Drop packet silently, if checksum is wrong */ 1155 /* No socket. Drop packet silently, if checksum is wrong */
1154 if (udp_checksum_complete(skb)) 1156 if (udp_checksum_complete(skb))
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 2d3849c38a0f..850d919591d1 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -11,6 +11,8 @@
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/string.h> 13#include <linux/string.h>
14#include <linux/netfilter.h>
15#include <linux/netfilter_ipv4.h>
14#include <net/inet_ecn.h> 16#include <net/inet_ecn.h>
15#include <net/ip.h> 17#include <net/ip.h>
16#include <net/xfrm.h> 18#include <net/xfrm.h>
@@ -45,6 +47,23 @@ static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
45 return xfrm_parse_spi(skb, nexthdr, spi, seq); 47 return xfrm_parse_spi(skb, nexthdr, spi, seq);
46} 48}
47 49
50#ifdef CONFIG_NETFILTER
51static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
52{
53 struct iphdr *iph = skb->nh.iph;
54
55 if (skb->dst == NULL) {
56 if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
57 skb->dev))
58 goto drop;
59 }
60 return dst_input(skb);
61drop:
62 kfree_skb(skb);
63 return NET_RX_DROP;
64}
65#endif
66
48int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) 67int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
49{ 68{
50 int err; 69 int err;
@@ -137,6 +156,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
137 memcpy(skb->sp->x+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(struct sec_decap_state)); 156 memcpy(skb->sp->x+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(struct sec_decap_state));
138 skb->sp->len += xfrm_nr; 157 skb->sp->len += xfrm_nr;
139 158
159 nf_reset(skb);
160
140 if (decaps) { 161 if (decaps) {
141 if (!(skb->dev->flags&IFF_LOOPBACK)) { 162 if (!(skb->dev->flags&IFF_LOOPBACK)) {
142 dst_release(skb->dst); 163 dst_release(skb->dst);
@@ -145,7 +166,17 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
145 netif_rx(skb); 166 netif_rx(skb);
146 return 0; 167 return 0;
147 } else { 168 } else {
169#ifdef CONFIG_NETFILTER
170 __skb_push(skb, skb->data - skb->nh.raw);
171 skb->nh.iph->tot_len = htons(skb->len);
172 ip_send_check(skb->nh.iph);
173
174 NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
175 xfrm4_rcv_encap_finish);
176 return 0;
177#else
148 return -skb->nh.iph->protocol; 178 return -skb->nh.iph->protocol;
179#endif
149 } 180 }
150 181
151drop_unlock: 182drop_unlock:
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 66620a95942a..d4df0ddd424b 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -8,8 +8,10 @@
8 * 2 of the License, or (at your option) any later version. 8 * 2 of the License, or (at your option) any later version.
9 */ 9 */
10 10
11#include <linux/compiler.h>
11#include <linux/skbuff.h> 12#include <linux/skbuff.h>
12#include <linux/spinlock.h> 13#include <linux/spinlock.h>
14#include <linux/netfilter_ipv4.h>
13#include <net/inet_ecn.h> 15#include <net/inet_ecn.h>
14#include <net/ip.h> 16#include <net/ip.h>
15#include <net/xfrm.h> 17#include <net/xfrm.h>
@@ -95,7 +97,7 @@ out:
95 return ret; 97 return ret;
96} 98}
97 99
98int xfrm4_output(struct sk_buff *skb) 100static int xfrm4_output_one(struct sk_buff *skb)
99{ 101{
100 struct dst_entry *dst = skb->dst; 102 struct dst_entry *dst = skb->dst;
101 struct xfrm_state *x = dst->xfrm; 103 struct xfrm_state *x = dst->xfrm;
@@ -113,27 +115,33 @@ int xfrm4_output(struct sk_buff *skb)
113 goto error_nolock; 115 goto error_nolock;
114 } 116 }
115 117
116 spin_lock_bh(&x->lock); 118 do {
117 err = xfrm_state_check(x, skb); 119 spin_lock_bh(&x->lock);
118 if (err) 120 err = xfrm_state_check(x, skb);
119 goto error; 121 if (err)
122 goto error;
120 123
121 xfrm4_encap(skb); 124 xfrm4_encap(skb);
122 125
123 err = x->type->output(x, skb); 126 err = x->type->output(x, skb);
124 if (err) 127 if (err)
125 goto error; 128 goto error;
126 129
127 x->curlft.bytes += skb->len; 130 x->curlft.bytes += skb->len;
128 x->curlft.packets++; 131 x->curlft.packets++;
129 132
130 spin_unlock_bh(&x->lock); 133 spin_unlock_bh(&x->lock);
131 134
132 if (!(skb->dst = dst_pop(dst))) { 135 if (!(skb->dst = dst_pop(dst))) {
133 err = -EHOSTUNREACH; 136 err = -EHOSTUNREACH;
134 goto error_nolock; 137 goto error_nolock;
135 } 138 }
136 err = NET_XMIT_BYPASS; 139 dst = skb->dst;
140 x = dst->xfrm;
141 } while (x && !x->props.mode);
142
143 IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
144 err = 0;
137 145
138out_exit: 146out_exit:
139 return err; 147 return err;
@@ -143,3 +151,33 @@ error_nolock:
143 kfree_skb(skb); 151 kfree_skb(skb);
144 goto out_exit; 152 goto out_exit;
145} 153}
154
155int xfrm4_output_finish(struct sk_buff *skb)
156{
157 int err;
158
159 while (likely((err = xfrm4_output_one(skb)) == 0)) {
160 nf_reset(skb);
161
162 err = nf_hook(PF_INET, NF_IP_LOCAL_OUT, &skb, NULL,
163 skb->dst->dev, dst_output);
164 if (unlikely(err != 1))
165 break;
166
167 if (!skb->dst->xfrm)
168 return dst_output(skb);
169
170 err = nf_hook(PF_INET, NF_IP_POST_ROUTING, &skb, NULL,
171 skb->dst->dev, xfrm4_output_finish);
172 if (unlikely(err != 1))
173 break;
174 }
175
176 return err;
177}
178
179int xfrm4_output(struct sk_buff *skb)
180{
181 return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev,
182 xfrm4_output_finish);
183}
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 704fb73e6c5f..e53e421eeee9 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1228,7 +1228,7 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
1228 1228
1229/* Gets referenced address, destroys ifaddr */ 1229/* Gets referenced address, destroys ifaddr */
1230 1230
1231void addrconf_dad_stop(struct inet6_ifaddr *ifp) 1231static void addrconf_dad_stop(struct inet6_ifaddr *ifp)
1232{ 1232{
1233 if (ifp->flags&IFA_F_PERMANENT) { 1233 if (ifp->flags&IFA_F_PERMANENT) {
1234 spin_lock_bh(&ifp->lock); 1234 spin_lock_bh(&ifp->lock);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 68afc53be662..25c3fe5005d9 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -689,11 +689,11 @@ snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign)
689 if (ptr == NULL) 689 if (ptr == NULL)
690 return -EINVAL; 690 return -EINVAL;
691 691
692 ptr[0] = __alloc_percpu(mibsize, mibalign); 692 ptr[0] = __alloc_percpu(mibsize);
693 if (!ptr[0]) 693 if (!ptr[0])
694 goto err0; 694 goto err0;
695 695
696 ptr[1] = __alloc_percpu(mibsize, mibalign); 696 ptr[1] = __alloc_percpu(mibsize);
697 if (!ptr[1]) 697 if (!ptr[1])
698 goto err1; 698 goto err1;
699 699
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 113374dc342c..2a1e7e45b890 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -152,7 +152,7 @@ static struct tlvtype_proc tlvprocdestopt_lst[] = {
152 {-1, NULL} 152 {-1, NULL}
153}; 153};
154 154
155static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp) 155static int ipv6_destopt_rcv(struct sk_buff **skbp)
156{ 156{
157 struct sk_buff *skb = *skbp; 157 struct sk_buff *skb = *skbp;
158 struct inet6_skb_parm *opt = IP6CB(skb); 158 struct inet6_skb_parm *opt = IP6CB(skb);
@@ -169,7 +169,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
169 169
170 if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { 170 if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
171 skb->h.raw += ((skb->h.raw[1]+1)<<3); 171 skb->h.raw += ((skb->h.raw[1]+1)<<3);
172 *nhoffp = opt->dst1; 172 opt->nhoff = opt->dst1;
173 return 1; 173 return 1;
174 } 174 }
175 175
@@ -192,7 +192,7 @@ void __init ipv6_destopt_init(void)
192 NONE header. No data in packet. 192 NONE header. No data in packet.
193 ********************************/ 193 ********************************/
194 194
195static int ipv6_nodata_rcv(struct sk_buff **skbp, unsigned int *nhoffp) 195static int ipv6_nodata_rcv(struct sk_buff **skbp)
196{ 196{
197 struct sk_buff *skb = *skbp; 197 struct sk_buff *skb = *skbp;
198 198
@@ -215,7 +215,7 @@ void __init ipv6_nodata_init(void)
215 Routing header. 215 Routing header.
216 ********************************/ 216 ********************************/
217 217
218static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp) 218static int ipv6_rthdr_rcv(struct sk_buff **skbp)
219{ 219{
220 struct sk_buff *skb = *skbp; 220 struct sk_buff *skb = *skbp;
221 struct inet6_skb_parm *opt = IP6CB(skb); 221 struct inet6_skb_parm *opt = IP6CB(skb);
@@ -249,7 +249,7 @@ looped_back:
249 skb->h.raw += (hdr->hdrlen + 1) << 3; 249 skb->h.raw += (hdr->hdrlen + 1) << 3;
250 opt->dst0 = opt->dst1; 250 opt->dst0 = opt->dst1;
251 opt->dst1 = 0; 251 opt->dst1 = 0;
252 *nhoffp = (&hdr->nexthdr) - skb->nh.raw; 252 opt->nhoff = (&hdr->nexthdr) - skb->nh.raw;
253 return 1; 253 return 1;
254 } 254 }
255 255
@@ -487,9 +487,14 @@ static struct tlvtype_proc tlvprochopopt_lst[] = {
487 487
488int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff) 488int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff)
489{ 489{
490 IP6CB(skb)->hop = sizeof(struct ipv6hdr); 490 struct inet6_skb_parm *opt = IP6CB(skb);
491 if (ip6_parse_tlv(tlvprochopopt_lst, skb)) 491
492 opt->hop = sizeof(struct ipv6hdr);
493 if (ip6_parse_tlv(tlvprochopopt_lst, skb)) {
494 skb->h.raw += (skb->h.raw[1]+1)<<3;
495 opt->nhoff = sizeof(struct ipv6hdr);
492 return sizeof(struct ipv6hdr); 496 return sizeof(struct ipv6hdr);
497 }
493 return -1; 498 return -1;
494} 499}
495 500
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 6ec6a2b549bb..53c81fcd20ba 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -79,7 +79,7 @@ DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics) __read_mostly;
79static DEFINE_PER_CPU(struct socket *, __icmpv6_socket) = NULL; 79static DEFINE_PER_CPU(struct socket *, __icmpv6_socket) = NULL;
80#define icmpv6_socket __get_cpu_var(__icmpv6_socket) 80#define icmpv6_socket __get_cpu_var(__icmpv6_socket)
81 81
82static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp); 82static int icmpv6_rcv(struct sk_buff **pskb);
83 83
84static struct inet6_protocol icmpv6_protocol = { 84static struct inet6_protocol icmpv6_protocol = {
85 .handler = icmpv6_rcv, 85 .handler = icmpv6_rcv,
@@ -581,7 +581,7 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info)
581 * Handle icmp messages 581 * Handle icmp messages
582 */ 582 */
583 583
584static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) 584static int icmpv6_rcv(struct sk_buff **pskb)
585{ 585{
586 struct sk_buff *skb = *pskb; 586 struct sk_buff *skb = *pskb;
587 struct net_device *dev = skb->dev; 587 struct net_device *dev = skb->dev;
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 792f90f0f9ec..f8f3a37a1494 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -25,6 +25,7 @@
25#include <net/inet_hashtables.h> 25#include <net/inet_hashtables.h>
26#include <net/ip6_route.h> 26#include <net/ip6_route.h>
27#include <net/sock.h> 27#include <net/sock.h>
28#include <net/inet6_connection_sock.h>
28 29
29int inet6_csk_bind_conflict(const struct sock *sk, 30int inet6_csk_bind_conflict(const struct sock *sk,
30 const struct inet_bind_bucket *tb) 31 const struct inet_bind_bucket *tb)
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index a6026d2787d2..29f73592e68e 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -48,7 +48,7 @@
48 48
49 49
50 50
51static inline int ip6_rcv_finish( struct sk_buff *skb) 51inline int ip6_rcv_finish( struct sk_buff *skb)
52{ 52{
53 if (skb->dst == NULL) 53 if (skb->dst == NULL)
54 ip6_route_input(skb); 54 ip6_route_input(skb);
@@ -97,6 +97,9 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
97 if (hdr->version != 6) 97 if (hdr->version != 6)
98 goto err; 98 goto err;
99 99
100 skb->h.raw = (u8 *)(hdr + 1);
101 IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
102
100 pkt_len = ntohs(hdr->payload_len); 103 pkt_len = ntohs(hdr->payload_len);
101 104
102 /* pkt_len may be zero if Jumbo payload option is present */ 105 /* pkt_len may be zero if Jumbo payload option is present */
@@ -111,8 +114,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
111 } 114 }
112 115
113 if (hdr->nexthdr == NEXTHDR_HOP) { 116 if (hdr->nexthdr == NEXTHDR_HOP) {
114 skb->h.raw = (u8*)(hdr+1); 117 if (ipv6_parse_hopopts(skb, IP6CB(skb)->nhoff) < 0) {
115 if (ipv6_parse_hopopts(skb, offsetof(struct ipv6hdr, nexthdr)) < 0) {
116 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 118 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
117 return 0; 119 return 0;
118 } 120 }
@@ -143,26 +145,15 @@ static inline int ip6_input_finish(struct sk_buff *skb)
143 int nexthdr; 145 int nexthdr;
144 u8 hash; 146 u8 hash;
145 147
146 skb->h.raw = skb->nh.raw + sizeof(struct ipv6hdr);
147
148 /* 148 /*
149 * Parse extension headers 149 * Parse extension headers
150 */ 150 */
151 151
152 nexthdr = skb->nh.ipv6h->nexthdr;
153 nhoff = offsetof(struct ipv6hdr, nexthdr);
154
155 /* Skip hop-by-hop options, they are already parsed. */
156 if (nexthdr == NEXTHDR_HOP) {
157 nhoff = sizeof(struct ipv6hdr);
158 nexthdr = skb->h.raw[0];
159 skb->h.raw += (skb->h.raw[1]+1)<<3;
160 }
161
162 rcu_read_lock(); 152 rcu_read_lock();
163resubmit: 153resubmit:
164 if (!pskb_pull(skb, skb->h.raw - skb->data)) 154 if (!pskb_pull(skb, skb->h.raw - skb->data))
165 goto discard; 155 goto discard;
156 nhoff = IP6CB(skb)->nhoff;
166 nexthdr = skb->nh.raw[nhoff]; 157 nexthdr = skb->nh.raw[nhoff];
167 158
168 raw_sk = sk_head(&raw_v6_htable[nexthdr & (MAX_INET_PROTOS - 1)]); 159 raw_sk = sk_head(&raw_v6_htable[nexthdr & (MAX_INET_PROTOS - 1)]);
@@ -194,7 +185,7 @@ resubmit:
194 !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) 185 !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
195 goto discard; 186 goto discard;
196 187
197 ret = ipprot->handler(&skb, &nhoff); 188 ret = ipprot->handler(&skb);
198 if (ret > 0) 189 if (ret > 0)
199 goto resubmit; 190 goto resubmit;
200 else if (ret == 0) 191 else if (ret == 0)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index e315d0f80af1..f079621c8b67 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -510,7 +510,7 @@ static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph,
510 **/ 510 **/
511 511
512static int 512static int
513ip6ip6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) 513ip6ip6_rcv(struct sk_buff **pskb)
514{ 514{
515 struct sk_buff *skb = *pskb; 515 struct sk_buff *skb = *pskb;
516 struct ipv6hdr *ipv6h; 516 struct ipv6hdr *ipv6h;
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index f8626ebf90fd..b63678328a3b 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -10,6 +10,7 @@
10#include <net/dst.h> 10#include <net/dst.h>
11#include <net/ipv6.h> 11#include <net/ipv6.h>
12#include <net/ip6_route.h> 12#include <net/ip6_route.h>
13#include <net/xfrm.h>
13 14
14int ip6_route_me_harder(struct sk_buff *skb) 15int ip6_route_me_harder(struct sk_buff *skb)
15{ 16{
@@ -21,11 +22,17 @@ int ip6_route_me_harder(struct sk_buff *skb)
21 { .ip6_u = 22 { .ip6_u =
22 { .daddr = iph->daddr, 23 { .daddr = iph->daddr,
23 .saddr = iph->saddr, } }, 24 .saddr = iph->saddr, } },
24 .proto = iph->nexthdr,
25 }; 25 };
26 26
27 dst = ip6_route_output(skb->sk, &fl); 27 dst = ip6_route_output(skb->sk, &fl);
28 28
29#ifdef CONFIG_XFRM
30 if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
31 xfrm_decode_session(skb, &fl, AF_INET6) == 0)
32 if (xfrm_lookup(&skb->dst, &fl, skb->sk, 0))
33 return -1;
34#endif
35
29 if (dst->error) { 36 if (dst->error) {
30 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); 37 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES);
31 LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); 38 LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 04912f9b35c3..105dd69ee9fb 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -179,6 +179,16 @@ config IP6_NF_MATCH_PHYSDEV
179 179
180 To compile it as a module, choose M here. If unsure, say N. 180 To compile it as a module, choose M here. If unsure, say N.
181 181
182config IP6_NF_MATCH_POLICY
183 tristate "IPsec policy match support"
184 depends on IP6_NF_IPTABLES && XFRM
185 help
186 Policy matching allows you to match packets based on the
187 IPsec policy that was used during decapsulation/will
188 be used during encapsulation.
189
190 To compile it as a module, choose M here. If unsure, say N.
191
182# The targets 192# The targets
183config IP6_NF_FILTER 193config IP6_NF_FILTER
184 tristate "Packet filtering" 194 tristate "Packet filtering"
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 9ab5b2ca1f59..c0c809b426e8 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
13obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o 13obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
14obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o 14obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o
15obj-$(CONFIG_IP6_NF_MATCH_AHESP) += ip6t_esp.o ip6t_ah.o 15obj-$(CONFIG_IP6_NF_MATCH_AHESP) += ip6t_esp.o ip6t_ah.o
16obj-$(CONFIG_IP6_NF_MATCH_POLICY) += ip6t_policy.o
16obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o 17obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
17obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o 18obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o
18obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o 19obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
diff --git a/net/ipv6/netfilter/ip6t_policy.c b/net/ipv6/netfilter/ip6t_policy.c
new file mode 100644
index 000000000000..13fedad48c1d
--- /dev/null
+++ b/net/ipv6/netfilter/ip6t_policy.c
@@ -0,0 +1,175 @@
1/* IP tables module for matching IPsec policy
2 *
3 * Copyright (c) 2004,2005 Patrick McHardy, <kaber@trash.net>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/kernel.h>
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/skbuff.h>
14#include <linux/init.h>
15#include <net/xfrm.h>
16
17#include <linux/netfilter_ipv6.h>
18#include <linux/netfilter_ipv6/ip6_tables.h>
19#include <linux/netfilter_ipv6/ip6t_policy.h>
20
21MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
22MODULE_DESCRIPTION("IPtables IPsec policy matching module");
23MODULE_LICENSE("GPL");
24
25
26static inline int
27match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e)
28{
29#define MATCH_ADDR(x,y,z) (!e->match.x || \
30 ((ip6_masked_addrcmp((z), &e->x, &e->y)) == 0) ^ e->invert.x)
31#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x))
32
33 return MATCH_ADDR(saddr, smask, (struct in6_addr *)&x->props.saddr.a6) &&
34 MATCH_ADDR(daddr, dmask, (struct in6_addr *)&x->id.daddr.a6) &&
35 MATCH(proto, x->id.proto) &&
36 MATCH(mode, x->props.mode) &&
37 MATCH(spi, x->id.spi) &&
38 MATCH(reqid, x->props.reqid);
39}
40
41static int
42match_policy_in(const struct sk_buff *skb, const struct ip6t_policy_info *info)
43{
44 const struct ip6t_policy_elem *e;
45 struct sec_path *sp = skb->sp;
46 int strict = info->flags & IP6T_POLICY_MATCH_STRICT;
47 int i, pos;
48
49 if (sp == NULL)
50 return -1;
51 if (strict && info->len != sp->len)
52 return 0;
53
54 for (i = sp->len - 1; i >= 0; i--) {
55 pos = strict ? i - sp->len + 1 : 0;
56 if (pos >= info->len)
57 return 0;
58 e = &info->pol[pos];
59
60 if (match_xfrm_state(sp->x[i].xvec, e)) {
61 if (!strict)
62 return 1;
63 } else if (strict)
64 return 0;
65 }
66
67 return strict ? 1 : 0;
68}
69
70static int
71match_policy_out(const struct sk_buff *skb, const struct ip6t_policy_info *info)
72{
73 const struct ip6t_policy_elem *e;
74 struct dst_entry *dst = skb->dst;
75 int strict = info->flags & IP6T_POLICY_MATCH_STRICT;
76 int i, pos;
77
78 if (dst->xfrm == NULL)
79 return -1;
80
81 for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
82 pos = strict ? i : 0;
83 if (pos >= info->len)
84 return 0;
85 e = &info->pol[pos];
86
87 if (match_xfrm_state(dst->xfrm, e)) {
88 if (!strict)
89 return 1;
90 } else if (strict)
91 return 0;
92 }
93
94 return strict ? 1 : 0;
95}
96
97static int match(const struct sk_buff *skb,
98 const struct net_device *in,
99 const struct net_device *out,
100 const void *matchinfo,
101 int offset,
102 unsigned int protoff,
103 int *hotdrop)
104{
105 const struct ip6t_policy_info *info = matchinfo;
106 int ret;
107
108 if (info->flags & IP6T_POLICY_MATCH_IN)
109 ret = match_policy_in(skb, info);
110 else
111 ret = match_policy_out(skb, info);
112
113 if (ret < 0)
114 ret = info->flags & IP6T_POLICY_MATCH_NONE ? 1 : 0;
115 else if (info->flags & IP6T_POLICY_MATCH_NONE)
116 ret = 0;
117
118 return ret;
119}
120
121static int checkentry(const char *tablename, const struct ip6t_ip6 *ip,
122 void *matchinfo, unsigned int matchsize,
123 unsigned int hook_mask)
124{
125 struct ip6t_policy_info *info = matchinfo;
126
127 if (matchsize != IP6T_ALIGN(sizeof(*info))) {
128 printk(KERN_ERR "ip6t_policy: matchsize %u != %zu\n",
129 matchsize, IP6T_ALIGN(sizeof(*info)));
130 return 0;
131 }
132 if (!(info->flags & (IP6T_POLICY_MATCH_IN|IP6T_POLICY_MATCH_OUT))) {
133 printk(KERN_ERR "ip6t_policy: neither incoming nor "
134 "outgoing policy selected\n");
135 return 0;
136 }
137 if (hook_mask & (1 << NF_IP6_PRE_ROUTING | 1 << NF_IP6_LOCAL_IN)
138 && info->flags & IP6T_POLICY_MATCH_OUT) {
139 printk(KERN_ERR "ip6t_policy: output policy not valid in "
140 "PRE_ROUTING and INPUT\n");
141 return 0;
142 }
143 if (hook_mask & (1 << NF_IP6_POST_ROUTING | 1 << NF_IP6_LOCAL_OUT)
144 && info->flags & IP6T_POLICY_MATCH_IN) {
145 printk(KERN_ERR "ip6t_policy: input policy not valid in "
146 "POST_ROUTING and OUTPUT\n");
147 return 0;
148 }
149 if (info->len > IP6T_POLICY_MAX_ELEM) {
150 printk(KERN_ERR "ip6t_policy: too many policy elements\n");
151 return 0;
152 }
153
154 return 1;
155}
156
157static struct ip6t_match policy_match = {
158 .name = "policy",
159 .match = match,
160 .checkentry = checkentry,
161 .me = THIS_MODULE,
162};
163
164static int __init init(void)
165{
166 return ip6t_register_match(&policy_match);
167}
168
169static void __exit fini(void)
170{
171 ip6t_unregister_match(&policy_match);
172}
173
174module_init(init);
175module_exit(fini);
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 5d316cb72ec9..15e1456b3f18 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -581,7 +581,6 @@ err:
581 * the last and the first frames arrived and all the bits are here. 581 * the last and the first frames arrived and all the bits are here.
582 */ 582 */
583static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in, 583static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
584 unsigned int *nhoffp,
585 struct net_device *dev) 584 struct net_device *dev)
586{ 585{
587 struct sk_buff *fp, *head = fq->fragments; 586 struct sk_buff *fp, *head = fq->fragments;
@@ -654,6 +653,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
654 head->dev = dev; 653 head->dev = dev;
655 skb_set_timestamp(head, &fq->stamp); 654 skb_set_timestamp(head, &fq->stamp);
656 head->nh.ipv6h->payload_len = htons(payload_len); 655 head->nh.ipv6h->payload_len = htons(payload_len);
656 IP6CB(head)->nhoff = nhoff;
657 657
658 *skb_in = head; 658 *skb_in = head;
659 659
@@ -663,7 +663,6 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
663 663
664 IP6_INC_STATS_BH(IPSTATS_MIB_REASMOKS); 664 IP6_INC_STATS_BH(IPSTATS_MIB_REASMOKS);
665 fq->fragments = NULL; 665 fq->fragments = NULL;
666 *nhoffp = nhoff;
667 return 1; 666 return 1;
668 667
669out_oversize: 668out_oversize:
@@ -678,7 +677,7 @@ out_fail:
678 return -1; 677 return -1;
679} 678}
680 679
681static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp) 680static int ipv6_frag_rcv(struct sk_buff **skbp)
682{ 681{
683 struct sk_buff *skb = *skbp; 682 struct sk_buff *skb = *skbp;
684 struct net_device *dev = skb->dev; 683 struct net_device *dev = skb->dev;
@@ -710,7 +709,7 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
710 skb->h.raw += sizeof(struct frag_hdr); 709 skb->h.raw += sizeof(struct frag_hdr);
711 IP6_INC_STATS_BH(IPSTATS_MIB_REASMOKS); 710 IP6_INC_STATS_BH(IPSTATS_MIB_REASMOKS);
712 711
713 *nhoffp = (u8*)fhdr - skb->nh.raw; 712 IP6CB(skb)->nhoff = (u8*)fhdr - skb->nh.raw;
714 return 1; 713 return 1;
715 } 714 }
716 715
@@ -722,11 +721,11 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
722 721
723 spin_lock(&fq->lock); 722 spin_lock(&fq->lock);
724 723
725 ip6_frag_queue(fq, skb, fhdr, *nhoffp); 724 ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff);
726 725
727 if (fq->last_in == (FIRST_IN|LAST_IN) && 726 if (fq->last_in == (FIRST_IN|LAST_IN) &&
728 fq->meat == fq->len) 727 fq->meat == fq->len)
729 ret = ip6_frag_reasm(fq, skbp, nhoffp, dev); 728 ret = ip6_frag_reasm(fq, skbp, dev);
730 729
731 spin_unlock(&fq->lock); 730 spin_unlock(&fq->lock);
732 fq_put(fq, NULL); 731 fq_put(fq, NULL);
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 577d49732b0f..02872ae8a439 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -381,6 +381,7 @@ static int ipip6_rcv(struct sk_buff *skb)
381 skb->mac.raw = skb->nh.raw; 381 skb->mac.raw = skb->nh.raw;
382 skb->nh.raw = skb->data; 382 skb->nh.raw = skb->data;
383 memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); 383 memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
384 IPCB(skb)->flags = 0;
384 skb->protocol = htons(ETH_P_IPV6); 385 skb->protocol = htons(ETH_P_IPV6);
385 skb->pkt_type = PACKET_HOST; 386 skb->pkt_type = PACKET_HOST;
386 tunnel->stat.rx_packets++; 387 tunnel->stat.rx_packets++;
@@ -552,6 +553,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
552 skb->h.raw = skb->nh.raw; 553 skb->h.raw = skb->nh.raw;
553 skb->nh.raw = skb_push(skb, sizeof(struct iphdr)); 554 skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
554 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 555 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
556 IPCB(skb)->flags = 0;
555 dst_release(skb->dst); 557 dst_release(skb->dst);
556 skb->dst = &rt->u.dst; 558 skb->dst = &rt->u.dst;
557 559
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 2947bc56d8a0..a25f4e8a8ada 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1153,7 +1153,7 @@ ipv6_pktoptions:
1153 return 0; 1153 return 0;
1154} 1154}
1155 1155
1156static int tcp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) 1156static int tcp_v6_rcv(struct sk_buff **pskb)
1157{ 1157{
1158 struct sk_buff *skb = *pskb; 1158 struct sk_buff *skb = *pskb;
1159 struct tcphdr *th; 1159 struct tcphdr *th;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index d8538dcea813..c47648892c04 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -435,7 +435,7 @@ out:
435 read_unlock(&udp_hash_lock); 435 read_unlock(&udp_hash_lock);
436} 436}
437 437
438static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) 438static int udpv6_rcv(struct sk_buff **pskb)
439{ 439{
440 struct sk_buff *skb = *pskb; 440 struct sk_buff *skb = *pskb;
441 struct sock *sk; 441 struct sock *sk;
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 28c29d78338e..1ca2da68ef69 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -11,6 +11,8 @@
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/string.h> 13#include <linux/string.h>
14#include <linux/netfilter.h>
15#include <linux/netfilter_ipv6.h>
14#include <net/dsfield.h> 16#include <net/dsfield.h>
15#include <net/inet_ecn.h> 17#include <net/inet_ecn.h>
16#include <net/ip.h> 18#include <net/ip.h>
@@ -26,7 +28,7 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
26 IP6_ECN_set_ce(inner_iph); 28 IP6_ECN_set_ce(inner_iph);
27} 29}
28 30
29int xfrm6_rcv_spi(struct sk_buff **pskb, unsigned int *nhoffp, u32 spi) 31int xfrm6_rcv_spi(struct sk_buff **pskb, u32 spi)
30{ 32{
31 struct sk_buff *skb = *pskb; 33 struct sk_buff *skb = *pskb;
32 int err; 34 int err;
@@ -38,7 +40,7 @@ int xfrm6_rcv_spi(struct sk_buff **pskb, unsigned int *nhoffp, u32 spi)
38 int nexthdr; 40 int nexthdr;
39 unsigned int nhoff; 41 unsigned int nhoff;
40 42
41 nhoff = *nhoffp; 43 nhoff = IP6CB(skb)->nhoff;
42 nexthdr = skb->nh.raw[nhoff]; 44 nexthdr = skb->nh.raw[nhoff];
43 45
44 seq = 0; 46 seq = 0;
@@ -121,6 +123,8 @@ int xfrm6_rcv_spi(struct sk_buff **pskb, unsigned int *nhoffp, u32 spi)
121 skb->sp->len += xfrm_nr; 123 skb->sp->len += xfrm_nr;
122 skb->ip_summed = CHECKSUM_NONE; 124 skb->ip_summed = CHECKSUM_NONE;
123 125
126 nf_reset(skb);
127
124 if (decaps) { 128 if (decaps) {
125 if (!(skb->dev->flags&IFF_LOOPBACK)) { 129 if (!(skb->dev->flags&IFF_LOOPBACK)) {
126 dst_release(skb->dst); 130 dst_release(skb->dst);
@@ -129,7 +133,16 @@ int xfrm6_rcv_spi(struct sk_buff **pskb, unsigned int *nhoffp, u32 spi)
129 netif_rx(skb); 133 netif_rx(skb);
130 return -1; 134 return -1;
131 } else { 135 } else {
136#ifdef CONFIG_NETFILTER
137 skb->nh.ipv6h->payload_len = htons(skb->len);
138 __skb_push(skb, skb->data - skb->nh.raw);
139
140 NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
141 ip6_rcv_finish);
142 return -1;
143#else
132 return 1; 144 return 1;
145#endif
133 } 146 }
134 147
135drop_unlock: 148drop_unlock:
@@ -144,7 +157,7 @@ drop:
144 157
145EXPORT_SYMBOL(xfrm6_rcv_spi); 158EXPORT_SYMBOL(xfrm6_rcv_spi);
146 159
147int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) 160int xfrm6_rcv(struct sk_buff **pskb)
148{ 161{
149 return xfrm6_rcv_spi(pskb, nhoffp, 0); 162 return xfrm6_rcv_spi(pskb, 0);
150} 163}
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 6b9867717d11..80242172a5df 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -9,9 +9,11 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 11
12#include <linux/compiler.h>
12#include <linux/skbuff.h> 13#include <linux/skbuff.h>
13#include <linux/spinlock.h> 14#include <linux/spinlock.h>
14#include <linux/icmpv6.h> 15#include <linux/icmpv6.h>
16#include <linux/netfilter_ipv6.h>
15#include <net/dsfield.h> 17#include <net/dsfield.h>
16#include <net/inet_ecn.h> 18#include <net/inet_ecn.h>
17#include <net/ipv6.h> 19#include <net/ipv6.h>
@@ -92,7 +94,7 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb)
92 return ret; 94 return ret;
93} 95}
94 96
95int xfrm6_output(struct sk_buff *skb) 97static int xfrm6_output_one(struct sk_buff *skb)
96{ 98{
97 struct dst_entry *dst = skb->dst; 99 struct dst_entry *dst = skb->dst;
98 struct xfrm_state *x = dst->xfrm; 100 struct xfrm_state *x = dst->xfrm;
@@ -110,29 +112,35 @@ int xfrm6_output(struct sk_buff *skb)
110 goto error_nolock; 112 goto error_nolock;
111 } 113 }
112 114
113 spin_lock_bh(&x->lock); 115 do {
114 err = xfrm_state_check(x, skb); 116 spin_lock_bh(&x->lock);
115 if (err) 117 err = xfrm_state_check(x, skb);
116 goto error; 118 if (err)
119 goto error;
117 120
118 xfrm6_encap(skb); 121 xfrm6_encap(skb);
119 122
120 err = x->type->output(x, skb); 123 err = x->type->output(x, skb);
121 if (err) 124 if (err)
122 goto error; 125 goto error;
123 126
124 x->curlft.bytes += skb->len; 127 x->curlft.bytes += skb->len;
125 x->curlft.packets++; 128 x->curlft.packets++;
126 129
127 spin_unlock_bh(&x->lock); 130 spin_unlock_bh(&x->lock);
128 131
129 skb->nh.raw = skb->data; 132 skb->nh.raw = skb->data;
130 133
131 if (!(skb->dst = dst_pop(dst))) { 134 if (!(skb->dst = dst_pop(dst))) {
132 err = -EHOSTUNREACH; 135 err = -EHOSTUNREACH;
133 goto error_nolock; 136 goto error_nolock;
134 } 137 }
135 err = NET_XMIT_BYPASS; 138 dst = skb->dst;
139 x = dst->xfrm;
140 } while (x && !x->props.mode);
141
142 IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
143 err = 0;
136 144
137out_exit: 145out_exit:
138 return err; 146 return err;
@@ -142,3 +150,33 @@ error_nolock:
142 kfree_skb(skb); 150 kfree_skb(skb);
143 goto out_exit; 151 goto out_exit;
144} 152}
153
154static int xfrm6_output_finish(struct sk_buff *skb)
155{
156 int err;
157
158 while (likely((err = xfrm6_output_one(skb)) == 0)) {
159 nf_reset(skb);
160
161 err = nf_hook(PF_INET6, NF_IP6_LOCAL_OUT, &skb, NULL,
162 skb->dst->dev, dst_output);
163 if (unlikely(err != 1))
164 break;
165
166 if (!skb->dst->xfrm)
167 return dst_output(skb);
168
169 err = nf_hook(PF_INET6, NF_IP6_POST_ROUTING, &skb, NULL,
170 skb->dst->dev, xfrm6_output_finish);
171 if (unlikely(err != 1))
172 break;
173 }
174
175 return err;
176}
177
178int xfrm6_output(struct sk_buff *skb)
179{
180 return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dst->dev,
181 xfrm6_output_finish);
182}
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index fbef7826a74f..da09ff258648 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -397,7 +397,7 @@ int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler)
397 397
398EXPORT_SYMBOL(xfrm6_tunnel_deregister); 398EXPORT_SYMBOL(xfrm6_tunnel_deregister);
399 399
400static int xfrm6_tunnel_rcv(struct sk_buff **pskb, unsigned int *nhoffp) 400static int xfrm6_tunnel_rcv(struct sk_buff **pskb)
401{ 401{
402 struct sk_buff *skb = *pskb; 402 struct sk_buff *skb = *pskb;
403 struct xfrm6_tunnel *handler = xfrm6_tunnel_handler; 403 struct xfrm6_tunnel *handler = xfrm6_tunnel_handler;
@@ -405,11 +405,11 @@ static int xfrm6_tunnel_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
405 u32 spi; 405 u32 spi;
406 406
407 /* device-like_ip6ip6_handler() */ 407 /* device-like_ip6ip6_handler() */
408 if (handler && handler->handler(pskb, nhoffp) == 0) 408 if (handler && handler->handler(pskb) == 0)
409 return 0; 409 return 0;
410 410
411 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr); 411 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
412 return xfrm6_rcv_spi(pskb, nhoffp, spi); 412 return xfrm6_rcv_spi(pskb, spi);
413} 413}
414 414
415static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 415static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 7849cac14d3a..a67f1b44c9a3 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -402,7 +402,7 @@ static int netlink_create(struct socket *sock, int protocol)
402 groups = nl_table[protocol].groups; 402 groups = nl_table[protocol].groups;
403 netlink_unlock_table(); 403 netlink_unlock_table();
404 404
405 if ((err = __netlink_create(sock, protocol) < 0)) 405 if ((err = __netlink_create(sock, protocol)) < 0)
406 goto out_module; 406 goto out_module;
407 407
408 nlk = nlk_sk(sock->sk); 408 nlk = nlk_sk(sock->sk);
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 238f1bffa684..4aa6fc60357c 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -225,6 +225,7 @@ int sctp_rcv(struct sk_buff *skb)
225 225
226 if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family)) 226 if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family))
227 goto discard_release; 227 goto discard_release;
228 nf_reset(skb);
228 229
229 ret = sk_filter(sk, skb, 1); 230 ret = sk_filter(sk, skb, 1);
230 if (ret) 231 if (ret)
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 15c05165c905..04c7fab4edc4 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -905,7 +905,7 @@ static struct inet_protosw sctpv6_stream_protosw = {
905 .flags = SCTP_PROTOSW_FLAG, 905 .flags = SCTP_PROTOSW_FLAG,
906}; 906};
907 907
908static int sctp6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) 908static int sctp6_rcv(struct sk_buff **pskb)
909{ 909{
910 return sctp_rcv(*pskb) ? -1 : 0; 910 return sctp_rcv(*pskb) ? -1 : 0;
911} 911}
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 24cc23af9b95..e14c1cae7460 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -495,7 +495,7 @@ rpc_depopulate(struct dentry *parent)
495repeat: 495repeat:
496 spin_lock(&dcache_lock); 496 spin_lock(&dcache_lock);
497 list_for_each_safe(pos, next, &parent->d_subdirs) { 497 list_for_each_safe(pos, next, &parent->d_subdirs) {
498 dentry = list_entry(pos, struct dentry, d_child); 498 dentry = list_entry(pos, struct dentry, d_u.d_child);
499 spin_lock(&dentry->d_lock); 499 spin_lock(&dentry->d_lock);
500 if (!d_unhashed(dentry)) { 500 if (!d_unhashed(dentry)) {
501 dget_locked(dentry); 501 dget_locked(dentry);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 64a447375fdb..59614a994b4e 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -22,6 +22,7 @@
22#include <linux/workqueue.h> 22#include <linux/workqueue.h>
23#include <linux/notifier.h> 23#include <linux/notifier.h>
24#include <linux/netdevice.h> 24#include <linux/netdevice.h>
25#include <linux/netfilter.h>
25#include <linux/module.h> 26#include <linux/module.h>
26#include <net/xfrm.h> 27#include <net/xfrm.h>
27#include <net/ip.h> 28#include <net/ip.h>
@@ -951,8 +952,8 @@ xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int start,
951 return start; 952 return start;
952} 953}
953 954
954static int 955int
955_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family) 956xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family)
956{ 957{
957 struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family); 958 struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
958 959
@@ -963,6 +964,7 @@ _decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family)
963 xfrm_policy_put_afinfo(afinfo); 964 xfrm_policy_put_afinfo(afinfo);
964 return 0; 965 return 0;
965} 966}
967EXPORT_SYMBOL(xfrm_decode_session);
966 968
967static inline int secpath_has_tunnel(struct sec_path *sp, int k) 969static inline int secpath_has_tunnel(struct sec_path *sp, int k)
968{ 970{
@@ -982,8 +984,9 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
982 u8 fl_dir = policy_to_flow_dir(dir); 984 u8 fl_dir = policy_to_flow_dir(dir);
983 u32 sk_sid; 985 u32 sk_sid;
984 986
985 if (_decode_session(skb, &fl, family) < 0) 987 if (xfrm_decode_session(skb, &fl, family) < 0)
986 return 0; 988 return 0;
989 nf_nat_decode_session(skb, &fl, family);
987 990
988 sk_sid = security_sk_sid(sk, &fl, fl_dir); 991 sk_sid = security_sk_sid(sk, &fl, fl_dir);
989 992
@@ -1055,7 +1058,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
1055{ 1058{
1056 struct flowi fl; 1059 struct flowi fl;
1057 1060
1058 if (_decode_session(skb, &fl, family) < 0) 1061 if (xfrm_decode_session(skb, &fl, family) < 0)
1059 return 0; 1062 return 0;
1060 1063
1061 return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0; 1064 return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0;
diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter
new file mode 100644
index 000000000000..75f21d843c1d
--- /dev/null
+++ b/scripts/bloat-o-meter
@@ -0,0 +1,58 @@
1#!/usr/bin/python
2#
3# Copyright 2004 Matt Mackall <mpm@selenic.com>
4#
5# inspired by perl Bloat-O-Meter (c) 1997 by Andi Kleen
6#
7# This software may be used and distributed according to the terms
8# of the GNU General Public License, incorporated herein by reference.
9
10import sys, os, re
11
12if len(sys.argv) != 3:
13 sys.stderr.write("usage: %s file1 file2\n" % sys.argv[0])
14 sys.exit(-1)
15
16def getsizes(file):
17 sym = {}
18 for l in os.popen("nm --size-sort " + file).readlines():
19 size, type, name = l[:-1].split()
20 if type in "tTdDbB":
21 sym[name] = int(size, 16)
22 return sym
23
24old = getsizes(sys.argv[1])
25new = getsizes(sys.argv[2])
26grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
27delta, common = [], {}
28
29for a in old:
30 if a in new:
31 common[a] = 1
32
33for name in old:
34 if name not in common:
35 remove += 1
36 down += old[name]
37 delta.append((-old[name], name))
38
39for name in new:
40 if name not in common:
41 add += 1
42 up += new[name]
43 delta.append((new[name], name))
44
45for name in common:
46 d = new.get(name, 0) - old.get(name, 0)
47 if d>0: grow, up = grow+1, up+d
48 if d<0: shrink, down = shrink+1, down-d
49 delta.append((d, name))
50
51delta.sort()
52delta.reverse()
53
54print "add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \
55 (add, remove, grow, shrink, up, -down, up-down)
56print "%-40s %7s %7s %+7s" % ("function", "old", "new", "delta")
57for d, n in delta:
58 if d: print "%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d)
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 8ba5d29d3d42..10eeae53d827 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -63,6 +63,20 @@ static void check_stdin(void)
63 } 63 }
64} 64}
65 65
66static char *fgets_check_stream(char *s, int size, FILE *stream)
67{
68 char *ret = fgets(s, size, stream);
69
70 if (ret == NULL && feof(stream)) {
71 printf(_("aborted!\n\n"));
72 printf(_("Console input is closed. "));
73 printf(_("Run 'make oldconfig' to update configuration.\n\n"));
74 exit(1);
75 }
76
77 return ret;
78}
79
66static void conf_askvalue(struct symbol *sym, const char *def) 80static void conf_askvalue(struct symbol *sym, const char *def)
67{ 81{
68 enum symbol_type type = sym_get_type(sym); 82 enum symbol_type type = sym_get_type(sym);
@@ -100,7 +114,7 @@ static void conf_askvalue(struct symbol *sym, const char *def)
100 check_stdin(); 114 check_stdin();
101 case ask_all: 115 case ask_all:
102 fflush(stdout); 116 fflush(stdout);
103 fgets(line, 128, stdin); 117 fgets_check_stream(line, 128, stdin);
104 return; 118 return;
105 case set_default: 119 case set_default:
106 printf("%s\n", def); 120 printf("%s\n", def);
@@ -356,7 +370,7 @@ static int conf_choice(struct menu *menu)
356 check_stdin(); 370 check_stdin();
357 case ask_all: 371 case ask_all:
358 fflush(stdout); 372 fflush(stdout);
359 fgets(line, 128, stdin); 373 fgets_check_stream(line, 128, stdin);
360 strip(line); 374 strip(line);
361 if (line[0] == '?') { 375 if (line[0] == '?') {
362 printf("\n%s\n", menu->sym->help ? 376 printf("\n%s\n", menu->sym->help ?
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index 7c03927d4c7c..e52f3e90bf0c 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -22,8 +22,8 @@ public:
22 22
23#if QT_VERSION >= 300 23#if QT_VERSION >= 300
24 void readListSettings(); 24 void readListSettings();
25 QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok); 25 QValueList<int> readSizes(const QString& key, bool *ok);
26 bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value); 26 bool writeSizes(const QString& key, const QValueList<int>& value);
27#endif 27#endif
28 28
29 bool showAll; 29 bool showAll;
@@ -124,7 +124,7 @@ public:
124 void setParentMenu(void); 124 void setParentMenu(void);
125 125
126 template <class P> 126 template <class P>
127 void ConfigList::updateMenuList(P*, struct menu*); 127 void updateMenuList(P*, struct menu*);
128 128
129 bool updateAll; 129 bool updateAll;
130 130
diff --git a/security/keys/compat.c b/security/keys/compat.c
index 3303673c636e..bcdb28533733 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -74,6 +74,12 @@ asmlinkage long compat_sys_keyctl(u32 option,
74 case KEYCTL_SET_REQKEY_KEYRING: 74 case KEYCTL_SET_REQKEY_KEYRING:
75 return keyctl_set_reqkey_keyring(arg2); 75 return keyctl_set_reqkey_keyring(arg2);
76 76
77 case KEYCTL_SET_TIMEOUT:
78 return keyctl_set_timeout(arg2, arg3);
79
80 case KEYCTL_ASSUME_AUTHORITY:
81 return keyctl_assume_authority(arg2);
82
77 default: 83 default:
78 return -EOPNOTSUPP; 84 return -EOPNOTSUPP;
79 } 85 }
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 39cba97c5eb9..e066e6057955 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -107,12 +107,13 @@ extern struct key *request_key_and_link(struct key_type *type,
107struct request_key_auth { 107struct request_key_auth {
108 struct key *target_key; 108 struct key *target_key;
109 struct task_struct *context; 109 struct task_struct *context;
110 const char *callout_info;
110 pid_t pid; 111 pid_t pid;
111}; 112};
112 113
113extern struct key_type key_type_request_key_auth; 114extern struct key_type key_type_request_key_auth;
114extern struct key *request_key_auth_new(struct key *target, 115extern struct key *request_key_auth_new(struct key *target,
115 struct key **_rkakey); 116 const char *callout_info);
116 117
117extern struct key *key_get_instantiation_authkey(key_serial_t target_id); 118extern struct key *key_get_instantiation_authkey(key_serial_t target_id);
118 119
@@ -136,6 +137,8 @@ extern long keyctl_instantiate_key(key_serial_t, const void __user *,
136 size_t, key_serial_t); 137 size_t, key_serial_t);
137extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t); 138extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t);
138extern long keyctl_set_reqkey_keyring(int); 139extern long keyctl_set_reqkey_keyring(int);
140extern long keyctl_set_timeout(key_serial_t, unsigned);
141extern long keyctl_assume_authority(key_serial_t);
139 142
140 143
141/* 144/*
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index b7a468fabdf9..3d2ebae029c1 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -834,6 +834,17 @@ long keyctl_instantiate_key(key_serial_t id,
834 if (plen > 32767) 834 if (plen > 32767)
835 goto error; 835 goto error;
836 836
837 /* the appropriate instantiation authorisation key must have been
838 * assumed before calling this */
839 ret = -EPERM;
840 instkey = current->request_key_auth;
841 if (!instkey)
842 goto error;
843
844 rka = instkey->payload.data;
845 if (rka->target_key->serial != id)
846 goto error;
847
837 /* pull the payload in if one was supplied */ 848 /* pull the payload in if one was supplied */
838 payload = NULL; 849 payload = NULL;
839 850
@@ -848,15 +859,6 @@ long keyctl_instantiate_key(key_serial_t id,
848 goto error2; 859 goto error2;
849 } 860 }
850 861
851 /* find the instantiation authorisation key */
852 instkey = key_get_instantiation_authkey(id);
853 if (IS_ERR(instkey)) {
854 ret = PTR_ERR(instkey);
855 goto error2;
856 }
857
858 rka = instkey->payload.data;
859
860 /* find the destination keyring amongst those belonging to the 862 /* find the destination keyring amongst those belonging to the
861 * requesting task */ 863 * requesting task */
862 keyring_ref = NULL; 864 keyring_ref = NULL;
@@ -865,7 +867,7 @@ long keyctl_instantiate_key(key_serial_t id,
865 KEY_WRITE); 867 KEY_WRITE);
866 if (IS_ERR(keyring_ref)) { 868 if (IS_ERR(keyring_ref)) {
867 ret = PTR_ERR(keyring_ref); 869 ret = PTR_ERR(keyring_ref);
868 goto error3; 870 goto error2;
869 } 871 }
870 } 872 }
871 873
@@ -874,11 +876,17 @@ long keyctl_instantiate_key(key_serial_t id,
874 key_ref_to_ptr(keyring_ref), instkey); 876 key_ref_to_ptr(keyring_ref), instkey);
875 877
876 key_ref_put(keyring_ref); 878 key_ref_put(keyring_ref);
877 error3: 879
878 key_put(instkey); 880 /* discard the assumed authority if it's just been disabled by
879 error2: 881 * instantiation of the key */
882 if (ret == 0) {
883 key_put(current->request_key_auth);
884 current->request_key_auth = NULL;
885 }
886
887error2:
880 kfree(payload); 888 kfree(payload);
881 error: 889error:
882 return ret; 890 return ret;
883 891
884} /* end keyctl_instantiate_key() */ 892} /* end keyctl_instantiate_key() */
@@ -895,14 +903,16 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
895 key_ref_t keyring_ref; 903 key_ref_t keyring_ref;
896 long ret; 904 long ret;
897 905
898 /* find the instantiation authorisation key */ 906 /* the appropriate instantiation authorisation key must have been
899 instkey = key_get_instantiation_authkey(id); 907 * assumed before calling this */
900 if (IS_ERR(instkey)) { 908 ret = -EPERM;
901 ret = PTR_ERR(instkey); 909 instkey = current->request_key_auth;
910 if (!instkey)
902 goto error; 911 goto error;
903 }
904 912
905 rka = instkey->payload.data; 913 rka = instkey->payload.data;
914 if (rka->target_key->serial != id)
915 goto error;
906 916
907 /* find the destination keyring if present (which must also be 917 /* find the destination keyring if present (which must also be
908 * writable) */ 918 * writable) */
@@ -911,7 +921,7 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
911 keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 921 keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
912 if (IS_ERR(keyring_ref)) { 922 if (IS_ERR(keyring_ref)) {
913 ret = PTR_ERR(keyring_ref); 923 ret = PTR_ERR(keyring_ref);
914 goto error2; 924 goto error;
915 } 925 }
916 } 926 }
917 927
@@ -920,9 +930,15 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
920 key_ref_to_ptr(keyring_ref), instkey); 930 key_ref_to_ptr(keyring_ref), instkey);
921 931
922 key_ref_put(keyring_ref); 932 key_ref_put(keyring_ref);
923 error2: 933
924 key_put(instkey); 934 /* discard the assumed authority if it's just been disabled by
925 error: 935 * instantiation of the key */
936 if (ret == 0) {
937 key_put(current->request_key_auth);
938 current->request_key_auth = NULL;
939 }
940
941error:
926 return ret; 942 return ret;
927 943
928} /* end keyctl_negate_key() */ 944} /* end keyctl_negate_key() */
@@ -967,6 +983,88 @@ long keyctl_set_reqkey_keyring(int reqkey_defl)
967 983
968/*****************************************************************************/ 984/*****************************************************************************/
969/* 985/*
986 * set or clear the timeout for a key
987 */
988long keyctl_set_timeout(key_serial_t id, unsigned timeout)
989{
990 struct timespec now;
991 struct key *key;
992 key_ref_t key_ref;
993 time_t expiry;
994 long ret;
995
996 key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
997 if (IS_ERR(key_ref)) {
998 ret = PTR_ERR(key_ref);
999 goto error;
1000 }
1001
1002 key = key_ref_to_ptr(key_ref);
1003
1004 /* make the changes with the locks held to prevent races */
1005 down_write(&key->sem);
1006
1007 expiry = 0;
1008 if (timeout > 0) {
1009 now = current_kernel_time();
1010 expiry = now.tv_sec + timeout;
1011 }
1012
1013 key->expiry = expiry;
1014
1015 up_write(&key->sem);
1016 key_put(key);
1017
1018 ret = 0;
1019error:
1020 return ret;
1021
1022} /* end keyctl_set_timeout() */
1023
1024/*****************************************************************************/
1025/*
1026 * assume the authority to instantiate the specified key
1027 */
1028long keyctl_assume_authority(key_serial_t id)
1029{
1030 struct key *authkey;
1031 long ret;
1032
1033 /* special key IDs aren't permitted */
1034 ret = -EINVAL;
1035 if (id < 0)
1036 goto error;
1037
1038 /* we divest ourselves of authority if given an ID of 0 */
1039 if (id == 0) {
1040 key_put(current->request_key_auth);
1041 current->request_key_auth = NULL;
1042 ret = 0;
1043 goto error;
1044 }
1045
1046 /* attempt to assume the authority temporarily granted to us whilst we
1047 * instantiate the specified key
1048 * - the authorisation key must be in the current task's keyrings
1049 * somewhere
1050 */
1051 authkey = key_get_instantiation_authkey(id);
1052 if (IS_ERR(authkey)) {
1053 ret = PTR_ERR(authkey);
1054 goto error;
1055 }
1056
1057 key_put(current->request_key_auth);
1058 current->request_key_auth = authkey;
1059 ret = authkey->serial;
1060
1061error:
1062 return ret;
1063
1064} /* end keyctl_assume_authority() */
1065
1066/*****************************************************************************/
1067/*
970 * the key control system call 1068 * the key control system call
971 */ 1069 */
972asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, 1070asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
@@ -1038,6 +1136,13 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
1038 case KEYCTL_SET_REQKEY_KEYRING: 1136 case KEYCTL_SET_REQKEY_KEYRING:
1039 return keyctl_set_reqkey_keyring(arg2); 1137 return keyctl_set_reqkey_keyring(arg2);
1040 1138
1139 case KEYCTL_SET_TIMEOUT:
1140 return keyctl_set_timeout((key_serial_t) arg2,
1141 (unsigned) arg3);
1142
1143 case KEYCTL_ASSUME_AUTHORITY:
1144 return keyctl_assume_authority((key_serial_t) arg2);
1145
1041 default: 1146 default:
1042 return -EOPNOTSUPP; 1147 return -EOPNOTSUPP;
1043 } 1148 }
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 5d22c0388b32..d65a180f888d 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -481,51 +481,6 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
481 481
482/*****************************************************************************/ 482/*****************************************************************************/
483/* 483/*
484 * search for an instantiation authorisation key matching a target key
485 * - the RCU read lock must be held by the caller
486 * - a target_id of zero specifies any valid token
487 */
488struct key *keyring_search_instkey(struct key *keyring,
489 key_serial_t target_id)
490{
491 struct request_key_auth *rka;
492 struct keyring_list *klist;
493 struct key *instkey;
494 int loop;
495
496 klist = rcu_dereference(keyring->payload.subscriptions);
497 if (klist) {
498 for (loop = 0; loop < klist->nkeys; loop++) {
499 instkey = klist->keys[loop];
500
501 if (instkey->type != &key_type_request_key_auth)
502 continue;
503
504 rka = instkey->payload.data;
505 if (target_id && rka->target_key->serial != target_id)
506 continue;
507
508 /* the auth key is revoked during instantiation */
509 if (!test_bit(KEY_FLAG_REVOKED, &instkey->flags))
510 goto found;
511
512 instkey = ERR_PTR(-EKEYREVOKED);
513 goto error;
514 }
515 }
516
517 instkey = ERR_PTR(-EACCES);
518 goto error;
519
520found:
521 atomic_inc(&instkey->usage);
522error:
523 return instkey;
524
525} /* end keyring_search_instkey() */
526
527/*****************************************************************************/
528/*
529 * find a keyring with the specified name 484 * find a keyring with the specified name
530 * - all named keyrings are searched 485 * - all named keyrings are searched
531 * - only find keyrings with search permission for the process 486 * - only find keyrings with search permission for the process
@@ -684,15 +639,31 @@ static void keyring_link_rcu_disposal(struct rcu_head *rcu)
684 639
685/*****************************************************************************/ 640/*****************************************************************************/
686/* 641/*
642 * dispose of a keyring list after the RCU grace period, freeing the unlinked
643 * key
644 */
645static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
646{
647 struct keyring_list *klist =
648 container_of(rcu, struct keyring_list, rcu);
649
650 key_put(klist->keys[klist->delkey]);
651 kfree(klist);
652
653} /* end keyring_unlink_rcu_disposal() */
654
655/*****************************************************************************/
656/*
687 * link a key into to a keyring 657 * link a key into to a keyring
688 * - must be called with the keyring's semaphore write-locked 658 * - must be called with the keyring's semaphore write-locked
659 * - discard already extant link to matching key if there is one
689 */ 660 */
690int __key_link(struct key *keyring, struct key *key) 661int __key_link(struct key *keyring, struct key *key)
691{ 662{
692 struct keyring_list *klist, *nklist; 663 struct keyring_list *klist, *nklist;
693 unsigned max; 664 unsigned max;
694 size_t size; 665 size_t size;
695 int ret; 666 int loop, ret;
696 667
697 ret = -EKEYREVOKED; 668 ret = -EKEYREVOKED;
698 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) 669 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
@@ -714,6 +685,48 @@ int __key_link(struct key *keyring, struct key *key)
714 goto error2; 685 goto error2;
715 } 686 }
716 687
688 /* see if there's a matching key we can displace */
689 klist = keyring->payload.subscriptions;
690
691 if (klist && klist->nkeys > 0) {
692 struct key_type *type = key->type;
693
694 for (loop = klist->nkeys - 1; loop >= 0; loop--) {
695 if (klist->keys[loop]->type == type &&
696 strcmp(klist->keys[loop]->description,
697 key->description) == 0
698 ) {
699 /* found a match - replace with new key */
700 size = sizeof(struct key *) * klist->maxkeys;
701 size += sizeof(*klist);
702 BUG_ON(size > PAGE_SIZE);
703
704 ret = -ENOMEM;
705 nklist = kmalloc(size, GFP_KERNEL);
706 if (!nklist)
707 goto error2;
708
709 memcpy(nklist, klist, size);
710
711 /* replace matched key */
712 atomic_inc(&key->usage);
713 nklist->keys[loop] = key;
714
715 rcu_assign_pointer(
716 keyring->payload.subscriptions,
717 nklist);
718
719 /* dispose of the old keyring list and the
720 * displaced key */
721 klist->delkey = loop;
722 call_rcu(&klist->rcu,
723 keyring_unlink_rcu_disposal);
724
725 goto done;
726 }
727 }
728 }
729
717 /* check that we aren't going to overrun the user's quota */ 730 /* check that we aren't going to overrun the user's quota */
718 ret = key_payload_reserve(keyring, 731 ret = key_payload_reserve(keyring,
719 keyring->datalen + KEYQUOTA_LINK_BYTES); 732 keyring->datalen + KEYQUOTA_LINK_BYTES);
@@ -730,8 +743,6 @@ int __key_link(struct key *keyring, struct key *key)
730 smp_wmb(); 743 smp_wmb();
731 klist->nkeys++; 744 klist->nkeys++;
732 smp_wmb(); 745 smp_wmb();
733
734 ret = 0;
735 } 746 }
736 else { 747 else {
737 /* grow the key list */ 748 /* grow the key list */
@@ -769,16 +780,16 @@ int __key_link(struct key *keyring, struct key *key)
769 /* dispose of the old keyring list */ 780 /* dispose of the old keyring list */
770 if (klist) 781 if (klist)
771 call_rcu(&klist->rcu, keyring_link_rcu_disposal); 782 call_rcu(&klist->rcu, keyring_link_rcu_disposal);
772
773 ret = 0;
774 } 783 }
775 784
776 error2: 785done:
786 ret = 0;
787error2:
777 up_write(&keyring_serialise_link_sem); 788 up_write(&keyring_serialise_link_sem);
778 error: 789error:
779 return ret; 790 return ret;
780 791
781 error3: 792error3:
782 /* undo the quota changes */ 793 /* undo the quota changes */
783 key_payload_reserve(keyring, 794 key_payload_reserve(keyring,
784 keyring->datalen - KEYQUOTA_LINK_BYTES); 795 keyring->datalen - KEYQUOTA_LINK_BYTES);
@@ -809,21 +820,6 @@ EXPORT_SYMBOL(key_link);
809 820
810/*****************************************************************************/ 821/*****************************************************************************/
811/* 822/*
812 * dispose of a keyring list after the RCU grace period, freeing the unlinked
813 * key
814 */
815static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
816{
817 struct keyring_list *klist =
818 container_of(rcu, struct keyring_list, rcu);
819
820 key_put(klist->keys[klist->delkey]);
821 kfree(klist);
822
823} /* end keyring_unlink_rcu_disposal() */
824
825/*****************************************************************************/
826/*
827 * unlink the first link to a key from a keyring 823 * unlink the first link to a key from a keyring
828 */ 824 */
829int key_unlink(struct key *keyring, struct key *key) 825int key_unlink(struct key *keyring, struct key *key)
diff --git a/security/keys/permission.c b/security/keys/permission.c
index e7f579c0eaf5..3b41f9b52537 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -73,3 +73,35 @@ use_these_perms:
73} /* end key_task_permission() */ 73} /* end key_task_permission() */
74 74
75EXPORT_SYMBOL(key_task_permission); 75EXPORT_SYMBOL(key_task_permission);
76
77/*****************************************************************************/
78/*
79 * validate a key
80 */
81int key_validate(struct key *key)
82{
83 struct timespec now;
84 int ret = 0;
85
86 if (key) {
87 /* check it's still accessible */
88 ret = -EKEYREVOKED;
89 if (test_bit(KEY_FLAG_REVOKED, &key->flags) ||
90 test_bit(KEY_FLAG_DEAD, &key->flags))
91 goto error;
92
93 /* check it hasn't expired */
94 ret = 0;
95 if (key->expiry) {
96 now = current_kernel_time();
97 if (now.tv_sec >= key->expiry)
98 ret = -EKEYEXPIRED;
99 }
100 }
101
102 error:
103 return ret;
104
105} /* end key_validate() */
106
107EXPORT_SYMBOL(key_validate);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 566b1cc0118a..74cb79eb917e 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -270,9 +270,14 @@ int copy_thread_group_keys(struct task_struct *tsk)
270int copy_keys(unsigned long clone_flags, struct task_struct *tsk) 270int copy_keys(unsigned long clone_flags, struct task_struct *tsk)
271{ 271{
272 key_check(tsk->thread_keyring); 272 key_check(tsk->thread_keyring);
273 key_check(tsk->request_key_auth);
273 274
274 /* no thread keyring yet */ 275 /* no thread keyring yet */
275 tsk->thread_keyring = NULL; 276 tsk->thread_keyring = NULL;
277
278 /* copy the request_key() authorisation for this thread */
279 key_get(tsk->request_key_auth);
280
276 return 0; 281 return 0;
277 282
278} /* end copy_keys() */ 283} /* end copy_keys() */
@@ -290,11 +295,12 @@ void exit_thread_group_keys(struct signal_struct *tg)
290 295
291/*****************************************************************************/ 296/*****************************************************************************/
292/* 297/*
293 * dispose of keys upon thread exit 298 * dispose of per-thread keys upon thread exit
294 */ 299 */
295void exit_keys(struct task_struct *tsk) 300void exit_keys(struct task_struct *tsk)
296{ 301{
297 key_put(tsk->thread_keyring); 302 key_put(tsk->thread_keyring);
303 key_put(tsk->request_key_auth);
298 304
299} /* end exit_keys() */ 305} /* end exit_keys() */
300 306
@@ -382,7 +388,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
382 struct task_struct *context) 388 struct task_struct *context)
383{ 389{
384 struct request_key_auth *rka; 390 struct request_key_auth *rka;
385 key_ref_t key_ref, ret, err, instkey_ref; 391 key_ref_t key_ref, ret, err;
386 392
387 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were 393 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
388 * searchable, but we failed to find a key or we found a negative key; 394 * searchable, but we failed to find a key or we found a negative key;
@@ -461,30 +467,12 @@ key_ref_t search_process_keyrings(struct key_type *type,
461 err = key_ref; 467 err = key_ref;
462 break; 468 break;
463 } 469 }
464 470 }
465 /* if this process has a session keyring and that has an 471 /* or search the user-session keyring */
466 * instantiation authorisation key in the bottom level, then we 472 else {
467 * also search the keyrings of the process mentioned there */ 473 key_ref = keyring_search_aux(
468 if (context != current) 474 make_key_ref(context->user->session_keyring, 1),
469 goto no_key; 475 context, type, description, match);
470
471 rcu_read_lock();
472 instkey_ref = __keyring_search_one(
473 make_key_ref(rcu_dereference(
474 context->signal->session_keyring),
475 1),
476 &key_type_request_key_auth, NULL, 0);
477 rcu_read_unlock();
478
479 if (IS_ERR(instkey_ref))
480 goto no_key;
481
482 rka = key_ref_to_ptr(instkey_ref)->payload.data;
483
484 key_ref = search_process_keyrings(type, description, match,
485 rka->context);
486 key_ref_put(instkey_ref);
487
488 if (!IS_ERR(key_ref)) 476 if (!IS_ERR(key_ref))
489 goto found; 477 goto found;
490 478
@@ -500,11 +488,21 @@ key_ref_t search_process_keyrings(struct key_type *type,
500 break; 488 break;
501 } 489 }
502 } 490 }
503 /* or search the user-session keyring */ 491
504 else { 492 /* if this process has an instantiation authorisation key, then we also
505 key_ref = keyring_search_aux( 493 * search the keyrings of the process mentioned there
506 make_key_ref(context->user->session_keyring, 1), 494 * - we don't permit access to request_key auth keys via this method
507 context, type, description, match); 495 */
496 if (context->request_key_auth &&
497 context == current &&
498 type != &key_type_request_key_auth &&
499 key_validate(context->request_key_auth) == 0
500 ) {
501 rka = context->request_key_auth->payload.data;
502
503 key_ref = search_process_keyrings(type, description, match,
504 rka->context);
505
508 if (!IS_ERR(key_ref)) 506 if (!IS_ERR(key_ref))
509 goto found; 507 goto found;
510 508
@@ -521,8 +519,6 @@ key_ref_t search_process_keyrings(struct key_type *type,
521 } 519 }
522 } 520 }
523 521
524
525no_key:
526 /* no key - decide on the error we're going to go for */ 522 /* no key - decide on the error we're going to go for */
527 key_ref = ret ? ret : err; 523 key_ref = ret ? ret : err;
528 524
@@ -628,6 +624,15 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
628 key = ERR_PTR(-EINVAL); 624 key = ERR_PTR(-EINVAL);
629 goto error; 625 goto error;
630 626
627 case KEY_SPEC_REQKEY_AUTH_KEY:
628 key = context->request_key_auth;
629 if (!key)
630 goto error;
631
632 atomic_inc(&key->usage);
633 key_ref = make_key_ref(key, 1);
634 break;
635
631 default: 636 default:
632 key_ref = ERR_PTR(-EINVAL); 637 key_ref = ERR_PTR(-EINVAL);
633 if (id < 1) 638 if (id < 1)
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 5cc4bba70db6..f030a0ccbb93 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -29,28 +29,36 @@ DECLARE_WAIT_QUEUE_HEAD(request_key_conswq);
29/*****************************************************************************/ 29/*****************************************************************************/
30/* 30/*
31 * request userspace finish the construction of a key 31 * request userspace finish the construction of a key
32 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring> <info>" 32 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>"
33 */ 33 */
34static int call_request_key(struct key *key, 34static int call_sbin_request_key(struct key *key,
35 const char *op, 35 struct key *authkey,
36 const char *callout_info) 36 const char *op)
37{ 37{
38 struct task_struct *tsk = current; 38 struct task_struct *tsk = current;
39 key_serial_t prkey, sskey; 39 key_serial_t prkey, sskey;
40 struct key *session_keyring, *rkakey; 40 struct key *keyring;
41 char *argv[10], *envp[3], uid_str[12], gid_str[12]; 41 char *argv[9], *envp[3], uid_str[12], gid_str[12];
42 char key_str[12], keyring_str[3][12]; 42 char key_str[12], keyring_str[3][12];
43 char desc[20];
43 int ret, i; 44 int ret, i;
44 45
45 kenter("{%d},%s,%s", key->serial, op, callout_info); 46 kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
46 47
47 /* generate a new session keyring with an auth key in it */ 48 /* allocate a new session keyring */
48 session_keyring = request_key_auth_new(key, &rkakey); 49 sprintf(desc, "_req.%u", key->serial);
49 if (IS_ERR(session_keyring)) { 50
50 ret = PTR_ERR(session_keyring); 51 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL);
51 goto error; 52 if (IS_ERR(keyring)) {
53 ret = PTR_ERR(keyring);
54 goto error_alloc;
52 } 55 }
53 56
57 /* attach the auth key to the session keyring */
58 ret = __key_link(keyring, authkey);
59 if (ret < 0)
60 goto error_link;
61
54 /* record the UID and GID */ 62 /* record the UID and GID */
55 sprintf(uid_str, "%d", current->fsuid); 63 sprintf(uid_str, "%d", current->fsuid);
56 sprintf(gid_str, "%d", current->fsgid); 64 sprintf(gid_str, "%d", current->fsgid);
@@ -95,22 +103,19 @@ static int call_request_key(struct key *key,
95 argv[i++] = keyring_str[0]; 103 argv[i++] = keyring_str[0];
96 argv[i++] = keyring_str[1]; 104 argv[i++] = keyring_str[1];
97 argv[i++] = keyring_str[2]; 105 argv[i++] = keyring_str[2];
98 argv[i++] = (char *) callout_info;
99 argv[i] = NULL; 106 argv[i] = NULL;
100 107
101 /* do it */ 108 /* do it */
102 ret = call_usermodehelper_keys(argv[0], argv, envp, session_keyring, 1); 109 ret = call_usermodehelper_keys(argv[0], argv, envp, keyring, 1);
103 110
104 /* dispose of the special keys */ 111error_link:
105 key_revoke(rkakey); 112 key_put(keyring);
106 key_put(rkakey);
107 key_put(session_keyring);
108 113
109 error: 114error_alloc:
110 kleave(" = %d", ret); 115 kleave(" = %d", ret);
111 return ret; 116 return ret;
112 117
113} /* end call_request_key() */ 118} /* end call_sbin_request_key() */
114 119
115/*****************************************************************************/ 120/*****************************************************************************/
116/* 121/*
@@ -122,9 +127,10 @@ static struct key *__request_key_construction(struct key_type *type,
122 const char *description, 127 const char *description,
123 const char *callout_info) 128 const char *callout_info)
124{ 129{
130 request_key_actor_t actor;
125 struct key_construction cons; 131 struct key_construction cons;
126 struct timespec now; 132 struct timespec now;
127 struct key *key; 133 struct key *key, *authkey;
128 int ret, negated; 134 int ret, negated;
129 135
130 kenter("%s,%s,%s", type->name, description, callout_info); 136 kenter("%s,%s,%s", type->name, description, callout_info);
@@ -143,8 +149,19 @@ static struct key *__request_key_construction(struct key_type *type,
143 /* we drop the construction sem here on behalf of the caller */ 149 /* we drop the construction sem here on behalf of the caller */
144 up_write(&key_construction_sem); 150 up_write(&key_construction_sem);
145 151
152 /* allocate an authorisation key */
153 authkey = request_key_auth_new(key, callout_info);
154 if (IS_ERR(authkey)) {
155 ret = PTR_ERR(authkey);
156 authkey = NULL;
157 goto alloc_authkey_failed;
158 }
159
146 /* make the call */ 160 /* make the call */
147 ret = call_request_key(key, "create", callout_info); 161 actor = call_sbin_request_key;
162 if (type->request_key)
163 actor = type->request_key;
164 ret = actor(key, authkey, "create");
148 if (ret < 0) 165 if (ret < 0)
149 goto request_failed; 166 goto request_failed;
150 167
@@ -153,22 +170,29 @@ static struct key *__request_key_construction(struct key_type *type,
153 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) 170 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
154 goto request_failed; 171 goto request_failed;
155 172
173 key_revoke(authkey);
174 key_put(authkey);
175
156 down_write(&key_construction_sem); 176 down_write(&key_construction_sem);
157 list_del(&cons.link); 177 list_del(&cons.link);
158 up_write(&key_construction_sem); 178 up_write(&key_construction_sem);
159 179
160 /* also give an error if the key was negatively instantiated */ 180 /* also give an error if the key was negatively instantiated */
161 check_not_negative: 181check_not_negative:
162 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { 182 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
163 key_put(key); 183 key_put(key);
164 key = ERR_PTR(-ENOKEY); 184 key = ERR_PTR(-ENOKEY);
165 } 185 }
166 186
167 out: 187out:
168 kleave(" = %p", key); 188 kleave(" = %p", key);
169 return key; 189 return key;
170 190
171 request_failed: 191request_failed:
192 key_revoke(authkey);
193 key_put(authkey);
194
195alloc_authkey_failed:
172 /* it wasn't instantiated 196 /* it wasn't instantiated
173 * - remove from construction queue 197 * - remove from construction queue
174 * - mark the key as dead 198 * - mark the key as dead
@@ -217,7 +241,7 @@ static struct key *__request_key_construction(struct key_type *type,
217 key = ERR_PTR(ret); 241 key = ERR_PTR(ret);
218 goto out; 242 goto out;
219 243
220 alloc_failed: 244alloc_failed:
221 up_write(&key_construction_sem); 245 up_write(&key_construction_sem);
222 goto out; 246 goto out;
223 247
@@ -464,35 +488,3 @@ struct key *request_key(struct key_type *type,
464} /* end request_key() */ 488} /* end request_key() */
465 489
466EXPORT_SYMBOL(request_key); 490EXPORT_SYMBOL(request_key);
467
468/*****************************************************************************/
469/*
470 * validate a key
471 */
472int key_validate(struct key *key)
473{
474 struct timespec now;
475 int ret = 0;
476
477 if (key) {
478 /* check it's still accessible */
479 ret = -EKEYREVOKED;
480 if (test_bit(KEY_FLAG_REVOKED, &key->flags) ||
481 test_bit(KEY_FLAG_DEAD, &key->flags))
482 goto error;
483
484 /* check it hasn't expired */
485 ret = 0;
486 if (key->expiry) {
487 now = current_kernel_time();
488 if (now.tv_sec >= key->expiry)
489 ret = -EKEYEXPIRED;
490 }
491 }
492
493 error:
494 return ret;
495
496} /* end key_validate() */
497
498EXPORT_SYMBOL(key_validate);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index a8e4069d48cb..cce6ba6b0323 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -15,11 +15,13 @@
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/seq_file.h> 17#include <linux/seq_file.h>
18#include <asm/uaccess.h>
18#include "internal.h" 19#include "internal.h"
19 20
20static int request_key_auth_instantiate(struct key *, const void *, size_t); 21static int request_key_auth_instantiate(struct key *, const void *, size_t);
21static void request_key_auth_describe(const struct key *, struct seq_file *); 22static void request_key_auth_describe(const struct key *, struct seq_file *);
22static void request_key_auth_destroy(struct key *); 23static void request_key_auth_destroy(struct key *);
24static long request_key_auth_read(const struct key *, char __user *, size_t);
23 25
24/* 26/*
25 * the request-key authorisation key type definition 27 * the request-key authorisation key type definition
@@ -30,51 +32,25 @@ struct key_type key_type_request_key_auth = {
30 .instantiate = request_key_auth_instantiate, 32 .instantiate = request_key_auth_instantiate,
31 .describe = request_key_auth_describe, 33 .describe = request_key_auth_describe,
32 .destroy = request_key_auth_destroy, 34 .destroy = request_key_auth_destroy,
35 .read = request_key_auth_read,
33}; 36};
34 37
35/*****************************************************************************/ 38/*****************************************************************************/
36/* 39/*
37 * instantiate a request-key authorisation record 40 * instantiate a request-key authorisation key
38 */ 41 */
39static int request_key_auth_instantiate(struct key *key, 42static int request_key_auth_instantiate(struct key *key,
40 const void *data, 43 const void *data,
41 size_t datalen) 44 size_t datalen)
42{ 45{
43 struct request_key_auth *rka, *irka; 46 key->payload.data = (struct request_key_auth *) data;
44 struct key *instkey; 47 return 0;
45 int ret;
46
47 ret = -ENOMEM;
48 rka = kmalloc(sizeof(*rka), GFP_KERNEL);
49 if (rka) {
50 /* see if the calling process is already servicing the key
51 * request of another process */
52 instkey = key_get_instantiation_authkey(0);
53 if (!IS_ERR(instkey)) {
54 /* it is - use that instantiation context here too */
55 irka = instkey->payload.data;
56 rka->context = irka->context;
57 rka->pid = irka->pid;
58 key_put(instkey);
59 }
60 else {
61 /* it isn't - use this process as the context */
62 rka->context = current;
63 rka->pid = current->pid;
64 }
65
66 rka->target_key = key_get((struct key *) data);
67 key->payload.data = rka;
68 ret = 0;
69 }
70
71 return ret;
72 48
73} /* end request_key_auth_instantiate() */ 49} /* end request_key_auth_instantiate() */
74 50
75/*****************************************************************************/ 51/*****************************************************************************/
76/* 52/*
77 * 53 * reading a request-key authorisation key retrieves the callout information
78 */ 54 */
79static void request_key_auth_describe(const struct key *key, 55static void request_key_auth_describe(const struct key *key,
80 struct seq_file *m) 56 struct seq_file *m)
@@ -83,12 +59,40 @@ static void request_key_auth_describe(const struct key *key,
83 59
84 seq_puts(m, "key:"); 60 seq_puts(m, "key:");
85 seq_puts(m, key->description); 61 seq_puts(m, key->description);
86 seq_printf(m, " pid:%d", rka->pid); 62 seq_printf(m, " pid:%d ci:%zu", rka->pid, strlen(rka->callout_info));
87 63
88} /* end request_key_auth_describe() */ 64} /* end request_key_auth_describe() */
89 65
90/*****************************************************************************/ 66/*****************************************************************************/
91/* 67/*
68 * read the callout_info data
69 * - the key's semaphore is read-locked
70 */
71static long request_key_auth_read(const struct key *key,
72 char __user *buffer, size_t buflen)
73{
74 struct request_key_auth *rka = key->payload.data;
75 size_t datalen;
76 long ret;
77
78 datalen = strlen(rka->callout_info);
79 ret = datalen;
80
81 /* we can return the data as is */
82 if (buffer && buflen > 0) {
83 if (buflen > datalen)
84 buflen = datalen;
85
86 if (copy_to_user(buffer, rka->callout_info, buflen) != 0)
87 ret = -EFAULT;
88 }
89
90 return ret;
91
92} /* end request_key_auth_read() */
93
94/*****************************************************************************/
95/*
92 * destroy an instantiation authorisation token key 96 * destroy an instantiation authorisation token key
93 */ 97 */
94static void request_key_auth_destroy(struct key *key) 98static void request_key_auth_destroy(struct key *key)
@@ -104,56 +108,89 @@ static void request_key_auth_destroy(struct key *key)
104 108
105/*****************************************************************************/ 109/*****************************************************************************/
106/* 110/*
107 * create a session keyring to be for the invokation of /sbin/request-key and 111 * create an authorisation token for /sbin/request-key or whoever to gain
108 * stick an authorisation token in it 112 * access to the caller's security data
109 */ 113 */
110struct key *request_key_auth_new(struct key *target, struct key **_rkakey) 114struct key *request_key_auth_new(struct key *target, const char *callout_info)
111{ 115{
112 struct key *keyring, *rkakey = NULL; 116 struct request_key_auth *rka, *irka;
117 struct key *authkey = NULL;
113 char desc[20]; 118 char desc[20];
114 int ret; 119 int ret;
115 120
116 kenter("%d,", target->serial); 121 kenter("%d,", target->serial);
117 122
118 /* allocate a new session keyring */ 123 /* allocate a auth record */
119 sprintf(desc, "_req.%u", target->serial); 124 rka = kmalloc(sizeof(*rka), GFP_KERNEL);
125 if (!rka) {
126 kleave(" = -ENOMEM");
127 return ERR_PTR(-ENOMEM);
128 }
120 129
121 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL); 130 /* see if the calling process is already servicing the key request of
122 if (IS_ERR(keyring)) { 131 * another process */
123 kleave("= %ld", PTR_ERR(keyring)); 132 if (current->request_key_auth) {
124 return keyring; 133 /* it is - use that instantiation context here too */
134 irka = current->request_key_auth->payload.data;
135 rka->context = irka->context;
136 rka->pid = irka->pid;
125 } 137 }
138 else {
139 /* it isn't - use this process as the context */
140 rka->context = current;
141 rka->pid = current->pid;
142 }
143
144 rka->target_key = key_get(target);
145 rka->callout_info = callout_info;
126 146
127 /* allocate the auth key */ 147 /* allocate the auth key */
128 sprintf(desc, "%x", target->serial); 148 sprintf(desc, "%x", target->serial);
129 149
130 rkakey = key_alloc(&key_type_request_key_auth, desc, 150 authkey = key_alloc(&key_type_request_key_auth, desc,
131 current->fsuid, current->fsgid, 151 current->fsuid, current->fsgid,
132 KEY_POS_VIEW | KEY_USR_VIEW, 1); 152 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
133 if (IS_ERR(rkakey)) { 153 KEY_USR_VIEW, 1);
134 key_put(keyring); 154 if (IS_ERR(authkey)) {
135 kleave("= %ld", PTR_ERR(rkakey)); 155 ret = PTR_ERR(authkey);
136 return rkakey; 156 goto error_alloc;
137 } 157 }
138 158
139 /* construct and attach to the keyring */ 159 /* construct and attach to the keyring */
140 ret = key_instantiate_and_link(rkakey, target, 0, keyring, NULL); 160 ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
141 if (ret < 0) { 161 if (ret < 0)
142 key_revoke(rkakey); 162 goto error_inst;
143 key_put(rkakey);
144 key_put(keyring);
145 kleave("= %d", ret);
146 return ERR_PTR(ret);
147 }
148 163
149 *_rkakey = rkakey; 164 kleave(" = {%d})", authkey->serial);
150 kleave(" = {%d} ({%d})", keyring->serial, rkakey->serial); 165 return authkey;
151 return keyring; 166
167error_inst:
168 key_revoke(authkey);
169 key_put(authkey);
170error_alloc:
171 key_put(rka->target_key);
172 kfree(rka);
173 kleave("= %d", ret);
174 return ERR_PTR(ret);
152 175
153} /* end request_key_auth_new() */ 176} /* end request_key_auth_new() */
154 177
155/*****************************************************************************/ 178/*****************************************************************************/
156/* 179/*
180 * see if an authorisation key is associated with a particular key
181 */
182static int key_get_instantiation_authkey_match(const struct key *key,
183 const void *_id)
184{
185 struct request_key_auth *rka = key->payload.data;
186 key_serial_t id = (key_serial_t)(unsigned long) _id;
187
188 return rka->target_key->serial == id;
189
190} /* end key_get_instantiation_authkey_match() */
191
192/*****************************************************************************/
193/*
157 * get the authorisation key for instantiation of a specific key if attached to 194 * get the authorisation key for instantiation of a specific key if attached to
158 * the current process's keyrings 195 * the current process's keyrings
159 * - this key is inserted into a keyring and that is set as /sbin/request-key's 196 * - this key is inserted into a keyring and that is set as /sbin/request-key's
@@ -162,22 +199,27 @@ struct key *request_key_auth_new(struct key *target, struct key **_rkakey)
162 */ 199 */
163struct key *key_get_instantiation_authkey(key_serial_t target_id) 200struct key *key_get_instantiation_authkey(key_serial_t target_id)
164{ 201{
165 struct task_struct *tsk = current; 202 struct key *authkey;
166 struct key *instkey; 203 key_ref_t authkey_ref;
167 204
168 /* we must have our own personal session keyring */ 205 authkey_ref = search_process_keyrings(
169 if (!tsk->signal->session_keyring) 206 &key_type_request_key_auth,
170 return ERR_PTR(-EACCES); 207 (void *) (unsigned long) target_id,
171 208 key_get_instantiation_authkey_match,
172 /* and it must contain a suitable request authorisation key 209 current);
173 * - lock RCU against session keyring changing 210
174 */ 211 if (IS_ERR(authkey_ref)) {
175 rcu_read_lock(); 212 authkey = ERR_PTR(PTR_ERR(authkey_ref));
213 goto error;
214 }
176 215
177 instkey = keyring_search_instkey( 216 authkey = key_ref_to_ptr(authkey_ref);
178 rcu_dereference(tsk->signal->session_keyring), target_id); 217 if (test_bit(KEY_FLAG_REVOKED, &authkey->flags)) {
218 key_put(authkey);
219 authkey = ERR_PTR(-EKEYREVOKED);
220 }
179 221
180 rcu_read_unlock(); 222error:
181 return instkey; 223 return authkey;
182 224
183} /* end key_get_instantiation_authkey() */ 225} /* end key_get_instantiation_authkey() */
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 3d496eae1b47..6647204e4636 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1663,7 +1663,7 @@ static inline void flush_unauthorized_files(struct files_struct * files)
1663 continue; 1663 continue;
1664 } 1664 }
1665 if (devnull) { 1665 if (devnull) {
1666 rcuref_inc(&devnull->f_count); 1666 get_file(devnull);
1667 } else { 1667 } else {
1668 devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR); 1668 devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR);
1669 if (!devnull) { 1669 if (!devnull) {
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index e59da6398d44..b5fa02d17b1e 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -889,7 +889,7 @@ static void sel_remove_bools(struct dentry *de)
889 spin_lock(&dcache_lock); 889 spin_lock(&dcache_lock);
890 node = de->d_subdirs.next; 890 node = de->d_subdirs.next;
891 while (node != &de->d_subdirs) { 891 while (node != &de->d_subdirs) {
892 struct dentry *d = list_entry(node, struct dentry, d_child); 892 struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
893 list_del_init(node); 893 list_del_init(node);
894 894
895 if (d->d_inode) { 895 if (d->d_inode) {
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index 5b7776504e4c..b2af7ca496c1 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -146,7 +146,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_us
146 return rc; 146 return rc;
147 147
148out: 148out:
149 *ctxp = 0; 149 *ctxp = NULL;
150 kfree(ctx); 150 kfree(ctx);
151 return rc; 151 return rc;
152} 152}
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index 679d0ae97e4f..ed81eec6e732 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -115,18 +115,11 @@ MODULE_PARM_DESC(osrun_time, "how many seconds to wait for the ICS2115 OS");
115 115
116#ifdef WF_DEBUG 116#ifdef WF_DEBUG
117 117
118#if defined(NEW_MACRO_VARARGS) || __GNUC__ >= 3
119#define DPRINT(cond, ...) \ 118#define DPRINT(cond, ...) \
120 if ((dev->debug & (cond)) == (cond)) { \ 119 if ((dev->debug & (cond)) == (cond)) { \
121 snd_printk (__VA_ARGS__); \ 120 snd_printk (__VA_ARGS__); \
122 } 121 }
123#else 122#else
124#define DPRINT(cond, args...) \
125 if ((dev->debug & (cond)) == (cond)) { \
126 snd_printk (args); \
127 }
128#endif
129#else
130#define DPRINT(cond, args...) 123#define DPRINT(cond, args...)
131#endif /* WF_DEBUG */ 124#endif /* WF_DEBUG */
132 125
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
index cebd881b91ae..74f975676ccb 100644
--- a/sound/oss/dmasound/dmasound_awacs.c
+++ b/sound/oss/dmasound/dmasound_awacs.c
@@ -125,6 +125,7 @@ static int awacs_rate_index;
125static int awacs_subframe; 125static int awacs_subframe;
126static struct device_node* awacs_node; 126static struct device_node* awacs_node;
127static struct device_node* i2s_node; 127static struct device_node* i2s_node;
128static struct resource awacs_rsrc[3];
128 129
129static char awacs_name[64]; 130static char awacs_name[64];
130static int awacs_revision; 131static int awacs_revision;
@@ -667,9 +668,12 @@ static void PMacIrqCleanup(void)
667 iounmap(awacs_txdma); 668 iounmap(awacs_txdma);
668 iounmap(awacs_rxdma); 669 iounmap(awacs_rxdma);
669 670
670 release_OF_resource(awacs_node, 0); 671 release_mem_region(awacs_rsrc[0].start,
671 release_OF_resource(awacs_node, 1); 672 awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
672 release_OF_resource(awacs_node, 2); 673 release_mem_region(awacs_rsrc[1].start,
674 awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
675 release_mem_region(awacs_rsrc[2].start,
676 awacs_rsrc[2].end - awacs_rsrc[2].start + 1);
673 677
674 kfree(awacs_tx_cmd_space); 678 kfree(awacs_tx_cmd_space);
675 kfree(awacs_rx_cmd_space); 679 kfree(awacs_rx_cmd_space);
@@ -2863,46 +2867,58 @@ printk("dmasound_pmac: couldn't find a Codec we can handle\n");
2863 * other info if necessary (early AWACS we want to read chip ids) 2867 * other info if necessary (early AWACS we want to read chip ids)
2864 */ 2868 */
2865 2869
2866 if (io->n_addrs < 3 || io->n_intrs < 3) { 2870 if (of_get_address(io, 2, NULL, NULL) == NULL || io->n_intrs < 3) {
2867 /* OK - maybe we need to use the 'awacs' node (on earlier 2871 /* OK - maybe we need to use the 'awacs' node (on earlier
2868 * machines). 2872 * machines).
2869 */ 2873 */
2870 if (awacs_node) { 2874 if (awacs_node) {
2871 io = awacs_node ; 2875 io = awacs_node ;
2872 if (io->n_addrs < 3 || io->n_intrs < 3) { 2876 if (of_get_address(io, 2, NULL, NULL) == NULL ||
2873 printk("dmasound_pmac: can't use %s" 2877 io->n_intrs < 3) {
2874 " (%d addrs, %d intrs)\n", 2878 printk("dmasound_pmac: can't use %s\n",
2875 io->full_name, io->n_addrs, io->n_intrs); 2879 io->full_name);
2876 return -ENODEV; 2880 return -ENODEV;
2877 } 2881 }
2878 } else { 2882 } else
2879 printk("dmasound_pmac: can't use %s (%d addrs, %d intrs)\n", 2883 printk("dmasound_pmac: can't use %s\n", io->full_name);
2880 io->full_name, io->n_addrs, io->n_intrs);
2881 }
2882 } 2884 }
2883 2885
2884 if (!request_OF_resource(io, 0, NULL)) { 2886 if (of_address_to_resource(io, 0, &awacs_rsrc[0]) ||
2887 request_mem_region(awacs_rsrc[0].start,
2888 awacs_rsrc[0].end - awacs_rsrc[0].start + 1,
2889 " (IO)") == NULL) {
2885 printk(KERN_ERR "dmasound: can't request IO resource !\n"); 2890 printk(KERN_ERR "dmasound: can't request IO resource !\n");
2886 return -ENODEV; 2891 return -ENODEV;
2887 } 2892 }
2888 if (!request_OF_resource(io, 1, " (tx dma)")) { 2893 if (of_address_to_resource(io, 1, &awacs_rsrc[1]) ||
2889 release_OF_resource(io, 0); 2894 request_mem_region(awacs_rsrc[1].start,
2890 printk(KERN_ERR "dmasound: can't request TX DMA resource !\n"); 2895 awacs_rsrc[1].end - awacs_rsrc[1].start + 1,
2896 " (tx dma)") == NULL) {
2897 release_mem_region(awacs_rsrc[0].start,
2898 awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
2899 printk(KERN_ERR "dmasound: can't request Tx DMA resource !\n");
2891 return -ENODEV; 2900 return -ENODEV;
2892 } 2901 }
2893 2902 if (of_address_to_resource(io, 2, &awacs_rsrc[2]) ||
2894 if (!request_OF_resource(io, 2, " (rx dma)")) { 2903 request_mem_region(awacs_rsrc[2].start,
2895 release_OF_resource(io, 0); 2904 awacs_rsrc[2].end - awacs_rsrc[2].start + 1,
2896 release_OF_resource(io, 1); 2905 " (rx dma)") == NULL) {
2897 printk(KERN_ERR "dmasound: can't request RX DMA resource !\n"); 2906 release_mem_region(awacs_rsrc[0].start,
2907 awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
2908 release_mem_region(awacs_rsrc[1].start,
2909 awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
2910 printk(KERN_ERR "dmasound: can't request Rx DMA resource !\n");
2898 return -ENODEV; 2911 return -ENODEV;
2899 } 2912 }
2900 2913
2901 awacs_beep_dev = input_allocate_device(); 2914 awacs_beep_dev = input_allocate_device();
2902 if (!awacs_beep_dev) { 2915 if (!awacs_beep_dev) {
2903 release_OF_resource(io, 0); 2916 release_mem_region(awacs_rsrc[0].start,
2904 release_OF_resource(io, 1); 2917 awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
2905 release_OF_resource(io, 2); 2918 release_mem_region(awacs_rsrc[1].start,
2919 awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
2920 release_mem_region(awacs_rsrc[2].start,
2921 awacs_rsrc[2].end - awacs_rsrc[2].start + 1);
2906 printk(KERN_ERR "dmasound: can't allocate input device !\n"); 2922 printk(KERN_ERR "dmasound: can't allocate input device !\n");
2907 return -ENOMEM; 2923 return -ENOMEM;
2908 } 2924 }
@@ -2916,11 +2932,11 @@ printk("dmasound_pmac: couldn't find a Codec we can handle\n");
2916 2932
2917 /* all OF versions I've seen use this value */ 2933 /* all OF versions I've seen use this value */
2918 if (i2s_node) 2934 if (i2s_node)
2919 i2s = ioremap(io->addrs[0].address, 0x1000); 2935 i2s = ioremap(awacs_rsrc[0].start, 0x1000);
2920 else 2936 else
2921 awacs = ioremap(io->addrs[0].address, 0x1000); 2937 awacs = ioremap(awacs_rsrc[0].start, 0x1000);
2922 awacs_txdma = ioremap(io->addrs[1].address, 0x100); 2938 awacs_txdma = ioremap(awacs_rsrc[1].start, 0x100);
2923 awacs_rxdma = ioremap(io->addrs[2].address, 0x100); 2939 awacs_rxdma = ioremap(awacs_rsrc[2].start, 0x100);
2924 2940
2925 /* first of all make sure that the chip is powered up....*/ 2941 /* first of all make sure that the chip is powered up....*/
2926 pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1); 2942 pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1);
@@ -3083,9 +3099,10 @@ printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev);
3083 struct device_node* mio; 3099 struct device_node* mio;
3084 macio_base = NULL; 3100 macio_base = NULL;
3085 for (mio = io->parent; mio; mio = mio->parent) { 3101 for (mio = io->parent; mio; mio = mio->parent) {
3086 if (strcmp(mio->name, "mac-io") == 0 3102 if (strcmp(mio->name, "mac-io") == 0) {
3087 && mio->n_addrs > 0) { 3103 struct resource r;
3088 macio_base = ioremap(mio->addrs[0].address, 0x40); 3104 if (of_address_to_resource(mio, 0, &r) == 0)
3105 macio_base = ioremap(r.start, 0x40);
3089 break; 3106 break;
3090 } 3107 }
3091 } 3108 }
diff --git a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c
index b9a640fe48b1..4600cd6742ce 100644
--- a/sound/oss/i810_audio.c
+++ b/sound/oss/i810_audio.c
@@ -3359,12 +3359,6 @@ static int __devinit i810_probe(struct pci_dev *pci_dev, const struct pci_device
3359 goto out_region2; 3359 goto out_region2;
3360 } 3360 }
3361 3361
3362 if (request_irq(card->irq, &i810_interrupt, SA_SHIRQ,
3363 card_names[pci_id->driver_data], card)) {
3364 printk(KERN_ERR "i810_audio: unable to allocate irq %d\n", card->irq);
3365 goto out_pio;
3366 }
3367
3368 if (card->use_mmio) { 3362 if (card->use_mmio) {
3369 if (request_mem_region(card->ac97base_mmio_phys, 512, "ich_audio MMBAR")) { 3363 if (request_mem_region(card->ac97base_mmio_phys, 512, "ich_audio MMBAR")) {
3370 if ((card->ac97base_mmio = ioremap(card->ac97base_mmio_phys, 512))) { /*@FIXME can ioremap fail? don't know (jsaw) */ 3364 if ((card->ac97base_mmio = ioremap(card->ac97base_mmio_phys, 512))) { /*@FIXME can ioremap fail? don't know (jsaw) */
@@ -3395,10 +3389,8 @@ static int __devinit i810_probe(struct pci_dev *pci_dev, const struct pci_device
3395 } 3389 }
3396 3390
3397 /* initialize AC97 codec and register /dev/mixer */ 3391 /* initialize AC97 codec and register /dev/mixer */
3398 if (i810_ac97_init(card) <= 0) { 3392 if (i810_ac97_init(card) <= 0)
3399 free_irq(card->irq, card);
3400 goto out_iospace; 3393 goto out_iospace;
3401 }
3402 pci_set_drvdata(pci_dev, card); 3394 pci_set_drvdata(pci_dev, card);
3403 3395
3404 if(clocking == 0) { 3396 if(clocking == 0) {
@@ -3410,7 +3402,6 @@ static int __devinit i810_probe(struct pci_dev *pci_dev, const struct pci_device
3410 if ((card->dev_audio = register_sound_dsp(&i810_audio_fops, -1)) < 0) { 3402 if ((card->dev_audio = register_sound_dsp(&i810_audio_fops, -1)) < 0) {
3411 int i; 3403 int i;
3412 printk(KERN_ERR "i810_audio: couldn't register DSP device!\n"); 3404 printk(KERN_ERR "i810_audio: couldn't register DSP device!\n");
3413 free_irq(card->irq, card);
3414 for (i = 0; i < NR_AC97; i++) 3405 for (i = 0; i < NR_AC97; i++)
3415 if (card->ac97_codec[i] != NULL) { 3406 if (card->ac97_codec[i] != NULL) {
3416 unregister_sound_mixer(card->ac97_codec[i]->dev_mixer); 3407 unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
@@ -3419,6 +3410,13 @@ static int __devinit i810_probe(struct pci_dev *pci_dev, const struct pci_device
3419 goto out_iospace; 3410 goto out_iospace;
3420 } 3411 }
3421 3412
3413 if (request_irq(card->irq, &i810_interrupt, SA_SHIRQ,
3414 card_names[pci_id->driver_data], card)) {
3415 printk(KERN_ERR "i810_audio: unable to allocate irq %d\n", card->irq);
3416 goto out_iospace;
3417 }
3418
3419
3422 card->initializing = 0; 3420 card->initializing = 0;
3423 return 0; 3421 return 0;
3424 3422
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index 9b2b00fdc1ae..a642e4cfcf45 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -803,21 +803,17 @@ static int snd_pmac_free(struct snd_pmac *chip)
803 iounmap(chip->playback.dma); 803 iounmap(chip->playback.dma);
804 if (chip->capture.dma) 804 if (chip->capture.dma)
805 iounmap(chip->capture.dma); 805 iounmap(chip->capture.dma);
806#ifndef CONFIG_PPC64 806
807 if (chip->node) { 807 if (chip->node) {
808 int i; 808 int i;
809
810 for (i = 0; i < 3; i++) { 809 for (i = 0; i < 3; i++) {
811 if (chip->of_requested & (1 << i)) { 810 if (chip->requested & (1 << i))
812 if (chip->is_k2) 811 release_mem_region(chip->rsrc[i].start,
813 release_OF_resource(chip->node->parent, 812 chip->rsrc[i].end -
814 i); 813 chip->rsrc[i].start + 1);
815 else
816 release_OF_resource(chip->node, i);
817 }
818 } 814 }
819 } 815 }
820#endif /* CONFIG_PPC64 */ 816
821 if (chip->pdev) 817 if (chip->pdev)
822 pci_dev_put(chip->pdev); 818 pci_dev_put(chip->pdev);
823 kfree(chip); 819 kfree(chip);
@@ -991,6 +987,11 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
991 chip->can_byte_swap = 0; /* FIXME: check this */ 987 chip->can_byte_swap = 0; /* FIXME: check this */
992 chip->control_mask = MASK_IEPC | 0x11;/* disable IEE */ 988 chip->control_mask = MASK_IEPC | 0x11;/* disable IEE */
993 break; 989 break;
990 default:
991 printk(KERN_ERR "snd: Unknown layout ID 0x%x\n",
992 layout_id);
993 return -ENODEV;
994
994 } 995 }
995 } 996 }
996 prop = (unsigned int *)get_property(sound, "device-id", NULL); 997 prop = (unsigned int *)get_property(sound, "device-id", NULL);
@@ -1175,46 +1176,69 @@ int __init snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
1175 } 1176 }
1176 1177
1177 np = chip->node; 1178 np = chip->node;
1179 chip->requested = 0;
1178 if (chip->is_k2) { 1180 if (chip->is_k2) {
1179 if (np->parent->n_addrs < 2 || np->n_intrs < 3) { 1181 static char *rnames[] = {
1182 "Sound Control", "Sound DMA" };
1183 if (np->n_intrs < 3) {
1180 err = -ENODEV; 1184 err = -ENODEV;
1181 goto __error; 1185 goto __error;
1182 } 1186 }
1183 for (i = 0; i < 2; i++) { 1187 for (i = 0; i < 2; i ++) {
1184#ifndef CONFIG_PPC64 1188 if (of_address_to_resource(np->parent, i,
1185 static char *name[2] = { "- Control", "- DMA" }; 1189 &chip->rsrc[i])) {
1186 if (! request_OF_resource(np->parent, i, name[i])) { 1190 printk(KERN_ERR "snd: can't translate rsrc "
1187 snd_printk(KERN_ERR "pmac: can't request resource %d!\n", i); 1191 " %d (%s)\n", i, rnames[i]);
1192 err = -ENODEV;
1193 goto __error;
1194 }
1195 if (request_mem_region(chip->rsrc[i].start,
1196 chip->rsrc[i].end -
1197 chip->rsrc[i].start + 1,
1198 rnames[i]) == NULL) {
1199 printk(KERN_ERR "snd: can't request rsrc "
1200 " %d (%s: 0x%08lx:%08lx)\n",
1201 i, rnames[i], chip->rsrc[i].start,
1202 chip->rsrc[i].end);
1188 err = -ENODEV; 1203 err = -ENODEV;
1189 goto __error; 1204 goto __error;
1190 } 1205 }
1191 chip->of_requested |= (1 << i); 1206 chip->requested |= (1 << i);
1192#endif /* CONFIG_PPC64 */
1193 ctrl_addr = np->parent->addrs[0].address;
1194 txdma_addr = np->parent->addrs[1].address;
1195 rxdma_addr = txdma_addr + 0x100;
1196 } 1207 }
1197 1208 ctrl_addr = chip->rsrc[0].start;
1209 txdma_addr = chip->rsrc[1].start;
1210 rxdma_addr = txdma_addr + 0x100;
1198 } else { 1211 } else {
1199 if (np->n_addrs < 3 || np->n_intrs < 3) { 1212 static char *rnames[] = {
1213 "Sound Control", "Sound Tx DMA", "Sound Rx DMA" };
1214 if (np->n_intrs < 3) {
1200 err = -ENODEV; 1215 err = -ENODEV;
1201 goto __error; 1216 goto __error;
1202 } 1217 }
1203 1218 for (i = 0; i < 3; i ++) {
1204 for (i = 0; i < 3; i++) { 1219 if (of_address_to_resource(np->parent, i,
1205#ifndef CONFIG_PPC64 1220 &chip->rsrc[i])) {
1206 static char *name[3] = { "- Control", "- Tx DMA", "- Rx DMA" }; 1221 printk(KERN_ERR "snd: can't translate rsrc "
1207 if (! request_OF_resource(np, i, name[i])) { 1222 " %d (%s)\n", i, rnames[i]);
1208 snd_printk(KERN_ERR "pmac: can't request resource %d!\n", i); 1223 err = -ENODEV;
1224 goto __error;
1225 }
1226 if (request_mem_region(chip->rsrc[i].start,
1227 chip->rsrc[i].end -
1228 chip->rsrc[i].start + 1,
1229 rnames[i]) == NULL) {
1230 printk(KERN_ERR "snd: can't request rsrc "
1231 " %d (%s: 0x%08lx:%08lx)\n",
1232 i, rnames[i], chip->rsrc[i].start,
1233 chip->rsrc[i].end);
1209 err = -ENODEV; 1234 err = -ENODEV;
1210 goto __error; 1235 goto __error;
1211 } 1236 }
1212 chip->of_requested |= (1 << i); 1237 chip->requested |= (1 << i);
1213#endif /* CONFIG_PPC64 */
1214 ctrl_addr = np->addrs[0].address;
1215 txdma_addr = np->addrs[1].address;
1216 rxdma_addr = np->addrs[2].address;
1217 } 1238 }
1239 ctrl_addr = chip->rsrc[0].start;
1240 txdma_addr = chip->rsrc[1].start;
1241 rxdma_addr = chip->rsrc[2].start;
1218 } 1242 }
1219 1243
1220 chip->awacs = ioremap(ctrl_addr, 0x1000); 1244 chip->awacs = ioremap(ctrl_addr, 0x1000);
@@ -1266,9 +1290,11 @@ int __init snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
1266 } else if (chip->is_pbook_G3) { 1290 } else if (chip->is_pbook_G3) {
1267 struct device_node* mio; 1291 struct device_node* mio;
1268 for (mio = chip->node->parent; mio; mio = mio->parent) { 1292 for (mio = chip->node->parent; mio; mio = mio->parent) {
1269 if (strcmp(mio->name, "mac-io") == 0 1293 if (strcmp(mio->name, "mac-io") == 0) {
1270 && mio->n_addrs > 0) { 1294 struct resource r;
1271 chip->macio_base = ioremap(mio->addrs[0].address, 0x40); 1295 if (of_address_to_resource(mio, 0, &r) == 0)
1296 chip->macio_base =
1297 ioremap(r.start, 0x40);
1272 break; 1298 break;
1273 } 1299 }
1274 } 1300 }
diff --git a/sound/ppc/pmac.h b/sound/ppc/pmac.h
index 086da7a18909..3a9bd4dbb9a6 100644
--- a/sound/ppc/pmac.h
+++ b/sound/ppc/pmac.h
@@ -113,7 +113,8 @@ struct snd_pmac {
113 unsigned int initialized : 1; 113 unsigned int initialized : 1;
114 unsigned int feature_is_set : 1; 114 unsigned int feature_is_set : 1;
115 115
116 unsigned int of_requested; 116 unsigned int requested;
117 struct resource rsrc[3];
117 118
118 int num_freqs; 119 int num_freqs;
119 int *freq_table; 120 int *freq_table;