From 183849eb18baa65e73ed21526b8afdaeb9f3d75b Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 15 Jul 2007 18:47:38 +0200 Subject: [PATCH] --- yaml --- r: 62301 b: refs/heads/master c: 81764fa9a472dd72b93385f30f718ed4f98ec129 h: refs/heads/master i: 62299: 7807aa7a21cc49420d927103817749dc93e785cc v: v3 --- [refs] | 2 +- trunk/.gitignore | 1 - trunk/CREDITS | 10 +- trunk/Documentation/kernel-parameters.txt | 5 - .../sound/alsa/ALSA-Configuration.txt | 75 +- .../sound/alsa/Audiophile-Usb.txt | 242 +- .../sound/alsa/OSS-Emulation.txt | 15 - trunk/Documentation/time_interpolators.txt | 41 + trunk/MAINTAINERS | 13 +- trunk/arch/arm/mm/fault.c | 6 +- trunk/arch/i386/boot/compressed/relocs.c | 1 - trunk/arch/i386/kernel/vsyscall-note.S | 15 +- trunk/arch/i386/xen/events.c | 1 - trunk/arch/i386/xen/setup.c | 15 - trunk/arch/i386/xen/vdso.h | 4 - trunk/arch/ia64/Kconfig | 6 +- trunk/arch/ia64/configs/bigsur_defconfig | 2 +- trunk/arch/ia64/configs/gensparse_defconfig | 2 +- trunk/arch/ia64/configs/sim_defconfig | 2 +- trunk/arch/ia64/configs/sn2_defconfig | 2 +- trunk/arch/ia64/configs/tiger_defconfig | 322 +- trunk/arch/ia64/configs/zx1_defconfig | 2 +- trunk/arch/ia64/defconfig | 338 +- trunk/arch/ia64/kernel/asm-offsets.c | 35 +- trunk/arch/ia64/kernel/cyclone.c | 46 +- trunk/arch/ia64/kernel/entry.S | 2 +- trunk/arch/ia64/kernel/fsys.S | 179 +- trunk/arch/ia64/kernel/fsyscall_gtod_data.h | 23 - trunk/arch/ia64/kernel/iosapic.c | 652 ++-- trunk/arch/ia64/kernel/irq.c | 2 +- trunk/arch/ia64/kernel/irq_ia64.c | 317 +- trunk/arch/ia64/kernel/msi_ia64.c | 23 +- trunk/arch/ia64/kernel/smpboot.c | 4 - trunk/arch/ia64/kernel/time.c | 96 +- trunk/arch/ia64/sn/kernel/sn2/timer.c | 29 +- trunk/arch/m68k/Kconfig | 7 - trunk/arch/m68k/apollo/config.c | 4 +- trunk/arch/m68k/apollo/dn_ints.c | 2 +- trunk/arch/m68k/atari/atakeyb.c | 9 +- trunk/arch/m68k/bvme6000/config.c | 2 +- trunk/arch/m68k/kernel/head.S | 2 +- trunk/arch/m68k/kernel/setup.c | 1 - trunk/arch/m68k/kernel/sun3-head.S | 2 +- trunk/arch/m68k/kernel/time.c | 2 +- trunk/arch/m68k/kernel/vmlinux-std.lds | 1 - trunk/arch/m68k/kernel/vmlinux-sun3.lds | 2 +- trunk/arch/m68k/mac/config.c | 7 +- trunk/arch/m68k/mac/macints.c | 4 +- trunk/arch/m68k/mm/init.c | 2 +- trunk/arch/m68k/mm/sun3kmap.c | 2 - trunk/arch/m68k/mvme147/config.c | 2 +- trunk/arch/m68k/mvme16x/config.c | 2 +- trunk/arch/m68k/q40/q40ints.c | 2 +- trunk/arch/m68k/sun3/sun3ints.c | 2 +- trunk/arch/m68k/sun3x/prom.c | 2 +- trunk/arch/m68knommu/kernel/setup.c | 41 +- trunk/arch/mips/Kconfig | 11 - trunk/arch/mips/kernel/cpu-probe.c | 26 +- trunk/arch/mips/kernel/process.c | 14 - trunk/arch/powerpc/Kconfig | 3 - trunk/arch/powerpc/configs/cell_defconfig | 3 +- trunk/arch/powerpc/kernel/crash.c | 67 - trunk/arch/powerpc/kernel/of_device.c | 122 +- trunk/arch/powerpc/kernel/of_platform.c | 82 +- trunk/arch/powerpc/kernel/prom.c | 250 +- trunk/arch/powerpc/kernel/time.c | 1 - trunk/arch/powerpc/oprofile/Kconfig | 7 - trunk/arch/powerpc/oprofile/Makefile | 4 +- trunk/arch/powerpc/oprofile/cell/pr_util.h | 97 - .../arch/powerpc/oprofile/cell/spu_profiler.c | 221 -- .../powerpc/oprofile/cell/spu_task_sync.c | 484 --- trunk/arch/powerpc/oprofile/cell/vma_map.c | 287 -- trunk/arch/powerpc/oprofile/common.c | 51 +- trunk/arch/powerpc/oprofile/op_model_7450.c | 14 +- trunk/arch/powerpc/oprofile/op_model_cell.c | 607 +-- .../powerpc/oprofile/op_model_fsl_booke.c | 11 +- trunk/arch/powerpc/oprofile/op_model_pa6t.c | 12 +- trunk/arch/powerpc/oprofile/op_model_power4.c | 11 +- trunk/arch/powerpc/oprofile/op_model_rs64.c | 10 +- trunk/arch/powerpc/platforms/Kconfig | 10 - trunk/arch/powerpc/platforms/cell/Kconfig | 10 - trunk/arch/powerpc/platforms/cell/Makefile | 6 +- trunk/arch/powerpc/platforms/cell/axon_msi.c | 445 --- .../arch/powerpc/platforms/cell/cbe_cpufreq.c | 217 +- .../arch/powerpc/platforms/cell/cbe_cpufreq.h | 24 - .../platforms/cell/cbe_cpufreq_pervasive.c | 115 - .../powerpc/platforms/cell/cbe_cpufreq_pmi.c | 148 - trunk/arch/powerpc/platforms/cell/cbe_regs.c | 7 - .../arch/powerpc/platforms/cell/cbe_thermal.c | 25 +- trunk/arch/powerpc/platforms/cell/spu_base.c | 295 +- .../powerpc/platforms/cell/spu_syscalls.c | 17 +- .../powerpc/platforms/cell/spufs/context.c | 42 +- .../powerpc/platforms/cell/spufs/coredump.c | 2 +- .../arch/powerpc/platforms/cell/spufs/fault.c | 8 +- .../arch/powerpc/platforms/cell/spufs/file.c | 104 +- .../arch/powerpc/platforms/cell/spufs/gang.c | 6 - .../arch/powerpc/platforms/cell/spufs/inode.c | 132 +- trunk/arch/powerpc/platforms/cell/spufs/run.c | 36 +- .../arch/powerpc/platforms/cell/spufs/sched.c | 377 +- .../platforms/cell/spufs/spu_restore.c | 6 +- .../cell/spufs/spu_restore_dump.h_shipped | 480 ++- .../arch/powerpc/platforms/cell/spufs/spufs.h | 99 +- .../powerpc/platforms/cell/spufs/switch.c | 72 +- .../powerpc/platforms/cell/spufs/syscalls.c | 34 +- trunk/arch/powerpc/sysdev/Makefile | 1 - trunk/arch/powerpc/sysdev/axonram.c | 381 -- trunk/arch/powerpc/sysdev/pmi.c | 51 +- trunk/arch/sh/Kconfig | 10 - trunk/arch/sh/Makefile | 3 +- trunk/arch/sh/boards/mpc1211/pci.c | 2 +- trunk/arch/sh/boards/renesas/r7780rp/setup.c | 54 - .../arch/sh/boards/renesas/rts7751r2d/setup.c | 3 +- trunk/arch/sh/boards/se/7722/irq.c | 96 +- trunk/arch/sh/boards/se/7722/setup.c | 5 +- trunk/arch/sh/cchips/hd6446x/Makefile | 2 - trunk/arch/sh/cchips/hd6446x/hd64461/Makefile | 6 + trunk/arch/sh/cchips/hd6446x/hd64461/io.c | 150 + .../hd6446x/{hd64461.c => hd64461/setup.c} | 1 + trunk/arch/sh/configs/landisk_defconfig | 2 +- trunk/arch/sh/configs/lboxre2_defconfig | 2 +- trunk/arch/sh/configs/r7780mp_defconfig | 2 +- trunk/arch/sh/configs/r7780rp_defconfig | 2 +- trunk/arch/sh/configs/rts7751r2d_defconfig | 8 +- trunk/arch/sh/configs/se7722_defconfig | 4 +- trunk/arch/sh/configs/se7750_defconfig | 2 +- trunk/arch/sh/configs/se7780_defconfig | 1 - trunk/arch/sh/drivers/dma/Kconfig | 3 +- trunk/arch/sh/drivers/heartbeat.c | 2 +- trunk/arch/sh/drivers/pci/Makefile | 1 - trunk/arch/sh/drivers/pci/ops-sh4.c | 2 +- trunk/arch/sh/drivers/pci/pci-st40.c | 2 +- trunk/arch/sh/drivers/pci/pci.c | 2 +- trunk/arch/sh/drivers/push-switch.c | 2 +- trunk/arch/sh/kernel/cpu/clock.c | 16 - trunk/arch/sh/kernel/cpu/irq/Makefile | 1 - trunk/arch/sh/kernel/cpu/irq/intc.c | 405 -- trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c | 2 +- trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 2 +- trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c | 2 +- trunk/arch/sh/kernel/cpu/sh3/setup-sh7709.c | 2 +- trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c | 2 +- trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c | 255 +- trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c | 8 +- trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 15 - trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 178 +- trunk/arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 221 +- trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 2 +- trunk/arch/sh/kernel/cpu/sh4a/setup-shx3.c | 2 +- trunk/arch/sh/kernel/cpufreq.c | 215 +- trunk/arch/sh/kernel/head.S | 3 +- trunk/arch/sh/kernel/irq.c | 9 +- trunk/arch/sh/kernel/setup.c | 7 +- trunk/arch/sh/kernel/sh_bios.c | 3 +- trunk/arch/sh/kernel/sh_ksyms.c | 35 - trunk/arch/sh/kernel/syscalls.S | 1 - trunk/arch/sh/kernel/vmlinux.lds.S | 1 - trunk/arch/sh/mm/Kconfig | 16 +- trunk/arch/sh64/configs/cayman_defconfig | 158 +- trunk/arch/sh64/kernel/head.S | 2 +- trunk/arch/sh64/kernel/pci_sh5.c | 4 +- trunk/arch/sh64/kernel/syscalls.S | 1 - trunk/arch/sh64/kernel/vmlinux.lds.S | 1 - trunk/arch/sh64/mm/ioremap.c | 2 +- trunk/arch/sparc/Kconfig | 3 - trunk/arch/sparc/kernel/ebus.c | 5 - trunk/arch/sparc/kernel/of_device.c | 227 +- trunk/arch/sparc/kernel/process.c | 8 +- trunk/arch/sparc/kernel/prom.c | 304 +- trunk/arch/sparc/kernel/setup.c | 65 +- trunk/arch/sparc/kernel/systbls.S | 9 +- trunk/arch/sparc/kernel/time.c | 2 +- trunk/arch/sparc/prom/console.c | 116 + trunk/arch/sparc/prom/misc.c | 4 +- trunk/arch/sparc64/Kconfig | 3 - trunk/arch/sparc64/defconfig | 24 +- trunk/arch/sparc64/kernel/auxio.c | 2 +- trunk/arch/sparc64/kernel/ds.c | 255 +- trunk/arch/sparc64/kernel/ebus.c | 5 - trunk/arch/sparc64/kernel/head.S | 1 + trunk/arch/sparc64/kernel/irq.c | 76 +- trunk/arch/sparc64/kernel/isa.c | 5 - trunk/arch/sparc64/kernel/mdesc.c | 62 +- trunk/arch/sparc64/kernel/of_device.c | 243 +- trunk/arch/sparc64/kernel/pci_sun4v.c | 4 +- trunk/arch/sparc64/kernel/power.c | 68 +- trunk/arch/sparc64/kernel/process.c | 6 +- trunk/arch/sparc64/kernel/prom.c | 229 +- trunk/arch/sparc64/kernel/setup.c | 70 +- trunk/arch/sparc64/kernel/sparc64_ksyms.c | 1 + trunk/arch/sparc64/kernel/sys_sparc32.c | 12 +- trunk/arch/sparc64/kernel/systbls.S | 11 +- trunk/arch/sparc64/kernel/time.c | 81 +- trunk/arch/sparc64/kernel/vio.c | 32 +- trunk/arch/sparc64/prom/console.c | 85 + trunk/arch/sparc64/prom/misc.c | 4 +- trunk/arch/sparc64/prom/tree.c | 8 - trunk/block/cfq-iosched.c | 67 +- trunk/crypto/async_tx/async_memcpy.c | 19 +- trunk/drivers/Kconfig | 2 - trunk/drivers/Makefile | 1 - trunk/drivers/acpi/processor_idle.c | 4 +- trunk/drivers/ata/ahci.c | 255 +- trunk/drivers/ata/libata-core.c | 79 +- trunk/drivers/ata/libata-eh.c | 204 +- trunk/drivers/ata/libata-scsi.c | 63 +- trunk/drivers/ata/libata-sff.c | 4 +- trunk/drivers/ata/libata.h | 3 +- trunk/drivers/ata/pata_cs5520.c | 2 +- trunk/drivers/ata/pata_platform.c | 5 +- trunk/drivers/ata/pata_scc.c | 29 +- trunk/drivers/ata/sata_inic162x.c | 16 +- trunk/drivers/ata/sata_mv.c | 203 +- trunk/drivers/ata/sata_nv.c | 38 +- trunk/drivers/ata/sata_promise.c | 25 +- trunk/drivers/ata/sata_qstor.c | 18 +- trunk/drivers/ata/sata_sil.c | 25 +- trunk/drivers/ata/sata_sil24.c | 139 +- trunk/drivers/ata/sata_sis.c | 22 +- trunk/drivers/ata/sata_svw.c | 13 +- trunk/drivers/ata/sata_uli.c | 16 +- trunk/drivers/ata/sata_via.c | 27 +- trunk/drivers/ata/sata_vsc.c | 13 +- trunk/drivers/block/sunvdc.c | 26 +- trunk/drivers/char/Kconfig | 6 +- trunk/drivers/char/hpet.c | 70 +- trunk/drivers/char/rtc.c | 30 +- trunk/drivers/char/serial167.c | 6 + trunk/drivers/char/tpm/tpm_bios.c | 22 +- trunk/drivers/char/vme_scc.c | 8 + trunk/drivers/char/watchdog/Kconfig | 2 +- trunk/drivers/ide/legacy/falconide.c | 2 - trunk/drivers/input/input.c | 29 +- trunk/drivers/input/joystick/Kconfig | 7 - trunk/drivers/input/joystick/xpad.c | 190 +- trunk/drivers/input/mouse/appletouch.c | 111 +- trunk/drivers/input/mouse/lifebook.c | 2 +- trunk/drivers/input/serio/i8042-x86ia64io.h | 36 +- trunk/drivers/input/touchscreen/Kconfig | 13 - trunk/drivers/input/touchscreen/Makefile | 1 - trunk/drivers/input/touchscreen/ads7846.c | 80 +- trunk/drivers/input/touchscreen/fujitsu_ts.c | 189 - trunk/drivers/kvm/kvm.h | 10 +- trunk/drivers/kvm/kvm_main.c | 76 +- trunk/drivers/kvm/mmu.c | 140 +- trunk/drivers/kvm/paging_tmpl.h | 2 - trunk/drivers/kvm/x86_emulate.c | 26 +- trunk/drivers/lguest/interrupts_and_traps.c | 10 +- trunk/drivers/lguest/io.c | 2 +- trunk/drivers/lguest/lguest.c | 9 +- trunk/drivers/lguest/lguest_asm.S | 4 +- trunk/drivers/md/raid5.c | 4 +- trunk/drivers/media/common/ir-functions.c | 4 +- trunk/drivers/media/dvb/ttpci/av7110.c | 2 +- trunk/drivers/media/radio/radio-aimslab.c | 2 +- trunk/drivers/media/radio/radio-cadet.c | 4 +- trunk/drivers/media/radio/radio-gemtek-pci.c | 3 + trunk/drivers/media/video/bt866.c | 2 +- trunk/drivers/media/video/bt8xx/bttv-cards.c | 2 +- trunk/drivers/media/video/bt8xx/bttv-input.c | 2 +- trunk/drivers/media/video/bt8xx/bttvp.h | 4 +- trunk/drivers/media/video/c-qcam.c | 4 +- trunk/drivers/media/video/cx88/cx88-video.c | 8 +- trunk/drivers/media/video/cx88/cx88.h | 2 +- trunk/drivers/media/video/ivtv/Kconfig | 5 +- trunk/drivers/media/video/ivtv/ivtv-driver.c | 43 +- trunk/drivers/media/video/ivtv/ivtv-driver.h | 2 +- trunk/drivers/media/video/ivtv/ivtv-fileops.c | 6 +- .../drivers/media/video/ivtv/ivtv-firmware.c | 25 +- trunk/drivers/media/video/ivtv/ivtv-gpio.c | 2 +- trunk/drivers/media/video/ivtv/ivtv-i2c.c | 20 +- trunk/drivers/media/video/ivtv/ivtv-irq.c | 11 +- trunk/drivers/media/video/ivtv/ivtv-mailbox.c | 33 +- trunk/drivers/media/video/ivtv/ivtv-streams.c | 12 +- trunk/drivers/media/video/saa5249.c | 8 +- trunk/drivers/media/video/saa7110.c | 4 +- trunk/drivers/media/video/saa7134/saa7134.h | 2 +- trunk/drivers/media/video/tvaudio.c | 4 +- trunk/drivers/media/video/v4l2-common.c | 19 +- trunk/drivers/media/video/vino.c | 2 +- trunk/drivers/media/video/wm8739.c | 2 - trunk/drivers/media/video/wm8775.c | 2 - trunk/drivers/net/mac89x0.c | 2 +- trunk/drivers/net/sky2.c | 7 +- trunk/drivers/net/sunvnet.c | 139 +- trunk/drivers/net/sunvnet.h | 11 - trunk/drivers/of/Kconfig | 3 - trunk/drivers/of/Makefile | 2 - trunk/drivers/of/base.c | 275 -- trunk/drivers/of/device.c | 131 - trunk/drivers/of/platform.c | 96 - trunk/drivers/oprofile/buffer_sync.c | 3 +- trunk/drivers/oprofile/event_buffer.h | 20 +- trunk/drivers/oprofile/oprof.c | 28 - trunk/drivers/parport/Kconfig | 2 +- trunk/drivers/rtc/Kconfig | 2 +- trunk/drivers/sbus/sbus.c | 5 - trunk/drivers/scsi/Kconfig | 2 +- trunk/drivers/scsi/NCR53C9x.c | 7 - trunk/drivers/scsi/iscsi_tcp.c | 2 +- trunk/drivers/serial/suncore.c | 123 +- trunk/drivers/serial/suncore.h | 2 - trunk/drivers/serial/sunhv.c | 13 +- trunk/drivers/serial/sunsab.c | 22 +- trunk/drivers/serial/sunsu.c | 23 +- trunk/drivers/serial/sunzilog.c | 24 +- trunk/drivers/usb/atm/cxacru.c | 3 +- trunk/drivers/usb/atm/speedtch.c | 7 +- trunk/drivers/usb/atm/ueagle-atm.c | 6 +- trunk/drivers/usb/atm/usbatm.c | 11 +- trunk/drivers/usb/class/cdc-acm.c | 18 +- trunk/drivers/usb/class/usblp.c | 27 +- trunk/drivers/usb/core/hcd.c | 131 +- trunk/drivers/usb/core/hub.c | 10 +- trunk/drivers/usb/core/message.c | 34 +- trunk/drivers/usb/core/sysfs.c | 53 - trunk/drivers/usb/core/urb.c | 88 +- trunk/drivers/usb/gadget/Kconfig | 57 +- trunk/drivers/usb/gadget/Makefile | 1 - trunk/drivers/usb/gadget/amd5536udc.c | 3454 ----------------- trunk/drivers/usb/gadget/amd5536udc.h | 626 --- trunk/drivers/usb/gadget/ether.c | 4 - trunk/drivers/usb/gadget/gadget_chips.h | 10 +- trunk/drivers/usb/gadget/m66592-udc.c | 255 +- trunk/drivers/usb/gadget/m66592-udc.h | 610 +-- trunk/drivers/usb/gadget/serial.c | 25 +- trunk/drivers/usb/host/isp116x-hcd.c | 187 +- trunk/drivers/usb/host/r8a66597-hcd.c | 110 +- trunk/drivers/usb/host/r8a66597.h | 87 +- trunk/drivers/usb/host/u132-hcd.c | 17 +- trunk/drivers/usb/host/uhci-q.c | 59 +- trunk/drivers/usb/image/mdc800.c | 45 +- trunk/drivers/usb/image/microtek.c | 19 +- trunk/drivers/usb/misc/adutux.c | 59 +- trunk/drivers/usb/misc/appledisplay.c | 9 +- trunk/drivers/usb/misc/auerswald.c | 25 +- trunk/drivers/usb/misc/ftdi-elan.c | 21 +- trunk/drivers/usb/misc/iowarrior.c | 21 +- trunk/drivers/usb/misc/ldusb.c | 20 +- trunk/drivers/usb/misc/legousbtower.c | 28 +- trunk/drivers/usb/misc/phidgetkit.c | 13 +- trunk/drivers/usb/misc/phidgetmotorcontrol.c | 13 +- trunk/drivers/usb/misc/usblcd.c | 11 +- trunk/drivers/usb/misc/usbtest.c | 4 +- trunk/drivers/usb/misc/uss720.c | 5 +- trunk/drivers/usb/serial/io_ti.c | 10 +- trunk/drivers/usb/serial/mos7720.c | 5 + trunk/drivers/usb/serial/mos7840.c | 19 + trunk/drivers/usb/serial/sierra.c | 119 +- trunk/drivers/usb/storage/dpcm.c | 56 +- trunk/drivers/usb/storage/onetouch.c | 13 +- trunk/drivers/usb/storage/unusual_devs.h | 18 - trunk/drivers/video/aty/atyfb_base.c | 4 + trunk/drivers/video/backlight/cr_bllcd.c | 2 +- trunk/drivers/video/igafb.c | 4 + trunk/fs/afs/rxrpc.c | 21 +- trunk/fs/buffer.c | 2 +- trunk/fs/ecryptfs/mmap.c | 5 +- trunk/fs/ocfs2/mmap.c | 2 +- trunk/fs/splice.c | 5 +- trunk/include/asm-ia64/hw_irq.h | 18 +- trunk/include/asm-ia64/iosapic.h | 6 +- trunk/include/asm-ia64/irq.h | 9 +- trunk/include/asm-ia64/rwsem.h | 4 - trunk/include/asm-ia64/unistd.h | 2 +- trunk/include/asm-m68k/io.h | 75 +- trunk/include/asm-m68k/raw_io.h | 8 +- trunk/include/asm-mips/atomic.h | 33 +- trunk/include/asm-mips/barrier.h | 9 - trunk/include/asm-mips/bitops.h | 10 +- trunk/include/asm-mips/ds1216.h | 31 + trunk/include/asm-mips/futex.h | 8 +- trunk/include/asm-mips/gfx.h | 55 + .../mach-cobalt/cpu-feature-overrides.h | 4 +- .../mach-excite/cpu-feature-overrides.h | 3 - .../mach-ip22/cpu-feature-overrides.h | 4 +- .../mach-ip27/cpu-feature-overrides.h | 4 +- .../mach-ip32/cpu-feature-overrides.h | 4 +- .../mach-qemu/cpu-feature-overrides.h | 3 +- .../asm-mips/mach-rm/cpu-feature-overrides.h | 4 +- .../mach-sibyte/cpu-feature-overrides.h | 4 +- .../mach-yosemite/cpu-feature-overrides.h | 4 +- trunk/include/asm-mips/spinlock.h | 18 +- trunk/include/asm-mips/system.h | 10 +- trunk/include/asm-powerpc/of_device.h | 22 +- trunk/include/asm-powerpc/of_platform.h | 38 +- trunk/include/asm-powerpc/oprofile_impl.h | 10 +- trunk/include/asm-powerpc/pmi.h | 8 +- trunk/include/asm-powerpc/prom.h | 50 +- trunk/include/asm-powerpc/spu.h | 62 +- trunk/include/asm-powerpc/spu_csa.h | 8 +- trunk/include/asm-sh/clock.h | 1 - trunk/include/asm-sh/hw_irq.h | 77 +- trunk/include/asm-sh/se7722.h | 40 +- trunk/include/asm-sh/unistd.h | 3 +- trunk/include/asm-sh64/unistd.h | 3 +- trunk/include/asm-sparc/device.h | 14 +- trunk/include/asm-sparc/fb.h | 9 - trunk/include/asm-sparc/of_device.h | 49 +- trunk/include/asm-sparc/of_platform.h | 32 - trunk/include/asm-sparc/oplib.h | 26 + trunk/include/asm-sparc/prom.h | 66 +- trunk/include/asm-sparc/unistd.h | 6 +- trunk/include/asm-sparc64/fb.h | 9 - trunk/include/asm-sparc64/of_device.h | 50 +- trunk/include/asm-sparc64/of_platform.h | 33 - trunk/include/asm-sparc64/oplib.h | 28 +- trunk/include/asm-sparc64/parport.h | 233 +- trunk/include/asm-sparc64/power.h | 7 + trunk/include/asm-sparc64/prom.h | 66 +- trunk/include/asm-sparc64/system.h | 6 + trunk/include/asm-sparc64/unistd.h | 6 +- trunk/include/asm-sparc64/vio.h | 2 - trunk/include/linux/async_tx.h | 6 + trunk/include/linux/clocksource.h | 6 - trunk/include/linux/dcookies.h | 1 - trunk/include/linux/elf-em.h | 3 +- trunk/include/linux/i2c-id.h | 7 +- trunk/include/linux/input.h | 3 +- trunk/include/linux/ioprio.h | 8 - trunk/include/linux/libata.h | 35 +- trunk/include/linux/of.h | 61 - trunk/include/linux/of_device.h | 26 - trunk/include/linux/of_platform.h | 57 - trunk/include/linux/oprofile.h | 35 - trunk/include/linux/serio.h | 1 - trunk/include/linux/slab.h | 2 +- trunk/include/linux/slub_def.h | 2 +- trunk/include/linux/spi/ads7846.h | 14 - trunk/include/linux/syscalls.h | 2 +- trunk/include/linux/timex.h | 60 + trunk/include/linux/videodev2.h | 1 - trunk/include/sound/ak4xxx-adda.h | 1 - trunk/include/sound/cs46xx.h | 4 - trunk/include/sound/cs46xx_dsp_spos.h | 2 - trunk/include/sound/emu10k1.h | 16 - trunk/include/sound/sb.h | 1 - trunk/include/sound/version.h | 2 +- trunk/include/sound/wavefront_fx.h | 9 + trunk/kernel/ksysfs.c | 4 +- trunk/kernel/time.c | 101 +- trunk/kernel/time/ntp.c | 10 + trunk/kernel/time/timekeeping.c | 4 + trunk/kernel/timer.c | 188 + trunk/mm/page_alloc.c | 2 +- trunk/net/netfilter/nf_conntrack_helper.c | 4 +- trunk/scripts/Lindent | 2 +- trunk/scripts/mod/modpost.c | 1 - trunk/sound/Kconfig | 2 - trunk/sound/Makefile | 2 +- trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c | 4 +- trunk/sound/core/pcm_native.c | 2 +- trunk/sound/core/seq/seq_instr.c | 6 +- trunk/sound/core/timer.c | 27 +- trunk/sound/drivers/dummy.c | 2 +- trunk/sound/drivers/mpu401/mpu401.c | 2 +- trunk/sound/drivers/portman2x4.c | 2 +- trunk/sound/drivers/serial-u16550.c | 2 +- trunk/sound/drivers/virmidi.c | 2 +- trunk/sound/i2c/other/ak4xxx-adda.c | 24 +- trunk/sound/isa/Kconfig | 32 +- trunk/sound/isa/ad1848/ad1848_lib.c | 4 +- trunk/sound/isa/opl3sa2.c | 2 - trunk/sound/isa/opti9xx/opti92x-ad1848.c | 3 - trunk/sound/isa/sb/Makefile | 15 +- trunk/sound/isa/sb/sb16_main.c | 10 - trunk/sound/isa/sb/sb_common.c | 5 +- trunk/sound/isa/sb/sb_mixer.c | 3 - trunk/sound/isa/sscape.c | 4 +- trunk/sound/isa/wavefront/wavefront_synth.c | 2 +- trunk/sound/pci/Kconfig | 11 - trunk/sound/pci/Makefile | 2 - trunk/sound/pci/ali5451/ali5451.c | 7 +- trunk/sound/pci/als300.c | 7 +- trunk/sound/pci/ca0106/ca0106_main.c | 19 - trunk/sound/pci/cs46xx/cs46xx_lib.c | 77 +- trunk/sound/pci/cs46xx/cs46xx_lib.h | 3 - trunk/sound/pci/cs46xx/dsp_spos.c | 170 +- trunk/sound/pci/cs5530.c | 306 -- trunk/sound/pci/emu10k1/emu10k1_main.c | 125 +- trunk/sound/pci/emu10k1/emufx.c | 78 +- trunk/sound/pci/emu10k1/emumixer.c | 16 - trunk/sound/pci/emu10k1/emupcm.c | 39 +- trunk/sound/pci/ens1370.c | 4 +- trunk/sound/pci/hda/hda_intel.c | 53 +- trunk/sound/pci/hda/hda_proc.c | 6 - trunk/sound/pci/hda/patch_analog.c | 630 +-- trunk/sound/pci/hda/patch_atihdmi.c | 1 - trunk/sound/pci/hda/patch_conexant.c | 2 - trunk/sound/pci/hda/patch_realtek.c | 925 +---- trunk/sound/pci/hda/patch_si3054.c | 4 - trunk/sound/pci/hda/patch_sigmatel.c | 266 +- trunk/sound/pci/ice1712/revo.c | 7 +- trunk/sound/pci/nm256/nm256.c | 3 +- trunk/sound/pci/rme9652/rme9652.c | 2 +- trunk/sound/pci/via82xx.c | 4 +- trunk/sound/pci/via82xx_modem.c | 4 +- trunk/sound/ppc/Kconfig | 20 - trunk/sound/ppc/Makefile | 3 +- trunk/sound/ppc/snd_ps3.c | 1125 ------ trunk/sound/ppc/snd_ps3.h | 135 - trunk/sound/ppc/snd_ps3_reg.h | 891 ----- trunk/sound/sh/Kconfig | 14 - trunk/sound/sh/Makefile | 8 - trunk/sound/sh/aica.c | 665 ---- trunk/sound/sh/aica.h | 81 - trunk/sound/soc/Kconfig | 1 - trunk/sound/soc/Makefile | 2 +- trunk/sound/soc/s3c24xx/Kconfig | 27 - trunk/sound/soc/s3c24xx/Makefile | 9 - trunk/sound/soc/s3c24xx/lm4857.h | 32 - trunk/sound/soc/s3c24xx/neo1973_wm8753.c | 670 ---- trunk/sound/soc/s3c24xx/s3c2443-ac97.c | 401 -- trunk/sound/soc/s3c24xx/s3c24xx-ac97.h | 25 - trunk/sound/soc/s3c24xx/s3c24xx-i2s.c | 4 +- trunk/sound/soc/s3c24xx/smdk2443_wm9710.c | 85 - trunk/sound/soc/sh/Kconfig | 38 - trunk/sound/soc/sh/Makefile | 14 - trunk/sound/soc/sh/dma-sh7760.c | 354 -- trunk/sound/soc/sh/hac.c | 322 -- trunk/sound/soc/sh/sh7760-ac97.c | 92 - trunk/sound/soc/sh/ssi.c | 400 -- trunk/sound/usb/usbaudio.c | 22 +- trunk/sound/usb/usbquirks.h | 72 +- trunk/sound/usb/usx2y/usbusx2yaudio.c | 7 +- 524 files changed, 8043 insertions(+), 24582 deletions(-) create mode 100644 trunk/Documentation/time_interpolators.txt delete mode 100644 trunk/arch/i386/xen/vdso.h delete mode 100644 trunk/arch/ia64/kernel/fsyscall_gtod_data.h delete mode 100644 trunk/arch/powerpc/oprofile/cell/pr_util.h delete mode 100644 trunk/arch/powerpc/oprofile/cell/spu_profiler.c delete mode 100644 trunk/arch/powerpc/oprofile/cell/spu_task_sync.c delete mode 100644 trunk/arch/powerpc/oprofile/cell/vma_map.c delete mode 100644 trunk/arch/powerpc/platforms/cell/axon_msi.c delete mode 100644 trunk/arch/powerpc/platforms/cell/cbe_cpufreq.h delete mode 100644 trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c delete mode 100644 trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c delete mode 100644 trunk/arch/powerpc/sysdev/axonram.c delete mode 100644 trunk/arch/sh/cchips/hd6446x/Makefile create mode 100644 trunk/arch/sh/cchips/hd6446x/hd64461/Makefile create mode 100644 trunk/arch/sh/cchips/hd6446x/hd64461/io.c rename trunk/arch/sh/cchips/hd6446x/{hd64461.c => hd64461/setup.c} (98%) delete mode 100644 trunk/arch/sh/kernel/cpu/irq/intc.c delete mode 100644 trunk/drivers/input/touchscreen/fujitsu_ts.c delete mode 100644 trunk/drivers/of/Kconfig delete mode 100644 trunk/drivers/of/Makefile delete mode 100644 trunk/drivers/of/base.c delete mode 100644 trunk/drivers/of/device.c delete mode 100644 trunk/drivers/of/platform.c delete mode 100644 trunk/drivers/usb/gadget/amd5536udc.c delete mode 100644 trunk/drivers/usb/gadget/amd5536udc.h create mode 100644 trunk/include/asm-mips/ds1216.h create mode 100644 trunk/include/asm-mips/gfx.h delete mode 100644 trunk/include/asm-sparc/of_platform.h delete mode 100644 trunk/include/asm-sparc64/of_platform.h create mode 100644 trunk/include/asm-sparc64/power.h delete mode 100644 trunk/include/linux/of.h delete mode 100644 trunk/include/linux/of_device.h delete mode 100644 trunk/include/linux/of_platform.h create mode 100644 trunk/include/sound/wavefront_fx.h delete mode 100644 trunk/sound/pci/cs5530.c delete mode 100644 trunk/sound/ppc/snd_ps3.c delete mode 100644 trunk/sound/ppc/snd_ps3.h delete mode 100644 trunk/sound/ppc/snd_ps3_reg.h delete mode 100644 trunk/sound/sh/Kconfig delete mode 100644 trunk/sound/sh/Makefile delete mode 100644 trunk/sound/sh/aica.c delete mode 100644 trunk/sound/sh/aica.h delete mode 100644 trunk/sound/soc/s3c24xx/lm4857.h delete mode 100644 trunk/sound/soc/s3c24xx/neo1973_wm8753.c delete mode 100644 trunk/sound/soc/s3c24xx/s3c2443-ac97.c delete mode 100644 trunk/sound/soc/s3c24xx/s3c24xx-ac97.h delete mode 100644 trunk/sound/soc/s3c24xx/smdk2443_wm9710.c delete mode 100644 trunk/sound/soc/sh/Kconfig delete mode 100644 trunk/sound/soc/sh/Makefile delete mode 100644 trunk/sound/soc/sh/dma-sh7760.c delete mode 100644 trunk/sound/soc/sh/hac.c delete mode 100644 trunk/sound/soc/sh/sh7760-ac97.c delete mode 100644 trunk/sound/soc/sh/ssi.c diff --git a/[refs] b/[refs] index 7db0469509ce..99f0f3cdb4c9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c2e68052429fdf87702fccd272951282bef1c60a +refs/heads/master: 81764fa9a472dd72b93385f30f718ed4f98ec129 diff --git a/trunk/.gitignore b/trunk/.gitignore index a232295b99ac..8d15830b883d 100644 --- a/trunk/.gitignore +++ b/trunk/.gitignore @@ -22,7 +22,6 @@ tags TAGS vmlinux* -!vmlinux.lds.S System.map Module.symvers diff --git a/trunk/CREDITS b/trunk/CREDITS index 10c214dc95e7..79fd13dbb8e4 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -2212,13 +2212,13 @@ S: 2300 Copenhagen S S: Denmark N: Claudio S. Matsuoka -E: cmatsuoka@gmail.com -E: claudio@mandriva.com +E: claudio@conectiva.com +E: claudio@helllabs.org W: http://helllabs.org/~claudio -D: V4L, OV511 and HDA-codec hacks +D: V4L, OV511 driver hacks S: Conectiva S.A. -S: Souza Naves 1250 -S: 80050-040 Curitiba PR +S: R. Tocantins 89 +S: 80050-430 Curitiba PR S: Brazil N: Heinz Mauelshagen diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 5fbe07706ae9..9a541486fb7e 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -1154,8 +1154,6 @@ and is between 256 and 4096 characters. It is defined in the file nointroute [IA-64] - nojitter [IA64] Disables jitter checking for ITC timers. - nolapic [IA-32,APIC] Do not enable or use the local APIC. nolapic_timer [IA-32,APIC] Do not use the local APIC timer. @@ -1887,9 +1885,6 @@ and is between 256 and 4096 characters. It is defined in the file vdso=1: enable VDSO (default) vdso=0: disable VDSO mapping - vector= [IA-64,SMP] - vector=percpu: enable percpu vector domain - video= [FB] Frame buffer configuration See Documentation/fb/modedb.txt. diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index 241e26c4ff92..355ff0a2bb7c 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -467,12 +467,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. above explicitly. The power-management is supported. - - Module snd-cs5530 - _________________ - - Module for Cyrix/NatSemi Geode 5530 chip. - + Module snd-cs5535audio ---------------------- @@ -764,7 +759,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. model - force the model name position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) - probe_mask - Bitmask to probe codecs (default = -1, meaning all slots) single_cmd - Use single immediate commands to communicate with codecs (for debugging only) enable_msi - Enable Message Signaled Interrupt (MSI) (default = off) @@ -809,8 +803,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. hp-3013 HP machines (3013-variant) fujitsu Fujitsu S7020 acer Acer TravelMate - will Will laptops (PB V7900) - replacer Replacer 672V basic fixed pin assignment (old default model) auto auto-config reading BIOS (default) @@ -819,31 +811,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. hp-bpc HP xw4400/6400/8400/9400 laptops hp-bpc-d7000 HP BPC D7000 benq Benq ED8 - benq-t31 Benq T31 hippo Hippo (ATI) with jack detection, Sony UX-90s hippo_1 Hippo (Benq) with jack detection - sony-assamd Sony ASSAMD basic fixed pin assignment w/o SPDIF auto auto-config reading BIOS (default) - ALC268 - 3stack 3-stack model - auto auto-config reading BIOS (default) - - ALC662 - 3stack-dig 3-stack (2-channel) with SPDIF - 3stack-6ch 3-stack (6-channel) - 3stack-6ch-dig 3-stack (6-channel) with SPDIF - 6stack-dig 6-stack with SPDIF - lenovo-101e Lenovo laptop - auto auto-config reading BIOS (default) - ALC882/885 3stack-dig 3-jack with SPDIF I/O 6stack-dig 6-jack digital with SPDIF I/O arima Arima W820Di1 macpro MacPro support - imac24 iMac 24'' with jack detection w2jc ASUS W2JC auto auto-config reading BIOS (default) @@ -855,15 +832,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 6stack-dig-demo 6-jack digital for Intel demo board acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc) medion Medion Laptops - medion-md2 Medion MD2 targa-dig Targa/MSI targa-2ch-dig Targs/MSI with 2-channel laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE) - lenovo-101e Lenovo 101E - lenovo-nb0763 Lenovo NB0763 - lenovo-ms7195-dig Lenovo MS7195 - 6stack-hp HP machines with 6stack (Nettle boards) - 3stack-hp HP machines with 3stack (Lucknow, Samba boards) auto auto-config reading BIOS (default) ALC861/660 @@ -882,9 +853,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 3stack-dig 3-jack with SPDIF OUT 6stack-dig 6-jack with SPDIF OUT 3stack-660 3-jack (for ALC660VD) - 3stack-660-digout 3-jack with SPDIF OUT (for ALC660VD) lenovo Lenovo 3000 C200 - dallas Dallas laptops auto auto-config reading BIOS (default) CMI9880 @@ -895,26 +864,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. allout 5-jack in back, 2-jack in front, SPDIF out auto auto-config reading BIOS (default) - AD1882 - 3stack 3-stack mode (default) - 6stack 6-stack mode - - AD1884 - N/A - AD1981 basic 3-jack (default) hp HP nx6320 thinkpad Lenovo Thinkpad T60/X60/Z60 toshiba Toshiba U205 - AD1983 - N/A - - AD1984 - basic default configuration - thinkpad Lenovo Thinkpad T61/X61 - AD1986A 6stack 6-jack, separate surrounds (default) 3stack 3-stack, shared surrounds @@ -952,18 +907,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ref Reference board 3stack D945 3stack 5stack D945 5stack + SPDIF - dell Dell XPS M1210 - intel-mac-v1 Intel Mac Type 1 - intel-mac-v2 Intel Mac Type 2 - intel-mac-v3 Intel Mac Type 3 - intel-mac-v4 Intel Mac Type 4 - intel-mac-v5 Intel Mac Type 5 - macmini Intel Mac Mini (equivalent with type 3) - macbook Intel Mac Book (eq. type 5) - macbook-pro-v1 Intel Mac Book Pro 1st generation (eq. type 3) - macbook-pro Intel Mac Book Pro 2nd generation (eq. type 3) - imac-intel Intel iMac (eq. type 2) - imac-intel-20 Intel iMac (newer version) (eq. type 3) + macmini Intel Mac Mini + macbook Intel Mac Book + macbook-pro-v1 Intel Mac Book Pro 1st generation + macbook-pro Intel Mac Book Pro 2nd generation + imac-intel Intel iMac STAC9202/9250/9251 ref Reference board, base config @@ -1008,17 +956,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. from the irq. Remember this is a last resort, and should be avoided as much as possible... - MORE NOTES ON "azx_get_response timeout" PROBLEMS: - On some hardwares, you may need to add a proper probe_mask option - to avoid the "azx_get_response timeout" problem above, instead. - This occurs when the access to non-existing or non-working codec slot - (likely a modem one) causes a stall of the communication via HD-audio - bus. You can see which codec slots are probed by enabling - CONFIG_SND_DEBUG_DETECT, or simply from the file name of the codec - proc files. Then limit the slots to probe by probe_mask option. - For example, probe_mask=1 means to probe only the first slot, and - probe_mask=4 means only the third slot. - The power-management is supported. Module snd-hdsp diff --git a/trunk/Documentation/sound/alsa/Audiophile-Usb.txt b/trunk/Documentation/sound/alsa/Audiophile-Usb.txt index 2ad5e6306c44..e40cce83327c 100644 --- a/trunk/Documentation/sound/alsa/Audiophile-Usb.txt +++ b/trunk/Documentation/sound/alsa/Audiophile-Usb.txt @@ -1,4 +1,4 @@ - Guide to using M-Audio Audiophile USB with ALSA and Jack v1.5 + Guide to using M-Audio Audiophile USB with ALSA and Jack v1.3 ======================================================== Thibault Le Meur @@ -6,19 +6,8 @@ This document is a guide to using the M-Audio Audiophile USB (tm) device with ALSA and JACK. -History -======= -* v1.4 - Thibault Le Meur (2007-07-11) - - Added Low Endianness nature of 16bits-modes - found by Hakan Lennestal - - Modifying document structure -* v1.5 - Thibault Le Meur (2007-07-12) - - Added AC3/DTS passthru info - - 1 - Audiophile USB Specs and correct usage ========================================== - This part is a reminder of important facts about the functions and limitations of the device. @@ -36,18 +25,18 @@ The device has 4 audio interfaces, and 2 MIDI ports: The internal DAC/ADC has the following characteristics: * sample depth of 16 or 24 bits * sample rate from 8kHz to 96kHz -* Two interfaces can't use different sample depths at the same time. -Moreover, the Audiophile USB documentation gives the following Warning: -"Please exit any audio application running before switching between bit depths" +* Two ports can't use different sample depths at the same time. Moreover, the +Audiophile USB documentation gives the following Warning: "Please exit any +audio application running before switching between bit depths" Due to the USB 1.1 bandwidth limitation, a limited number of interfaces can be activated at the same time depending on the audio mode selected: - * 16-bit/48kHz ==> 4 channels in + 4 channels out + * 16-bit/48kHz ==> 4 channels in/4 channels out - Ai+Ao+Di+Do - * 24-bit/48kHz ==> 4 channels in + 2 channels out, - or 2 channels in + 4 channels out + * 24-bit/48kHz ==> 4 channels in/2 channels out, + or 2 channels in/4 channels out - Ai+Ao+Do or Ai+Di+Ao or Ai+Di+Do or Di+Ao+Do - * 24-bit/96kHz ==> 2 channels in _or_ 2 channels out (half duplex only) + * 24-bit/96kHz ==> 2 channels in, or 2 channels out (half duplex only) - Ai or Ao or Di or Do Important facts about the Digital interface: @@ -63,56 +52,44 @@ source is connected synchronization error (for instance sound played at an odd sample rate) -2 - Audiophile USB MIDI support in ALSA -======================================= +2 - Audiophile USB support in ALSA +================================== -The Audiophile USB MIDI ports will be automatically supported once the +2.1 - MIDI ports +---------------- +The Audiophile USB MIDI ports will be automatically supported once the following modules have been loaded: * snd-usb-audio * snd-seq-midi No additional setting is required. - -3 - Audiophile USB Audio support in ALSA -======================================== +2.2 - Audio ports +----------------- Audio functions of the Audiophile USB device are handled by the snd-usb-audio module. This module can work in a default mode (without any device-specific parameter), or in an "advanced" mode with the device-specific parameter called "device_setup". -3.1 - Default Alsa driver mode ------------------------------- - -The default behavior of the snd-usb-audio driver is to list the device -capabilities at startup and activate the required mode when required -by the applications: for instance if the user is recording in a -24bit-depth-mode and immediately after wants to switch to a 16bit-depth mode, -the snd-usb-audio module will reconfigure the device on the fly. - -This approach has the advantage to let the driver automatically switch from sample -rates/depths automatically according to the user's needs. However, those who -are using the device under windows know that this is not how the device is meant to -work: under windows applications must be closed before using the m-audio control -panel to switch the device working mode. Thus as we'll see in next section, this -Default Alsa driver mode can lead to device misconfigurations. - -Let's get back to the Default Alsa driver mode for now. In this case the -Audiophile interfaces are mapped to alsa pcm devices in the following -way (I suppose the device's index is 1): +2.2.1 - Default Alsa driver mode + +The default behavior of the snd-usb-audio driver is to parse the device +capabilities at startup and enable all functions inside the device (including +all ports at any supported sample rates and sample depths). This approach +has the advantage to let the driver easily switch from sample rates/depths +automatically according to the need of the application claiming the device. + +In this case the Audiophile ports are mapped to alsa pcm devices in the +following way (I suppose the device's index is 1): * hw:1,0 is Ao in playback and Di in capture * hw:1,1 is Do in playback and Ai in capture * hw:1,2 is Do in AC3/DTS passthrough mode -In this mode, the device uses Big Endian byte-encoding so that -supported audio format are S16_BE for 16-bit depth modes and S24_3BE for -24-bits depth mode. - -One exception is the hw:1,2 port which was reported to be Little Endian -compliant (supposedly supporting S16_LE) but processes in fact only S16_BE streams. -This has been fixed in kernel 2.6.23 and above and now the hw:1,2 interface -is reported to be big endian in this default driver mode. +You must note as well that the device uses Big Endian byte encoding so that +supported audio format are S16_BE for 16-bit depth modes and S24_3BE for +24-bits depth mode. One exception is the hw:1,2 port which is Little Endian +compliant and thus uses S16_LE. Examples: * playing a S24_3BE encoded raw file to the Ao port @@ -121,26 +98,22 @@ Examples: % arecord -D hw:1,1 -c2 -t raw -r48000 -fS24_3BE test.raw * playing a S16_BE encoded raw file to the Do port % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test.raw - * playing an ac3 sample file to the Do port - % aplay -D hw:1,2 --channels=6 ac3_S16_BE_encoded_file.raw -If you're happy with the default Alsa driver mode and don't experience any +If you're happy with the default Alsa driver setup and don't experience any issue with this mode, then you can skip the following chapter. -3.2 - Advanced module setup ---------------------------- +2.2.2 - Advanced module setup Due to the hardware constraints described above, the device initialization made by the Alsa driver in default mode may result in a corrupted state of the device. For instance, a particularly annoying issue is that the sound captured -from the Ai interface sounds distorted (as if boosted with an excessive high -volume gain). +from the Ai port sounds distorted (as if boosted with an excessive high volume +gain). For people having this problem, the snd-usb-audio module has a new module -parameter called "device_setup" (this parameter was introduced in kernel -release 2.6.17) +parameter called "device_setup". -3.2.1 - Initializing the working mode of the Audiophile USB +2.2.2.1 - Initializing the working mode of the Audiophile USB As far as the Audiophile USB device is concerned, this value let the user specify: @@ -148,57 +121,33 @@ specify: * the sample rate * whether the Di port is used or not -When initialized with "device_setup=0x00", the snd-usb-audio module has -the same behaviour as when the parameter is omitted (see paragraph "Default -Alsa driver mode" above) - -Others modes are described in the following subsections. - -3.2.1.1 - 16-bit modes - -The two supported modes are: - +Here is a list of supported device_setup values for this device: + * device_setup=0x00 (or omitted) + - Alsa driver default mode + - maintains backward compatibility with setups that do not use this + parameter by not introducing any change + - results sometimes in corrupted sound as described earlier * device_setup=0x01 - 16bits 48kHz mode with Di disabled - Ai,Ao,Do can be used at the same time - hw:1,0 is not available in capture mode - hw:1,2 is not available - * device_setup=0x11 - 16bits 48kHz mode with Di enabled - Ai,Ao,Di,Do can be used at the same time - hw:1,0 is available in capture mode - hw:1,2 is not available - -In this modes the device operates only at 16bits-modes. Before kernel 2.6.23, -the devices where reported to be Big-Endian when in fact they were Little-Endian -so that playing a file was a matter of using: - % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test_S16_LE.raw -where "test_S16_LE.raw" was in fact a little-endian sample file. - -Thanks to Hakan Lennestal (who discovered the Little-Endiannes of the device in -these modes) a fix has been committed (expected in kernel 2.6.23) and -Alsa now reports Little-Endian interfaces. Thus playing a file now is as simple as -using: - % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_LE test_S16_LE.raw - -3.2.1.2 - 24-bit modes - -The three supported modes are: - * device_setup=0x09 - 24bits 48kHz mode with Di disabled - Ai,Ao,Do can be used at the same time - hw:1,0 is not available in capture mode - hw:1,2 is not available - * device_setup=0x19 - 24bits 48kHz mode with Di enabled - 3 ports from {Ai,Ao,Di,Do} can be used at the same time - hw:1,0 is available in capture mode and an active digital source must be connected to Di - hw:1,2 is not available - * device_setup=0x0D or 0x10 - 24bits 96kHz mode - Di is enabled by default for this mode but does not need to be connected @@ -206,64 +155,34 @@ The three supported modes are: - Only 1 port from {Ai,Ao,Di,Do} can be used at the same time - hw:1,0 is available in captured mode - hw:1,2 is not available - -In these modes the device is only Big-Endian compliant (see "Default Alsa driver -mode" above for an aplay command example) - -3.2.1.3 - AC3 w/ DTS passthru mode - -Thanks to Hakan Lennestal, I now have a report saying that this mode works. - * device_setup=0x03 - 16bits 48kHz mode with only the Do port enabled - - AC3 with DTS passthru + - AC3 with DTS passthru (not tested) - Caution with this setup the Do port is mapped to the pcm device hw:1,0 -The command line used to playback the AC3/DTS encoded .wav-files in this mode: - % aplay -D hw:1,0 --channels=6 ac3_S16_LE_encoded_file.raw - -3.2.2 - How to use the device_setup parameter ----------------------------------------------- +2.2.2.2 - Setting and switching configurations with the device_setup parameter The parameter can be given: - * By manually probing the device (as root): # modprobe -r snd-usb-audio # modprobe snd-usb-audio index=1 device_setup=0x09 - * Or while configuring the modules options in your modules configuration file - For Fedora distributions, edit the /etc/modprobe.conf file: alias snd-card-1 snd-usb-audio options snd-usb-audio index=1 device_setup=0x09 -CAUTION when initializaing the device -------------------------------------- - - * Correct initialization on the device requires that device_setup is given to - the module BEFORE the device is turned on. So, if you use the "manual probing" - method described above, take care to power-on the device AFTER this initialization. - - * Failing to respect this will lead in a misconfiguration of the device. In this case - turn off the device, unproble the snd-usb-audio module, then probe it again with - correct device_setup parameter and then (and only then) turn on the device again. - - * If you've correctly initialized the device in a valid mode and then want to switch - to another mode (possibly with another sample-depth), please use also the following - procedure: +IMPORTANT NOTE WHEN SWITCHING CONFIGURATION: +------------------------------------------- + * You may need to _first_ initialize the module with the correct device_setup + parameter and _only_after_ turn on the Audiophile USB device + * This is especially true when switching the sample depth: - first turn off the device - de-register the snd-usb-audio module (modprobe -r) - change the device_setup parameter by changing the device_setup option in /etc/modprobe.conf - turn on the device - * A workaround for this last issue has been applied to kernel 2.6.23, but it may not - be enough to ensure the 'stability' of the device initialization. -3.2.3 - Technical details for hackers -------------------------------------- -This section is for hackers, wanting to understand details about the device -internals and how Alsa supports it. - -3.2.3.1 - Audiophile USB's device_setup structure +2.2.2.3 - Audiophile USB's device_setup structure If you want to understand the device_setup magic numbers for the Audiophile USB, you need some very basic understanding of binary computation. However, @@ -309,12 +228,12 @@ Caution: - choosing b2 will prepare all interfaces for 24bits/96kHz but you'll only be able to use one at the same time -3.2.3.2 - USB implementation details for this device +2.2.3 - USB implementation details for this device You may safely skip this section if you're not interested in driver -hacking. +development. -This section describes some internal aspects of the device and summarizes the +This section describes some internal aspects of the device and summarize the data I got by usb-snooping the windows and Linux drivers. The M-Audio Audiophile USB has 7 USB Interfaces: @@ -374,45 +293,43 @@ parse_audio_endpoints function uses a quirk called "audiophile_skip_setting_quirk" in order to prevent AltSettings not corresponding to device_setup from being registered in the driver. -4 - Audiophile USB and Jack support +3 - Audiophile USB and Jack support =================================== This section deals with support of the Audiophile USB device in Jack. +The main issue regarding this support is that the device is Big Endian +compliant. -There are 2 main potential issues when using Jackd with the device: -* support for Big-Endian devices in 24-bit modes -* support for 4-in / 4-out channels - -4.1 - Direct support in Jackd ------------------------------ +3.1 - Using the plug alsa plugin +-------------------------------- -Jack supports big endian devices only in recent versions (thanks to -Andreas Steinmetz for his first big-endian patch). I can't remember -extacly when this support was released into jackd, let's just say that -with jackd version 0.103.0 it's almost ok (just a small bug is affecting -16bits Big-Endian devices, but since you've read carefully the above -paragraphs, you're now using kernel >= 2.6.23 and your 16bits devices -are now Little Endians ;-) ). - -You can run jackd with the following command for playback with Ao and -record with Ai: - % jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1 - -4.2 - Using Alsa plughw ------------------------ -If you don't have a recent Jackd installed, you can downgrade to using -the Alsa "plug" converter. +Jack doesn't directly support big endian devices. Thus, one way to have support +for this device with Alsa is to use the Alsa "plug" converter. For instance here is one way to run Jack with 2 playback channels on Ao and 2 capture channels from Ai: % jackd -R -dalsa -dplughw:1 -r48000 -p256 -n2 -D -Cplughw:1,1 + However you may see the following warning message: "You appear to be using the ALSA software "plug" layer, probably a result of using the "default" ALSA device. This is less efficient than it could be. Consider using a hardware device instead rather than using the plug layer." -4.3 - Getting 2 input and/or output interfaces in Jack +3.2 - Patching alsa to use direct pcm device +-------------------------------------------- +A patch for Jack by Andreas Steinmetz adds support for Big Endian devices. +However it has not been included in the CVS tree. + +You can find it at the following URL: +http://sourceforge.net/tracker/index.php?func=detail&aid=1289682&group_id=39687& +atid=425939 + +After having applied the patch you can run jackd with the following command +line: + % jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1 + +3.2 - Getting 2 input and/or output interfaces in Jack ------------------------------------------------------ As you can see, starting the Jack server this way will only enable 1 stereo @@ -422,7 +339,6 @@ This is due to the following restrictions: * Jack can only open one capture device and one playback device at a time * The Audiophile USB is seen as 2 (or three) Alsa devices: hw:1,0, hw:1,1 (and optionally hw:1,2) - If you want to get Ai+Di and/or Ao+Do support with Jack, you would need to combine the Alsa devices into one logical "complex" device. @@ -432,11 +348,13 @@ It is related to another device (ice1712) but can be adapted to suit the Audiophile USB. Enabling multiple Audiophile USB interfaces for Jackd will certainly require: -* Making sure your Jackd version has the MMAP_COMPLEX patch (see the ice1712 page) -* (maybe) patching the alsa-lib/src/pcm/pcm_multi.c file (see the ice1712 page) +* patching Jack with the previously mentioned "Big Endian" patch +* patching Jackd with the MMAP_COMPLEX patch (see the ice1712 page) +* patching the alsa-lib/src/pcm/pcm_multi.c file (see the ice1712 page) * define a multi device (combination of hw:1,0 and hw:1,1) in your .asoundrc file * start jackd with this device -I had no success in testing this for now, if you have any success with this kind -of setup, please drop me an email. +I had no success in testing this for now, but this may be due to my OS +configuration. If you have any success with this kind of setup, please +drop me an email. diff --git a/trunk/Documentation/sound/alsa/OSS-Emulation.txt b/trunk/Documentation/sound/alsa/OSS-Emulation.txt index bfa0c9aacb4b..ec2a02541d5b 100644 --- a/trunk/Documentation/sound/alsa/OSS-Emulation.txt +++ b/trunk/Documentation/sound/alsa/OSS-Emulation.txt @@ -278,21 +278,6 @@ current mixer configuration by reading and writing the whole file image. -Duplex Streams -============== - -Note that when attempting to use a single device file for playback and -capture, the OSS API provides no way to set the format, sample rate or -number of channels different in each direction. Thus - io_handle = open("device", O_RDWR) -will only function correctly if the values are the same in each direction. - -To use different values in the two directions, use both - input_handle = open("device", O_RDONLY) - output_handle = open("device", O_WRONLY) -and set the values for the corresponding handle. - - Unsupported Features ==================== diff --git a/trunk/Documentation/time_interpolators.txt b/trunk/Documentation/time_interpolators.txt new file mode 100644 index 000000000000..e3b60854fbc2 --- /dev/null +++ b/trunk/Documentation/time_interpolators.txt @@ -0,0 +1,41 @@ +Time Interpolators +------------------ + +Time interpolators are a base of time calculation between timer ticks and +allow an accurate determination of time down to the accuracy of the time +source in nanoseconds. + +The architecture specific code typically provides gettimeofday and +settimeofday under Linux. The time interpolator provides both if an arch +defines CONFIG_TIME_INTERPOLATION. The arch still must set up timer tick +operations and call the necessary functions to advance the clock. + +With the time interpolator a standardized interface exists for time +interpolation between ticks. The provided logic is highly scalable +and has been tested in SMP situations of up to 512 CPUs. + +If CONFIG_TIME_INTERPOLATION is defined then the architecture specific code +(or the device drivers - like HPET) may register time interpolators. +These are typically defined in the following way: + +static struct time_interpolator my_interpolator { + .frequency = MY_FREQUENCY, + .source = TIME_SOURCE_MMIO32, + .shift = 8, /* scaling for higher accuracy */ + .drift = -1, /* Unknown drift */ + .jitter = 0 /* time source is stable */ +}; + +void time_init(void) +{ + .... + /* Initialization of the timer *. + my_interpolator.address = &my_timer; + register_time_interpolator(&my_interpolator); + .... +} + +For more details see include/linux/timex.h and kernel/timer.c. + +Christoph Lameter , October 31, 2004 + diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index f49c5563f060..c9fab2be2c2c 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -329,12 +329,6 @@ P: Ivan Kokshaysky M: ink@jurassic.park.msu.ru S: Maintained for 2.4; PCI support for 2.6. -AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER -P: Thomas Dahlmann -M: thomas.dahlmann@amd.com -L: info-linux@geode.amd.com -S: Supported - AMD GEODE PROCESSOR/CHIPSET SUPPORT P: Jordan Crouse M: info-linux@geode.amd.com @@ -651,7 +645,12 @@ W: http://linux-atm.sourceforge.net S: Maintained ATMEL AT91 MCI DRIVER -S: Orphan +P: Nicolas Ferre +M: nicolas.ferre@rfo.atmel.com +L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) +W: http://www.atmel.com/products/AT91/ +W: http://www.at91.com/ +S: Maintained ATMEL MACB ETHERNET DRIVER P: Haavard Skinnemoen diff --git a/trunk/arch/arm/mm/fault.c b/trunk/arch/arm/mm/fault.c index 846cce48e2b7..c04124a095cf 100644 --- a/trunk/arch/arm/mm/fault.c +++ b/trunk/arch/arm/mm/fault.c @@ -145,8 +145,8 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) __do_kernel_fault(mm, addr, fsr, regs); } -#define VM_FAULT_BADMAP 0x010000 -#define VM_FAULT_BADACCESS 0x020000 +#define VM_FAULT_BADMAP (-20) +#define VM_FAULT_BADACCESS (-21) static int __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, @@ -249,7 +249,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) /* * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR */ - if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) + if (likely(!(fault & VM_FAULT_ERROR))) return 0; /* diff --git a/trunk/arch/i386/boot/compressed/relocs.c b/trunk/arch/i386/boot/compressed/relocs.c index 2d77ee728f92..b0e21c3cee5c 100644 --- a/trunk/arch/i386/boot/compressed/relocs.c +++ b/trunk/arch/i386/boot/compressed/relocs.c @@ -31,7 +31,6 @@ static const char* safe_abs_relocs[] = { "__kernel_rt_sigreturn", "__kernel_sigreturn", "SYSENTER_RETURN", - "VDSO_NOTE_MASK", "xen_irq_disable_direct_reloc", "xen_save_fl_direct_reloc", }; diff --git a/trunk/arch/i386/kernel/vsyscall-note.S b/trunk/arch/i386/kernel/vsyscall-note.S index 07c0daf78237..271f16a8ca01 100644 --- a/trunk/arch/i386/kernel/vsyscall-note.S +++ b/trunk/arch/i386/kernel/vsyscall-note.S @@ -14,6 +14,7 @@ ELFNOTE_START(Linux, 0, "a") ELFNOTE_END #ifdef CONFIG_XEN + /* * Add a special note telling glibc's dynamic linker a fake hardware * flavor that it will use to choose the search path for libraries in the @@ -27,19 +28,15 @@ ELFNOTE_END * It should contain: * hwcap 1 nosegneg * to match the mapping of bit to name that we give here. - * - * At runtime, the fake hardware feature will be considered to be present - * if its bit is set in the mask word. So, we start with the mask 0, and - * at boot time we set VDSO_NOTE_NONEGSEG_BIT if running under Xen. */ -#include "../xen/vdso.h" /* Defines VDSO_NOTE_NONEGSEG_BIT. */ +/* Bit used for the pseudo-hwcap for non-negative segments. We use + bit 1 to avoid bugs in some versions of glibc when bit 0 is + used; the choice is otherwise arbitrary. */ +#define VDSO_NOTE_NONEGSEG_BIT 1 - .globl VDSO_NOTE_MASK ELFNOTE_START(GNU, 2, "a") - .long 1 /* ncaps */ -VDSO_NOTE_MASK: - .long 0 /* mask */ + .long 1, 1< #include #include -#include #include #include diff --git a/trunk/arch/i386/xen/setup.c b/trunk/arch/i386/xen/setup.c index f84e77226646..2fe6eac510f0 100644 --- a/trunk/arch/i386/xen/setup.c +++ b/trunk/arch/i386/xen/setup.c @@ -19,7 +19,6 @@ #include #include "xen-ops.h" -#include "vdso.h" /* These are code, but not functions. Defined in entry.S */ extern const char xen_hypervisor_callback[]; @@ -56,18 +55,6 @@ static void xen_idle(void) } } -/* - * Set the bit indicating "nosegneg" library variants should be used. - */ -static void fiddle_vdso(void) -{ - extern u32 VDSO_NOTE_MASK; /* See ../kernel/vsyscall-note.S. */ - extern char vsyscall_int80_start; - u32 *mask = (u32 *) ((unsigned long) &VDSO_NOTE_MASK - VDSO_PRELINK + - &vsyscall_int80_start); - *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT; -} - void __init xen_arch_setup(void) { struct physdev_set_iopl set_iopl; @@ -106,6 +93,4 @@ void __init xen_arch_setup(void) #endif paravirt_disable_iospace(); - - fiddle_vdso(); } diff --git a/trunk/arch/i386/xen/vdso.h b/trunk/arch/i386/xen/vdso.h deleted file mode 100644 index 861fedfe5230..000000000000 --- a/trunk/arch/i386/xen/vdso.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Bit used for the pseudo-hwcap for non-negative segments. We use - bit 1 to avoid bugs in some versions of glibc when bit 0 is - used; the choice is otherwise arbitrary. */ -#define VDSO_NOTE_NONEGSEG_BIT 1 diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index 36c7b9682aa6..616c96e73483 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -62,11 +62,7 @@ config GENERIC_CALIBRATE_DELAY bool default y -config GENERIC_TIME - bool - default y - -config GENERIC_TIME_VSYSCALL +config TIME_INTERPOLATION bool default y diff --git a/trunk/arch/ia64/configs/bigsur_defconfig b/trunk/arch/ia64/configs/bigsur_defconfig index 9eb48c0927b0..90e9c2e61bf4 100644 --- a/trunk/arch/ia64/configs/bigsur_defconfig +++ b/trunk/arch/ia64/configs/bigsur_defconfig @@ -85,7 +85,7 @@ CONFIG_MMU=y CONFIG_SWIOTLB=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y +CONFIG_TIME_INTERPOLATION=y CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y diff --git a/trunk/arch/ia64/configs/gensparse_defconfig b/trunk/arch/ia64/configs/gensparse_defconfig index 3a9ed951db08..0d29aa2066b3 100644 --- a/trunk/arch/ia64/configs/gensparse_defconfig +++ b/trunk/arch/ia64/configs/gensparse_defconfig @@ -86,7 +86,7 @@ CONFIG_MMU=y CONFIG_SWIOTLB=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y +CONFIG_TIME_INTERPOLATION=y CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y diff --git a/trunk/arch/ia64/configs/sim_defconfig b/trunk/arch/ia64/configs/sim_defconfig index c420d9f3df98..d9146c31ea13 100644 --- a/trunk/arch/ia64/configs/sim_defconfig +++ b/trunk/arch/ia64/configs/sim_defconfig @@ -86,7 +86,7 @@ CONFIG_MMU=y CONFIG_SWIOTLB=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y +CONFIG_TIME_INTERPOLATION=y CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y diff --git a/trunk/arch/ia64/configs/sn2_defconfig b/trunk/arch/ia64/configs/sn2_defconfig index 4c9ffc47bc7a..64e951de4e57 100644 --- a/trunk/arch/ia64/configs/sn2_defconfig +++ b/trunk/arch/ia64/configs/sn2_defconfig @@ -93,7 +93,7 @@ CONFIG_SWIOTLB=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y +CONFIG_TIME_INTERPOLATION=y CONFIG_DMI=y CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y diff --git a/trunk/arch/ia64/configs/tiger_defconfig b/trunk/arch/ia64/configs/tiger_defconfig index 3dbb3987df27..a1446931b401 100644 --- a/trunk/arch/ia64/configs/tiger_defconfig +++ b/trunk/arch/ia64/configs/tiger_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22 -# Thu Jul 19 13:54:47 2007 +# Linux kernel version: 2.6.21-rc3 +# Thu Mar 8 11:07:09 2007 # CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -19,15 +19,15 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=20 # CONFIG_CPUSETS is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set @@ -46,19 +46,18 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set +CONFIG_VM_EVENT_COUNTERS=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set @@ -66,9 +65,12 @@ CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_KMOD=y CONFIG_STOP_MACHINE=y + +# +# Block layer +# CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -89,7 +91,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_IA64=y CONFIG_64BIT=y CONFIG_ZONE_DMA=y -CONFIG_QUICKLIST=y CONFIG_MMU=y CONFIG_SWIOTLB=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y @@ -97,7 +98,7 @@ CONFIG_RWSEM_XCHGADD_ALGORITHM=y # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y +CONFIG_TIME_INTERPOLATION=y CONFIG_DMI=y CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y @@ -113,8 +114,8 @@ CONFIG_IA64_DIG=y CONFIG_MCKINLEY=y # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set -# CONFIG_IA64_PAGE_SIZE_16KB is not set -CONFIG_IA64_PAGE_SIZE_64KB=y +CONFIG_IA64_PAGE_SIZE_16KB=y +# CONFIG_IA64_PAGE_SIZE_64KB is not set CONFIG_PGTABLE_3=y # CONFIG_PGTABLE_4 is not set # CONFIG_HZ_100 is not set @@ -144,9 +145,6 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_RESOURCES_64BIT=y CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_NR_QUICK=1 -CONFIG_VIRT_TO_BUS=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_DISCONTIGMEM_ENABLE=y CONFIG_ARCH_FLATMEM_ENABLE=y @@ -154,11 +152,11 @@ CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_VIRTUAL_MEM_MAP=y CONFIG_HOLES_IN_ZONE=y -# CONFIG_IA32_SUPPORT is not set +CONFIG_IA32_SUPPORT=y +CONFIG_COMPAT=y CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y -# CONFIG_IA64_MC_ERR_INJECT is not set # CONFIG_IA64_ESI is not set CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set @@ -168,7 +166,6 @@ CONFIG_KEXEC=y # CONFIG_EFI_VARS=y CONFIG_EFI_PCDP=y -CONFIG_DMIID=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m @@ -178,6 +175,7 @@ CONFIG_BINFMT_MISC=m CONFIG_PM=y CONFIG_PM_LEGACY=y # CONFIG_PM_DEBUG is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set # # ACPI (Advanced Configuration and Power Interface) Support @@ -207,11 +205,13 @@ CONFIG_ACPI_CONTAINER=m # CONFIG_PCI=y CONFIG_PCI_DOMAINS=y -CONFIG_PCI_SYSCALL=y # CONFIG_PCIEPORTBUS is not set -CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCI_MSI is not set # CONFIG_PCI_DEBUG is not set + +# +# PCI Hotplug Support +# CONFIG_HOTPLUG_PCI=m # CONFIG_HOTPLUG_PCI_FAKE is not set CONFIG_HOTPLUG_PCI_ACPI=m @@ -232,6 +232,7 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -269,8 +270,20 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# # CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# # CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -296,17 +309,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set # # Device Drivers @@ -321,9 +324,25 @@ CONFIG_FW_LOADER=m # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# # CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# # CONFIG_MTD is not set + +# +# Parallel port support +# # CONFIG_PARPORT is not set + +# +# Plug and Play support +# CONFIG_PNP=y # CONFIG_PNP_DEBUG is not set @@ -331,7 +350,10 @@ CONFIG_PNP=y # Protocols # CONFIG_PNPACPI=y -CONFIG_BLK_DEV=y + +# +# Block devices +# # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -348,11 +370,16 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y -# CONFIG_PHANTOM is not set -# CONFIG_EEPROM_93CX6 is not set + +# +# Misc devices +# # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set + +# +# ATA/ATAPI/MFM/RLL support +# CONFIG_IDE=y CONFIG_IDE_MAX_HWIFS=4 CONFIG_BLK_DEV_IDE=y @@ -369,7 +396,6 @@ CONFIG_BLK_DEV_IDEFLOPPY=y CONFIG_BLK_DEV_IDESCSI=m # CONFIG_BLK_DEV_IDEACPI is not set # CONFIG_IDE_TASK_IOCTL is not set -CONFIG_IDE_PROC_FS=y # # IDE chipset support/bugfixes @@ -378,12 +404,12 @@ CONFIG_IDE_PROC_FS=y # CONFIG_BLK_DEV_IDEPNP is not set CONFIG_BLK_DEV_IDEPCI=y # CONFIG_IDEPCI_SHARE_IRQ is not set -CONFIG_IDEPCI_PCIBUS_ORDER=y # CONFIG_BLK_DEV_OFFBOARD is not set CONFIG_BLK_DEV_GENERIC=y # CONFIG_BLK_DEV_OPTI621 is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set @@ -412,6 +438,7 @@ CONFIG_BLK_DEV_PIIX=y # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y # CONFIG_BLK_DEV_HD is not set # @@ -419,7 +446,6 @@ CONFIG_BLK_DEV_IDEDMA=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -CONFIG_SCSI_DMA=y # CONFIG_SCSI_TGT is not set CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y @@ -442,7 +468,6 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -489,7 +514,15 @@ CONFIG_SCSI_QLOGIC_1280=y # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SRP is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# # CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# CONFIG_MD=y CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m @@ -506,7 +539,6 @@ CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m # CONFIG_DM_MULTIPATH is not set -# CONFIG_DM_DELAY is not set # # Fusion MPT device support @@ -521,25 +553,46 @@ CONFIG_FUSION_CTL=y # # IEEE 1394 (FireWire) support # -# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set + +# +# I2O device support +# # CONFIG_I2O is not set + +# +# Network device support +# CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set CONFIG_DUMMY=m # CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_NET_SB1000 is not set + +# +# ARCnet devices +# # CONFIG_ARCNET is not set + +# +# PHY device support +# # CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# CONFIG_NET_ETHERNET=y CONFIG_MII=m # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# CONFIG_NET_TULIP=y # CONFIG_DE2104X is not set CONFIG_TULIP=m @@ -570,7 +623,10 @@ CONFIG_E100=m # CONFIG_SUNDANCE is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set -CONFIG_NETDEV_1000=y + +# +# Ethernet (1000 Mbit) +# # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=y @@ -583,36 +639,36 @@ CONFIG_E1000=y # CONFIG_SIS190 is not set # CONFIG_SKGE is not set # CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y # CONFIG_BNX2 is not set # CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set -CONFIG_NETDEV_10000=y + +# +# Ethernet (10000 Mbit) +# # CONFIG_CHELSIO_T1 is not set # CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set -# CONFIG_MLX4_CORE is not set + +# +# Token Ring devices +# # CONFIG_TR is not set # -# Wireless LAN +# Wireless LAN (non-hamradio) # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_NET_RADIO is not set # -# USB Network Adapters +# Wan interfaces # -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -622,9 +678,18 @@ CONFIG_NETDEV_10000=y # CONFIG_SHAPER is not set CONFIG_NETCONSOLE=y CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set # CONFIG_NETPOLL_TRAP is not set CONFIG_NET_POLL_CONTROLLER=y + +# +# ISDN subsystem +# # CONFIG_ISDN is not set + +# +# Telephony Support +# # CONFIG_PHONE is not set # @@ -632,7 +697,6 @@ CONFIG_NET_POLL_CONTROLLER=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -658,17 +722,9 @@ CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_LIFEBOOK=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_TOUCHKIT is not set # CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_APPLETOUCH is not set # CONFIG_MOUSE_VSXXXAA is not set # CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -734,10 +790,19 @@ CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# # CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set CONFIG_EFI_RTC=y +# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set CONFIG_AGP=m @@ -756,8 +821,15 @@ CONFIG_HPET=y # CONFIG_HPET_RTC_IRQ is not set CONFIG_HPET_MMAP=y # CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# # CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y + +# +# I2C support +# # CONFIG_I2C is not set # @@ -765,17 +837,21 @@ CONFIG_DEVPORT=y # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# # CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set + +# +# Hardware Monitoring support +# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_W83627HF is not set # CONFIG_HWMON_DEBUG_CHIP is not set # @@ -787,20 +863,17 @@ CONFIG_HWMON=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set # -# Graphics support +# Digital Video Broadcasting Devices # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set # -# Display device support +# Graphics support # -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_VGASTATE is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # CONFIG_FB is not set # @@ -814,18 +887,16 @@ CONFIG_DUMMY_CONSOLE=y # Sound # # CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y + +# +# HID Devices +# CONFIG_HID=y # CONFIG_HID_DEBUG is not set # -# USB Input Devices +# USB support # -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set -CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y @@ -836,10 +907,8 @@ CONFIG_USB=y # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y -CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set -# CONFIG_USB_PERSIST is not set # CONFIG_USB_OTG is not set # @@ -849,6 +918,7 @@ CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set # CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=m # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set @@ -856,7 +926,6 @@ CONFIG_USB_OHCI_HCD=m CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set # # USB Device Class drivers @@ -885,11 +954,42 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_LIBUSUAL is not set +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set +# CONFIG_USB_GTCO is not set + # # USB Imaging devices # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set # CONFIG_USB_MON is not set # @@ -933,6 +1033,10 @@ CONFIG_USB_STORAGE=m # USB Gadget Support # # CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# # CONFIG_MMC is not set # @@ -947,8 +1051,16 @@ CONFIG_USB_STORAGE=m # # LED Triggers # + +# +# InfiniBand support +# # CONFIG_INFINIBAND is not set +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + # # Real Time Clock # @@ -968,9 +1080,12 @@ CONFIG_USB_STORAGE=m # # -# Userspace I/O +# Auxiliary Display support +# + +# +# Virtualization # -# CONFIG_UIO is not set # CONFIG_MSPEC is not set # @@ -1085,8 +1200,7 @@ CONFIG_EXPORTFS=m CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m -# CONFIG_SUNRPC_BIND34 is not set -CONFIG_RPCSEC_GSS_KRB5=y +CONFIG_RPCSEC_GSS_KRB5=m # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m CONFIG_SMB_NLS_DEFAULT=y @@ -1100,6 +1214,7 @@ CONFIG_CIFS=m # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -1121,7 +1236,6 @@ CONFIG_SGI_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set CONFIG_EFI_PARTITION=y -# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -1178,14 +1292,11 @@ CONFIG_NLS_UTF8=m CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y -# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_PENDING_IRQ=y @@ -1208,8 +1319,8 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOG_BUF_SHIFT=20 CONFIG_DETECT_SOFTLOCKUP=y -CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set @@ -1232,12 +1343,17 @@ CONFIG_IA64_GRANULE_16MB=y # CONFIG_DISABLE_VHPT is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_SYSVIPC_COMPAT=y # # Security options # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set + +# +# Cryptographic options +# CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=m @@ -1257,7 +1373,6 @@ CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=m # CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set @@ -1275,4 +1390,7 @@ CONFIG_CRYPTO_DES=m # CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set -CONFIG_CRYPTO_HW=y + +# +# Hardware crypto devices +# diff --git a/trunk/arch/ia64/configs/zx1_defconfig b/trunk/arch/ia64/configs/zx1_defconfig index 4a060fc39934..1c7955c16358 100644 --- a/trunk/arch/ia64/configs/zx1_defconfig +++ b/trunk/arch/ia64/configs/zx1_defconfig @@ -96,7 +96,7 @@ CONFIG_RWSEM_XCHGADD_ALGORITHM=y # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y +CONFIG_TIME_INTERPOLATION=y CONFIG_DMI=y CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y diff --git a/trunk/arch/ia64/defconfig b/trunk/arch/ia64/defconfig index 03172dc8c403..90bd9601cdde 100644 --- a/trunk/arch/ia64/defconfig +++ b/trunk/arch/ia64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22 -# Thu Jul 19 13:55:32 2007 +# Linux kernel version: 2.6.21-rc3 +# Thu Mar 8 11:01:03 2007 # CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -19,15 +19,15 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=20 # CONFIG_CPUSETS is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set @@ -46,19 +46,18 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set +CONFIG_VM_EVENT_COUNTERS=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set @@ -66,9 +65,12 @@ CONFIG_MODVERSIONS=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y CONFIG_STOP_MACHINE=y + +# +# Block layer +# CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -89,7 +91,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_IA64=y CONFIG_64BIT=y CONFIG_ZONE_DMA=y -CONFIG_QUICKLIST=y CONFIG_MMU=y CONFIG_SWIOTLB=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y @@ -97,7 +98,7 @@ CONFIG_RWSEM_XCHGADD_ALGORITHM=y # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y +CONFIG_TIME_INTERPOLATION=y CONFIG_DMI=y CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y @@ -113,8 +114,8 @@ CONFIG_IA64_GENERIC=y CONFIG_MCKINLEY=y # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set -# CONFIG_IA64_PAGE_SIZE_16KB is not set -CONFIG_IA64_PAGE_SIZE_64KB=y +CONFIG_IA64_PAGE_SIZE_16KB=y +# CONFIG_IA64_PAGE_SIZE_64KB is not set CONFIG_PGTABLE_3=y # CONFIG_PGTABLE_4 is not set # CONFIG_HZ_100 is not set @@ -146,9 +147,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y CONFIG_RESOURCES_64BIT=y CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_NR_QUICK=1 -CONFIG_VIRT_TO_BUS=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_DISCONTIGMEM_ENABLE=y CONFIG_ARCH_FLATMEM_ENABLE=y @@ -166,7 +164,7 @@ CONFIG_COMPAT=y CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y -# CONFIG_IA64_MC_ERR_INJECT is not set +# CONFIG_MC_ERR_INJECT is not set CONFIG_SGI_SN=y # CONFIG_IA64_ESI is not set @@ -182,7 +180,6 @@ CONFIG_CRASH_DUMP=y # CONFIG_EFI_VARS=y CONFIG_EFI_PCDP=y -CONFIG_DMIID=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m @@ -192,6 +189,7 @@ CONFIG_BINFMT_MISC=m CONFIG_PM=y CONFIG_PM_LEGACY=y # CONFIG_PM_DEBUG is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set # # ACPI (Advanced Configuration and Power Interface) Support @@ -222,11 +220,13 @@ CONFIG_ACPI_CONTAINER=m # CONFIG_PCI=y CONFIG_PCI_DOMAINS=y -CONFIG_PCI_SYSCALL=y # CONFIG_PCIEPORTBUS is not set -CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCI_MSI is not set # CONFIG_PCI_DEBUG is not set + +# +# PCI Hotplug Support +# CONFIG_HOTPLUG_PCI=m # CONFIG_HOTPLUG_PCI_FAKE is not set CONFIG_HOTPLUG_PCI_ACPI=m @@ -248,6 +248,7 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -285,8 +286,20 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# # CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# # CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -312,17 +325,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set # # Device Drivers @@ -337,9 +340,25 @@ CONFIG_FW_LOADER=m # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# # CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# # CONFIG_MTD is not set + +# +# Parallel port support +# # CONFIG_PARPORT is not set + +# +# Plug and Play support +# CONFIG_PNP=y # CONFIG_PNP_DEBUG is not set @@ -347,7 +366,10 @@ CONFIG_PNP=y # Protocols # CONFIG_PNPACPI=y -CONFIG_BLK_DEV=y + +# +# Block devices +# # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -364,11 +386,16 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y -# CONFIG_PHANTOM is not set -# CONFIG_EEPROM_93CX6 is not set + +# +# Misc devices +# CONFIG_SGI_IOC4=y # CONFIG_TIFM_CORE is not set + +# +# ATA/ATAPI/MFM/RLL support +# CONFIG_IDE=y CONFIG_IDE_MAX_HWIFS=4 CONFIG_BLK_DEV_IDE=y @@ -385,7 +412,6 @@ CONFIG_BLK_DEV_IDEFLOPPY=y CONFIG_BLK_DEV_IDESCSI=m # CONFIG_BLK_DEV_IDEACPI is not set # CONFIG_IDE_TASK_IOCTL is not set -CONFIG_IDE_PROC_FS=y # # IDE chipset support/bugfixes @@ -394,12 +420,12 @@ CONFIG_IDE_PROC_FS=y # CONFIG_BLK_DEV_IDEPNP is not set CONFIG_BLK_DEV_IDEPCI=y CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_IDEPCI_PCIBUS_ORDER=y # CONFIG_BLK_DEV_OFFBOARD is not set CONFIG_BLK_DEV_GENERIC=y # CONFIG_BLK_DEV_OPTI621 is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set @@ -429,6 +455,7 @@ CONFIG_BLK_DEV_SGIIOC4=y # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y # CONFIG_BLK_DEV_HD is not set # @@ -436,7 +463,6 @@ CONFIG_BLK_DEV_IDEDMA=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -CONFIG_SCSI_DMA=y # CONFIG_SCSI_TGT is not set CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y @@ -459,7 +485,6 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -467,7 +492,7 @@ CONFIG_SCSI_WAIT_SCAN=m CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y # CONFIG_SCSI_ISCSI_ATTRS is not set -CONFIG_SCSI_SAS_ATTRS=y +# CONFIG_SCSI_SAS_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set # @@ -506,7 +531,15 @@ CONFIG_SCSI_QLOGIC_1280=y # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SRP is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# # CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# CONFIG_MD=y CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m @@ -524,8 +557,6 @@ CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m # CONFIG_DM_MULTIPATH_EMC is not set -# CONFIG_DM_MULTIPATH_RDAC is not set -# CONFIG_DM_DELAY is not set # # Fusion MPT device support @@ -533,32 +564,53 @@ CONFIG_DM_MULTIPATH=m CONFIG_FUSION=y CONFIG_FUSION_SPI=y CONFIG_FUSION_FC=m -CONFIG_FUSION_SAS=y +# CONFIG_FUSION_SAS is not set CONFIG_FUSION_MAX_SGE=128 # CONFIG_FUSION_CTL is not set # # IEEE 1394 (FireWire) support # -# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set + +# +# I2O device support +# # CONFIG_I2O is not set + +# +# Network device support +# CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set CONFIG_DUMMY=m # CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_NET_SB1000 is not set + +# +# ARCnet devices +# # CONFIG_ARCNET is not set + +# +# PHY device support +# # CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# CONFIG_NET_ETHERNET=y CONFIG_MII=m # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# CONFIG_NET_TULIP=y # CONFIG_DE2104X is not set CONFIG_TULIP=m @@ -589,7 +641,10 @@ CONFIG_E100=m # CONFIG_SUNDANCE is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set -CONFIG_NETDEV_1000=y + +# +# Ethernet (1000 Mbit) +# # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=y @@ -602,36 +657,36 @@ CONFIG_E1000=y # CONFIG_SIS190 is not set # CONFIG_SKGE is not set # CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y # CONFIG_BNX2 is not set # CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set -CONFIG_NETDEV_10000=y + +# +# Ethernet (10000 Mbit) +# # CONFIG_CHELSIO_T1 is not set # CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set -# CONFIG_MLX4_CORE is not set + +# +# Token Ring devices +# # CONFIG_TR is not set # -# Wireless LAN +# Wireless LAN (non-hamradio) # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_NET_RADIO is not set # -# USB Network Adapters +# Wan interfaces # -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -641,9 +696,18 @@ CONFIG_NETDEV_10000=y # CONFIG_SHAPER is not set CONFIG_NETCONSOLE=y CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set # CONFIG_NETPOLL_TRAP is not set CONFIG_NET_POLL_CONTROLLER=y + +# +# ISDN subsystem +# # CONFIG_ISDN is not set + +# +# Telephony Support +# # CONFIG_PHONE is not set # @@ -651,7 +715,6 @@ CONFIG_NET_POLL_CONTROLLER=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -677,17 +740,9 @@ CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_LIFEBOOK=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_TOUCHKIT is not set # CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_APPLETOUCH is not set # CONFIG_MOUSE_VSXXXAA is not set # CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -759,10 +814,19 @@ CONFIG_SERIAL_SGI_IOC4=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# # CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set CONFIG_EFI_RTC=y +# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set CONFIG_AGP=m @@ -784,8 +848,15 @@ CONFIG_HPET=y CONFIG_HPET_MMAP=y # CONFIG_HANGCHECK_TIMER is not set CONFIG_MMTIMER=y + +# +# TPM devices +# # CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y + +# +# I2C support +# # CONFIG_I2C is not set # @@ -793,17 +864,21 @@ CONFIG_DEVPORT=y # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# # CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set + +# +# Hardware Monitoring support +# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_W83627HF is not set # CONFIG_HWMON_DEBUG_CHIP is not set # @@ -815,20 +890,17 @@ CONFIG_HWMON=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set # -# Graphics support +# Digital Video Broadcasting Devices # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set # -# Display device support +# Graphics support # -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_VGASTATE is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # CONFIG_FB is not set # @@ -942,10 +1014,9 @@ CONFIG_SND_FM801=m # USB devices # # CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_CAIAQ is not set # -# System on Chip audio support +# SoC audio support # # CONFIG_SND_SOC is not set @@ -954,24 +1025,16 @@ CONFIG_SND_FM801=m # # CONFIG_SOUND_PRIME is not set CONFIG_AC97_BUS=m -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # -# USB Input Devices +# HID Devices # -CONFIG_USB_HID=m -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set # -# USB HID Boot Protocol drivers +# USB support # -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y @@ -982,10 +1045,8 @@ CONFIG_USB=m # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y -CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set -# CONFIG_USB_PERSIST is not set # CONFIG_USB_OTG is not set # @@ -995,6 +1056,7 @@ CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set # CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=m # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set @@ -1002,7 +1064,6 @@ CONFIG_USB_OHCI_HCD=m CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_UHCI_HCD=m # CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set # # USB Device Class drivers @@ -1031,11 +1092,48 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_LIBUSUAL is not set +# +# USB Input Devices +# +CONFIG_USB_HID=m +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set +# CONFIG_USB_GTCO is not set + # # USB Imaging devices # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set CONFIG_USB_MON=y # @@ -1079,6 +1177,10 @@ CONFIG_USB_MON=y # USB Gadget Support # # CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# # CONFIG_MMC is not set # @@ -1093,6 +1195,10 @@ CONFIG_USB_MON=y # # LED Triggers # + +# +# InfiniBand support +# CONFIG_INFINIBAND=m # CONFIG_INFINIBAND_USER_MAD is not set # CONFIG_INFINIBAND_USER_ACCESS is not set @@ -1100,7 +1206,6 @@ CONFIG_INFINIBAND_ADDR_TRANS=y CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_MTHCA_DEBUG=y # CONFIG_INFINIBAND_AMSO1100 is not set -# CONFIG_MLX4_INFINIBAND is not set CONFIG_INFINIBAND_IPOIB=m # CONFIG_INFINIBAND_IPOIB_CM is not set CONFIG_INFINIBAND_IPOIB_DEBUG=y @@ -1108,6 +1213,10 @@ CONFIG_INFINIBAND_IPOIB_DEBUG=y # CONFIG_INFINIBAND_SRP is not set # CONFIG_INFINIBAND_ISER is not set +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + # # Real Time Clock # @@ -1127,9 +1236,12 @@ CONFIG_INFINIBAND_IPOIB_DEBUG=y # # -# Userspace I/O +# Auxiliary Display support +# + +# +# Virtualization # -# CONFIG_UIO is not set # CONFIG_MSPEC is not set # @@ -1245,8 +1357,7 @@ CONFIG_EXPORTFS=m CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m -# CONFIG_SUNRPC_BIND34 is not set -CONFIG_RPCSEC_GSS_KRB5=y +CONFIG_RPCSEC_GSS_KRB5=m # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m CONFIG_SMB_NLS_DEFAULT=y @@ -1260,6 +1371,7 @@ CONFIG_CIFS=m # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -1281,7 +1393,6 @@ CONFIG_SGI_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set CONFIG_EFI_PARTITION=y -# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -1338,14 +1449,11 @@ CONFIG_NLS_UTF8=m CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y -# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_PENDING_IRQ=y @@ -1375,8 +1483,8 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOG_BUF_SHIFT=20 CONFIG_DETECT_SOFTLOCKUP=y -CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set @@ -1406,6 +1514,10 @@ CONFIG_SYSVIPC_COMPAT=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set + +# +# Cryptographic options +# CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=m @@ -1425,7 +1537,6 @@ CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=m # CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set @@ -1443,4 +1554,7 @@ CONFIG_CRYPTO_DES=m # CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set -CONFIG_CRYPTO_HW=y + +# +# Hardware crypto devices +# diff --git a/trunk/arch/ia64/kernel/asm-offsets.c b/trunk/arch/ia64/kernel/asm-offsets.c index 0aebc6f79e95..2236fabbb3c6 100644 --- a/trunk/arch/ia64/kernel/asm-offsets.c +++ b/trunk/arch/ia64/kernel/asm-offsets.c @@ -7,7 +7,6 @@ #define ASM_OFFSETS_C 1 #include -#include #include #include @@ -16,7 +15,6 @@ #include #include "../kernel/sigframe.h" -#include "../kernel/fsyscall_gtod_data.h" #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -258,24 +256,17 @@ void foo(void) BLANK(); /* used by fsys_gettimeofday in arch/ia64/kernel/fsys.S */ - DEFINE(IA64_GTOD_LOCK_OFFSET, - offsetof (struct fsyscall_gtod_data_t, lock)); - DEFINE(IA64_GTOD_WALL_TIME_OFFSET, - offsetof (struct fsyscall_gtod_data_t, wall_time)); - DEFINE(IA64_GTOD_MONO_TIME_OFFSET, - offsetof (struct fsyscall_gtod_data_t, monotonic_time)); - DEFINE(IA64_CLKSRC_MASK_OFFSET, - offsetof (struct fsyscall_gtod_data_t, clk_mask)); - DEFINE(IA64_CLKSRC_MULT_OFFSET, - offsetof (struct fsyscall_gtod_data_t, clk_mult)); - DEFINE(IA64_CLKSRC_SHIFT_OFFSET, - offsetof (struct fsyscall_gtod_data_t, clk_shift)); - DEFINE(IA64_CLKSRC_MMIO_OFFSET, - offsetof (struct fsyscall_gtod_data_t, clk_fsys_mmio)); - DEFINE(IA64_CLKSRC_CYCLE_LAST_OFFSET, - offsetof (struct fsyscall_gtod_data_t, clk_cycle_last)); - DEFINE(IA64_ITC_JITTER_OFFSET, - offsetof (struct itc_jitter_data_t, itc_jitter)); - DEFINE(IA64_ITC_LASTCYCLE_OFFSET, - offsetof (struct itc_jitter_data_t, itc_lastcycle)); + DEFINE(IA64_TIME_INTERPOLATOR_ADDRESS_OFFSET, offsetof (struct time_interpolator, addr)); + DEFINE(IA64_TIME_INTERPOLATOR_SOURCE_OFFSET, offsetof (struct time_interpolator, source)); + DEFINE(IA64_TIME_INTERPOLATOR_SHIFT_OFFSET, offsetof (struct time_interpolator, shift)); + DEFINE(IA64_TIME_INTERPOLATOR_NSEC_OFFSET, offsetof (struct time_interpolator, nsec_per_cyc)); + DEFINE(IA64_TIME_INTERPOLATOR_OFFSET_OFFSET, offsetof (struct time_interpolator, offset)); + DEFINE(IA64_TIME_INTERPOLATOR_LAST_CYCLE_OFFSET, offsetof (struct time_interpolator, last_cycle)); + DEFINE(IA64_TIME_INTERPOLATOR_LAST_COUNTER_OFFSET, offsetof (struct time_interpolator, last_counter)); + DEFINE(IA64_TIME_INTERPOLATOR_JITTER_OFFSET, offsetof (struct time_interpolator, jitter)); + DEFINE(IA64_TIME_INTERPOLATOR_MASK_OFFSET, offsetof (struct time_interpolator, mask)); + DEFINE(IA64_TIME_SOURCE_CPU, TIME_SOURCE_CPU); + DEFINE(IA64_TIME_SOURCE_MMIO64, TIME_SOURCE_MMIO64); + DEFINE(IA64_TIME_SOURCE_MMIO32, TIME_SOURCE_MMIO32); + DEFINE(IA64_TIMESPEC_TV_NSEC_OFFSET, offsetof (struct timespec, tv_nsec)); } diff --git a/trunk/arch/ia64/kernel/cyclone.c b/trunk/arch/ia64/kernel/cyclone.c index 2fd96d9062a1..e00b21514f7c 100644 --- a/trunk/arch/ia64/kernel/cyclone.c +++ b/trunk/arch/ia64/kernel/cyclone.c @@ -3,7 +3,6 @@ #include #include #include -#include #include /* IBM Summit (EXA) Cyclone counter code*/ @@ -19,21 +18,13 @@ void __init cyclone_setup(void) use_cyclone = 1; } -static void __iomem *cyclone_mc; -static cycle_t read_cyclone(void) -{ - return (cycle_t)readq((void __iomem *)cyclone_mc); -} - -static struct clocksource clocksource_cyclone = { - .name = "cyclone", - .rating = 300, - .read = read_cyclone, - .mask = (1LL << 40) - 1, - .mult = 0, /*to be caluclated*/ - .shift = 16, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, +struct time_interpolator cyclone_interpolator = { + .source = TIME_SOURCE_MMIO64, + .shift = 16, + .frequency = CYCLONE_TIMER_FREQ, + .drift = -100, + .mask = (1LL << 40) - 1 }; int __init init_cyclone_clock(void) @@ -53,15 +44,13 @@ int __init init_cyclone_clock(void) offset = (CYCLONE_CBAR_ADDR); reg = (u64*)ioremap_nocache(offset, sizeof(u64)); if(!reg){ - printk(KERN_ERR "Summit chipset: Could not find valid CBAR" - " register.\n"); + printk(KERN_ERR "Summit chipset: Could not find valid CBAR register.\n"); use_cyclone = 0; return -ENODEV; } base = readq(reg); if(!base){ - printk(KERN_ERR "Summit chipset: Could not find valid CBAR" - " value.\n"); + printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n"); use_cyclone = 0; return -ENODEV; } @@ -71,8 +60,7 @@ int __init init_cyclone_clock(void) offset = (base + CYCLONE_PMCC_OFFSET); reg = (u64*)ioremap_nocache(offset, sizeof(u64)); if(!reg){ - printk(KERN_ERR "Summit chipset: Could not find valid PMCC" - " register.\n"); + printk(KERN_ERR "Summit chipset: Could not find valid PMCC register.\n"); use_cyclone = 0; return -ENODEV; } @@ -83,8 +71,7 @@ int __init init_cyclone_clock(void) offset = (base + CYCLONE_MPCS_OFFSET); reg = (u64*)ioremap_nocache(offset, sizeof(u64)); if(!reg){ - printk(KERN_ERR "Summit chipset: Could not find valid MPCS" - " register.\n"); + printk(KERN_ERR "Summit chipset: Could not find valid MPCS register.\n"); use_cyclone = 0; return -ENODEV; } @@ -95,8 +82,7 @@ int __init init_cyclone_clock(void) offset = (base + CYCLONE_MPMC_OFFSET); cyclone_timer = (u32*)ioremap_nocache(offset, sizeof(u32)); if(!cyclone_timer){ - printk(KERN_ERR "Summit chipset: Could not find valid MPMC" - " register.\n"); + printk(KERN_ERR "Summit chipset: Could not find valid MPMC register.\n"); use_cyclone = 0; return -ENODEV; } @@ -107,8 +93,7 @@ int __init init_cyclone_clock(void) int stall = 100; while(stall--) barrier(); if(readl(cyclone_timer) == old){ - printk(KERN_ERR "Summit chipset: Counter not counting!" - " DISABLED\n"); + printk(KERN_ERR "Summit chipset: Counter not counting! DISABLED\n"); iounmap(cyclone_timer); cyclone_timer = 0; use_cyclone = 0; @@ -116,11 +101,8 @@ int __init init_cyclone_clock(void) } } /* initialize last tick */ - cyclone_mc = cyclone_timer; - clocksource_cyclone.fsys_mmio = cyclone_timer; - clocksource_cyclone.mult = clocksource_hz2mult(CYCLONE_TIMER_FREQ, - clocksource_cyclone.shift); - clocksource_register(&clocksource_cyclone); + cyclone_interpolator.addr = cyclone_timer; + register_time_interpolator(&cyclone_interpolator); return 0; } diff --git a/trunk/arch/ia64/kernel/entry.S b/trunk/arch/ia64/kernel/entry.S index c36f43c94600..95f517515235 100644 --- a/trunk/arch/ia64/kernel/entry.S +++ b/trunk/arch/ia64/kernel/entry.S @@ -1581,7 +1581,7 @@ sys_call_table: data8 sys_sync_file_range // 1300 data8 sys_tee data8 sys_vmsplice - data8 sys_fallocate + data8 sys_ni_syscall // reserved for move_pages data8 sys_getcpu data8 sys_epoll_pwait // 1305 data8 sys_utimensat diff --git a/trunk/arch/ia64/kernel/fsys.S b/trunk/arch/ia64/kernel/fsys.S index 44841971f077..3f926c2dc708 100644 --- a/trunk/arch/ia64/kernel/fsys.S +++ b/trunk/arch/ia64/kernel/fsys.S @@ -147,11 +147,12 @@ ENTRY(fsys_set_tid_address) FSYS_RETURN END(fsys_set_tid_address) -#if IA64_GTOD_LOCK_OFFSET !=0 -#error fsys_gettimeofday incompatible with changes to struct fsyscall_gtod_data_t -#endif -#if IA64_ITC_JITTER_OFFSET !=0 -#error fsys_gettimeofday incompatible with changes to struct itc_jitter_data_t +/* + * Ensure that the time interpolator structure is compatible with the asm code + */ +#if IA64_TIME_INTERPOLATOR_SOURCE_OFFSET !=0 || IA64_TIME_INTERPOLATOR_SHIFT_OFFSET != 2 \ + || IA64_TIME_INTERPOLATOR_JITTER_OFFSET != 3 || IA64_TIME_INTERPOLATOR_NSEC_OFFSET != 4 +#error fsys_gettimeofday incompatible with changes to struct time_interpolator #endif #define CLOCK_REALTIME 0 #define CLOCK_MONOTONIC 1 @@ -178,124 +179,126 @@ ENTRY(fsys_gettimeofday) // r11 = preserved: saved ar.pfs // r12 = preserved: memory stack // r13 = preserved: thread pointer - // r14 = address of mask / mask value + // r14 = address of mask / mask // r15 = preserved: system call number // r16 = preserved: current task pointer - // r17 = (not used) - // r18 = (not used) - // r19 = address of itc_lastcycle - // r20 = struct fsyscall_gtod_data (= address of gtod_lock.sequence) - // r21 = address of mmio_ptr - // r22 = address of wall_time or monotonic_time - // r23 = address of shift / value - // r24 = address mult factor / cycle_last value - // r25 = itc_lastcycle value - // r26 = address clocksource cycle_last - // r27 = (not used) + // r17 = wall to monotonic use + // r18 = time_interpolator->offset + // r19 = address of wall_to_monotonic + // r20 = pointer to struct time_interpolator / pointer to time_interpolator->address + // r21 = shift factor + // r22 = address of time interpolator->last_counter + // r23 = address of time_interpolator->last_cycle + // r24 = adress of time_interpolator->offset + // r25 = last_cycle value + // r26 = last_counter value + // r27 = pointer to xtime // r28 = sequence number at the beginning of critcal section - // r29 = address of itc_jitter + // r29 = address of seqlock // r30 = time processing flags / memory address // r31 = pointer to result // Predicates // p6,p7 short term use // p8 = timesource ar.itc // p9 = timesource mmio64 - // p10 = timesource mmio32 - not used + // p10 = timesource mmio32 // p11 = timesource not to be handled by asm code - // p12 = memory time source ( = p9 | p10) - not used - // p13 = do cmpxchg with itc_lastcycle + // p12 = memory time source ( = p9 | p10) + // p13 = do cmpxchg with time_interpolator_last_cycle // p14 = Divide by 1000 // p15 = Add monotonic // - // Note that instructions are optimized for McKinley. McKinley can - // process two bundles simultaneously and therefore we continuously - // try to feed the CPU two bundles and then a stop. - // - // Additional note that code has changed a lot. Optimization is TBD. - // Comments begin with "?" are maybe outdated. - tnat.nz p6,p0 = r31 // ? branch deferred to fit later bundle + // Note that instructions are optimized for McKinley. McKinley can process two + // bundles simultaneously and therefore we continuously try to feed the CPU + // two bundles and then a stop. + tnat.nz p6,p0 = r31 // branch deferred since it does not fit into bundle structure mov pr = r30,0xc000 // Set predicates according to function add r2 = TI_FLAGS+IA64_TASK_SIZE,r16 - movl r20 = fsyscall_gtod_data // load fsyscall gettimeofday data address + movl r20 = time_interpolator ;; - movl r29 = itc_jitter_data // itc_jitter - add r22 = IA64_GTOD_WALL_TIME_OFFSET,r20 // wall_time + ld8 r20 = [r20] // get pointer to time_interpolator structure + movl r29 = xtime_lock ld4 r2 = [r2] // process work pending flags - ;; -(p15) add r22 = IA64_GTOD_MONO_TIME_OFFSET,r20 // monotonic_time - add r21 = IA64_CLKSRC_MMIO_OFFSET,r20 - add r19 = IA64_ITC_LASTCYCLE_OFFSET,r29 + movl r27 = xtime + ;; // only one bundle here + ld8 r21 = [r20] // first quad with control information and r2 = TIF_ALLWORK_MASK,r2 -(p6) br.cond.spnt.few .fail_einval // ? deferred branch +(p6) br.cond.spnt.few .fail_einval // deferred branch ;; - add r26 = IA64_CLKSRC_CYCLE_LAST_OFFSET,r20 // clksrc_cycle_last + add r10 = IA64_TIME_INTERPOLATOR_ADDRESS_OFFSET,r20 + extr r3 = r21,32,32 // time_interpolator->nsec_per_cyc + extr r8 = r21,0,16 // time_interpolator->source cmp.ne p6, p0 = 0, r2 // Fallback if work is scheduled (p6) br.cond.spnt.many fsys_fallback_syscall ;; - // Begin critical section -.time_redo: - ld4.acq r28 = [r20] // gtod_lock.sequence, Must take first - ;; - and r28 = ~1,r28 // And make sequence even to force retry if odd + cmp.eq p8,p12 = 0,r8 // Check for cpu timer + cmp.eq p9,p0 = 1,r8 // MMIO64 ? + extr r2 = r21,24,8 // time_interpolator->jitter + cmp.eq p10,p0 = 2,r8 // MMIO32 ? + cmp.ltu p11,p0 = 2,r8 // function or other clock +(p11) br.cond.spnt.many fsys_fallback_syscall ;; - ld8 r30 = [r21] // clocksource->mmio_ptr - add r24 = IA64_CLKSRC_MULT_OFFSET,r20 - ld4 r2 = [r29] // itc_jitter value - add r23 = IA64_CLKSRC_SHIFT_OFFSET,r20 - add r14 = IA64_CLKSRC_MASK_OFFSET,r20 + setf.sig f7 = r3 // Setup for scaling of counter +(p15) movl r19 = wall_to_monotonic +(p12) ld8 r30 = [r10] + cmp.ne p13,p0 = r2,r0 // need jitter compensation? + extr r21 = r21,16,8 // shift factor ;; - ld4 r3 = [r24] // clocksource mult value - ld8 r14 = [r14] // clocksource mask value - cmp.eq p8,p9 = 0,r30 // use cpu timer if no mmio_ptr +.time_redo: + .pred.rel.mutex p8,p9,p10 + ld4.acq r28 = [r29] // xtime_lock.sequence. Must come first for locking purposes ;; - setf.sig f7 = r3 // Setup for mult scaling of counter -(p8) cmp.ne p13,p0 = r2,r0 // need itc_jitter compensation, set p13 - ld4 r23 = [r23] // clocksource shift value - ld8 r24 = [r26] // get clksrc_cycle_last value -(p9) cmp.eq p13,p0 = 0,r30 // if mmio_ptr, clear p13 jitter control + and r28 = ~1,r28 // Make sequence even to force retry if odd ;; - .pred.rel.mutex p8,p9 (p8) mov r2 = ar.itc // CPU_TIMER. 36 clocks latency!!! -(p9) ld8 r2 = [r30] // MMIO_TIMER. Could also have latency issues.. -(p13) ld8 r25 = [r19] // get itc_lastcycle value - ;; // ? could be removed by moving the last add upward - ld8 r9 = [r22],IA64_TIMESPEC_TV_NSEC_OFFSET // tv_sec - ;; - ld8 r8 = [r22],-IA64_TIMESPEC_TV_NSEC_OFFSET // tv_nsec -(p13) sub r3 = r25,r2 // Diff needed before comparison (thanks davidm) - ;; -(p13) cmp.gt.unc p6,p7 = r3,r0 // check if it is less than last. p6,p7 cleared - sub r10 = r2,r24 // current_cycle - last_cycle - ;; -(p6) sub r10 = r25,r24 // time we got was less than last_cycle + add r22 = IA64_TIME_INTERPOLATOR_LAST_COUNTER_OFFSET,r20 +(p9) ld8 r2 = [r30] // readq(ti->address). Could also have latency issues.. +(p10) ld4 r2 = [r30] // readw(ti->address) +(p13) add r23 = IA64_TIME_INTERPOLATOR_LAST_CYCLE_OFFSET,r20 + ;; // could be removed by moving the last add upward + ld8 r26 = [r22] // time_interpolator->last_counter +(p13) ld8 r25 = [r23] // time interpolator->last_cycle + add r24 = IA64_TIME_INTERPOLATOR_OFFSET_OFFSET,r20 +(p15) ld8 r17 = [r19],IA64_TIMESPEC_TV_NSEC_OFFSET + ld8 r9 = [r27],IA64_TIMESPEC_TV_NSEC_OFFSET + add r14 = IA64_TIME_INTERPOLATOR_MASK_OFFSET, r20 + ;; + ld8 r18 = [r24] // time_interpolator->offset + ld8 r8 = [r27],-IA64_TIMESPEC_TV_NSEC_OFFSET // xtime.tv_nsec +(p13) sub r3 = r25,r2 // Diff needed before comparison (thanks davidm) + ;; + ld8 r14 = [r14] // time_interpolator->mask +(p13) cmp.gt.unc p6,p7 = r3,r0 // check if it is less than last. p6,p7 cleared + sub r10 = r2,r26 // current_counter - last_counter + ;; +(p6) sub r10 = r25,r26 // time we got was less than last_cycle (p7) mov ar.ccv = r25 // more than last_cycle. Prep for cmpxchg ;; -(p7) cmpxchg8.rel r3 = [r19],r2,ar.ccv - ;; -(p7) cmp.ne p7,p0 = r25,r3 // if cmpxchg not successful - ;; -(p7) sub r10 = r3,r24 // then use new last_cycle instead - ;; and r10 = r10,r14 // Apply mask ;; setf.sig f8 = r10 nop.i 123 ;; - // fault check takes 5 cycles and we have spare time -EX(.fail_efault, probe.w.fault r31, 3) +(p7) cmpxchg8.rel r3 = [r23],r2,ar.ccv +EX(.fail_efault, probe.w.fault r31, 3) // This takes 5 cycles and we have spare time xmpy.l f8 = f8,f7 // nsec_per_cyc*(counter-last_counter) +(p15) add r9 = r9,r17 // Add wall to monotonic.secs to result secs ;; - // ? simulate tbit.nz.or p7,p0 = r28,0 +(p15) ld8 r17 = [r19],-IA64_TIMESPEC_TV_NSEC_OFFSET +(p7) cmp.ne p7,p0 = r25,r3 // if cmpxchg not successful redo + // simulate tbit.nz.or p7,p0 = r28,0 getf.sig r2 = f8 mf + add r8 = r8,r18 // Add time interpolator offset ;; - ld4 r10 = [r20] // gtod_lock.sequence - shr.u r2 = r2,r23 // shift by factor - ;; // ? overloaded 3 bundles! - add r8 = r8,r2 // Add xtime.nsecs - cmp4.ne p7,p0 = r28,r10 -(p7) br.cond.dpnt.few .time_redo // sequence number changed, redo + ld4 r10 = [r29] // xtime_lock.sequence +(p15) add r8 = r8, r17 // Add monotonic.nsecs to nsecs + shr.u r2 = r2,r21 + ;; // overloaded 3 bundles! // End critical section. + add r8 = r8,r2 // Add xtime.nsecs + cmp4.ne.or p7,p0 = r28,r10 +(p7) br.cond.dpnt.few .time_redo // sequence number changed ? // Now r8=tv->tv_nsec and r9=tv->tv_sec mov r10 = r0 movl r2 = 1000000000 @@ -305,19 +308,19 @@ EX(.fail_efault, probe.w.fault r31, 3) .time_normalize: mov r21 = r8 cmp.ge p6,p0 = r8,r2 -(p14) shr.u r20 = r8, 3 // We can repeat this if necessary just wasting time +(p14) shr.u r20 = r8, 3 // We can repeat this if necessary just wasting some time ;; (p14) setf.sig f8 = r20 (p6) sub r8 = r8,r2 -(p6) add r9 = 1,r9 // two nops before the branch. -(p14) setf.sig f7 = r3 // Chances for repeats are 1 in 10000 for gettod +(p6) add r9 = 1,r9 // two nops before the branch. +(p14) setf.sig f7 = r3 // Chances for repeats are 1 in 10000 for gettod (p6) br.cond.dpnt.few .time_normalize ;; // Divided by 8 though shift. Now divide by 125 // The compiler was able to do that with a multiply // and a shift and we do the same -EX(.fail_efault, probe.w.fault r23, 3) // This also costs 5 cycles -(p14) xmpy.hu f8 = f8, f7 // xmpy has 5 cycles latency so use it +EX(.fail_efault, probe.w.fault r23, 3) // This also costs 5 cycles +(p14) xmpy.hu f8 = f8, f7 // xmpy has 5 cycles latency so use it... ;; mov r8 = r0 (p14) getf.sig r2 = f8 diff --git a/trunk/arch/ia64/kernel/fsyscall_gtod_data.h b/trunk/arch/ia64/kernel/fsyscall_gtod_data.h deleted file mode 100644 index 490dab55fba3..000000000000 --- a/trunk/arch/ia64/kernel/fsyscall_gtod_data.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * (c) Copyright 2007 Hewlett-Packard Development Company, L.P. - * Contributed by Peter Keilty - * - * fsyscall gettimeofday data - */ - -struct fsyscall_gtod_data_t { - seqlock_t lock; - struct timespec wall_time; - struct timespec monotonic_time; - cycle_t clk_mask; - u32 clk_mult; - u32 clk_shift; - void *clk_fsys_mmio; - cycle_t clk_cycle_last; -} __attribute__ ((aligned (L1_CACHE_BYTES))); - -struct itc_jitter_data_t { - int itc_jitter; - cycle_t itc_lastcycle; -} __attribute__ ((aligned (L1_CACHE_BYTES))); - diff --git a/trunk/arch/ia64/kernel/iosapic.c b/trunk/arch/ia64/kernel/iosapic.c index 91e6dc1e7baf..37f46527d233 100644 --- a/trunk/arch/ia64/kernel/iosapic.c +++ b/trunk/arch/ia64/kernel/iosapic.c @@ -118,25 +118,15 @@ static DEFINE_SPINLOCK(iosapic_lock); * vector. */ -#define NO_REF_RTE 0 - -static struct iosapic { - char __iomem *addr; /* base address of IOSAPIC */ - unsigned int gsi_base; /* GSI base */ - unsigned short num_rte; /* # of RTEs on this IOSAPIC */ - int rtes_inuse; /* # of RTEs in use on this IOSAPIC */ -#ifdef CONFIG_NUMA - unsigned short node; /* numa node association via pxm */ -#endif - spinlock_t lock; /* lock for indirect reg access */ -} iosapic_lists[NR_IOSAPICS]; - struct iosapic_rte_info { - struct list_head rte_list; /* RTEs sharing the same vector */ + struct list_head rte_list; /* node in list of RTEs sharing the + * same vector */ + char __iomem *addr; /* base address of IOSAPIC */ + unsigned int gsi_base; /* first GSI assigned to this + * IOSAPIC */ char rte_index; /* IOSAPIC RTE index */ int refcnt; /* reference counter */ unsigned int flags; /* flags */ - struct iosapic *iosapic; } ____cacheline_aligned; static struct iosapic_intr_info { @@ -150,23 +140,24 @@ static struct iosapic_intr_info { unsigned char polarity: 1; /* interrupt polarity * (see iosapic.h) */ unsigned char trigger : 1; /* trigger mode (see iosapic.h) */ -} iosapic_intr_info[NR_IRQS]; +} iosapic_intr_info[IA64_NUM_VECTORS]; + +static struct iosapic { + char __iomem *addr; /* base address of IOSAPIC */ + unsigned int gsi_base; /* first GSI assigned to this + * IOSAPIC */ + unsigned short num_rte; /* # of RTEs on this IOSAPIC */ + int rtes_inuse; /* # of RTEs in use on this IOSAPIC */ +#ifdef CONFIG_NUMA + unsigned short node; /* numa node association via pxm */ +#endif +} iosapic_lists[NR_IOSAPICS]; static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */ static int iosapic_kmalloc_ok; static LIST_HEAD(free_rte_list); -static inline void -iosapic_write(struct iosapic *iosapic, unsigned int reg, u32 val) -{ - unsigned long flags; - - spin_lock_irqsave(&iosapic->lock, flags); - __iosapic_write(iosapic->addr, reg, val); - spin_unlock_irqrestore(&iosapic->lock, flags); -} - /* * Find an IOSAPIC associated with a GSI */ @@ -184,18 +175,17 @@ find_iosapic (unsigned int gsi) return -1; } -static inline int __gsi_to_irq(unsigned int gsi) +static inline int +_gsi_to_vector (unsigned int gsi) { - int irq; struct iosapic_intr_info *info; struct iosapic_rte_info *rte; - for (irq = 0; irq < NR_IRQS; irq++) { - info = &iosapic_intr_info[irq]; + for (info = iosapic_intr_info; info < + iosapic_intr_info + IA64_NUM_VECTORS; ++info) list_for_each_entry(rte, &info->rtes, rte_list) - if (rte->iosapic->gsi_base + rte->rte_index == gsi) - return irq; - } + if (rte->gsi_base + rte->rte_index == gsi) + return info - iosapic_intr_info; return -1; } @@ -206,10 +196,7 @@ static inline int __gsi_to_irq(unsigned int gsi) inline int gsi_to_vector (unsigned int gsi) { - int irq = __gsi_to_irq(gsi); - if (check_irq_used(irq) < 0) - return -1; - return irq_to_vector(irq); + return _gsi_to_vector(gsi); } int @@ -217,48 +204,66 @@ gsi_to_irq (unsigned int gsi) { unsigned long flags; int irq; - + /* + * XXX fix me: this assumes an identity mapping between IA-64 vector + * and Linux irq numbers... + */ spin_lock_irqsave(&iosapic_lock, flags); - irq = __gsi_to_irq(gsi); + { + irq = _gsi_to_vector(gsi); + } spin_unlock_irqrestore(&iosapic_lock, flags); + return irq; } -static struct iosapic_rte_info *find_rte(unsigned int irq, unsigned int gsi) +static struct iosapic_rte_info *gsi_vector_to_rte(unsigned int gsi, + unsigned int vec) { struct iosapic_rte_info *rte; - list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) - if (rte->iosapic->gsi_base + rte->rte_index == gsi) + list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) + if (rte->gsi_base + rte->rte_index == gsi) return rte; return NULL; } static void -set_rte (unsigned int gsi, unsigned int irq, unsigned int dest, int mask) +set_rte (unsigned int gsi, unsigned int vector, unsigned int dest, int mask) { unsigned long pol, trigger, dmode; u32 low32, high32; + char __iomem *addr; int rte_index; char redir; struct iosapic_rte_info *rte; - ia64_vector vector = irq_to_vector(irq); DBG(KERN_DEBUG"IOSAPIC: routing vector %d to 0x%x\n", vector, dest); - rte = find_rte(irq, gsi); + rte = gsi_vector_to_rte(gsi, vector); if (!rte) return; /* not an IOSAPIC interrupt */ rte_index = rte->rte_index; - pol = iosapic_intr_info[irq].polarity; - trigger = iosapic_intr_info[irq].trigger; - dmode = iosapic_intr_info[irq].dmode; + addr = rte->addr; + pol = iosapic_intr_info[vector].polarity; + trigger = iosapic_intr_info[vector].trigger; + dmode = iosapic_intr_info[vector].dmode; redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0; #ifdef CONFIG_SMP - set_irq_affinity_info(irq, (int)(dest & 0xffff), redir); + { + unsigned int irq; + + for (irq = 0; irq < NR_IRQS; ++irq) + if (irq_to_vector(irq) == vector) { + set_irq_affinity_info(irq, + (int)(dest & 0xffff), + redir); + break; + } + } #endif low32 = ((pol << IOSAPIC_POLARITY_SHIFT) | @@ -270,10 +275,10 @@ set_rte (unsigned int gsi, unsigned int irq, unsigned int dest, int mask) /* dest contains both id and eid */ high32 = (dest << IOSAPIC_DEST_SHIFT); - iosapic_write(rte->iosapic, IOSAPIC_RTE_HIGH(rte_index), high32); - iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte_index), low32); - iosapic_intr_info[irq].low32 = low32; - iosapic_intr_info[irq].dest = dest; + iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32); + iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); + iosapic_intr_info[vector].low32 = low32; + iosapic_intr_info[vector].dest = dest; } static void @@ -289,18 +294,15 @@ kexec_disable_iosapic(void) { struct iosapic_intr_info *info; struct iosapic_rte_info *rte; - ia64_vector vec; - int irq; - - for (irq = 0; irq < NR_IRQS; irq++) { - info = &iosapic_intr_info[irq]; - vec = irq_to_vector(irq); + u8 vec = 0; + for (info = iosapic_intr_info; info < + iosapic_intr_info + IA64_NUM_VECTORS; ++info, ++vec) { list_for_each_entry(rte, &info->rtes, rte_list) { - iosapic_write(rte->iosapic, + iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index), IOSAPIC_MASK|vec); - iosapic_eoi(rte->iosapic->addr, vec); + iosapic_eoi(rte->addr, vec); } } } @@ -309,36 +311,54 @@ kexec_disable_iosapic(void) static void mask_irq (unsigned int irq) { + unsigned long flags; + char __iomem *addr; u32 low32; int rte_index; + ia64_vector vec = irq_to_vector(irq); struct iosapic_rte_info *rte; - if (list_empty(&iosapic_intr_info[irq].rtes)) + if (list_empty(&iosapic_intr_info[vec].rtes)) return; /* not an IOSAPIC interrupt! */ - /* set only the mask bit */ - low32 = iosapic_intr_info[irq].low32 |= IOSAPIC_MASK; - list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) { - rte_index = rte->rte_index; - iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte_index), low32); + spin_lock_irqsave(&iosapic_lock, flags); + { + /* set only the mask bit */ + low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK; + list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, + rte_list) { + addr = rte->addr; + rte_index = rte->rte_index; + iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); + } } + spin_unlock_irqrestore(&iosapic_lock, flags); } static void unmask_irq (unsigned int irq) { + unsigned long flags; + char __iomem *addr; u32 low32; int rte_index; + ia64_vector vec = irq_to_vector(irq); struct iosapic_rte_info *rte; - if (list_empty(&iosapic_intr_info[irq].rtes)) + if (list_empty(&iosapic_intr_info[vec].rtes)) return; /* not an IOSAPIC interrupt! */ - low32 = iosapic_intr_info[irq].low32 &= ~IOSAPIC_MASK; - list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) { - rte_index = rte->rte_index; - iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte_index), low32); + spin_lock_irqsave(&iosapic_lock, flags); + { + low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK; + list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, + rte_list) { + addr = rte->addr; + rte_index = rte->rte_index; + iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); + } } + spin_unlock_irqrestore(&iosapic_lock, flags); } @@ -346,24 +366,23 @@ static void iosapic_set_affinity (unsigned int irq, cpumask_t mask) { #ifdef CONFIG_SMP + unsigned long flags; u32 high32, low32; int dest, rte_index; + char __iomem *addr; int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0; + ia64_vector vec; struct iosapic_rte_info *rte; - struct iosapic *iosapic; irq &= (~IA64_IRQ_REDIRECTED); + vec = irq_to_vector(irq); - cpus_and(mask, mask, cpu_online_map); if (cpus_empty(mask)) return; - if (reassign_irq_vector(irq, first_cpu(mask))) - return; - dest = cpu_physical_id(first_cpu(mask)); - if (list_empty(&iosapic_intr_info[irq].rtes)) + if (list_empty(&iosapic_intr_info[vec].rtes)) return; /* not an IOSAPIC interrupt */ set_irq_affinity_info(irq, dest, redir); @@ -371,24 +390,31 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask) /* dest contains both id and eid */ high32 = dest << IOSAPIC_DEST_SHIFT; - low32 = iosapic_intr_info[irq].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT); - if (redir) - /* change delivery mode to lowest priority */ - low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT); - else - /* change delivery mode to fixed */ - low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT); - low32 &= IOSAPIC_VECTOR_MASK; - low32 |= irq_to_vector(irq); - - iosapic_intr_info[irq].low32 = low32; - iosapic_intr_info[irq].dest = dest; - list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) { - iosapic = rte->iosapic; - rte_index = rte->rte_index; - iosapic_write(iosapic, IOSAPIC_RTE_HIGH(rte_index), high32); - iosapic_write(iosapic, IOSAPIC_RTE_LOW(rte_index), low32); + spin_lock_irqsave(&iosapic_lock, flags); + { + low32 = iosapic_intr_info[vec].low32 & + ~(7 << IOSAPIC_DELIVERY_SHIFT); + + if (redir) + /* change delivery mode to lowest priority */ + low32 |= (IOSAPIC_LOWEST_PRIORITY << + IOSAPIC_DELIVERY_SHIFT); + else + /* change delivery mode to fixed */ + low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT); + + iosapic_intr_info[vec].low32 = low32; + iosapic_intr_info[vec].dest = dest; + list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, + rte_list) { + addr = rte->addr; + rte_index = rte->rte_index; + iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), + high32); + iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); + } } + spin_unlock_irqrestore(&iosapic_lock, flags); #endif } @@ -408,20 +434,10 @@ iosapic_end_level_irq (unsigned int irq) { ia64_vector vec = irq_to_vector(irq); struct iosapic_rte_info *rte; - int do_unmask_irq = 0; - - if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) { - do_unmask_irq = 1; - mask_irq(irq); - } - - list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) - iosapic_eoi(rte->iosapic->addr, vec); - if (unlikely(do_unmask_irq)) { - move_masked_irq(irq); - unmask_irq(irq); - } + move_native_irq(irq); + list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) + iosapic_eoi(rte->addr, vec); } #define iosapic_shutdown_level_irq mask_irq @@ -503,12 +519,13 @@ iosapic_version (char __iomem *addr) * unsigned int reserved2 : 8; * } */ - return __iosapic_read(addr, IOSAPIC_VERSION); + return iosapic_read(addr, IOSAPIC_VERSION); } -static int iosapic_find_sharable_irq(unsigned long trigger, unsigned long pol) +static int iosapic_find_sharable_vector (unsigned long trigger, + unsigned long pol) { - int i, irq = -ENOSPC, min_count = -1; + int i, vector = -1, min_count = -1; struct iosapic_intr_info *info; /* @@ -516,21 +533,21 @@ static int iosapic_find_sharable_irq(unsigned long trigger, unsigned long pol) * supported yet */ if (trigger == IOSAPIC_EDGE) - return -EINVAL; + return -1; - for (i = 0; i <= NR_IRQS; i++) { + for (i = IA64_FIRST_DEVICE_VECTOR; i <= IA64_LAST_DEVICE_VECTOR; i++) { info = &iosapic_intr_info[i]; if (info->trigger == trigger && info->polarity == pol && - (info->dmode == IOSAPIC_FIXED || - info->dmode == IOSAPIC_LOWEST_PRIORITY) && - can_request_irq(i, IRQF_SHARED)) { + (info->dmode == IOSAPIC_FIXED || info->dmode == + IOSAPIC_LOWEST_PRIORITY)) { if (min_count == -1 || info->count < min_count) { - irq = i; + vector = i; min_count = info->count; } } } - return irq; + + return vector; } /* @@ -538,25 +555,25 @@ static int iosapic_find_sharable_irq(unsigned long trigger, unsigned long pol) * assign a new vector for the other and make the vector available */ static void __init -iosapic_reassign_vector (int irq) +iosapic_reassign_vector (int vector) { - int new_irq; + int new_vector; - if (!list_empty(&iosapic_intr_info[irq].rtes)) { - new_irq = create_irq(); - if (new_irq < 0) + if (!list_empty(&iosapic_intr_info[vector].rtes)) { + new_vector = assign_irq_vector(AUTO_ASSIGN); + if (new_vector < 0) panic("%s: out of interrupt vectors!\n", __FUNCTION__); printk(KERN_INFO "Reassigning vector %d to %d\n", - irq_to_vector(irq), irq_to_vector(new_irq)); - memcpy(&iosapic_intr_info[new_irq], &iosapic_intr_info[irq], + vector, new_vector); + memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], sizeof(struct iosapic_intr_info)); - INIT_LIST_HEAD(&iosapic_intr_info[new_irq].rtes); - list_move(iosapic_intr_info[irq].rtes.next, - &iosapic_intr_info[new_irq].rtes); - memset(&iosapic_intr_info[irq], 0, + INIT_LIST_HEAD(&iosapic_intr_info[new_vector].rtes); + list_move(iosapic_intr_info[vector].rtes.next, + &iosapic_intr_info[new_vector].rtes); + memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); - iosapic_intr_info[irq].low32 = IOSAPIC_MASK; - INIT_LIST_HEAD(&iosapic_intr_info[irq].rtes); + iosapic_intr_info[vector].low32 = IOSAPIC_MASK; + INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); } } @@ -593,18 +610,29 @@ static struct iosapic_rte_info *iosapic_alloc_rte (void) return rte; } -static inline int irq_is_shared (int irq) +static void iosapic_free_rte (struct iosapic_rte_info *rte) { - return (iosapic_intr_info[irq].count > 1); + if (rte->flags & RTE_PREALLOCATED) + list_add_tail(&rte->rte_list, &free_rte_list); + else + kfree(rte); +} + +static inline int vector_is_shared (int vector) +{ + return (iosapic_intr_info[vector].count > 1); } static int -register_intr (unsigned int gsi, int irq, unsigned char delivery, +register_intr (unsigned int gsi, int vector, unsigned char delivery, unsigned long polarity, unsigned long trigger) { irq_desc_t *idesc; struct hw_interrupt_type *irq_type; + int rte_index; int index; + unsigned long gsi_base; + void __iomem *iosapic_address; struct iosapic_rte_info *rte; index = find_iosapic(gsi); @@ -614,7 +642,10 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery, return -ENODEV; } - rte = find_rte(irq, gsi); + iosapic_address = iosapic_lists[index].addr; + gsi_base = iosapic_lists[index].gsi_base; + + rte = gsi_vector_to_rte(gsi, vector); if (!rte) { rte = iosapic_alloc_rte(); if (!rte) { @@ -623,42 +654,40 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery, return -ENOMEM; } - rte->iosapic = &iosapic_lists[index]; - rte->rte_index = gsi - rte->iosapic->gsi_base; + rte_index = gsi - gsi_base; + rte->rte_index = rte_index; + rte->addr = iosapic_address; + rte->gsi_base = gsi_base; rte->refcnt++; - list_add_tail(&rte->rte_list, &iosapic_intr_info[irq].rtes); - iosapic_intr_info[irq].count++; + list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes); + iosapic_intr_info[vector].count++; iosapic_lists[index].rtes_inuse++; } - else if (rte->refcnt == NO_REF_RTE) { - struct iosapic_intr_info *info = &iosapic_intr_info[irq]; - if (info->count > 0 && - (info->trigger != trigger || info->polarity != polarity)){ + else if (vector_is_shared(vector)) { + struct iosapic_intr_info *info = &iosapic_intr_info[vector]; + if (info->trigger != trigger || info->polarity != polarity) { printk (KERN_WARNING "%s: cannot override the interrupt\n", __FUNCTION__); return -EINVAL; } - rte->refcnt++; - iosapic_intr_info[irq].count++; - iosapic_lists[index].rtes_inuse++; } - iosapic_intr_info[irq].polarity = polarity; - iosapic_intr_info[irq].dmode = delivery; - iosapic_intr_info[irq].trigger = trigger; + iosapic_intr_info[vector].polarity = polarity; + iosapic_intr_info[vector].dmode = delivery; + iosapic_intr_info[vector].trigger = trigger; if (trigger == IOSAPIC_EDGE) irq_type = &irq_type_iosapic_edge; else irq_type = &irq_type_iosapic_level; - idesc = irq_desc + irq; + idesc = irq_desc + vector; if (idesc->chip != irq_type) { if (idesc->chip != &no_irq_type) printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", - __FUNCTION__, irq_to_vector(irq), + __FUNCTION__, vector, idesc->chip->name, irq_type->name); idesc->chip = irq_type; } @@ -666,19 +695,18 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery, } static unsigned int -get_target_cpu (unsigned int gsi, int irq) +get_target_cpu (unsigned int gsi, int vector) { #ifdef CONFIG_SMP static int cpu = -1; extern int cpe_vector; - cpumask_t domain = irq_to_domain(irq); /* * In case of vector shared by multiple RTEs, all RTEs that * share the vector need to use the same destination CPU. */ - if (!list_empty(&iosapic_intr_info[irq].rtes)) - return iosapic_intr_info[irq].dest; + if (!list_empty(&iosapic_intr_info[vector].rtes)) + return iosapic_intr_info[vector].dest; /* * If the platform supports redirection via XTP, let it @@ -695,7 +723,7 @@ get_target_cpu (unsigned int gsi, int irq) return cpu_physical_id(smp_processor_id()); #ifdef CONFIG_ACPI - if (cpe_vector > 0 && irq_to_vector(irq) == IA64_CPEP_VECTOR) + if (cpe_vector > 0 && vector == IA64_CPEP_VECTOR) return get_cpei_target_cpu(); #endif @@ -710,7 +738,7 @@ get_target_cpu (unsigned int gsi, int irq) goto skip_numa_setup; cpu_mask = node_to_cpumask(iosapic_lists[iosapic_index].node); - cpus_and(cpu_mask, cpu_mask, domain); + for_each_cpu_mask(numa_cpu, cpu_mask) { if (!cpu_online(numa_cpu)) cpu_clear(numa_cpu, cpu_mask); @@ -721,8 +749,8 @@ get_target_cpu (unsigned int gsi, int irq) if (!num_cpus) goto skip_numa_setup; - /* Use irq assignment to distribute across cpus in node */ - cpu_index = irq % num_cpus; + /* Use vector assignment to distribute across cpus in node */ + cpu_index = vector % num_cpus; for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++) numa_cpu = next_cpu(numa_cpu, cpu_mask); @@ -740,7 +768,7 @@ get_target_cpu (unsigned int gsi, int irq) do { if (++cpu >= NR_CPUS) cpu = 0; - } while (!cpu_online(cpu) || !cpu_isset(cpu, domain)); + } while (!cpu_online(cpu)); return cpu_physical_id(cpu); #else /* CONFIG_SMP */ @@ -757,72 +785,84 @@ int iosapic_register_intr (unsigned int gsi, unsigned long polarity, unsigned long trigger) { - int irq, mask = 1, err; + int vector, mask = 1, err; unsigned int dest; unsigned long flags; struct iosapic_rte_info *rte; u32 low32; - +again: /* * If this GSI has already been registered (i.e., it's a * shared interrupt, or we lost a race to register it), * don't touch the RTE. */ spin_lock_irqsave(&iosapic_lock, flags); - irq = __gsi_to_irq(gsi); - if (irq > 0) { - rte = find_rte(irq, gsi); - if(iosapic_intr_info[irq].count == 0) { - assign_irq_vector(irq); - dynamic_irq_init(irq); - } else if (rte->refcnt != NO_REF_RTE) { + { + vector = gsi_to_vector(gsi); + if (vector > 0) { + rte = gsi_vector_to_rte(gsi, vector); rte->refcnt++; - goto unlock_iosapic_lock; + spin_unlock_irqrestore(&iosapic_lock, flags); + return vector; } - } else - irq = create_irq(); + } + spin_unlock_irqrestore(&iosapic_lock, flags); /* If vector is running out, we try to find a sharable vector */ - if (irq < 0) { - irq = iosapic_find_sharable_irq(trigger, polarity); - if (irq < 0) - goto unlock_iosapic_lock; + vector = assign_irq_vector(AUTO_ASSIGN); + if (vector < 0) { + vector = iosapic_find_sharable_vector(trigger, polarity); + if (vector < 0) + return -ENOSPC; } - spin_lock(&irq_desc[irq].lock); - dest = get_target_cpu(gsi, irq); - err = register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY, - polarity, trigger); - if (err < 0) { - irq = err; - goto unlock_all; - } + spin_lock_irqsave(&irq_desc[vector].lock, flags); + spin_lock(&iosapic_lock); + { + if (gsi_to_vector(gsi) > 0) { + if (list_empty(&iosapic_intr_info[vector].rtes)) + free_irq_vector(vector); + spin_unlock(&iosapic_lock); + spin_unlock_irqrestore(&irq_desc[vector].lock, + flags); + goto again; + } - /* - * If the vector is shared and already unmasked for other - * interrupt sources, don't mask it. - */ - low32 = iosapic_intr_info[irq].low32; - if (irq_is_shared(irq) && !(low32 & IOSAPIC_MASK)) - mask = 0; - set_rte(gsi, irq, dest, mask); + dest = get_target_cpu(gsi, vector); + err = register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, + polarity, trigger); + if (err < 0) { + spin_unlock(&iosapic_lock); + spin_unlock_irqrestore(&irq_desc[vector].lock, + flags); + return err; + } + + /* + * If the vector is shared and already unmasked for + * other interrupt sources, don't mask it. + */ + low32 = iosapic_intr_info[vector].low32; + if (vector_is_shared(vector) && !(low32 & IOSAPIC_MASK)) + mask = 0; + set_rte(gsi, vector, dest, mask); + } + spin_unlock(&iosapic_lock); + spin_unlock_irqrestore(&irq_desc[vector].lock, flags); printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), - cpu_logical_id(dest), dest, irq_to_vector(irq)); - unlock_all: - spin_unlock(&irq_desc[irq].lock); - unlock_iosapic_lock: - spin_unlock_irqrestore(&iosapic_lock, flags); - return irq; + cpu_logical_id(dest), dest, vector); + + return vector; } void iosapic_unregister_intr (unsigned int gsi) { unsigned long flags; - int irq, index; + int irq, vector, index; irq_desc_t *idesc; u32 low32; unsigned long trigger, polarity; @@ -841,56 +881,78 @@ iosapic_unregister_intr (unsigned int gsi) WARN_ON(1); return; } + vector = irq_to_vector(irq); - spin_lock_irqsave(&iosapic_lock, flags); - if ((rte = find_rte(irq, gsi)) == NULL) { - printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", - gsi); - WARN_ON(1); - goto out; - } + idesc = irq_desc + irq; + spin_lock_irqsave(&idesc->lock, flags); + spin_lock(&iosapic_lock); + { + if ((rte = gsi_vector_to_rte(gsi, vector)) == NULL) { + printk(KERN_ERR + "iosapic_unregister_intr(%u) unbalanced\n", + gsi); + WARN_ON(1); + goto out; + } - if (--rte->refcnt > 0) - goto out; + if (--rte->refcnt > 0) + goto out; - idesc = irq_desc + irq; - rte->refcnt = NO_REF_RTE; + /* Mask the interrupt */ + low32 = iosapic_intr_info[vector].low32 | IOSAPIC_MASK; + iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index), + low32); - /* Mask the interrupt */ - low32 = iosapic_intr_info[irq].low32 | IOSAPIC_MASK; - iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte->rte_index), low32); + /* Remove the rte entry from the list */ + list_del(&rte->rte_list); + iosapic_intr_info[vector].count--; + iosapic_free_rte(rte); + index = find_iosapic(gsi); + iosapic_lists[index].rtes_inuse--; + WARN_ON(iosapic_lists[index].rtes_inuse < 0); + + trigger = iosapic_intr_info[vector].trigger; + polarity = iosapic_intr_info[vector].polarity; + dest = iosapic_intr_info[vector].dest; + printk(KERN_INFO + "GSI %u (%s, %s) -> CPU %d (0x%04x)" + " vector %d unregistered\n", + gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), + (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), + cpu_logical_id(dest), dest, vector); - iosapic_intr_info[irq].count--; - index = find_iosapic(gsi); - iosapic_lists[index].rtes_inuse--; - WARN_ON(iosapic_lists[index].rtes_inuse < 0); + if (list_empty(&iosapic_intr_info[vector].rtes)) { + /* Sanity check */ + BUG_ON(iosapic_intr_info[vector].count); - trigger = iosapic_intr_info[irq].trigger; - polarity = iosapic_intr_info[irq].polarity; - dest = iosapic_intr_info[irq].dest; - printk(KERN_INFO - "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d unregistered\n", - gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), - (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), - cpu_logical_id(dest), dest, irq_to_vector(irq)); + /* Clear the interrupt controller descriptor */ + idesc->chip = &no_irq_type; - if (iosapic_intr_info[irq].count == 0) { #ifdef CONFIG_SMP - /* Clear affinity */ - cpus_setall(idesc->affinity); + /* Clear affinity */ + cpus_setall(idesc->affinity); #endif - /* Clear the interrupt information */ - iosapic_intr_info[irq].dest = 0; - iosapic_intr_info[irq].dmode = 0; - iosapic_intr_info[irq].polarity = 0; - iosapic_intr_info[irq].trigger = 0; - iosapic_intr_info[irq].low32 |= IOSAPIC_MASK; - - /* Destroy and reserve IRQ */ - destroy_and_reserve_irq(irq); + + /* Clear the interrupt information */ + memset(&iosapic_intr_info[vector], 0, + sizeof(struct iosapic_intr_info)); + iosapic_intr_info[vector].low32 |= IOSAPIC_MASK; + INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); + + if (idesc->action) { + printk(KERN_ERR + "interrupt handlers still exist on" + "IRQ %u\n", irq); + WARN_ON(1); + } + + /* Free the interrupt vector */ + free_irq_vector(vector); + } } out: - spin_unlock_irqrestore(&iosapic_lock, flags); + spin_unlock(&iosapic_lock); + spin_unlock_irqrestore(&idesc->lock, flags); } /* @@ -903,30 +965,27 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, { static const char * const name[] = {"unknown", "PMI", "INIT", "CPEI"}; unsigned char delivery; - int irq, vector, mask = 0; + int vector, mask = 0; unsigned int dest = ((id << 8) | eid) & 0xffff; switch (int_type) { case ACPI_INTERRUPT_PMI: - irq = vector = iosapic_vector; - bind_irq_vector(irq, vector, CPU_MASK_ALL); + vector = iosapic_vector; /* * since PMI vector is alloc'd by FW(ACPI) not by kernel, * we need to make sure the vector is available */ - iosapic_reassign_vector(irq); + iosapic_reassign_vector(vector); delivery = IOSAPIC_PMI; break; case ACPI_INTERRUPT_INIT: - irq = create_irq(); - if (irq < 0) + vector = assign_irq_vector(AUTO_ASSIGN); + if (vector < 0) panic("%s: out of interrupt vectors!\n", __FUNCTION__); - vector = irq_to_vector(irq); delivery = IOSAPIC_INIT; break; case ACPI_INTERRUPT_CPEI: - irq = vector = IA64_CPE_VECTOR; - BUG_ON(bind_irq_vector(irq, vector, CPU_MASK_ALL)); + vector = IA64_CPE_VECTOR; delivery = IOSAPIC_LOWEST_PRIORITY; mask = 1; break; @@ -936,7 +995,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, return -1; } - register_intr(gsi, irq, delivery, polarity, trigger); + register_intr(gsi, vector, delivery, polarity, trigger); printk(KERN_INFO "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x)" @@ -946,7 +1005,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), cpu_logical_id(dest), dest, vector); - set_rte(gsi, irq, dest, mask); + set_rte(gsi, vector, dest, mask); return vector; } @@ -958,32 +1017,30 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, unsigned long polarity, unsigned long trigger) { - int vector, irq; + int vector; unsigned int dest = cpu_physical_id(smp_processor_id()); - irq = vector = isa_irq_to_vector(isa_irq); - BUG_ON(bind_irq_vector(irq, vector, CPU_MASK_ALL)); - register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY, polarity, trigger); + vector = isa_irq_to_vector(isa_irq); + + register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger); DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n", isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level", polarity == IOSAPIC_POL_HIGH ? "high" : "low", cpu_logical_id(dest), dest, vector); - set_rte(gsi, irq, dest, 1); + set_rte(gsi, vector, dest, 1); } void __init iosapic_system_init (int system_pcat_compat) { - int irq; + int vector; - for (irq = 0; irq < NR_IRQS; ++irq) { - iosapic_intr_info[irq].low32 = IOSAPIC_MASK; + for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) { + iosapic_intr_info[vector].low32 = IOSAPIC_MASK; /* mark as unused */ - INIT_LIST_HEAD(&iosapic_intr_info[irq].rtes); - - iosapic_intr_info[irq].count = 0; + INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); } pcat_compat = system_pcat_compat; @@ -1051,35 +1108,31 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base) unsigned long flags; spin_lock_irqsave(&iosapic_lock, flags); - index = find_iosapic(gsi_base); - if (index >= 0) { - spin_unlock_irqrestore(&iosapic_lock, flags); - return -EBUSY; - } + { + addr = ioremap(phys_addr, 0); + ver = iosapic_version(addr); - addr = ioremap(phys_addr, 0); - ver = iosapic_version(addr); - if ((err = iosapic_check_gsi_range(gsi_base, ver))) { - iounmap(addr); - spin_unlock_irqrestore(&iosapic_lock, flags); - return err; - } + if ((err = iosapic_check_gsi_range(gsi_base, ver))) { + iounmap(addr); + spin_unlock_irqrestore(&iosapic_lock, flags); + return err; + } - /* - * The MAX_REDIR register holds the highest input pin number - * (starting from 0). We add 1 so that we can use it for - * number of pins (= RTEs) - */ - num_rte = ((ver >> 16) & 0xff) + 1; + /* + * The MAX_REDIR register holds the highest input pin + * number (starting from 0). + * We add 1 so that we can use it for number of pins (= RTEs) + */ + num_rte = ((ver >> 16) & 0xff) + 1; - index = iosapic_alloc(); - iosapic_lists[index].addr = addr; - iosapic_lists[index].gsi_base = gsi_base; - iosapic_lists[index].num_rte = num_rte; + index = iosapic_alloc(); + iosapic_lists[index].addr = addr; + iosapic_lists[index].gsi_base = gsi_base; + iosapic_lists[index].num_rte = num_rte; #ifdef CONFIG_NUMA - iosapic_lists[index].node = MAX_NUMNODES; + iosapic_lists[index].node = MAX_NUMNODES; #endif - spin_lock_init(&iosapic_lists[index].lock); + } spin_unlock_irqrestore(&iosapic_lock, flags); if ((gsi_base == 0) && pcat_compat) { @@ -1104,22 +1157,25 @@ iosapic_remove (unsigned int gsi_base) unsigned long flags; spin_lock_irqsave(&iosapic_lock, flags); - index = find_iosapic(gsi_base); - if (index < 0) { - printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n", - __FUNCTION__, gsi_base); - goto out; - } + { + index = find_iosapic(gsi_base); + if (index < 0) { + printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n", + __FUNCTION__, gsi_base); + goto out; + } - if (iosapic_lists[index].rtes_inuse) { - err = -EBUSY; - printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n", - __FUNCTION__, gsi_base); - goto out; - } + if (iosapic_lists[index].rtes_inuse) { + err = -EBUSY; + printk(KERN_WARNING + "%s: IOSAPIC for GSI base %u is busy\n", + __FUNCTION__, gsi_base); + goto out; + } - iounmap(iosapic_lists[index].addr); - iosapic_free(index); + iounmap(iosapic_lists[index].addr); + iosapic_free(index); + } out: spin_unlock_irqrestore(&iosapic_lock, flags); return err; diff --git a/trunk/arch/ia64/kernel/irq.c b/trunk/arch/ia64/kernel/irq.c index cc3ee4ef37af..407b45870489 100644 --- a/trunk/arch/ia64/kernel/irq.c +++ b/trunk/arch/ia64/kernel/irq.c @@ -35,7 +35,7 @@ void ack_bad_irq(unsigned int irq) #ifdef CONFIG_IA64_GENERIC unsigned int __ia64_local_vector_to_irq (ia64_vector vec) { - return __get_cpu_var(vector_irq)[vec]; + return (unsigned int) vec; } #endif diff --git a/trunk/arch/ia64/kernel/irq_ia64.c b/trunk/arch/ia64/kernel/irq_ia64.c index 91797c111162..bc47049f060f 100644 --- a/trunk/arch/ia64/kernel/irq_ia64.c +++ b/trunk/arch/ia64/kernel/irq_ia64.c @@ -46,12 +46,6 @@ #define IRQ_DEBUG 0 -#define IRQ_VECTOR_UNASSIGNED (0) - -#define IRQ_UNUSED (0) -#define IRQ_USED (1) -#define IRQ_RSVD (2) - /* These can be overridden in platform_irq_init */ int ia64_first_device_vector = IA64_DEF_FIRST_DEVICE_VECTOR; int ia64_last_device_vector = IA64_DEF_LAST_DEVICE_VECTOR; @@ -60,8 +54,6 @@ int ia64_last_device_vector = IA64_DEF_LAST_DEVICE_VECTOR; void __iomem *ipi_base_addr = ((void __iomem *) (__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR)); -static cpumask_t vector_allocation_domain(int cpu); - /* * Legacy IRQ to IA-64 vector translation table. */ @@ -72,269 +64,46 @@ __u8 isa_irq_to_vector_map[16] = { }; EXPORT_SYMBOL(isa_irq_to_vector_map); -DEFINE_SPINLOCK(vector_lock); - -struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = { - [0 ... NR_IRQS - 1] = { - .vector = IRQ_VECTOR_UNASSIGNED, - .domain = CPU_MASK_NONE - } -}; - -DEFINE_PER_CPU(int[IA64_NUM_VECTORS], vector_irq) = { - [0 ... IA64_NUM_VECTORS - 1] = IA64_SPURIOUS_INT_VECTOR -}; - -static cpumask_t vector_table[IA64_MAX_DEVICE_VECTORS] = { - [0 ... IA64_MAX_DEVICE_VECTORS - 1] = CPU_MASK_NONE -}; - -static int irq_status[NR_IRQS] = { - [0 ... NR_IRQS -1] = IRQ_UNUSED -}; - -int check_irq_used(int irq) -{ - if (irq_status[irq] == IRQ_USED) - return 1; - - return -1; -} - -static void reserve_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&vector_lock, flags); - irq_status[irq] = IRQ_RSVD; - spin_unlock_irqrestore(&vector_lock, flags); -} - -static inline int find_unassigned_irq(void) -{ - int irq; - - for (irq = IA64_FIRST_DEVICE_VECTOR; irq < NR_IRQS; irq++) - if (irq_status[irq] == IRQ_UNUSED) - return irq; - return -ENOSPC; -} - -static inline int find_unassigned_vector(cpumask_t domain) -{ - cpumask_t mask; - int pos; - - cpus_and(mask, domain, cpu_online_map); - if (cpus_empty(mask)) - return -EINVAL; - - for (pos = 0; pos < IA64_NUM_DEVICE_VECTORS; pos++) { - cpus_and(mask, domain, vector_table[pos]); - if (!cpus_empty(mask)) - continue; - return IA64_FIRST_DEVICE_VECTOR + pos; - } - return -ENOSPC; -} - -static int __bind_irq_vector(int irq, int vector, cpumask_t domain) -{ - cpumask_t mask; - int cpu, pos; - struct irq_cfg *cfg = &irq_cfg[irq]; - - cpus_and(mask, domain, cpu_online_map); - if (cpus_empty(mask)) - return -EINVAL; - if ((cfg->vector == vector) && cpus_equal(cfg->domain, domain)) - return 0; - if (cfg->vector != IRQ_VECTOR_UNASSIGNED) - return -EBUSY; - for_each_cpu_mask(cpu, mask) - per_cpu(vector_irq, cpu)[vector] = irq; - cfg->vector = vector; - cfg->domain = domain; - irq_status[irq] = IRQ_USED; - pos = vector - IA64_FIRST_DEVICE_VECTOR; - cpus_or(vector_table[pos], vector_table[pos], domain); - return 0; -} - -int bind_irq_vector(int irq, int vector, cpumask_t domain) -{ - unsigned long flags; - int ret; - - spin_lock_irqsave(&vector_lock, flags); - ret = __bind_irq_vector(irq, vector, domain); - spin_unlock_irqrestore(&vector_lock, flags); - return ret; -} - -static void __clear_irq_vector(int irq) -{ - int vector, cpu, pos; - cpumask_t mask; - cpumask_t domain; - struct irq_cfg *cfg = &irq_cfg[irq]; - - BUG_ON((unsigned)irq >= NR_IRQS); - BUG_ON(cfg->vector == IRQ_VECTOR_UNASSIGNED); - vector = cfg->vector; - domain = cfg->domain; - cpus_and(mask, cfg->domain, cpu_online_map); - for_each_cpu_mask(cpu, mask) - per_cpu(vector_irq, cpu)[vector] = IA64_SPURIOUS_INT_VECTOR; - cfg->vector = IRQ_VECTOR_UNASSIGNED; - cfg->domain = CPU_MASK_NONE; - irq_status[irq] = IRQ_UNUSED; - pos = vector - IA64_FIRST_DEVICE_VECTOR; - cpus_andnot(vector_table[pos], vector_table[pos], domain); -} - -static void clear_irq_vector(int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&vector_lock, flags); - __clear_irq_vector(irq); - spin_unlock_irqrestore(&vector_lock, flags); -} +static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_MAX_DEVICE_VECTORS)]; int assign_irq_vector (int irq) { - unsigned long flags; - int vector, cpu; - cpumask_t domain; - - vector = -ENOSPC; - - spin_lock_irqsave(&vector_lock, flags); - if (irq < 0) { - goto out; - } - for_each_online_cpu(cpu) { - domain = vector_allocation_domain(cpu); - vector = find_unassigned_vector(domain); - if (vector >= 0) - break; - } - if (vector < 0) - goto out; - BUG_ON(__bind_irq_vector(irq, vector, domain)); - out: - spin_unlock_irqrestore(&vector_lock, flags); + int pos, vector; + again: + pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS); + vector = IA64_FIRST_DEVICE_VECTOR + pos; + if (vector > IA64_LAST_DEVICE_VECTOR) + return -ENOSPC; + if (test_and_set_bit(pos, ia64_vector_mask)) + goto again; return vector; } void free_irq_vector (int vector) { - if (vector < IA64_FIRST_DEVICE_VECTOR || - vector > IA64_LAST_DEVICE_VECTOR) + int pos; + + if (vector < IA64_FIRST_DEVICE_VECTOR || vector > IA64_LAST_DEVICE_VECTOR) return; - clear_irq_vector(vector); + + pos = vector - IA64_FIRST_DEVICE_VECTOR; + if (!test_and_clear_bit(pos, ia64_vector_mask)) + printk(KERN_WARNING "%s: double free!\n", __FUNCTION__); } int reserve_irq_vector (int vector) { + int pos; + if (vector < IA64_FIRST_DEVICE_VECTOR || vector > IA64_LAST_DEVICE_VECTOR) return -EINVAL; - return !!bind_irq_vector(vector, vector, CPU_MASK_ALL); -} - -/* - * Initialize vector_irq on a new cpu. This function must be called - * with vector_lock held. - */ -void __setup_vector_irq(int cpu) -{ - int irq, vector; - - /* Clear vector_irq */ - for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) - per_cpu(vector_irq, cpu)[vector] = IA64_SPURIOUS_INT_VECTOR; - /* Mark the inuse vectors */ - for (irq = 0; irq < NR_IRQS; ++irq) { - if (!cpu_isset(cpu, irq_cfg[irq].domain)) - continue; - vector = irq_to_vector(irq); - per_cpu(vector_irq, cpu)[vector] = irq; - } -} - -#if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG)) -static enum vector_domain_type { - VECTOR_DOMAIN_NONE, - VECTOR_DOMAIN_PERCPU -} vector_domain_type = VECTOR_DOMAIN_NONE; -static cpumask_t vector_allocation_domain(int cpu) -{ - if (vector_domain_type == VECTOR_DOMAIN_PERCPU) - return cpumask_of_cpu(cpu); - return CPU_MASK_ALL; -} - -static int __init parse_vector_domain(char *arg) -{ - if (!arg) - return -EINVAL; - if (!strcmp(arg, "percpu")) { - vector_domain_type = VECTOR_DOMAIN_PERCPU; - no_int_routing = 1; - } - return 1; -} -early_param("vector", parse_vector_domain); -#else -static cpumask_t vector_allocation_domain(int cpu) -{ - return CPU_MASK_ALL; -} -#endif - - -void destroy_and_reserve_irq(unsigned int irq) -{ - dynamic_irq_cleanup(irq); - - clear_irq_vector(irq); - reserve_irq(irq); -} - -static int __reassign_irq_vector(int irq, int cpu) -{ - struct irq_cfg *cfg = &irq_cfg[irq]; - int vector; - cpumask_t domain; - - if (cfg->vector == IRQ_VECTOR_UNASSIGNED || !cpu_online(cpu)) - return -EINVAL; - if (cpu_isset(cpu, cfg->domain)) - return 0; - domain = vector_allocation_domain(cpu); - vector = find_unassigned_vector(domain); - if (vector < 0) - return -ENOSPC; - __clear_irq_vector(irq); - BUG_ON(__bind_irq_vector(irq, vector, domain)); - return 0; -} - -int reassign_irq_vector(int irq, int cpu) -{ - unsigned long flags; - int ret; - - spin_lock_irqsave(&vector_lock, flags); - ret = __reassign_irq_vector(irq, cpu); - spin_unlock_irqrestore(&vector_lock, flags); - return ret; + pos = vector - IA64_FIRST_DEVICE_VECTOR; + return test_and_set_bit(pos, ia64_vector_mask); } /* @@ -342,35 +111,18 @@ int reassign_irq_vector(int irq, int cpu) */ int create_irq(void) { - unsigned long flags; - int irq, vector, cpu; - cpumask_t domain; - - irq = vector = -ENOSPC; - spin_lock_irqsave(&vector_lock, flags); - for_each_online_cpu(cpu) { - domain = vector_allocation_domain(cpu); - vector = find_unassigned_vector(domain); - if (vector >= 0) - break; - } - if (vector < 0) - goto out; - irq = find_unassigned_irq(); - if (irq < 0) - goto out; - BUG_ON(__bind_irq_vector(irq, vector, domain)); - out: - spin_unlock_irqrestore(&vector_lock, flags); - if (irq >= 0) - dynamic_irq_init(irq); - return irq; + int vector = assign_irq_vector(AUTO_ASSIGN); + + if (vector >= 0) + dynamic_irq_init(vector); + + return vector; } void destroy_irq(unsigned int irq) { dynamic_irq_cleanup(irq); - clear_irq_vector(irq); + free_irq_vector(irq); } #ifdef CONFIG_SMP @@ -549,13 +301,14 @@ register_percpu_irq (ia64_vector vec, struct irqaction *action) irq_desc_t *desc; unsigned int irq; - irq = vec; - BUG_ON(bind_irq_vector(irq, vec, CPU_MASK_ALL)); - desc = irq_desc + irq; - desc->status |= IRQ_PER_CPU; - desc->chip = &irq_type_ia64_lsapic; - if (action) - setup_irq(irq, action); + for (irq = 0; irq < NR_IRQS; ++irq) + if (irq_to_vector(irq) == vec) { + desc = irq_desc + irq; + desc->status |= IRQ_PER_CPU; + desc->chip = &irq_type_ia64_lsapic; + if (action) + setup_irq(irq, action); + } } void __init diff --git a/trunk/arch/ia64/kernel/msi_ia64.c b/trunk/arch/ia64/kernel/msi_ia64.c index 2fdbd5c3f213..c81080df70df 100644 --- a/trunk/arch/ia64/kernel/msi_ia64.c +++ b/trunk/arch/ia64/kernel/msi_ia64.c @@ -13,7 +13,6 @@ #define MSI_DATA_VECTOR_SHIFT 0 #define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT) -#define MSI_DATA_VECTOR_MASK 0xffffff00 #define MSI_DATA_DELIVERY_SHIFT 8 #define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT) @@ -51,29 +50,17 @@ static struct irq_chip ia64_msi_chip; static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask) { struct msi_msg msg; - u32 addr, data; - int cpu = first_cpu(cpu_mask); - - if (!cpu_online(cpu)) - return; - - if (reassign_irq_vector(irq, cpu)) - return; + u32 addr; read_msi_msg(irq, &msg); addr = msg.address_lo; addr &= MSI_ADDR_DESTID_MASK; - addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(cpu)); + addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(first_cpu(cpu_mask))); msg.address_lo = addr; - data = msg.data; - data &= MSI_DATA_VECTOR_MASK; - data |= MSI_DATA_VECTOR(irq_to_vector(irq)); - msg.data = data; - write_msi_msg(irq, &msg); - irq_desc[irq].affinity = cpumask_of_cpu(cpu); + irq_desc[irq].affinity = cpu_mask; } #endif /* CONFIG_SMP */ @@ -82,15 +69,13 @@ int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) struct msi_msg msg; unsigned long dest_phys_id; int irq, vector; - cpumask_t mask; irq = create_irq(); if (irq < 0) return irq; set_irq_msi(irq, desc); - cpus_and(mask, irq_to_domain(irq), cpu_online_map); - dest_phys_id = cpu_physical_id(first_cpu(mask)); + dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map)); vector = irq_to_vector(irq); msg.address_hi = 0; diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c index 9f5c90b594b9..3c9d8e6089cf 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -395,13 +395,9 @@ smp_callin (void) fix_b0_for_bsp(); lock_ipi_calllock(); - spin_lock(&vector_lock); - /* Setup the per cpu irq handling data structures */ - __setup_vector_irq(cpuid); cpu_set(cpuid, cpu_online_map); unlock_ipi_calllock(); per_cpu(cpu_state, cpuid) = CPU_ONLINE; - spin_unlock(&vector_lock); smp_setup_percpu_timer(); diff --git a/trunk/arch/ia64/kernel/time.c b/trunk/arch/ia64/kernel/time.c index 627785c48ea9..3486fe7d6e65 100644 --- a/trunk/arch/ia64/kernel/time.c +++ b/trunk/arch/ia64/kernel/time.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -29,16 +28,6 @@ #include #include -#include "fsyscall_gtod_data.h" - -static cycle_t itc_get_cycles(void); - -struct fsyscall_gtod_data_t fsyscall_gtod_data = { - .lock = SEQLOCK_UNLOCKED, -}; - -struct itc_jitter_data_t itc_jitter_data; - volatile int time_keeper_id = 0; /* smp_processor_id() of time-keeper */ #ifdef CONFIG_IA64_DEBUG_IRQ @@ -48,16 +37,11 @@ EXPORT_SYMBOL(last_cli_ip); #endif -static struct clocksource clocksource_itc = { - .name = "itc", - .rating = 350, - .read = itc_get_cycles, - .mask = 0xffffffffffffffff, - .mult = 0, /*to be caluclated*/ - .shift = 16, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, +static struct time_interpolator itc_interpolator = { + .shift = 16, + .mask = 0xffffffffffffffffLL, + .source = TIME_SOURCE_CPU }; -static struct clocksource *itc_clocksource; static irqreturn_t timer_interrupt (int irq, void *dev_id) @@ -226,6 +210,8 @@ ia64_init_itm (void) + itc_freq/2)/itc_freq; if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) { + itc_interpolator.frequency = local_cpu_data->itc_freq; + itc_interpolator.drift = itc_drift; #ifdef CONFIG_SMP /* On IA64 in an SMP configuration ITCs are never accurately synchronized. * Jitter compensation requires a cmpxchg which may limit @@ -237,50 +223,15 @@ ia64_init_itm (void) * even going backward) if the ITC offsets between the individual CPUs * are too large. */ - if (!nojitter) - itc_jitter_data.itc_jitter = 1; + if (!nojitter) itc_interpolator.jitter = 1; #endif + register_time_interpolator(&itc_interpolator); } /* Setup the CPU local timer tick */ ia64_cpu_local_tick(); - - if (!itc_clocksource) { - /* Sort out mult/shift values: */ - clocksource_itc.mult = - clocksource_hz2mult(local_cpu_data->itc_freq, - clocksource_itc.shift); - clocksource_register(&clocksource_itc); - itc_clocksource = &clocksource_itc; - } } -static cycle_t itc_get_cycles() -{ - u64 lcycle, now, ret; - - if (!itc_jitter_data.itc_jitter) - return get_cycles(); - - lcycle = itc_jitter_data.itc_lastcycle; - now = get_cycles(); - if (lcycle && time_after(lcycle, now)) - return lcycle; - - /* - * Keep track of the last timer value returned. - * In an SMP environment, you could lose out in contention of - * cmpxchg. If so, your cmpxchg returns new value which the - * winner of contention updated to. Use the new value instead. - */ - ret = cmpxchg(&itc_jitter_data.itc_lastcycle, lcycle, now); - if (unlikely(ret != lcycle)) - return ret; - - return now; -} - - static struct irqaction timer_irqaction = { .handler = timer_interrupt, .flags = IRQF_DISABLED | IRQF_IRQPOLL, @@ -356,34 +307,3 @@ ia64_setup_printk_clock(void) if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) ia64_printk_clock = ia64_itc_printk_clock; } - -void update_vsyscall(struct timespec *wall, struct clocksource *c) -{ - unsigned long flags; - - write_seqlock_irqsave(&fsyscall_gtod_data.lock, flags); - - /* copy fsyscall clock data */ - fsyscall_gtod_data.clk_mask = c->mask; - fsyscall_gtod_data.clk_mult = c->mult; - fsyscall_gtod_data.clk_shift = c->shift; - fsyscall_gtod_data.clk_fsys_mmio = c->fsys_mmio; - fsyscall_gtod_data.clk_cycle_last = c->cycle_last; - - /* copy kernel time structures */ - fsyscall_gtod_data.wall_time.tv_sec = wall->tv_sec; - fsyscall_gtod_data.wall_time.tv_nsec = wall->tv_nsec; - fsyscall_gtod_data.monotonic_time.tv_sec = wall_to_monotonic.tv_sec - + wall->tv_sec; - fsyscall_gtod_data.monotonic_time.tv_nsec = wall_to_monotonic.tv_nsec - + wall->tv_nsec; - - /* normalize */ - while (fsyscall_gtod_data.monotonic_time.tv_nsec >= NSEC_PER_SEC) { - fsyscall_gtod_data.monotonic_time.tv_nsec -= NSEC_PER_SEC; - fsyscall_gtod_data.monotonic_time.tv_sec++; - } - - write_sequnlock_irqrestore(&fsyscall_gtod_data.lock, flags); -} - diff --git a/trunk/arch/ia64/sn/kernel/sn2/timer.c b/trunk/arch/ia64/sn/kernel/sn2/timer.c index 19e25d2b64fc..56a88b6df4b4 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/timer.c +++ b/trunk/arch/ia64/sn/kernel/sn2/timer.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -23,21 +22,11 @@ extern unsigned long sn_rtc_cycles_per_second; -static void __iomem *sn2_mc; - -static cycle_t read_sn2(void) -{ - return (cycle_t)readq(sn2_mc); -} - -static struct clocksource clocksource_sn2 = { - .name = "sn2_rtc", - .rating = 300, - .read = read_sn2, - .mask = (1LL << 55) - 1, - .mult = 0, - .shift = 10, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, +static struct time_interpolator sn2_interpolator = { + .drift = -1, + .shift = 10, + .mask = (1LL << 55) - 1, + .source = TIME_SOURCE_MMIO64 }; /* @@ -58,11 +47,9 @@ ia64_sn_udelay (unsigned long usecs) void __init sn_timer_init(void) { - sn2_mc = RTC_COUNTER_ADDR; - clocksource_sn2.fsys_mmio = RTC_COUNTER_ADDR; - clocksource_sn2.mult = clocksource_hz2mult(sn_rtc_cycles_per_second, - clocksource_sn2.shift); - clocksource_register(&clocksource_sn2); + sn2_interpolator.frequency = sn_rtc_cycles_per_second; + sn2_interpolator.addr = RTC_COUNTER_ADDR; + register_time_interpolator(&sn2_interpolator); ia64_udelay = &ia64_sn_udelay; } diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index 20a9c08e59c3..a86e2e9a639f 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -37,10 +37,6 @@ config TIME_LOW_RES bool default y -config GENERIC_IOMAP - bool - default y - config ARCH_MAY_HAVE_PC_FDC bool depends on Q40 || (BROKEN && SUN3X) @@ -49,9 +45,6 @@ config ARCH_MAY_HAVE_PC_FDC config NO_IOPORT def_bool y -config NO_DMA - def_bool SUN3 - mainmenu "Linux/68k Kernel Configuration" source "init/Kconfig" diff --git a/trunk/arch/m68k/apollo/config.c b/trunk/arch/m68k/apollo/config.c index 78df98f2029a..cb8e7609df4c 100644 --- a/trunk/arch/m68k/apollo/config.c +++ b/trunk/arch/m68k/apollo/config.c @@ -148,8 +148,8 @@ void dn_serial_print (const char *str) } } -void __init config_apollo(void) -{ +void config_apollo(void) { + int i; dn_setup_model(); diff --git a/trunk/arch/m68k/apollo/dn_ints.c b/trunk/arch/m68k/apollo/dn_ints.c index 5d47f3aa3810..13bd41bed28e 100644 --- a/trunk/arch/m68k/apollo/dn_ints.c +++ b/trunk/arch/m68k/apollo/dn_ints.c @@ -37,7 +37,7 @@ static struct irq_controller apollo_irq_controller = { }; -void __init dn_init_IRQ(void) +void dn_init_IRQ(void) { m68k_setup_user_interrupt(VEC_USER + 96, 16, dn_process_int); m68k_setup_irq_controller(&apollo_irq_controller, IRQ_APOLLO, 16); diff --git a/trunk/arch/m68k/atari/atakeyb.c b/trunk/arch/m68k/atari/atakeyb.c index 2b5f64726a2e..1c29603b16b3 100644 --- a/trunk/arch/m68k/atari/atakeyb.c +++ b/trunk/arch/m68k/atari/atakeyb.c @@ -13,7 +13,6 @@ * enhanced by Bjoern Brauel and Roman Hodek */ -#include #include #include #include @@ -43,9 +42,6 @@ void (*atari_mouse_interrupt_hook) (char *); void (*atari_input_keyboard_interrupt_hook) (unsigned char, char); /* Hook for mouse inputdev driver */ void (*atari_input_mouse_interrupt_hook) (char *); -EXPORT_SYMBOL(atari_mouse_interrupt_hook); -EXPORT_SYMBOL(atari_input_keyboard_interrupt_hook); -EXPORT_SYMBOL(atari_input_mouse_interrupt_hook); /* variables for IKBD self test: */ @@ -433,7 +429,6 @@ void ikbd_mouse_rel_pos(void) ikbd_write(cmd, 1); } -EXPORT_SYMBOL(ikbd_mouse_rel_pos); /* Set absolute mouse position reporting */ void ikbd_mouse_abs_pos(int xmax, int ymax) @@ -458,7 +453,6 @@ void ikbd_mouse_thresh(int x, int y) ikbd_write(cmd, 3); } -EXPORT_SYMBOL(ikbd_mouse_thresh); /* Set mouse scale */ void ikbd_mouse_scale(int x, int y) @@ -501,7 +495,6 @@ void ikbd_mouse_y0_top(void) ikbd_write(cmd, 1); } -EXPORT_SYMBOL(ikbd_mouse_y0_top); /* Resume */ void ikbd_resume(void) @@ -518,7 +511,6 @@ void ikbd_mouse_disable(void) ikbd_write(cmd, 1); } -EXPORT_SYMBOL(ikbd_mouse_disable); /* Pause output */ void ikbd_pause(void) @@ -704,6 +696,7 @@ int __init atari_keyb_init(void) return 0; } + int atari_kbdrate(struct kbd_repeat *k) { if (k->delay > 0) { diff --git a/trunk/arch/m68k/bvme6000/config.c b/trunk/arch/m68k/bvme6000/config.c index 9433a88a33c4..896ae3d3d919 100644 --- a/trunk/arch/m68k/bvme6000/config.c +++ b/trunk/arch/m68k/bvme6000/config.c @@ -97,7 +97,7 @@ static int bvme6000_get_hardware_list(char *buffer) * This function is called during kernel startup to initialize * the bvme6000 IRQ handling routines. */ -static void __init bvme6000_init_IRQ(void) +static void bvme6000_init_IRQ(void) { m68k_setup_user_interrupt(VEC_USER, 192, NULL); } diff --git a/trunk/arch/m68k/kernel/head.S b/trunk/arch/m68k/kernel/head.S index faa6764f1d13..05741f233567 100644 --- a/trunk/arch/m68k/kernel/head.S +++ b/trunk/arch/m68k/kernel/head.S @@ -577,7 +577,7 @@ func_define putn,1 #endif .endm -.section ".text.head","ax" +.text ENTRY(_stext) /* * Version numbers of the bootinfo interface diff --git a/trunk/arch/m68k/kernel/setup.c b/trunk/arch/m68k/kernel/setup.c index 7e6d5fb75390..215c7bd43924 100644 --- a/trunk/arch/m68k/kernel/setup.c +++ b/trunk/arch/m68k/kernel/setup.c @@ -58,7 +58,6 @@ extern int end; extern unsigned long availmem; int m68k_num_memory; -EXPORT_SYMBOL(m68k_num_memory); int m68k_realnum_memory; EXPORT_SYMBOL(m68k_realnum_memory); unsigned long m68k_memoffset; diff --git a/trunk/arch/m68k/kernel/sun3-head.S b/trunk/arch/m68k/kernel/sun3-head.S index aad01592dbbc..4b5f050204e8 100644 --- a/trunk/arch/m68k/kernel/sun3-head.S +++ b/trunk/arch/m68k/kernel/sun3-head.S @@ -29,7 +29,7 @@ kernel_pmd_table: .skip 0x2000 .globl kernel_pg_dir .equ kernel_pg_dir,kernel_pmd_table - .section .text.head + .section .head ENTRY(_stext) ENTRY(_start) diff --git a/trunk/arch/m68k/kernel/time.c b/trunk/arch/m68k/kernel/time.c index 7db41594d7b6..4c065f9ceffc 100644 --- a/trunk/arch/m68k/kernel/time.c +++ b/trunk/arch/m68k/kernel/time.c @@ -72,7 +72,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy) return IRQ_HANDLED; } -void __init time_init(void) +void time_init(void) { struct rtc_time time; diff --git a/trunk/arch/m68k/kernel/vmlinux-std.lds b/trunk/arch/m68k/kernel/vmlinux-std.lds index c42245775a4d..40f02b128f22 100644 --- a/trunk/arch/m68k/kernel/vmlinux-std.lds +++ b/trunk/arch/m68k/kernel/vmlinux-std.lds @@ -11,7 +11,6 @@ SECTIONS . = 0x1000; _text = .; /* Text and read-only data */ .text : { - *(.text.head) TEXT_TEXT SCHED_TEXT LOCK_TEXT diff --git a/trunk/arch/m68k/kernel/vmlinux-sun3.lds b/trunk/arch/m68k/kernel/vmlinux-sun3.lds index 4adffefb5c48..f06425b6d206 100644 --- a/trunk/arch/m68k/kernel/vmlinux-sun3.lds +++ b/trunk/arch/m68k/kernel/vmlinux-sun3.lds @@ -11,7 +11,7 @@ SECTIONS . = 0xE002000; _text = .; /* Text and read-only data */ .text : { - *(.text.head) + *(.head) TEXT_TEXT SCHED_TEXT LOCK_TEXT diff --git a/trunk/arch/m68k/mac/config.c b/trunk/arch/m68k/mac/config.c index 8547dbc5e8d7..5fd413246f89 100644 --- a/trunk/arch/m68k/mac/config.c +++ b/trunk/arch/m68k/mac/config.c @@ -49,7 +49,6 @@ struct mac_booter_data mac_bi_data; int mac_bisize = sizeof mac_bi_data; struct mac_hw_present mac_hw_present; -EXPORT_SYMBOL(mac_hw_present); /* New m68k bootinfo stuff and videobase */ @@ -85,7 +84,7 @@ extern void nubus_sweep_video(void); static void mac_get_model(char *str); -static void __init mac_sched_init(irq_handler_t vector) +static void mac_sched_init(irq_handler_t vector) { via_init_clock(vector); } @@ -770,7 +769,7 @@ static struct mac_model mac_data_table[] = { } }; -void __init mac_identify(void) +void mac_identify(void) { struct mac_model *m; @@ -847,7 +846,7 @@ void __init mac_identify(void) baboon_init(); } -void __init mac_report_hardware(void) +void mac_report_hardware(void) { printk(KERN_INFO "Apple Macintosh %s\n", macintosh_config->name); } diff --git a/trunk/arch/m68k/mac/macints.c b/trunk/arch/m68k/mac/macints.c index ecddac4a02b9..0fc72d8f786e 100644 --- a/trunk/arch/m68k/mac/macints.c +++ b/trunk/arch/m68k/mac/macints.c @@ -114,7 +114,6 @@ * */ -#include #include #include #include @@ -225,7 +224,7 @@ static struct irq_controller mac_irq_controller = { .disable = mac_disable_irq, }; -void __init mac_init_IRQ(void) +void mac_init_IRQ(void) { #ifdef DEBUG_MACINTS printk("mac_init_IRQ(): Setting things up...\n"); @@ -392,7 +391,6 @@ int mac_irq_pending(unsigned int irq) } return 0; } -EXPORT_SYMBOL(mac_irq_pending); static int num_debug[8]; diff --git a/trunk/arch/m68k/mm/init.c b/trunk/arch/m68k/mm/init.c index f42caa79e4e8..f1de19e1dde6 100644 --- a/trunk/arch/m68k/mm/init.c +++ b/trunk/arch/m68k/mm/init.c @@ -44,7 +44,7 @@ pg_data_t *pg_data_table[65]; EXPORT_SYMBOL(pg_data_table); #endif -void __init m68k_setup_node(int node) +void m68k_setup_node(int node) { #ifndef CONFIG_SINGLE_MEMORY_CHUNK struct mem_info *info = m68k_memory + node; diff --git a/trunk/arch/m68k/mm/sun3kmap.c b/trunk/arch/m68k/mm/sun3kmap.c index 3dc41158c05e..1af24cb5bfe1 100644 --- a/trunk/arch/m68k/mm/sun3kmap.c +++ b/trunk/arch/m68k/mm/sun3kmap.c @@ -105,7 +105,6 @@ void __iomem *sun3_ioremap(unsigned long phys, unsigned long size, return (void __iomem *)ret; } -EXPORT_SYMBOL(sun3_ioremap); void __iomem *__ioremap(unsigned long phys, unsigned long size, int cache) @@ -158,4 +157,3 @@ int sun3_map_test(unsigned long addr, char *val) return ret; } -EXPORT_SYMBOL(sun3_map_test); diff --git a/trunk/arch/m68k/mvme147/config.c b/trunk/arch/m68k/mvme147/config.c index 92fe50714112..4a7df9c3f85a 100644 --- a/trunk/arch/m68k/mvme147/config.c +++ b/trunk/arch/m68k/mvme147/config.c @@ -89,7 +89,7 @@ static int mvme147_get_hardware_list(char *buffer) * the mvme147 IRQ handling routines. */ -void __init mvme147_init_IRQ(void) +void mvme147_init_IRQ(void) { m68k_setup_user_interrupt(VEC_USER, 192, NULL); } diff --git a/trunk/arch/m68k/mvme16x/config.c b/trunk/arch/m68k/mvme16x/config.c index daa785161401..c829ebb6b1af 100644 --- a/trunk/arch/m68k/mvme16x/config.c +++ b/trunk/arch/m68k/mvme16x/config.c @@ -119,7 +119,7 @@ static int mvme16x_get_hardware_list(char *buffer) * that the base vectors for the VMEChip2 and PCCChip2 are valid. */ -static void __init mvme16x_init_IRQ (void) +static void mvme16x_init_IRQ (void) { m68k_setup_user_interrupt(VEC_USER, 192, NULL); } diff --git a/trunk/arch/m68k/q40/q40ints.c b/trunk/arch/m68k/q40/q40ints.c index ad3ed1fb8879..2fb25ae46a8a 100644 --- a/trunk/arch/m68k/q40/q40ints.c +++ b/trunk/arch/m68k/q40/q40ints.c @@ -79,7 +79,7 @@ static struct irq_controller q40_irq_controller = { static int disabled; -void __init q40_init_IRQ(void) +void q40_init_IRQ(void) { m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX); diff --git a/trunk/arch/m68k/sun3/sun3ints.c b/trunk/arch/m68k/sun3/sun3ints.c index cf93481adb1d..50df34bf80e3 100644 --- a/trunk/arch/m68k/sun3/sun3ints.c +++ b/trunk/arch/m68k/sun3/sun3ints.c @@ -97,7 +97,7 @@ static struct irq_controller sun3_irq_controller = { .disable = sun3_disable_irq, }; -void __init sun3_init_IRQ(void) +void sun3_init_IRQ(void) { *sun3_intreg = 1; diff --git a/trunk/arch/m68k/sun3x/prom.c b/trunk/arch/m68k/sun3x/prom.c index a7b7e818d627..48f8eb7b1565 100644 --- a/trunk/arch/m68k/sun3x/prom.c +++ b/trunk/arch/m68k/sun3x/prom.c @@ -92,7 +92,7 @@ static struct console sun3x_debug = { .index = -1, }; -void __init sun3x_prom_init(void) +void sun3x_prom_init(void) { /* Read the vector table */ diff --git a/trunk/arch/m68knommu/kernel/setup.c b/trunk/arch/m68knommu/kernel/setup.c index 2203f694f26b..80f4e9d74ac1 100644 --- a/trunk/arch/m68knommu/kernel/setup.c +++ b/trunk/arch/m68knommu/kernel/setup.c @@ -231,33 +231,32 @@ void setup_arch(char **cmdline_p) /* * Get CPU information for use by the procfs. */ + static int show_cpuinfo(struct seq_file *m, void *v) { - char *cpu, *mmu, *fpu; - u_long clockfreq; + char *cpu, *mmu, *fpu; + u_long clockfreq; - cpu = CPU; - mmu = "none"; - fpu = "none"; + cpu = CPU; + mmu = "none"; + fpu = "none"; #ifdef CONFIG_COLDFIRE - clockfreq = (loops_per_jiffy * HZ) * 3; + clockfreq = (loops_per_jiffy*HZ)*3; #else - clockfreq = (loops_per_jiffy * HZ) * 16; -#endif - - seq_printf(m, "CPU:\t\t%s\n" - "MMU:\t\t%s\n" - "FPU:\t\t%s\n" - "Clocking:\t%lu.%1luMHz\n" - "BogoMips:\t%lu.%02lu\n" - "Calibration:\t%lu loops\n", - cpu, mmu, fpu, - clockfreq / 1000000, - (clockfreq / 100000) % 10, - (loops_per_jiffy * HZ) / 500000, - ((loops_per_jiffy * HZ) / 5000) % 100, - (loops_per_jiffy * HZ)); + clockfreq = (loops_per_jiffy*HZ)*16; +#endif + + seq_printf(m, "CPU:\t\t%s\n" + "MMU:\t\t%s\n" + "FPU:\t\t%s\n" + "Clocking:\t%lu.%1luMHz\n" + "BogoMips:\t%lu.%02lu\n" + "Calibration:\t%lu loops\n", + cpu, mmu, fpu, + clockfreq/1000000,(clockfreq/100000)%10, + (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100, + (loops_per_jiffy*HZ)); return 0; } diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 1e3aeccd7322..5c863bcd5614 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -1190,19 +1190,8 @@ config SYS_HAS_CPU_RM9000 config SYS_HAS_CPU_SB1 bool -# -# CPU may reorder R->R, R->W, W->R, W->W -# Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC -# config WEAK_ORDERING bool - -# -# CPU may reorder reads and writes beyond LL/SC -# CPU may reorder R->LL, R->LL, W->LL, W->LL, R->SC, R->SC, W->SC, W->SC -# -config WEAK_REORDERING_BEYOND_LLSC - bool endmenu # diff --git a/trunk/arch/mips/kernel/cpu-probe.c b/trunk/arch/mips/kernel/cpu-probe.c index 06448a9656dc..c6b8b074a81a 100644 --- a/trunk/arch/mips/kernel/cpu-probe.c +++ b/trunk/arch/mips/kernel/cpu-probe.c @@ -75,27 +75,6 @@ static void r4k_wait_irqoff(void) local_irq_enable(); } -/* - * The RM7000 variant has to handle erratum 38. The workaround is to not - * have any pending stores when the WAIT instruction is executed. - */ -static void rm7k_wait_irqoff(void) -{ - local_irq_disable(); - if (!need_resched()) - __asm__( - " .set push \n" - " .set mips3 \n" - " .set noat \n" - " mfc0 $1, $12 \n" - " sync \n" - " mtc0 $1, $12 # stalls until W stage \n" - " wait \n" - " mtc0 $1, $12 # stalls until W stage \n" - " .set pop \n"); - local_irq_enable(); -} - /* The Au1xxx wait is available only if using 32khz counter or * external timer source, but specifically not CP0 Counter. */ int allow_au1k_wait; @@ -153,6 +132,7 @@ static inline void check_wait(void) case CPU_R4700: case CPU_R5000: case CPU_NEVADA: + case CPU_RM7000: case CPU_4KC: case CPU_4KEC: case CPU_4KSC: @@ -162,10 +142,6 @@ static inline void check_wait(void) cpu_wait = r4k_wait; break; - case CPU_RM7000: - cpu_wait = rm7k_wait_irqoff; - break; - case CPU_24K: case CPU_34K: cpu_wait = r4k_wait; diff --git a/trunk/arch/mips/kernel/process.c b/trunk/arch/mips/kernel/process.c index bd05f5a927ea..8f4cf27c7157 100644 --- a/trunk/arch/mips/kernel/process.c +++ b/trunk/arch/mips/kernel/process.c @@ -25,9 +25,7 @@ #include #include #include -#include -#include #include #include #include @@ -462,15 +460,3 @@ unsigned long get_wchan(struct task_struct *task) out: return pc; } - -/* - * Don't forget that the stack pointer must be aligned on a 8 bytes - * boundary for 32-bits ABI and 16 bytes for 64-bits ABI. - */ -unsigned long arch_align_stack(unsigned long sp) -{ - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) - sp -= get_random_int() & ~PAGE_MASK; - - return sp & ALMASK; -} diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 853c282da22e..d860b640a140 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -92,9 +92,6 @@ config ARCH_MAY_HAVE_PC_FDC config PPC_OF def_bool y -config OF - def_bool y - config PPC_UDBG_16550 bool default n diff --git a/trunk/arch/powerpc/configs/cell_defconfig b/trunk/arch/powerpc/configs/cell_defconfig index d9ac24e8de16..74f83f4a4e5e 100644 --- a/trunk/arch/powerpc/configs/cell_defconfig +++ b/trunk/arch/powerpc/configs/cell_defconfig @@ -1455,8 +1455,7 @@ CONFIG_HAS_DMA=y # Instrumentation Support # CONFIG_PROFILING=y -CONFIG_OPROFILE=m -CONFIG_OPROFILE_CELL=y +CONFIG_OPROFILE=y # CONFIG_KPROBES is not set # diff --git a/trunk/arch/powerpc/kernel/crash.c b/trunk/arch/powerpc/kernel/crash.c index 37658ea417fa..d3f2080d2eee 100644 --- a/trunk/arch/powerpc/kernel/crash.c +++ b/trunk/arch/powerpc/kernel/crash.c @@ -219,72 +219,6 @@ void crash_kexec_secondary(struct pt_regs *regs) cpus_in_sr = CPU_MASK_NONE; } #endif -#ifdef CONFIG_SPU_BASE - -#include -#include - -struct crash_spu_info { - struct spu *spu; - u32 saved_spu_runcntl_RW; - u32 saved_spu_status_R; - u32 saved_spu_npc_RW; - u64 saved_mfc_sr1_RW; - u64 saved_mfc_dar; - u64 saved_mfc_dsisr; -}; - -#define CRASH_NUM_SPUS 16 /* Enough for current hardware */ -static struct crash_spu_info crash_spu_info[CRASH_NUM_SPUS]; - -static void crash_kexec_stop_spus(void) -{ - struct spu *spu; - int i; - u64 tmp; - - for (i = 0; i < CRASH_NUM_SPUS; i++) { - if (!crash_spu_info[i].spu) - continue; - - spu = crash_spu_info[i].spu; - - crash_spu_info[i].saved_spu_runcntl_RW = - in_be32(&spu->problem->spu_runcntl_RW); - crash_spu_info[i].saved_spu_status_R = - in_be32(&spu->problem->spu_status_R); - crash_spu_info[i].saved_spu_npc_RW = - in_be32(&spu->problem->spu_npc_RW); - - crash_spu_info[i].saved_mfc_dar = spu_mfc_dar_get(spu); - crash_spu_info[i].saved_mfc_dsisr = spu_mfc_dsisr_get(spu); - tmp = spu_mfc_sr1_get(spu); - crash_spu_info[i].saved_mfc_sr1_RW = tmp; - - tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK; - spu_mfc_sr1_set(spu, tmp); - - __delay(200); - } -} - -void crash_register_spus(struct list_head *list) -{ - struct spu *spu; - - list_for_each_entry(spu, list, full_list) { - if (WARN_ON(spu->number >= CRASH_NUM_SPUS)) - continue; - - crash_spu_info[spu->number].spu = spu; - } -} - -#else -static inline void crash_kexec_stop_spus(void) -{ -} -#endif /* CONFIG_SPU_BASE */ void default_machine_crash_shutdown(struct pt_regs *regs) { @@ -320,7 +254,6 @@ void default_machine_crash_shutdown(struct pt_regs *regs) crash_save_cpu(regs, crashing_cpu); crash_kexec_prepare_cpus(crashing_cpu); cpu_set(crashing_cpu, cpus_in_crash); - crash_kexec_stop_spus(); if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(1, 0); } diff --git a/trunk/arch/powerpc/kernel/of_device.c b/trunk/arch/powerpc/kernel/of_device.c index 89b911e83c04..a464d67248df 100644 --- a/trunk/arch/powerpc/kernel/of_device.c +++ b/trunk/arch/powerpc/kernel/of_device.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -9,6 +8,118 @@ #include #include +/** + * of_match_node - Tell if an device_node has a matching of_match structure + * @ids: array of of device match structures to search in + * @node: the of device structure to match against + * + * Low level utility function used by device matching. + */ +const struct of_device_id *of_match_node(const struct of_device_id *matches, + const struct device_node *node) +{ + while (matches->name[0] || matches->type[0] || matches->compatible[0]) { + int match = 1; + if (matches->name[0]) + match &= node->name + && !strcmp(matches->name, node->name); + if (matches->type[0]) + match &= node->type + && !strcmp(matches->type, node->type); + if (matches->compatible[0]) + match &= of_device_is_compatible(node, + matches->compatible); + if (match) + return matches; + matches++; + } + return NULL; +} + +/** + * of_match_device - Tell if an of_device structure has a matching + * of_match structure + * @ids: array of of device match structures to search in + * @dev: the of device structure to match against + * + * Used by a driver to check whether an of_device present in the + * system is in its list of supported devices. + */ +const struct of_device_id *of_match_device(const struct of_device_id *matches, + const struct of_device *dev) +{ + if (!dev->node) + return NULL; + return of_match_node(matches, dev->node); +} + +struct of_device *of_dev_get(struct of_device *dev) +{ + struct device *tmp; + + if (!dev) + return NULL; + tmp = get_device(&dev->dev); + if (tmp) + return to_of_device(tmp); + else + return NULL; +} + +void of_dev_put(struct of_device *dev) +{ + if (dev) + put_device(&dev->dev); +} + +static ssize_t dev_show_devspec(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct of_device *ofdev; + + ofdev = to_of_device(dev); + return sprintf(buf, "%s", ofdev->node->full_name); +} + +static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); + +/** + * of_release_dev - free an of device structure when all users of it are finished. + * @dev: device that's been disconnected + * + * Will be called only by the device core when all users of this of device are + * done. + */ +void of_release_dev(struct device *dev) +{ + struct of_device *ofdev; + + ofdev = to_of_device(dev); + of_node_put(ofdev->node); + kfree(ofdev); +} + +int of_device_register(struct of_device *ofdev) +{ + int rc; + + BUG_ON(ofdev->node == NULL); + + rc = device_register(&ofdev->dev); + if (rc) + return rc; + + return device_create_file(&ofdev->dev, &dev_attr_devspec); +} + +void of_device_unregister(struct of_device *ofdev) +{ + device_remove_file(&ofdev->dev, &dev_attr_devspec); + + device_unregister(&ofdev->dev); +} + + ssize_t of_device_get_modalias(struct of_device *ofdev, char *str, ssize_t len) { @@ -118,5 +229,14 @@ int of_device_uevent(struct device *dev, return 0; } + + +EXPORT_SYMBOL(of_match_node); +EXPORT_SYMBOL(of_match_device); +EXPORT_SYMBOL(of_device_register); +EXPORT_SYMBOL(of_device_unregister); +EXPORT_SYMBOL(of_dev_get); +EXPORT_SYMBOL(of_dev_put); +EXPORT_SYMBOL(of_release_dev); EXPORT_SYMBOL(of_device_uevent); EXPORT_SYMBOL(of_device_get_modalias); diff --git a/trunk/arch/powerpc/kernel/of_platform.c b/trunk/arch/powerpc/kernel/of_platform.c index f70e787d556f..8ded4e7dc87e 100644 --- a/trunk/arch/powerpc/kernel/of_platform.c +++ b/trunk/arch/powerpc/kernel/of_platform.c @@ -55,14 +55,94 @@ static struct of_device_id of_default_bus_ids[] = { static atomic_t bus_no_reg_magic; +/* + * + * OF platform device type definition & base infrastructure + * + */ + +static int of_platform_bus_match(struct device *dev, struct device_driver *drv) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * of_drv = to_of_platform_driver(drv); + const struct of_device_id * matches = of_drv->match_table; + + if (!matches) + return 0; + + return of_match_device(matches, of_dev) != NULL; +} + +static int of_platform_device_probe(struct device *dev) +{ + int error = -ENODEV; + struct of_platform_driver *drv; + struct of_device *of_dev; + const struct of_device_id *match; + + drv = to_of_platform_driver(dev->driver); + of_dev = to_of_device(dev); + + if (!drv->probe) + return error; + + of_dev_get(of_dev); + + match = of_match_device(drv->match_table, of_dev); + if (match) + error = drv->probe(of_dev, match); + if (error) + of_dev_put(of_dev); + + return error; +} + +static int of_platform_device_remove(struct device *dev) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + + if (dev->driver && drv->remove) + drv->remove(of_dev); + return 0; +} + +static int of_platform_device_suspend(struct device *dev, pm_message_t state) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + int error = 0; + + if (dev->driver && drv->suspend) + error = drv->suspend(of_dev, state); + return error; +} + +static int of_platform_device_resume(struct device * dev) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + int error = 0; + + if (dev->driver && drv->resume) + error = drv->resume(of_dev); + return error; +} + struct bus_type of_platform_bus_type = { + .name = "of_platform", + .match = of_platform_bus_match, .uevent = of_device_uevent, + .probe = of_platform_device_probe, + .remove = of_platform_device_remove, + .suspend = of_platform_device_suspend, + .resume = of_platform_device_resume, }; EXPORT_SYMBOL(of_platform_bus_type); static int __init of_bus_driver_init(void) { - return of_bus_type_init(&of_platform_bus_type, "of_platform"); + return bus_register(&of_platform_bus_type); } postcore_initcall(of_bus_driver_init); diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c index bdcd23d8d8b9..37ff99bd98b4 100644 --- a/trunk/arch/powerpc/kernel/prom.c +++ b/trunk/arch/powerpc/kernel/prom.c @@ -78,9 +78,12 @@ static struct boot_param_header *initial_boot_params __initdata; struct boot_param_header *initial_boot_params; #endif -extern struct device_node *allnodes; /* temporary while merging */ +static struct device_node *allnodes = NULL; -extern rwlock_t devtree_lock; /* temporary while merging */ +/* use when traversing tree through the allnext, child, sibling, + * or parent members of struct device_node. + */ +static DEFINE_RWLOCK(devtree_lock); /* export that to outside world */ struct device_node *of_chosen; @@ -1053,6 +1056,60 @@ void __init early_init_devtree(void *params) DBG(" <- early_init_devtree()\n"); } +int of_n_addr_cells(struct device_node* np) +{ + const int *ip; + do { + if (np->parent) + np = np->parent; + ip = of_get_property(np, "#address-cells", NULL); + if (ip != NULL) + return *ip; + } while (np->parent); + /* No #address-cells property for the root node, default to 1 */ + return 1; +} +EXPORT_SYMBOL(of_n_addr_cells); + +int of_n_size_cells(struct device_node* np) +{ + const int* ip; + do { + if (np->parent) + np = np->parent; + ip = of_get_property(np, "#size-cells", NULL); + if (ip != NULL) + return *ip; + } while (np->parent); + /* No #size-cells property for the root node, default to 1 */ + return 1; +} +EXPORT_SYMBOL(of_n_size_cells); + +/** Checks if the given "compat" string matches one of the strings in + * the device's "compatible" property + */ +int of_device_is_compatible(const struct device_node *device, + const char *compat) +{ + const char* cp; + int cplen, l; + + cp = of_get_property(device, "compatible", &cplen); + if (cp == NULL) + return 0; + while (cplen > 0) { + if (strncasecmp(cp, compat, strlen(compat)) == 0) + return 1; + l = strlen(cp) + 1; + cp += l; + cplen -= l; + } + + return 0; +} +EXPORT_SYMBOL(of_device_is_compatible); + /** * Indicates whether the root node has a given value in its @@ -1083,6 +1140,119 @@ EXPORT_SYMBOL(machine_is_compatible); * *******/ +/** + * of_find_node_by_name - Find a node by its "name" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @name: The name string to match against + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_name(struct device_node *from, + const char *name) +{ + struct device_node *np; + + read_lock(&devtree_lock); + np = from ? from->allnext : allnodes; + for (; np != NULL; np = np->allnext) + if (np->name != NULL && strcasecmp(np->name, name) == 0 + && of_node_get(np)) + break; + of_node_put(from); + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_find_node_by_name); + +/** + * of_find_node_by_type - Find a node by its "device_type" property + * @from: The node to start searching from, or NULL to start searching + * the entire device tree. The node you pass will not be + * searched, only the next one will; typically, you pass + * what the previous call returned. of_node_put() will be + * called on from for you. + * @type: The type string to match against + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_type(struct device_node *from, + const char *type) +{ + struct device_node *np; + + read_lock(&devtree_lock); + np = from ? from->allnext : allnodes; + for (; np != 0; np = np->allnext) + if (np->type != 0 && strcasecmp(np->type, type) == 0 + && of_node_get(np)) + break; + of_node_put(from); + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_find_node_by_type); + +/** + * of_find_compatible_node - Find a node based on type and one of the + * tokens in its "compatible" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @type: The type string to match "device_type" or NULL to ignore + * @compatible: The string to match to one of the tokens in the device + * "compatible" list. + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_compatible_node(struct device_node *from, + const char *type, const char *compatible) +{ + struct device_node *np; + + read_lock(&devtree_lock); + np = from ? from->allnext : allnodes; + for (; np != 0; np = np->allnext) { + if (type != NULL + && !(np->type != 0 && strcasecmp(np->type, type) == 0)) + continue; + if (of_device_is_compatible(np, compatible) && of_node_get(np)) + break; + } + of_node_put(from); + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_find_compatible_node); + +/** + * of_find_node_by_path - Find a node matching a full OF path + * @path: The full path to match + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_path(const char *path) +{ + struct device_node *np = allnodes; + + read_lock(&devtree_lock); + for (; np != 0; np = np->allnext) { + if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0 + && of_node_get(np)) + break; + } + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_find_node_by_path); + /** * of_find_node_by_phandle - Find a node given a phandle * @handle: phandle of the node to find @@ -1127,6 +1297,51 @@ struct device_node *of_find_all_nodes(struct device_node *prev) } EXPORT_SYMBOL(of_find_all_nodes); +/** + * of_get_parent - Get a node's parent if any + * @node: Node to get parent + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_get_parent(const struct device_node *node) +{ + struct device_node *np; + + if (!node) + return NULL; + + read_lock(&devtree_lock); + np = of_node_get(node->parent); + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_get_parent); + +/** + * of_get_next_child - Iterate a node childs + * @node: parent node + * @prev: previous child of the parent node, or NULL to get first + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_get_next_child(const struct device_node *node, + struct device_node *prev) +{ + struct device_node *next; + + read_lock(&devtree_lock); + next = prev ? prev->sibling : node->child; + for (; next != 0; next = next->sibling) + if (of_node_get(next)) + break; + of_node_put(prev); + read_unlock(&devtree_lock); + return next; +} +EXPORT_SYMBOL(of_get_next_child); + /** * of_node_get - Increment refcount of a node * @node: Node to inc refcount, NULL is supported to @@ -1328,6 +1543,37 @@ static int __init prom_reconfig_setup(void) __initcall(prom_reconfig_setup); #endif +struct property *of_find_property(const struct device_node *np, + const char *name, + int *lenp) +{ + struct property *pp; + + read_lock(&devtree_lock); + for (pp = np->properties; pp != 0; pp = pp->next) + if (strcmp(pp->name, name) == 0) { + if (lenp != 0) + *lenp = pp->length; + break; + } + read_unlock(&devtree_lock); + + return pp; +} +EXPORT_SYMBOL(of_find_property); + +/* + * Find a property with a given name for a given node + * and return the value. + */ +const void *of_get_property(const struct device_node *np, const char *name, + int *lenp) +{ + struct property *pp = of_find_property(np,name,lenp); + return pp ? pp->value : NULL; +} +EXPORT_SYMBOL(of_get_property); + /* * Add a property to a node */ diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index 727a6699f2f4..e5df167f7824 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -122,7 +122,6 @@ extern struct timezone sys_tz; static long timezone_offset; unsigned long ppc_proc_freq; -EXPORT_SYMBOL(ppc_proc_freq); unsigned long ppc_tb_freq; static u64 tb_last_jiffy __cacheline_aligned_in_smp; diff --git a/trunk/arch/powerpc/oprofile/Kconfig b/trunk/arch/powerpc/oprofile/Kconfig index 7089e79689b9..eb2dece76a54 100644 --- a/trunk/arch/powerpc/oprofile/Kconfig +++ b/trunk/arch/powerpc/oprofile/Kconfig @@ -15,10 +15,3 @@ config OPROFILE If unsure, say N. -config OPROFILE_CELL - bool "OProfile for Cell Broadband Engine" - depends on (SPU_FS = y && OPROFILE = m) || (SPU_FS = y && OPROFILE = y) || (SPU_FS = m && OPROFILE = m) - default y - help - Profiling of Cell BE SPUs requires special support enabled - by this option. diff --git a/trunk/arch/powerpc/oprofile/Makefile b/trunk/arch/powerpc/oprofile/Makefile index c5f64c3bd668..4b5f9528218c 100644 --- a/trunk/arch/powerpc/oprofile/Makefile +++ b/trunk/arch/powerpc/oprofile/Makefile @@ -11,9 +11,7 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ timer_int.o ) oprofile-y := $(DRIVER_OBJS) common.o backtrace.o -oprofile-$(CONFIG_OPROFILE_CELL) += op_model_cell.o \ - cell/spu_profiler.o cell/vma_map.o \ - cell/spu_task_sync.o +oprofile-$(CONFIG_PPC_CELL_NATIVE) += op_model_cell.o oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o op_model_pa6t.o oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o oprofile-$(CONFIG_6xx) += op_model_7450.o diff --git a/trunk/arch/powerpc/oprofile/cell/pr_util.h b/trunk/arch/powerpc/oprofile/cell/pr_util.h deleted file mode 100644 index e5704f00c8b4..000000000000 --- a/trunk/arch/powerpc/oprofile/cell/pr_util.h +++ /dev/null @@ -1,97 +0,0 @@ - /* - * Cell Broadband Engine OProfile Support - * - * (C) Copyright IBM Corporation 2006 - * - * Author: Maynard Johnson - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#ifndef PR_UTIL_H -#define PR_UTIL_H - -#include -#include -#include -#include - -#include "../../platforms/cell/cbe_regs.h" - -/* Defines used for sync_start */ -#define SKIP_GENERIC_SYNC 0 -#define SYNC_START_ERROR -1 -#define DO_GENERIC_SYNC 1 - -struct spu_overlay_info { /* map of sections within an SPU overlay */ - unsigned int vma; /* SPU virtual memory address from elf */ - unsigned int size; /* size of section from elf */ - unsigned int offset; /* offset of section into elf file */ - unsigned int buf; -}; - -struct vma_to_fileoffset_map { /* map of sections within an SPU program */ - struct vma_to_fileoffset_map *next; /* list pointer */ - unsigned int vma; /* SPU virtual memory address from elf */ - unsigned int size; /* size of section from elf */ - unsigned int offset; /* offset of section into elf file */ - unsigned int guard_ptr; - unsigned int guard_val; - /* - * The guard pointer is an entry in the _ovly_buf_table, - * computed using ovly.buf as the index into the table. Since - * ovly.buf values begin at '1' to reference the first (or 0th) - * entry in the _ovly_buf_table, the computation subtracts 1 - * from ovly.buf. - * The guard value is stored in the _ovly_buf_table entry and - * is an index (starting at 1) back to the _ovly_table entry - * that is pointing at this _ovly_buf_table entry. So, for - * example, for an overlay scenario with one overlay segment - * and two overlay sections: - * - Section 1 points to the first entry of the - * _ovly_buf_table, which contains a guard value - * of '1', referencing the first (index=0) entry of - * _ovly_table. - * - Section 2 points to the second entry of the - * _ovly_buf_table, which contains a guard value - * of '2', referencing the second (index=1) entry of - * _ovly_table. - */ - -}; - -/* The three functions below are for maintaining and accessing - * the vma-to-fileoffset map. - */ -struct vma_to_fileoffset_map *create_vma_map(const struct spu *spu, - u64 objectid); -unsigned int vma_map_lookup(struct vma_to_fileoffset_map *map, - unsigned int vma, const struct spu *aSpu, - int *grd_val); -void vma_map_free(struct vma_to_fileoffset_map *map); - -/* - * Entry point for SPU profiling. - * cycles_reset is the SPU_CYCLES count value specified by the user. - */ -int start_spu_profiling(unsigned int cycles_reset); - -void stop_spu_profiling(void); - - -/* add the necessary profiling hooks */ -int spu_sync_start(void); - -/* remove the hooks */ -int spu_sync_stop(void); - -/* Record SPU program counter samples to the oprofile event buffer. */ -void spu_sync_buffer(int spu_num, unsigned int *samples, - int num_samples); - -void set_spu_profiling_frequency(unsigned int freq_khz, unsigned int cycles_reset); - -#endif /* PR_UTIL_H */ diff --git a/trunk/arch/powerpc/oprofile/cell/spu_profiler.c b/trunk/arch/powerpc/oprofile/cell/spu_profiler.c deleted file mode 100644 index 380d7e217531..000000000000 --- a/trunk/arch/powerpc/oprofile/cell/spu_profiler.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Cell Broadband Engine OProfile Support - * - * (C) Copyright IBM Corporation 2006 - * - * Authors: Maynard Johnson - * Carl Love - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include "pr_util.h" - -#define TRACE_ARRAY_SIZE 1024 -#define SCALE_SHIFT 14 - -static u32 *samples; - -static int spu_prof_running; -static unsigned int profiling_interval; - -#define NUM_SPU_BITS_TRBUF 16 -#define SPUS_PER_TB_ENTRY 4 -#define SPUS_PER_NODE 8 - -#define SPU_PC_MASK 0xFFFF - -static DEFINE_SPINLOCK(sample_array_lock); -unsigned long sample_array_lock_flags; - -void set_spu_profiling_frequency(unsigned int freq_khz, unsigned int cycles_reset) -{ - unsigned long ns_per_cyc; - - if (!freq_khz) - freq_khz = ppc_proc_freq/1000; - - /* To calculate a timeout in nanoseconds, the basic - * formula is ns = cycles_reset * (NSEC_PER_SEC / cpu frequency). - * To avoid floating point math, we use the scale math - * technique as described in linux/jiffies.h. We use - * a scale factor of SCALE_SHIFT, which provides 4 decimal places - * of precision. This is close enough for the purpose at hand. - * - * The value of the timeout should be small enough that the hw - * trace buffer will not get more then about 1/3 full for the - * maximum user specified (the LFSR value) hw sampling frequency. - * This is to ensure the trace buffer will never fill even if the - * kernel thread scheduling varies under a heavy system load. - */ - - ns_per_cyc = (USEC_PER_SEC << SCALE_SHIFT)/freq_khz; - profiling_interval = (ns_per_cyc * cycles_reset) >> SCALE_SHIFT; - -} - -/* - * Extract SPU PC from trace buffer entry - */ -static void spu_pc_extract(int cpu, int entry) -{ - /* the trace buffer is 128 bits */ - u64 trace_buffer[2]; - u64 spu_mask; - int spu; - - spu_mask = SPU_PC_MASK; - - /* Each SPU PC is 16 bits; hence, four spus in each of - * the two 64-bit buffer entries that make up the - * 128-bit trace_buffer entry. Process two 64-bit values - * simultaneously. - * trace[0] SPU PC contents are: 0 1 2 3 - * trace[1] SPU PC contents are: 4 5 6 7 - */ - - cbe_read_trace_buffer(cpu, trace_buffer); - - for (spu = SPUS_PER_TB_ENTRY-1; spu >= 0; spu--) { - /* spu PC trace entry is upper 16 bits of the - * 18 bit SPU program counter - */ - samples[spu * TRACE_ARRAY_SIZE + entry] - = (spu_mask & trace_buffer[0]) << 2; - samples[(spu + SPUS_PER_TB_ENTRY) * TRACE_ARRAY_SIZE + entry] - = (spu_mask & trace_buffer[1]) << 2; - - trace_buffer[0] = trace_buffer[0] >> NUM_SPU_BITS_TRBUF; - trace_buffer[1] = trace_buffer[1] >> NUM_SPU_BITS_TRBUF; - } -} - -static int cell_spu_pc_collection(int cpu) -{ - u32 trace_addr; - int entry; - - /* process the collected SPU PC for the node */ - - entry = 0; - - trace_addr = cbe_read_pm(cpu, trace_address); - while (!(trace_addr & CBE_PM_TRACE_BUF_EMPTY)) { - /* there is data in the trace buffer to process */ - spu_pc_extract(cpu, entry); - - entry++; - - if (entry >= TRACE_ARRAY_SIZE) - /* spu_samples is full */ - break; - - trace_addr = cbe_read_pm(cpu, trace_address); - } - - return entry; -} - - -static enum hrtimer_restart profile_spus(struct hrtimer *timer) -{ - ktime_t kt; - int cpu, node, k, num_samples, spu_num; - - if (!spu_prof_running) - goto stop; - - for_each_online_cpu(cpu) { - if (cbe_get_hw_thread_id(cpu)) - continue; - - node = cbe_cpu_to_node(cpu); - - /* There should only be one kernel thread at a time processing - * the samples. In the very unlikely case that the processing - * is taking a very long time and multiple kernel threads are - * started to process the samples. Make sure only one kernel - * thread is working on the samples array at a time. The - * sample array must be loaded and then processed for a given - * cpu. The sample array is not per cpu. - */ - spin_lock_irqsave(&sample_array_lock, - sample_array_lock_flags); - num_samples = cell_spu_pc_collection(cpu); - - if (num_samples == 0) { - spin_unlock_irqrestore(&sample_array_lock, - sample_array_lock_flags); - continue; - } - - for (k = 0; k < SPUS_PER_NODE; k++) { - spu_num = k + (node * SPUS_PER_NODE); - spu_sync_buffer(spu_num, - samples + (k * TRACE_ARRAY_SIZE), - num_samples); - } - - spin_unlock_irqrestore(&sample_array_lock, - sample_array_lock_flags); - - } - smp_wmb(); /* insure spu event buffer updates are written */ - /* don't want events intermingled... */ - - kt = ktime_set(0, profiling_interval); - if (!spu_prof_running) - goto stop; - hrtimer_forward(timer, timer->base->get_time(), kt); - return HRTIMER_RESTART; - - stop: - printk(KERN_INFO "SPU_PROF: spu-prof timer ending\n"); - return HRTIMER_NORESTART; -} - -static struct hrtimer timer; -/* - * Entry point for SPU profiling. - * NOTE: SPU profiling is done system-wide, not per-CPU. - * - * cycles_reset is the count value specified by the user when - * setting up OProfile to count SPU_CYCLES. - */ -int start_spu_profiling(unsigned int cycles_reset) -{ - ktime_t kt; - - pr_debug("timer resolution: %lu\n", TICK_NSEC); - kt = ktime_set(0, profiling_interval); - hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - timer.expires = kt; - timer.function = profile_spus; - - /* Allocate arrays for collecting SPU PC samples */ - samples = kzalloc(SPUS_PER_NODE * - TRACE_ARRAY_SIZE * sizeof(u32), GFP_KERNEL); - - if (!samples) - return -ENOMEM; - - spu_prof_running = 1; - hrtimer_start(&timer, kt, HRTIMER_MODE_REL); - - return 0; -} - -void stop_spu_profiling(void) -{ - spu_prof_running = 0; - hrtimer_cancel(&timer); - kfree(samples); - pr_debug("SPU_PROF: stop_spu_profiling issued\n"); -} diff --git a/trunk/arch/powerpc/oprofile/cell/spu_task_sync.c b/trunk/arch/powerpc/oprofile/cell/spu_task_sync.c deleted file mode 100644 index 133665754a75..000000000000 --- a/trunk/arch/powerpc/oprofile/cell/spu_task_sync.c +++ /dev/null @@ -1,484 +0,0 @@ -/* - * Cell Broadband Engine OProfile Support - * - * (C) Copyright IBM Corporation 2006 - * - * Author: Maynard Johnson - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -/* The purpose of this file is to handle SPU event task switching - * and to record SPU context information into the OProfile - * event buffer. - * - * Additionally, the spu_sync_buffer function is provided as a helper - * for recoding actual SPU program counter samples to the event buffer. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "pr_util.h" - -#define RELEASE_ALL 9999 - -static DEFINE_SPINLOCK(buffer_lock); -static DEFINE_SPINLOCK(cache_lock); -static int num_spu_nodes; -int spu_prof_num_nodes; -int last_guard_val[MAX_NUMNODES * 8]; - -/* Container for caching information about an active SPU task. */ -struct cached_info { - struct vma_to_fileoffset_map *map; - struct spu *the_spu; /* needed to access pointer to local_store */ - struct kref cache_ref; -}; - -static struct cached_info *spu_info[MAX_NUMNODES * 8]; - -static void destroy_cached_info(struct kref *kref) -{ - struct cached_info *info; - - info = container_of(kref, struct cached_info, cache_ref); - vma_map_free(info->map); - kfree(info); - module_put(THIS_MODULE); -} - -/* Return the cached_info for the passed SPU number. - * ATTENTION: Callers are responsible for obtaining the - * cache_lock if needed prior to invoking this function. - */ -static struct cached_info *get_cached_info(struct spu *the_spu, int spu_num) -{ - struct kref *ref; - struct cached_info *ret_info; - - if (spu_num >= num_spu_nodes) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: Invalid index %d into spu info cache\n", - __FUNCTION__, __LINE__, spu_num); - ret_info = NULL; - goto out; - } - if (!spu_info[spu_num] && the_spu) { - ref = spu_get_profile_private_kref(the_spu->ctx); - if (ref) { - spu_info[spu_num] = container_of(ref, struct cached_info, cache_ref); - kref_get(&spu_info[spu_num]->cache_ref); - } - } - - ret_info = spu_info[spu_num]; - out: - return ret_info; -} - - -/* Looks for cached info for the passed spu. If not found, the - * cached info is created for the passed spu. - * Returns 0 for success; otherwise, -1 for error. - */ -static int -prepare_cached_spu_info(struct spu *spu, unsigned long objectId) -{ - unsigned long flags; - struct vma_to_fileoffset_map *new_map; - int retval = 0; - struct cached_info *info; - - /* We won't bother getting cache_lock here since - * don't do anything with the cached_info that's returned. - */ - info = get_cached_info(spu, spu->number); - - if (info) { - pr_debug("Found cached SPU info.\n"); - goto out; - } - - /* Create cached_info and set spu_info[spu->number] to point to it. - * spu->number is a system-wide value, not a per-node value. - */ - info = kzalloc(sizeof(struct cached_info), GFP_KERNEL); - if (!info) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: create vma_map failed\n", - __FUNCTION__, __LINE__); - retval = -ENOMEM; - goto err_alloc; - } - new_map = create_vma_map(spu, objectId); - if (!new_map) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: create vma_map failed\n", - __FUNCTION__, __LINE__); - retval = -ENOMEM; - goto err_alloc; - } - - pr_debug("Created vma_map\n"); - info->map = new_map; - info->the_spu = spu; - kref_init(&info->cache_ref); - spin_lock_irqsave(&cache_lock, flags); - spu_info[spu->number] = info; - /* Increment count before passing off ref to SPUFS. */ - kref_get(&info->cache_ref); - - /* We increment the module refcount here since SPUFS is - * responsible for the final destruction of the cached_info, - * and it must be able to access the destroy_cached_info() - * function defined in the OProfile module. We decrement - * the module refcount in destroy_cached_info. - */ - try_module_get(THIS_MODULE); - spu_set_profile_private_kref(spu->ctx, &info->cache_ref, - destroy_cached_info); - spin_unlock_irqrestore(&cache_lock, flags); - goto out; - -err_alloc: - kfree(info); -out: - return retval; -} - -/* - * NOTE: The caller is responsible for locking the - * cache_lock prior to calling this function. - */ -static int release_cached_info(int spu_index) -{ - int index, end; - - if (spu_index == RELEASE_ALL) { - end = num_spu_nodes; - index = 0; - } else { - if (spu_index >= num_spu_nodes) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: " - "Invalid index %d into spu info cache\n", - __FUNCTION__, __LINE__, spu_index); - goto out; - } - end = spu_index + 1; - index = spu_index; - } - for (; index < end; index++) { - if (spu_info[index]) { - kref_put(&spu_info[index]->cache_ref, - destroy_cached_info); - spu_info[index] = NULL; - } - } - -out: - return 0; -} - -/* The source code for fast_get_dcookie was "borrowed" - * from drivers/oprofile/buffer_sync.c. - */ - -/* Optimisation. We can manage without taking the dcookie sem - * because we cannot reach this code without at least one - * dcookie user still being registered (namely, the reader - * of the event buffer). - */ -static inline unsigned long fast_get_dcookie(struct dentry *dentry, - struct vfsmount *vfsmnt) -{ - unsigned long cookie; - - if (dentry->d_cookie) - return (unsigned long)dentry; - get_dcookie(dentry, vfsmnt, &cookie); - return cookie; -} - -/* Look up the dcookie for the task's first VM_EXECUTABLE mapping, - * which corresponds loosely to "application name". Also, determine - * the offset for the SPU ELF object. If computed offset is - * non-zero, it implies an embedded SPU object; otherwise, it's a - * separate SPU binary, in which case we retrieve it's dcookie. - * For the embedded case, we must determine if SPU ELF is embedded - * in the executable application or another file (i.e., shared lib). - * If embedded in a shared lib, we must get the dcookie and return - * that to the caller. - */ -static unsigned long -get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp, - unsigned long *spu_bin_dcookie, - unsigned long spu_ref) -{ - unsigned long app_cookie = 0; - unsigned int my_offset = 0; - struct file *app = NULL; - struct vm_area_struct *vma; - struct mm_struct *mm = spu->mm; - - if (!mm) - goto out; - - down_read(&mm->mmap_sem); - - for (vma = mm->mmap; vma; vma = vma->vm_next) { - if (!vma->vm_file) - continue; - if (!(vma->vm_flags & VM_EXECUTABLE)) - continue; - app_cookie = fast_get_dcookie(vma->vm_file->f_dentry, - vma->vm_file->f_vfsmnt); - pr_debug("got dcookie for %s\n", - vma->vm_file->f_dentry->d_name.name); - app = vma->vm_file; - break; - } - - for (vma = mm->mmap; vma; vma = vma->vm_next) { - if (vma->vm_start > spu_ref || vma->vm_end <= spu_ref) - continue; - my_offset = spu_ref - vma->vm_start; - if (!vma->vm_file) - goto fail_no_image_cookie; - - pr_debug("Found spu ELF at %X(object-id:%lx) for file %s\n", - my_offset, spu_ref, - vma->vm_file->f_dentry->d_name.name); - *offsetp = my_offset; - break; - } - - *spu_bin_dcookie = fast_get_dcookie(vma->vm_file->f_dentry, - vma->vm_file->f_vfsmnt); - pr_debug("got dcookie for %s\n", vma->vm_file->f_dentry->d_name.name); - - up_read(&mm->mmap_sem); - -out: - return app_cookie; - -fail_no_image_cookie: - up_read(&mm->mmap_sem); - - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: Cannot find dcookie for SPU binary\n", - __FUNCTION__, __LINE__); - goto out; -} - - - -/* This function finds or creates cached context information for the - * passed SPU and records SPU context information into the OProfile - * event buffer. - */ -static int process_context_switch(struct spu *spu, unsigned long objectId) -{ - unsigned long flags; - int retval; - unsigned int offset = 0; - unsigned long spu_cookie = 0, app_dcookie; - - retval = prepare_cached_spu_info(spu, objectId); - if (retval) - goto out; - - /* Get dcookie first because a mutex_lock is taken in that - * code path, so interrupts must not be disabled. - */ - app_dcookie = get_exec_dcookie_and_offset(spu, &offset, &spu_cookie, objectId); - if (!app_dcookie || !spu_cookie) { - retval = -ENOENT; - goto out; - } - - /* Record context info in event buffer */ - spin_lock_irqsave(&buffer_lock, flags); - add_event_entry(ESCAPE_CODE); - add_event_entry(SPU_CTX_SWITCH_CODE); - add_event_entry(spu->number); - add_event_entry(spu->pid); - add_event_entry(spu->tgid); - add_event_entry(app_dcookie); - add_event_entry(spu_cookie); - add_event_entry(offset); - spin_unlock_irqrestore(&buffer_lock, flags); - smp_wmb(); /* insure spu event buffer updates are written */ - /* don't want entries intermingled... */ -out: - return retval; -} - -/* - * This function is invoked on either a bind_context or unbind_context. - * If called for an unbind_context, the val arg is 0; otherwise, - * it is the object-id value for the spu context. - * The data arg is of type 'struct spu *'. - */ -static int spu_active_notify(struct notifier_block *self, unsigned long val, - void *data) -{ - int retval; - unsigned long flags; - struct spu *the_spu = data; - - pr_debug("SPU event notification arrived\n"); - if (!val) { - spin_lock_irqsave(&cache_lock, flags); - retval = release_cached_info(the_spu->number); - spin_unlock_irqrestore(&cache_lock, flags); - } else { - retval = process_context_switch(the_spu, val); - } - return retval; -} - -static struct notifier_block spu_active = { - .notifier_call = spu_active_notify, -}; - -static int number_of_online_nodes(void) -{ - u32 cpu; u32 tmp; - int nodes = 0; - for_each_online_cpu(cpu) { - tmp = cbe_cpu_to_node(cpu) + 1; - if (tmp > nodes) - nodes++; - } - return nodes; -} - -/* The main purpose of this function is to synchronize - * OProfile with SPUFS by registering to be notified of - * SPU task switches. - * - * NOTE: When profiling SPUs, we must ensure that only - * spu_sync_start is invoked and not the generic sync_start - * in drivers/oprofile/oprof.c. A return value of - * SKIP_GENERIC_SYNC or SYNC_START_ERROR will - * accomplish this. - */ -int spu_sync_start(void) -{ - int k; - int ret = SKIP_GENERIC_SYNC; - int register_ret; - unsigned long flags = 0; - - spu_prof_num_nodes = number_of_online_nodes(); - num_spu_nodes = spu_prof_num_nodes * 8; - - spin_lock_irqsave(&buffer_lock, flags); - add_event_entry(ESCAPE_CODE); - add_event_entry(SPU_PROFILING_CODE); - add_event_entry(num_spu_nodes); - spin_unlock_irqrestore(&buffer_lock, flags); - - /* Register for SPU events */ - register_ret = spu_switch_event_register(&spu_active); - if (register_ret) { - ret = SYNC_START_ERROR; - goto out; - } - - for (k = 0; k < (MAX_NUMNODES * 8); k++) - last_guard_val[k] = 0; - pr_debug("spu_sync_start -- running.\n"); -out: - return ret; -} - -/* Record SPU program counter samples to the oprofile event buffer. */ -void spu_sync_buffer(int spu_num, unsigned int *samples, - int num_samples) -{ - unsigned long long file_offset; - unsigned long flags; - int i; - struct vma_to_fileoffset_map *map; - struct spu *the_spu; - unsigned long long spu_num_ll = spu_num; - unsigned long long spu_num_shifted = spu_num_ll << 32; - struct cached_info *c_info; - - /* We need to obtain the cache_lock here because it's - * possible that after getting the cached_info, the SPU job - * corresponding to this cached_info may end, thus resulting - * in the destruction of the cached_info. - */ - spin_lock_irqsave(&cache_lock, flags); - c_info = get_cached_info(NULL, spu_num); - if (!c_info) { - /* This legitimately happens when the SPU task ends before all - * samples are recorded. - * No big deal -- so we just drop a few samples. - */ - pr_debug("SPU_PROF: No cached SPU contex " - "for SPU #%d. Dropping samples.\n", spu_num); - goto out; - } - - map = c_info->map; - the_spu = c_info->the_spu; - spin_lock(&buffer_lock); - for (i = 0; i < num_samples; i++) { - unsigned int sample = *(samples+i); - int grd_val = 0; - file_offset = 0; - if (sample == 0) - continue; - file_offset = vma_map_lookup( map, sample, the_spu, &grd_val); - - /* If overlays are used by this SPU application, the guard - * value is non-zero, indicating which overlay section is in - * use. We need to discard samples taken during the time - * period which an overlay occurs (i.e., guard value changes). - */ - if (grd_val && grd_val != last_guard_val[spu_num]) { - last_guard_val[spu_num] = grd_val; - /* Drop the rest of the samples. */ - break; - } - - add_event_entry(file_offset | spu_num_shifted); - } - spin_unlock(&buffer_lock); -out: - spin_unlock_irqrestore(&cache_lock, flags); -} - - -int spu_sync_stop(void) -{ - unsigned long flags = 0; - int ret = spu_switch_event_unregister(&spu_active); - if (ret) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: spu_switch_event_unregister returned %d\n", - __FUNCTION__, __LINE__, ret); - goto out; - } - - spin_lock_irqsave(&cache_lock, flags); - ret = release_cached_info(RELEASE_ALL); - spin_unlock_irqrestore(&cache_lock, flags); -out: - pr_debug("spu_sync_stop -- done.\n"); - return ret; -} - - diff --git a/trunk/arch/powerpc/oprofile/cell/vma_map.c b/trunk/arch/powerpc/oprofile/cell/vma_map.c deleted file mode 100644 index 76ec1d16aef7..000000000000 --- a/trunk/arch/powerpc/oprofile/cell/vma_map.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Cell Broadband Engine OProfile Support - * - * (C) Copyright IBM Corporation 2006 - * - * Author: Maynard Johnson - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -/* The code in this source file is responsible for generating - * vma-to-fileOffset maps for both overlay and non-overlay SPU - * applications. - */ - -#include -#include -#include -#include -#include "pr_util.h" - - -void vma_map_free(struct vma_to_fileoffset_map *map) -{ - while (map) { - struct vma_to_fileoffset_map *next = map->next; - kfree(map); - map = next; - } -} - -unsigned int -vma_map_lookup(struct vma_to_fileoffset_map *map, unsigned int vma, - const struct spu *aSpu, int *grd_val) -{ - /* - * Default the offset to the physical address + a flag value. - * Addresses of dynamically generated code can't be found in the vma - * map. For those addresses the flagged value will be sent on to - * the user space tools so they can be reported rather than just - * thrown away. - */ - u32 offset = 0x10000000 + vma; - u32 ovly_grd; - - for (; map; map = map->next) { - if (vma < map->vma || vma >= map->vma + map->size) - continue; - - if (map->guard_ptr) { - ovly_grd = *(u32 *)(aSpu->local_store + map->guard_ptr); - if (ovly_grd != map->guard_val) - continue; - *grd_val = ovly_grd; - } - offset = vma - map->vma + map->offset; - break; - } - - return offset; -} - -static struct vma_to_fileoffset_map * -vma_map_add(struct vma_to_fileoffset_map *map, unsigned int vma, - unsigned int size, unsigned int offset, unsigned int guard_ptr, - unsigned int guard_val) -{ - struct vma_to_fileoffset_map *new = - kzalloc(sizeof(struct vma_to_fileoffset_map), GFP_KERNEL); - if (!new) { - printk(KERN_ERR "SPU_PROF: %s, line %d: malloc failed\n", - __FUNCTION__, __LINE__); - vma_map_free(map); - return NULL; - } - - new->next = map; - new->vma = vma; - new->size = size; - new->offset = offset; - new->guard_ptr = guard_ptr; - new->guard_val = guard_val; - - return new; -} - - -/* Parse SPE ELF header and generate a list of vma_maps. - * A pointer to the first vma_map in the generated list - * of vma_maps is returned. */ -struct vma_to_fileoffset_map *create_vma_map(const struct spu *aSpu, - unsigned long spu_elf_start) -{ - static const unsigned char expected[EI_PAD] = { - [EI_MAG0] = ELFMAG0, - [EI_MAG1] = ELFMAG1, - [EI_MAG2] = ELFMAG2, - [EI_MAG3] = ELFMAG3, - [EI_CLASS] = ELFCLASS32, - [EI_DATA] = ELFDATA2MSB, - [EI_VERSION] = EV_CURRENT, - [EI_OSABI] = ELFOSABI_NONE - }; - - int grd_val; - struct vma_to_fileoffset_map *map = NULL; - struct spu_overlay_info ovly; - unsigned int overlay_tbl_offset = -1; - unsigned long phdr_start, shdr_start; - Elf32_Ehdr ehdr; - Elf32_Phdr phdr; - Elf32_Shdr shdr, shdr_str; - Elf32_Sym sym; - int i, j; - char name[32]; - - unsigned int ovly_table_sym = 0; - unsigned int ovly_buf_table_sym = 0; - unsigned int ovly_table_end_sym = 0; - unsigned int ovly_buf_table_end_sym = 0; - unsigned long ovly_table; - unsigned int n_ovlys; - - /* Get and validate ELF header. */ - - if (copy_from_user(&ehdr, (void *) spu_elf_start, sizeof (ehdr))) - goto fail; - - if (memcmp(ehdr.e_ident, expected, EI_PAD) != 0) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: Unexpected e_ident parsing SPU ELF\n", - __FUNCTION__, __LINE__); - goto fail; - } - if (ehdr.e_machine != EM_SPU) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: Unexpected e_machine parsing SPU ELF\n", - __FUNCTION__, __LINE__); - goto fail; - } - if (ehdr.e_type != ET_EXEC) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: Unexpected e_type parsing SPU ELF\n", - __FUNCTION__, __LINE__); - goto fail; - } - phdr_start = spu_elf_start + ehdr.e_phoff; - shdr_start = spu_elf_start + ehdr.e_shoff; - - /* Traverse program headers. */ - for (i = 0; i < ehdr.e_phnum; i++) { - if (copy_from_user(&phdr, - (void *) (phdr_start + i * sizeof(phdr)), - sizeof(phdr))) - goto fail; - - if (phdr.p_type != PT_LOAD) - continue; - if (phdr.p_flags & (1 << 27)) - continue; - - map = vma_map_add(map, phdr.p_vaddr, phdr.p_memsz, - phdr.p_offset, 0, 0); - if (!map) - goto fail; - } - - pr_debug("SPU_PROF: Created non-overlay maps\n"); - /* Traverse section table and search for overlay-related symbols. */ - for (i = 0; i < ehdr.e_shnum; i++) { - if (copy_from_user(&shdr, - (void *) (shdr_start + i * sizeof(shdr)), - sizeof(shdr))) - goto fail; - - if (shdr.sh_type != SHT_SYMTAB) - continue; - if (shdr.sh_entsize != sizeof (sym)) - continue; - - if (copy_from_user(&shdr_str, - (void *) (shdr_start + shdr.sh_link * - sizeof(shdr)), - sizeof(shdr))) - goto fail; - - if (shdr_str.sh_type != SHT_STRTAB) - goto fail;; - - for (j = 0; j < shdr.sh_size / sizeof (sym); j++) { - if (copy_from_user(&sym, (void *) (spu_elf_start + - shdr.sh_offset + j * - sizeof (sym)), - sizeof (sym))) - goto fail; - - if (copy_from_user(name, (void *) - (spu_elf_start + shdr_str.sh_offset + - sym.st_name), - 20)) - goto fail; - - if (memcmp(name, "_ovly_table", 12) == 0) - ovly_table_sym = sym.st_value; - if (memcmp(name, "_ovly_buf_table", 16) == 0) - ovly_buf_table_sym = sym.st_value; - if (memcmp(name, "_ovly_table_end", 16) == 0) - ovly_table_end_sym = sym.st_value; - if (memcmp(name, "_ovly_buf_table_end", 20) == 0) - ovly_buf_table_end_sym = sym.st_value; - } - } - - /* If we don't have overlays, we're done. */ - if (ovly_table_sym == 0 || ovly_buf_table_sym == 0 - || ovly_table_end_sym == 0 || ovly_buf_table_end_sym == 0) { - pr_debug("SPU_PROF: No overlay table found\n"); - goto out; - } else { - pr_debug("SPU_PROF: Overlay table found\n"); - } - - /* The _ovly_table symbol represents a table with one entry - * per overlay section. The _ovly_buf_table symbol represents - * a table with one entry per overlay region. - * The struct spu_overlay_info gives the structure of the _ovly_table - * entries. The structure of _ovly_table_buf is simply one - * u32 word per entry. - */ - overlay_tbl_offset = vma_map_lookup(map, ovly_table_sym, - aSpu, &grd_val); - if (overlay_tbl_offset < 0) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: Error finding SPU overlay table\n", - __FUNCTION__, __LINE__); - goto fail; - } - ovly_table = spu_elf_start + overlay_tbl_offset; - - n_ovlys = (ovly_table_end_sym - - ovly_table_sym) / sizeof (ovly); - - /* Traverse overlay table. */ - for (i = 0; i < n_ovlys; i++) { - if (copy_from_user(&ovly, (void *) - (ovly_table + i * sizeof (ovly)), - sizeof (ovly))) - goto fail; - - /* The ovly.vma/size/offset arguments are analogous to the same - * arguments used above for non-overlay maps. The final two - * args are referred to as the guard pointer and the guard - * value. - * The guard pointer is an entry in the _ovly_buf_table, - * computed using ovly.buf as the index into the table. Since - * ovly.buf values begin at '1' to reference the first (or 0th) - * entry in the _ovly_buf_table, the computation subtracts 1 - * from ovly.buf. - * The guard value is stored in the _ovly_buf_table entry and - * is an index (starting at 1) back to the _ovly_table entry - * that is pointing at this _ovly_buf_table entry. So, for - * example, for an overlay scenario with one overlay segment - * and two overlay sections: - * - Section 1 points to the first entry of the - * _ovly_buf_table, which contains a guard value - * of '1', referencing the first (index=0) entry of - * _ovly_table. - * - Section 2 points to the second entry of the - * _ovly_buf_table, which contains a guard value - * of '2', referencing the second (index=1) entry of - * _ovly_table. - */ - map = vma_map_add(map, ovly.vma, ovly.size, ovly.offset, - ovly_buf_table_sym + (ovly.buf-1) * 4, i+1); - if (!map) - goto fail; - } - goto out; - - fail: - map = NULL; - out: - return map; -} diff --git a/trunk/arch/powerpc/oprofile/common.c b/trunk/arch/powerpc/oprofile/common.c index a28cce1d6c24..1a7ef7e246d2 100644 --- a/trunk/arch/powerpc/oprofile/common.c +++ b/trunk/arch/powerpc/oprofile/common.c @@ -29,8 +29,6 @@ static struct op_powerpc_model *model; static struct op_counter_config ctr[OP_MAX_COUNTER]; static struct op_system_config sys; -static int op_per_cpu_rc; - static void op_handle_interrupt(struct pt_regs *regs) { model->handle_interrupt(regs, ctr); @@ -38,41 +36,25 @@ static void op_handle_interrupt(struct pt_regs *regs) static void op_powerpc_cpu_setup(void *dummy) { - int ret; - - ret = model->cpu_setup(ctr); - - if (ret != 0) - op_per_cpu_rc = ret; + model->cpu_setup(ctr); } static int op_powerpc_setup(void) { int err; - op_per_cpu_rc = 0; - /* Grab the hardware */ err = reserve_pmc_hardware(op_handle_interrupt); if (err) return err; /* Pre-compute the values to stuff in the hardware registers. */ - op_per_cpu_rc = model->reg_setup(ctr, &sys, model->num_counters); + model->reg_setup(ctr, &sys, model->num_counters); - if (op_per_cpu_rc) - goto out; - - /* Configure the registers on all cpus. If an error occurs on one - * of the cpus, op_per_cpu_rc will be set to the error */ + /* Configure the registers on all cpus. */ on_each_cpu(op_powerpc_cpu_setup, NULL, 0, 1); -out: if (op_per_cpu_rc) { - /* error on setup release the performance counter hardware */ - release_pmc_hardware(); - } - - return op_per_cpu_rc; + return 0; } static void op_powerpc_shutdown(void) @@ -82,29 +64,16 @@ static void op_powerpc_shutdown(void) static void op_powerpc_cpu_start(void *dummy) { - /* If any of the cpus have return an error, set the - * global flag to the error so it can be returned - * to the generic OProfile caller. - */ - int ret; - - ret = model->start(ctr); - if (ret != 0) - op_per_cpu_rc = ret; + model->start(ctr); } static int op_powerpc_start(void) { - op_per_cpu_rc = 0; - if (model->global_start) - return model->global_start(ctr); - if (model->start) { + model->global_start(ctr); + if (model->start) on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1); - return op_per_cpu_rc; - } - return -EIO; /* No start function is defined for this - power architecture */ + return 0; } static inline void op_powerpc_cpu_stop(void *dummy) @@ -178,13 +147,11 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) switch (cur_cpu_spec->oprofile_type) { #ifdef CONFIG_PPC64 -#ifdef CONFIG_OPROFILE_CELL +#ifdef CONFIG_PPC_CELL_NATIVE case PPC_OPROFILE_CELL: if (firmware_has_feature(FW_FEATURE_LPAR)) return -ENODEV; model = &op_model_cell; - ops->sync_start = model->sync_start; - ops->sync_stop = model->sync_stop; break; #endif case PPC_OPROFILE_RS64: diff --git a/trunk/arch/powerpc/oprofile/op_model_7450.c b/trunk/arch/powerpc/oprofile/op_model_7450.c index cc599eb8768b..5d1bbaf35ccb 100644 --- a/trunk/arch/powerpc/oprofile/op_model_7450.c +++ b/trunk/arch/powerpc/oprofile/op_model_7450.c @@ -81,7 +81,7 @@ static void pmc_stop_ctrs(void) /* Configures the counters on this CPU based on the global * settings */ -static int fsl7450_cpu_setup(struct op_counter_config *ctr) +static void fsl7450_cpu_setup(struct op_counter_config *ctr) { /* freeze all counters */ pmc_stop_ctrs(); @@ -89,14 +89,12 @@ static int fsl7450_cpu_setup(struct op_counter_config *ctr) mtspr(SPRN_MMCR0, mmcr0_val); mtspr(SPRN_MMCR1, mmcr1_val); mtspr(SPRN_MMCR2, mmcr2_val); - - return 0; } #define NUM_CTRS 6 /* Configures the global settings for the countes on all CPUs. */ -static int fsl7450_reg_setup(struct op_counter_config *ctr, +static void fsl7450_reg_setup(struct op_counter_config *ctr, struct op_system_config *sys, int num_ctrs) { @@ -128,12 +126,10 @@ static int fsl7450_reg_setup(struct op_counter_config *ctr, | mmcr1_event6(ctr[5].event); mmcr2_val = 0; - - return 0; } /* Sets the counters on this CPU to the chosen values, and starts them */ -static int fsl7450_start(struct op_counter_config *ctr) +static void fsl7450_start(struct op_counter_config *ctr) { int i; @@ -152,8 +148,6 @@ static int fsl7450_start(struct op_counter_config *ctr) pmc_start_ctrs(); oprofile_running = 1; - - return 0; } /* Stop the counters on this CPU */ @@ -199,7 +193,7 @@ static void fsl7450_handle_interrupt(struct pt_regs *regs, /* The freeze bit was set by the interrupt. */ /* Clear the freeze bit, and reenable the interrupt. * The counters won't actually start until the rfi clears - * the PM/M bit */ + * the PMM bit */ pmc_start_ctrs(); } diff --git a/trunk/arch/powerpc/oprofile/op_model_cell.c b/trunk/arch/powerpc/oprofile/op_model_cell.c index d928b54f3a0f..c29293befba9 100644 --- a/trunk/arch/powerpc/oprofile/op_model_cell.c +++ b/trunk/arch/powerpc/oprofile/op_model_cell.c @@ -5,8 +5,8 @@ * * Author: David Erb (djerb@us.ibm.com) * Modifications: - * Carl Love - * Maynard Johnson + * Carl Love + * Maynard Johnson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -38,25 +38,12 @@ #include "../platforms/cell/interrupt.h" #include "../platforms/cell/cbe_regs.h" -#include "cell/pr_util.h" - -static void cell_global_stop_spu(void); - -/* - * spu_cycle_reset is the number of cycles between samples. - * This variable is used for SPU profiling and should ONLY be set - * at the beginning of cell_reg_setup; otherwise, it's read-only. - */ -static unsigned int spu_cycle_reset; - -#define NUM_SPUS_PER_NODE 8 -#define SPU_CYCLES_EVENT_NUM 2 /* event number for SPU_CYCLES */ #define PPU_CYCLES_EVENT_NUM 1 /* event number for CYCLES */ -#define PPU_CYCLES_GRP_NUM 1 /* special group number for identifying - * PPU_CYCLES event - */ -#define CBE_COUNT_ALL_CYCLES 0x42800000 /* PPU cycle event specifier */ +#define PPU_CYCLES_GRP_NUM 1 /* special group number for identifying + * PPU_CYCLES event + */ +#define CBE_COUNT_ALL_CYCLES 0x42800000 /* PPU cycle event specifier */ #define NUM_THREADS 2 /* number of physical threads in * physical processor @@ -64,7 +51,6 @@ static unsigned int spu_cycle_reset; #define NUM_TRACE_BUS_WORDS 4 #define NUM_INPUT_BUS_WORDS 2 -#define MAX_SPU_COUNT 0xFFFFFF /* maximum 24 bit LFSR value */ struct pmc_cntrl_data { unsigned long vcntr; @@ -76,10 +62,11 @@ struct pmc_cntrl_data { /* * ibm,cbe-perftools rtas parameters */ + struct pm_signal { u16 cpu; /* Processor to modify */ - u16 sub_unit; /* hw subunit this applies to (if applicable)*/ - short int signal_group; /* Signal Group to Enable/Disable */ + u16 sub_unit; /* hw subunit this applies to (if applicable) */ + short int signal_group; /* Signal Group to Enable/Disable */ u8 bus_word; /* Enable/Disable on this Trace/Trigger/Event * Bus Word(s) (bitmask) */ @@ -125,42 +112,21 @@ static DEFINE_PER_CPU(unsigned long[NR_PHYS_CTRS], pmc_values); static struct pmc_cntrl_data pmc_cntrl[NUM_THREADS][NR_PHYS_CTRS]; -/* - * The CELL profiling code makes rtas calls to setup the debug bus to - * route the performance signals. Additionally, SPU profiling requires - * a second rtas call to setup the hardware to capture the SPU PCs. - * The EIO error value is returned if the token lookups or the rtas - * call fail. The EIO error number is the best choice of the existing - * error numbers. The probability of rtas related error is very low. But - * by returning EIO and printing additional information to dmsg the user - * will know that OProfile did not start and dmesg will tell them why. - * OProfile does not support returning errors on Stop. Not a huge issue - * since failure to reset the debug bus or stop the SPU PC collection is - * not a fatel issue. Chances are if the Stop failed, Start doesn't work - * either. - */ - -/* - * Interpetation of hdw_thread: +/* Interpetation of hdw_thread: * 0 - even virtual cpus 0, 2, 4,... * 1 - odd virtual cpus 1, 3, 5, ... - * - * FIXME: this is strictly wrong, we need to clean this up in a number - * of places. It works for now. -arnd */ static u32 hdw_thread; static u32 virt_cntr_inter_mask; static struct timer_list timer_virt_cntr; -/* - * pm_signal needs to be global since it is initialized in +/* pm_signal needs to be global since it is initialized in * cell_reg_setup at the time when the necessary information * is available. */ static struct pm_signal pm_signal[NR_PHYS_CTRS]; -static int pm_rtas_token; /* token for debug bus setup call */ -static int spu_rtas_token; /* token for SPU cycle profiling */ +static int pm_rtas_token; static u32 reset_value[NR_PHYS_CTRS]; static int num_counters; @@ -181,8 +147,8 @@ rtas_ibm_cbe_perftools(int subfunc, int passthru, { u64 paddr = __pa(address); - return rtas_call(pm_rtas_token, 5, 1, NULL, subfunc, - passthru, paddr >> 32, paddr & 0xffffffff, length); + return rtas_call(pm_rtas_token, 5, 1, NULL, subfunc, passthru, + paddr >> 32, paddr & 0xffffffff, length); } static void pm_rtas_reset_signals(u32 node) @@ -190,13 +156,12 @@ static void pm_rtas_reset_signals(u32 node) int ret; struct pm_signal pm_signal_local; - /* - * The debug bus is being set to the passthru disable state. - * However, the FW still expects atleast one legal signal routing - * entry or it will return an error on the arguments. If we don't - * supply a valid entry, we must ignore all return values. Ignoring - * all return values means we might miss an error we should be - * concerned about. + /* The debug bus is being set to the passthru disable state. + * However, the FW still expects atleast one legal signal routing + * entry or it will return an error on the arguments. If we don't + * supply a valid entry, we must ignore all return values. Ignoring + * all return values means we might miss an error we should be + * concerned about. */ /* fw expects physical cpu #. */ @@ -210,24 +175,18 @@ static void pm_rtas_reset_signals(u32 node) &pm_signal_local, sizeof(struct pm_signal)); - if (unlikely(ret)) - /* - * Not a fatal error. For Oprofile stop, the oprofile - * functions do not support returning an error for - * failure to stop OProfile. - */ + if (ret) printk(KERN_WARNING "%s: rtas returned: %d\n", __FUNCTION__, ret); } -static int pm_rtas_activate_signals(u32 node, u32 count) +static void pm_rtas_activate_signals(u32 node, u32 count) { int ret; int i, j; struct pm_signal pm_signal_local[NR_PHYS_CTRS]; - /* - * There is no debug setup required for the cycles event. + /* There is no debug setup required for the cycles event. * Note that only events in the same group can be used. * Otherwise, there will be conflicts in correctly routing * the signals on the debug bus. It is the responsiblity @@ -254,14 +213,10 @@ static int pm_rtas_activate_signals(u32 node, u32 count) pm_signal_local, i * sizeof(struct pm_signal)); - if (unlikely(ret)) { + if (ret) printk(KERN_WARNING "%s: rtas returned: %d\n", __FUNCTION__, ret); - return -EIO; - } } - - return 0; } /* @@ -305,12 +260,11 @@ static void set_pm_event(u32 ctr, int event, u32 unit_mask) pm_regs.pm07_cntrl[ctr] |= PM07_CTR_POLARITY(polarity); pm_regs.pm07_cntrl[ctr] |= PM07_CTR_INPUT_CONTROL(input_control); - /* - * Some of the islands signal selection is based on 64 bit words. + /* Some of the islands signal selection is based on 64 bit words. * The debug bus words are 32 bits, the input words to the performance * counters are defined as 32 bits. Need to convert the 64 bit island * specification to the appropriate 32 input bit and bus word for the - * performance counter event selection. See the CELL Performance + * performance counter event selection. See the CELL Performance * monitoring signals manual and the Perf cntr hardware descriptions * for the details. */ @@ -344,7 +298,6 @@ static void set_pm_event(u32 ctr, int event, u32 unit_mask) input_bus[j] = i; pm_regs.group_control |= (i << (31 - i)); - break; } } @@ -356,8 +309,7 @@ static void set_pm_event(u32 ctr, int event, u32 unit_mask) static void write_pm_cntrl(int cpu) { - /* - * Oprofile will use 32 bit counters, set bits 7:10 to 0 + /* Oprofile will use 32 bit counters, set bits 7:10 to 0 * pmregs.pm_cntrl is a global */ @@ -374,8 +326,7 @@ static void write_pm_cntrl(int cpu) if (pm_regs.pm_cntrl.freeze == 1) val |= CBE_PM_FREEZE_ALL_CTRS; - /* - * Routine set_count_mode must be called previously to set + /* Routine set_count_mode must be called previously to set * the count mode based on the user selection of user and kernel. */ val |= CBE_PM_COUNT_MODE_SET(pm_regs.pm_cntrl.count_mode); @@ -385,8 +336,7 @@ static void write_pm_cntrl(int cpu) static inline void set_count_mode(u32 kernel, u32 user) { - /* - * The user must specify user and kernel if they want them. If + /* The user must specify user and kernel if they want them. If * neither is specified, OProfile will count in hypervisor mode. * pm_regs.pm_cntrl is a global */ @@ -414,7 +364,7 @@ static inline void enable_ctr(u32 cpu, u32 ctr, u32 * pm07_cntrl) /* * Oprofile is expected to collect data on all CPUs simultaneously. - * However, there is one set of performance counters per node. There are + * However, there is one set of performance counters per node. There are * two hardware threads or virtual CPUs on each node. Hence, OProfile must * multiplex in time the performance counter collection on the two virtual * CPUs. The multiplexing of the performance counters is done by this @@ -427,19 +377,19 @@ static inline void enable_ctr(u32 cpu, u32 ctr, u32 * pm07_cntrl) * pair of per-cpu arrays is used for storing the previous and next * pmc values for a given node. * NOTE: We use the per-cpu variable to improve cache performance. - * - * This routine will alternate loading the virtual counters for - * virtual CPUs */ static void cell_virtual_cntr(unsigned long data) { + /* This routine will alternate loading the virtual counters for + * virtual CPUs + */ int i, prev_hdw_thread, next_hdw_thread; u32 cpu; unsigned long flags; - /* - * Make sure that the interrupt_hander and the virt counter are - * not both playing with the counters on the same node. + /* Make sure that the interrupt_hander and + * the virt counter are not both playing with + * the counters on the same node. */ spin_lock_irqsave(&virt_cntr_lock, flags); @@ -450,25 +400,22 @@ static void cell_virtual_cntr(unsigned long data) hdw_thread = 1 ^ hdw_thread; next_hdw_thread = hdw_thread; - /* - * There are some per thread events. Must do the + for (i = 0; i < num_counters; i++) + /* There are some per thread events. Must do the * set event, for the thread that is being started */ - for (i = 0; i < num_counters; i++) set_pm_event(i, pmc_cntrl[next_hdw_thread][i].evnts, pmc_cntrl[next_hdw_thread][i].masks); - /* - * The following is done only once per each node, but + /* The following is done only once per each node, but * we need cpu #, not node #, to pass to the cbe_xxx functions. */ for_each_online_cpu(cpu) { if (cbe_get_hw_thread_id(cpu)) continue; - /* - * stop counters, save counter values, restore counts + /* stop counters, save counter values, restore counts * for previous thread */ cbe_disable_pm(cpu); @@ -481,7 +428,7 @@ static void cell_virtual_cntr(unsigned long data) == 0xFFFFFFFF) /* If the cntr value is 0xffffffff, we must * reset that to 0xfffffff0 when the current - * thread is restarted. This will generate a + * thread is restarted. This will generate a * new interrupt and make sure that we never * restore the counters to the max value. If * the counters were restored to the max value, @@ -497,15 +444,13 @@ static void cell_virtual_cntr(unsigned long data) next_hdw_thread)[i]); } - /* - * Switch to the other thread. Change the interrupt + /* Switch to the other thread. Change the interrupt * and control regs to be scheduled on the CPU * corresponding to the thread to execute. */ for (i = 0; i < num_counters; i++) { if (pmc_cntrl[next_hdw_thread][i].enabled) { - /* - * There are some per thread events. + /* There are some per thread events. * Must do the set event, enable_cntr * for each cpu. */ @@ -537,42 +482,17 @@ static void start_virt_cntrs(void) } /* This function is called once for all cpus combined */ -static int cell_reg_setup(struct op_counter_config *ctr, - struct op_system_config *sys, int num_ctrs) +static void +cell_reg_setup(struct op_counter_config *ctr, + struct op_system_config *sys, int num_ctrs) { int i, j, cpu; - spu_cycle_reset = 0; - - if (ctr[0].event == SPU_CYCLES_EVENT_NUM) { - spu_cycle_reset = ctr[0].count; - - /* - * Each node will need to make the rtas call to start - * and stop SPU profiling. Get the token once and store it. - */ - spu_rtas_token = rtas_token("ibm,cbe-spu-perftools"); - - if (unlikely(spu_rtas_token == RTAS_UNKNOWN_SERVICE)) { - printk(KERN_ERR - "%s: rtas token ibm,cbe-spu-perftools unknown\n", - __FUNCTION__); - return -EIO; - } - } pm_rtas_token = rtas_token("ibm,cbe-perftools"); - - /* - * For all events excetp PPU CYCLEs, each node will need to make - * the rtas cbe-perftools call to setup and reset the debug bus. - * Make the token lookup call once and store it in the global - * variable pm_rtas_token. - */ - if (unlikely(pm_rtas_token == RTAS_UNKNOWN_SERVICE)) { - printk(KERN_ERR - "%s: rtas token ibm,cbe-perftools unknown\n", + if (pm_rtas_token == RTAS_UNKNOWN_SERVICE) { + printk(KERN_WARNING "%s: RTAS_UNKNOWN_SERVICE\n", __FUNCTION__); - return -EIO; + goto out; } num_counters = num_ctrs; @@ -600,8 +520,7 @@ static int cell_reg_setup(struct op_counter_config *ctr, per_cpu(pmc_values, j)[i] = 0; } - /* - * Setup the thread 1 events, map the thread 0 event to the + /* Setup the thread 1 events, map the thread 0 event to the * equivalent thread 1 event. */ for (i = 0; i < num_ctrs; ++i) { @@ -625,10 +544,9 @@ static int cell_reg_setup(struct op_counter_config *ctr, for (i = 0; i < NUM_INPUT_BUS_WORDS; i++) input_bus[i] = 0xff; - /* - * Our counters count up, and "count" refers to + /* Our counters count up, and "count" refers to * how much before the next interrupt, and we interrupt - * on overflow. So we calculate the starting value + * on overflow. So we calculate the starting value * which will give us "count" until overflow. * Then we set the events on the enabled counters. */ @@ -651,27 +569,28 @@ static int cell_reg_setup(struct op_counter_config *ctr, for (i = 0; i < num_counters; ++i) { per_cpu(pmc_values, cpu)[i] = reset_value[i]; } - - return 0; +out: + ; } - - /* This function is called once for each cpu */ -static int cell_cpu_setup(struct op_counter_config *cntr) +static void cell_cpu_setup(struct op_counter_config *cntr) { u32 cpu = smp_processor_id(); u32 num_enabled = 0; int i; - if (spu_cycle_reset) - return 0; - /* There is one performance monitor per processor chip (i.e. node), * so we only need to perform this function once per node. */ if (cbe_get_hw_thread_id(cpu)) - return 0; + goto out; + + if (pm_rtas_token == RTAS_UNKNOWN_SERVICE) { + printk(KERN_WARNING "%s: RTAS_UNKNOWN_SERVICE\n", + __FUNCTION__); + goto out; + } /* Stop all counters */ cbe_disable_pm(cpu); @@ -690,286 +609,16 @@ static int cell_cpu_setup(struct op_counter_config *cntr) } } - /* - * The pm_rtas_activate_signals will return -EIO if the FW - * call failed. - */ - return pm_rtas_activate_signals(cbe_cpu_to_node(cpu), num_enabled); -} - -#define ENTRIES 303 -#define MAXLFSR 0xFFFFFF - -/* precomputed table of 24 bit LFSR values */ -static int initial_lfsr[] = { - 8221349, 12579195, 5379618, 10097839, 7512963, 7519310, 3955098, 10753424, - 15507573, 7458917, 285419, 2641121, 9780088, 3915503, 6668768, 1548716, - 4885000, 8774424, 9650099, 2044357, 2304411, 9326253, 10332526, 4421547, - 3440748, 10179459, 13332843, 10375561, 1313462, 8375100, 5198480, 6071392, - 9341783, 1526887, 3985002, 1439429, 13923762, 7010104, 11969769, 4547026, - 2040072, 4025602, 3437678, 7939992, 11444177, 4496094, 9803157, 10745556, - 3671780, 4257846, 5662259, 13196905, 3237343, 12077182, 16222879, 7587769, - 14706824, 2184640, 12591135, 10420257, 7406075, 3648978, 11042541, 15906893, - 11914928, 4732944, 10695697, 12928164, 11980531, 4430912, 11939291, 2917017, - 6119256, 4172004, 9373765, 8410071, 14788383, 5047459, 5474428, 1737756, - 15967514, 13351758, 6691285, 8034329, 2856544, 14394753, 11310160, 12149558, - 7487528, 7542781, 15668898, 12525138, 12790975, 3707933, 9106617, 1965401, - 16219109, 12801644, 2443203, 4909502, 8762329, 3120803, 6360315, 9309720, - 15164599, 10844842, 4456529, 6667610, 14924259, 884312, 6234963, 3326042, - 15973422, 13919464, 5272099, 6414643, 3909029, 2764324, 5237926, 4774955, - 10445906, 4955302, 5203726, 10798229, 11443419, 2303395, 333836, 9646934, - 3464726, 4159182, 568492, 995747, 10318756, 13299332, 4836017, 8237783, - 3878992, 2581665, 11394667, 5672745, 14412947, 3159169, 9094251, 16467278, - 8671392, 15230076, 4843545, 7009238, 15504095, 1494895, 9627886, 14485051, - 8304291, 252817, 12421642, 16085736, 4774072, 2456177, 4160695, 15409741, - 4902868, 5793091, 13162925, 16039714, 782255, 11347835, 14884586, 366972, - 16308990, 11913488, 13390465, 2958444, 10340278, 1177858, 1319431, 10426302, - 2868597, 126119, 5784857, 5245324, 10903900, 16436004, 3389013, 1742384, - 14674502, 10279218, 8536112, 10364279, 6877778, 14051163, 1025130, 6072469, - 1988305, 8354440, 8216060, 16342977, 13112639, 3976679, 5913576, 8816697, - 6879995, 14043764, 3339515, 9364420, 15808858, 12261651, 2141560, 5636398, - 10345425, 10414756, 781725, 6155650, 4746914, 5078683, 7469001, 6799140, - 10156444, 9667150, 10116470, 4133858, 2121972, 1124204, 1003577, 1611214, - 14304602, 16221850, 13878465, 13577744, 3629235, 8772583, 10881308, 2410386, - 7300044, 5378855, 9301235, 12755149, 4977682, 8083074, 10327581, 6395087, - 9155434, 15501696, 7514362, 14520507, 15808945, 3244584, 4741962, 9658130, - 14336147, 8654727, 7969093, 15759799, 14029445, 5038459, 9894848, 8659300, - 13699287, 8834306, 10712885, 14753895, 10410465, 3373251, 309501, 9561475, - 5526688, 14647426, 14209836, 5339224, 207299, 14069911, 8722990, 2290950, - 3258216, 12505185, 6007317, 9218111, 14661019, 10537428, 11731949, 9027003, - 6641507, 9490160, 200241, 9720425, 16277895, 10816638, 1554761, 10431375, - 7467528, 6790302, 3429078, 14633753, 14428997, 11463204, 3576212, 2003426, - 6123687, 820520, 9992513, 15784513, 5778891, 6428165, 8388607 -}; - -/* - * The hardware uses an LFSR counting sequence to determine when to capture - * the SPU PCs. An LFSR sequence is like a puesdo random number sequence - * where each number occurs once in the sequence but the sequence is not in - * numerical order. The SPU PC capture is done when the LFSR sequence reaches - * the last value in the sequence. Hence the user specified value N - * corresponds to the LFSR number that is N from the end of the sequence. - * - * To avoid the time to compute the LFSR, a lookup table is used. The 24 bit - * LFSR sequence is broken into four ranges. The spacing of the precomputed - * values is adjusted in each range so the error between the user specifed - * number (N) of events between samples and the actual number of events based - * on the precomputed value will be les then about 6.2%. Note, if the user - * specifies N < 2^16, the LFSR value that is 2^16 from the end will be used. - * This is to prevent the loss of samples because the trace buffer is full. - * - * User specified N Step between Index in - * precomputed values precomputed - * table - * 0 to 2^16-1 ---- 0 - * 2^16 to 2^16+2^19-1 2^12 1 to 128 - * 2^16+2^19 to 2^16+2^19+2^22-1 2^15 129 to 256 - * 2^16+2^19+2^22 to 2^24-1 2^18 257 to 302 - * - * - * For example, the LFSR values in the second range are computed for 2^16, - * 2^16+2^12, ... , 2^19-2^16, 2^19 and stored in the table at indicies - * 1, 2,..., 127, 128. - * - * The 24 bit LFSR value for the nth number in the sequence can be - * calculated using the following code: - * - * #define size 24 - * int calculate_lfsr(int n) - * { - * int i; - * unsigned int newlfsr0; - * unsigned int lfsr = 0xFFFFFF; - * unsigned int howmany = n; - * - * for (i = 2; i < howmany + 2; i++) { - * newlfsr0 = (((lfsr >> (size - 1 - 0)) & 1) ^ - * ((lfsr >> (size - 1 - 1)) & 1) ^ - * (((lfsr >> (size - 1 - 6)) & 1) ^ - * ((lfsr >> (size - 1 - 23)) & 1))); - * - * lfsr >>= 1; - * lfsr = lfsr | (newlfsr0 << (size - 1)); - * } - * return lfsr; - * } - */ - -#define V2_16 (0x1 << 16) -#define V2_19 (0x1 << 19) -#define V2_22 (0x1 << 22) - -static int calculate_lfsr(int n) -{ - /* - * The ranges and steps are in powers of 2 so the calculations - * can be done using shifts rather then divide. - */ - int index; - - if ((n >> 16) == 0) - index = 0; - else if (((n - V2_16) >> 19) == 0) - index = ((n - V2_16) >> 12) + 1; - else if (((n - V2_16 - V2_19) >> 22) == 0) - index = ((n - V2_16 - V2_19) >> 15 ) + 1 + 128; - else if (((n - V2_16 - V2_19 - V2_22) >> 24) == 0) - index = ((n - V2_16 - V2_19 - V2_22) >> 18 ) + 1 + 256; - else - index = ENTRIES-1; - - /* make sure index is valid */ - if ((index > ENTRIES) || (index < 0)) - index = ENTRIES-1; - - return initial_lfsr[index]; -} - -static int pm_rtas_activate_spu_profiling(u32 node) -{ - int ret, i; - struct pm_signal pm_signal_local[NR_PHYS_CTRS]; - - /* - * Set up the rtas call to configure the debug bus to - * route the SPU PCs. Setup the pm_signal for each SPU - */ - for (i = 0; i < NUM_SPUS_PER_NODE; i++) { - pm_signal_local[i].cpu = node; - pm_signal_local[i].signal_group = 41; - /* spu i on word (i/2) */ - pm_signal_local[i].bus_word = 1 << i / 2; - /* spu i */ - pm_signal_local[i].sub_unit = i; - pm_signal_local[i].bit = 63; - } - - ret = rtas_ibm_cbe_perftools(SUBFUNC_ACTIVATE, - PASSTHRU_ENABLE, pm_signal_local, - (NUM_SPUS_PER_NODE - * sizeof(struct pm_signal))); - - if (unlikely(ret)) { - printk(KERN_WARNING "%s: rtas returned: %d\n", - __FUNCTION__, ret); - return -EIO; - } - - return 0; -} - -#ifdef CONFIG_CPU_FREQ -static int -oprof_cpufreq_notify(struct notifier_block *nb, unsigned long val, void *data) -{ - int ret = 0; - struct cpufreq_freqs *frq = data; - if ((val == CPUFREQ_PRECHANGE && frq->old < frq->new) || - (val == CPUFREQ_POSTCHANGE && frq->old > frq->new) || - (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) - set_spu_profiling_frequency(frq->new, spu_cycle_reset); - return ret; -} - -static struct notifier_block cpu_freq_notifier_block = { - .notifier_call = oprof_cpufreq_notify -}; -#endif - -static int cell_global_start_spu(struct op_counter_config *ctr) -{ - int subfunc; - unsigned int lfsr_value; - int cpu; - int ret; - int rtas_error; - unsigned int cpu_khzfreq = 0; - - /* The SPU profiling uses time-based profiling based on - * cpu frequency, so if configured with the CPU_FREQ - * option, we should detect frequency changes and react - * accordingly. - */ -#ifdef CONFIG_CPU_FREQ - ret = cpufreq_register_notifier(&cpu_freq_notifier_block, - CPUFREQ_TRANSITION_NOTIFIER); - if (ret < 0) - /* this is not a fatal error */ - printk(KERN_ERR "CPU freq change registration failed: %d\n", - ret); - - else - cpu_khzfreq = cpufreq_quick_get(smp_processor_id()); -#endif - - set_spu_profiling_frequency(cpu_khzfreq, spu_cycle_reset); - - for_each_online_cpu(cpu) { - if (cbe_get_hw_thread_id(cpu)) - continue; - - /* - * Setup SPU cycle-based profiling. - * Set perf_mon_control bit 0 to a zero before - * enabling spu collection hardware. - */ - cbe_write_pm(cpu, pm_control, 0); - - if (spu_cycle_reset > MAX_SPU_COUNT) - /* use largest possible value */ - lfsr_value = calculate_lfsr(MAX_SPU_COUNT-1); - else - lfsr_value = calculate_lfsr(spu_cycle_reset); - - /* must use a non zero value. Zero disables data collection. */ - if (lfsr_value == 0) - lfsr_value = calculate_lfsr(1); - - lfsr_value = lfsr_value << 8; /* shift lfsr to correct - * register location - */ - - /* debug bus setup */ - ret = pm_rtas_activate_spu_profiling(cbe_cpu_to_node(cpu)); - - if (unlikely(ret)) { - rtas_error = ret; - goto out; - } - - - subfunc = 2; /* 2 - activate SPU tracing, 3 - deactivate */ - - /* start profiling */ - ret = rtas_call(spu_rtas_token, 3, 1, NULL, subfunc, - cbe_cpu_to_node(cpu), lfsr_value); - - if (unlikely(ret != 0)) { - printk(KERN_ERR - "%s: rtas call ibm,cbe-spu-perftools failed, return = %d\n", - __FUNCTION__, ret); - rtas_error = -EIO; - goto out; - } - } - - rtas_error = start_spu_profiling(spu_cycle_reset); - if (rtas_error) - goto out_stop; - - oprofile_running = 1; - return 0; - -out_stop: - cell_global_stop_spu(); /* clean up the PMU/debug bus */ + pm_rtas_activate_signals(cbe_cpu_to_node(cpu), num_enabled); out: - return rtas_error; + ; } -static int cell_global_start_ppu(struct op_counter_config *ctr) +static void cell_global_start(struct op_counter_config *ctr) { - u32 cpu, i; + u32 cpu; u32 interrupt_mask = 0; + u32 i; /* This routine gets called once for the system. * There is one performance monitor per node, so we @@ -1002,79 +651,19 @@ static int cell_global_start_ppu(struct op_counter_config *ctr) oprofile_running = 1; smp_wmb(); - /* - * NOTE: start_virt_cntrs will result in cell_virtual_cntr() being - * executed which manipulates the PMU. We start the "virtual counter" + /* NOTE: start_virt_cntrs will result in cell_virtual_cntr() being + * executed which manipulates the PMU. We start the "virtual counter" * here so that we do not need to synchronize access to the PMU in * the above for-loop. */ start_virt_cntrs(); - - return 0; } -static int cell_global_start(struct op_counter_config *ctr) -{ - if (spu_cycle_reset) - return cell_global_start_spu(ctr); - else - return cell_global_start_ppu(ctr); -} - -/* - * Note the generic OProfile stop calls do not support returning - * an error on stop. Hence, will not return an error if the FW - * calls fail on stop. Failure to reset the debug bus is not an issue. - * Failure to disable the SPU profiling is not an issue. The FW calls - * to enable the performance counters and debug bus will work even if - * the hardware was not cleanly reset. - */ -static void cell_global_stop_spu(void) -{ - int subfunc, rtn_value; - unsigned int lfsr_value; - int cpu; - - oprofile_running = 0; - -#ifdef CONFIG_CPU_FREQ - cpufreq_unregister_notifier(&cpu_freq_notifier_block, - CPUFREQ_TRANSITION_NOTIFIER); -#endif - - for_each_online_cpu(cpu) { - if (cbe_get_hw_thread_id(cpu)) - continue; - - subfunc = 3; /* - * 2 - activate SPU tracing, - * 3 - deactivate - */ - lfsr_value = 0x8f100000; - - rtn_value = rtas_call(spu_rtas_token, 3, 1, NULL, - subfunc, cbe_cpu_to_node(cpu), - lfsr_value); - - if (unlikely(rtn_value != 0)) { - printk(KERN_ERR - "%s: rtas call ibm,cbe-spu-perftools failed, return = %d\n", - __FUNCTION__, rtn_value); - } - - /* Deactivate the signals */ - pm_rtas_reset_signals(cbe_cpu_to_node(cpu)); - } - - stop_spu_profiling(); -} - -static void cell_global_stop_ppu(void) +static void cell_global_stop(void) { int cpu; - /* - * This routine will be called once for the system. + /* This routine will be called once for the system. * There is one performance monitor per node, so we * only need to perform this function once per node. */ @@ -1098,16 +687,8 @@ static void cell_global_stop_ppu(void) } } -static void cell_global_stop(void) -{ - if (spu_cycle_reset) - cell_global_stop_spu(); - else - cell_global_stop_ppu(); -} - -static void cell_handle_interrupt(struct pt_regs *regs, - struct op_counter_config *ctr) +static void +cell_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr) { u32 cpu; u64 pc; @@ -1118,15 +699,13 @@ static void cell_handle_interrupt(struct pt_regs *regs, cpu = smp_processor_id(); - /* - * Need to make sure the interrupt handler and the virt counter + /* Need to make sure the interrupt handler and the virt counter * routine are not running at the same time. See the * cell_virtual_cntr() routine for additional comments. */ spin_lock_irqsave(&virt_cntr_lock, flags); - /* - * Need to disable and reenable the performance counters + /* Need to disable and reenable the performance counters * to get the desired behavior from the hardware. This * is hardware specific. */ @@ -1135,8 +714,7 @@ static void cell_handle_interrupt(struct pt_regs *regs, interrupt_mask = cbe_get_and_clear_pm_interrupts(cpu); - /* - * If the interrupt mask has been cleared, then the virt cntr + /* If the interrupt mask has been cleared, then the virt cntr * has cleared the interrupt. When the thread that generated * the interrupt is restored, the data count will be restored to * 0xffffff0 to cause the interrupt to be regenerated. @@ -1154,20 +732,18 @@ static void cell_handle_interrupt(struct pt_regs *regs, } } - /* - * The counters were frozen by the interrupt. + /* The counters were frozen by the interrupt. * Reenable the interrupt and restart the counters. * If there was a race between the interrupt handler and - * the virtual counter routine. The virutal counter + * the virtual counter routine. The virutal counter * routine may have cleared the interrupts. Hence must * use the virt_cntr_inter_mask to re-enable the interrupts. */ cbe_enable_pm_interrupts(cpu, hdw_thread, virt_cntr_inter_mask); - /* - * The writes to the various performance counters only writes - * to a latch. The new values (interrupt setting bits, reset + /* The writes to the various performance counters only writes + * to a latch. The new values (interrupt setting bits, reset * counter value etc.) are not copied to the actual registers * until the performance monitor is enabled. In order to get * this to work as desired, the permormance monitor needs to @@ -1179,33 +755,10 @@ static void cell_handle_interrupt(struct pt_regs *regs, spin_unlock_irqrestore(&virt_cntr_lock, flags); } -/* - * This function is called from the generic OProfile - * driver. When profiling PPUs, we need to do the - * generic sync start; otherwise, do spu_sync_start. - */ -static int cell_sync_start(void) -{ - if (spu_cycle_reset) - return spu_sync_start(); - else - return DO_GENERIC_SYNC; -} - -static int cell_sync_stop(void) -{ - if (spu_cycle_reset) - return spu_sync_stop(); - else - return 1; -} - struct op_powerpc_model op_model_cell = { .reg_setup = cell_reg_setup, .cpu_setup = cell_cpu_setup, .global_start = cell_global_start, .global_stop = cell_global_stop, - .sync_start = cell_sync_start, - .sync_stop = cell_sync_stop, .handle_interrupt = cell_handle_interrupt, }; diff --git a/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c b/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c index 183a28bb1812..2267eb8c661b 100644 --- a/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c +++ b/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c @@ -244,7 +244,7 @@ static void dump_pmcs(void) mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3)); } -static int fsl_booke_cpu_setup(struct op_counter_config *ctr) +static void fsl_booke_cpu_setup(struct op_counter_config *ctr) { int i; @@ -258,11 +258,9 @@ static int fsl_booke_cpu_setup(struct op_counter_config *ctr) set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel); } - - return 0; } -static int fsl_booke_reg_setup(struct op_counter_config *ctr, +static void fsl_booke_reg_setup(struct op_counter_config *ctr, struct op_system_config *sys, int num_ctrs) { @@ -278,10 +276,9 @@ static int fsl_booke_reg_setup(struct op_counter_config *ctr, for (i = 0; i < num_counters; ++i) reset_value[i] = 0x80000000UL - ctr[i].count; - return 0; } -static int fsl_booke_start(struct op_counter_config *ctr) +static void fsl_booke_start(struct op_counter_config *ctr) { int i; @@ -311,8 +308,6 @@ static int fsl_booke_start(struct op_counter_config *ctr) pr_debug("start on cpu %d, pmgc0 %x\n", smp_processor_id(), mfpmr(PMRN_PMGC0)); - - return 0; } static void fsl_booke_stop(void) diff --git a/trunk/arch/powerpc/oprofile/op_model_pa6t.c b/trunk/arch/powerpc/oprofile/op_model_pa6t.c index c40de461fd4e..e8a56b0adadc 100644 --- a/trunk/arch/powerpc/oprofile/op_model_pa6t.c +++ b/trunk/arch/powerpc/oprofile/op_model_pa6t.c @@ -89,7 +89,7 @@ static inline void ctr_write(unsigned int i, u64 val) /* precompute the values to stuff in the hardware registers */ -static int pa6t_reg_setup(struct op_counter_config *ctr, +static void pa6t_reg_setup(struct op_counter_config *ctr, struct op_system_config *sys, int num_ctrs) { @@ -135,12 +135,10 @@ static int pa6t_reg_setup(struct op_counter_config *ctr, pr_debug("reset_value for pmc%u inited to 0x%lx\n", pmc, reset_value[pmc]); } - - return 0; } /* configure registers on this cpu */ -static int pa6t_cpu_setup(struct op_counter_config *ctr) +static void pa6t_cpu_setup(struct op_counter_config *ctr) { u64 mmcr0 = mmcr0_val; u64 mmcr1 = mmcr1_val; @@ -156,11 +154,9 @@ static int pa6t_cpu_setup(struct op_counter_config *ctr) mfspr(SPRN_PA6T_MMCR0)); pr_debug("setup on cpu %d, mmcr1 %016lx\n", smp_processor_id(), mfspr(SPRN_PA6T_MMCR1)); - - return 0; } -static int pa6t_start(struct op_counter_config *ctr) +static void pa6t_start(struct op_counter_config *ctr) { int i; @@ -178,8 +174,6 @@ static int pa6t_start(struct op_counter_config *ctr) oprofile_running = 1; pr_debug("start on cpu %d, mmcr0 %lx\n", smp_processor_id(), mmcr0); - - return 0; } static void pa6t_stop(void) diff --git a/trunk/arch/powerpc/oprofile/op_model_power4.c b/trunk/arch/powerpc/oprofile/op_model_power4.c index cddc250a6a5c..a7c206b665af 100644 --- a/trunk/arch/powerpc/oprofile/op_model_power4.c +++ b/trunk/arch/powerpc/oprofile/op_model_power4.c @@ -32,7 +32,7 @@ static u32 mmcr0_val; static u64 mmcr1_val; static u64 mmcra_val; -static int power4_reg_setup(struct op_counter_config *ctr, +static void power4_reg_setup(struct op_counter_config *ctr, struct op_system_config *sys, int num_ctrs) { @@ -60,8 +60,6 @@ static int power4_reg_setup(struct op_counter_config *ctr, mmcr0_val &= ~MMCR0_PROBLEM_DISABLE; else mmcr0_val |= MMCR0_PROBLEM_DISABLE; - - return 0; } extern void ppc64_enable_pmcs(void); @@ -86,7 +84,7 @@ static inline int mmcra_must_set_sample(void) return 0; } -static int power4_cpu_setup(struct op_counter_config *ctr) +static void power4_cpu_setup(struct op_counter_config *ctr) { unsigned int mmcr0 = mmcr0_val; unsigned long mmcra = mmcra_val; @@ -113,11 +111,9 @@ static int power4_cpu_setup(struct op_counter_config *ctr) mfspr(SPRN_MMCR1)); dbg("setup on cpu %d, mmcra %lx\n", smp_processor_id(), mfspr(SPRN_MMCRA)); - - return 0; } -static int power4_start(struct op_counter_config *ctr) +static void power4_start(struct op_counter_config *ctr) { int i; unsigned int mmcr0; @@ -152,7 +148,6 @@ static int power4_start(struct op_counter_config *ctr) oprofile_running = 1; dbg("start on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0); - return 0; } static void power4_stop(void) diff --git a/trunk/arch/powerpc/oprofile/op_model_rs64.c b/trunk/arch/powerpc/oprofile/op_model_rs64.c index a20afe45d936..c731acbfb2a5 100644 --- a/trunk/arch/powerpc/oprofile/op_model_rs64.c +++ b/trunk/arch/powerpc/oprofile/op_model_rs64.c @@ -88,7 +88,7 @@ static unsigned long reset_value[OP_MAX_COUNTER]; static int num_counters; -static int rs64_reg_setup(struct op_counter_config *ctr, +static void rs64_reg_setup(struct op_counter_config *ctr, struct op_system_config *sys, int num_ctrs) { @@ -100,10 +100,9 @@ static int rs64_reg_setup(struct op_counter_config *ctr, reset_value[i] = 0x80000000UL - ctr[i].count; /* XXX setup user and kernel profiling */ - return 0; } -static int rs64_cpu_setup(struct op_counter_config *ctr) +static void rs64_cpu_setup(struct op_counter_config *ctr) { unsigned int mmcr0; @@ -126,11 +125,9 @@ static int rs64_cpu_setup(struct op_counter_config *ctr) mfspr(SPRN_MMCR0)); dbg("setup on cpu %d, mmcr1 %lx\n", smp_processor_id(), mfspr(SPRN_MMCR1)); - - return 0; } -static int rs64_start(struct op_counter_config *ctr) +static void rs64_start(struct op_counter_config *ctr) { int i; unsigned int mmcr0; @@ -158,7 +155,6 @@ static int rs64_start(struct op_counter_config *ctr) mtspr(SPRN_MMCR0, mmcr0); dbg("start on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0); - return 0; } static void rs64_stop(void) diff --git a/trunk/arch/powerpc/platforms/Kconfig b/trunk/arch/powerpc/platforms/Kconfig index 932538a93c2b..33545d352e92 100644 --- a/trunk/arch/powerpc/platforms/Kconfig +++ b/trunk/arch/powerpc/platforms/Kconfig @@ -272,14 +272,4 @@ config CPM2 you wish to build a kernel for a machine with a CPM2 coprocessor on it (826x, 827x, 8560). -config AXON_RAM - tristate "Axon DDR2 memory device driver" - depends on PPC_IBM_CELL_BLADE - default m - help - It registers one block device per Axon's DDR2 memory bank found - on a system. Block devices are called axonram?, their major and - minor numbers are available in /proc/devices, /proc/partitions or - in /sys/block/axonram?/dev. - endmenu diff --git a/trunk/arch/powerpc/platforms/cell/Kconfig b/trunk/arch/powerpc/platforms/cell/Kconfig index ac8032034fb8..9b2b386ccf48 100644 --- a/trunk/arch/powerpc/platforms/cell/Kconfig +++ b/trunk/arch/powerpc/platforms/cell/Kconfig @@ -73,14 +73,4 @@ config CBE_CPUFREQ For details, take a look at . If you don't have such processor, say N -config CBE_CPUFREQ_PMI - tristate "CBE frequency scaling using PMI interface" - depends on CBE_CPUFREQ && PPC_PMI && EXPERIMENTAL - default n - help - Select this, if you want to use the PMI interface - to switch frequencies. Using PMI, the - processor will not only be able to run at lower speed, - but also at lower core voltage. - endmenu diff --git a/trunk/arch/powerpc/platforms/cell/Makefile b/trunk/arch/powerpc/platforms/cell/Makefile index f88a7c76f296..869af89df6ff 100644 --- a/trunk/arch/powerpc/platforms/cell/Makefile +++ b/trunk/arch/powerpc/platforms/cell/Makefile @@ -4,9 +4,7 @@ obj-$(CONFIG_PPC_CELL_NATIVE) += interrupt.o iommu.o setup.o \ obj-$(CONFIG_CBE_RAS) += ras.o obj-$(CONFIG_CBE_THERM) += cbe_thermal.o -obj-$(CONFIG_CBE_CPUFREQ_PMI) += cbe_cpufreq_pmi.o -obj-$(CONFIG_CBE_CPUFREQ) += cbe-cpufreq.o -cbe-cpufreq-y += cbe_cpufreq_pervasive.o cbe_cpufreq.o +obj-$(CONFIG_CBE_CPUFREQ) += cbe_cpufreq.o ifeq ($(CONFIG_SMP),y) obj-$(CONFIG_PPC_CELL_NATIVE) += smp.o @@ -25,5 +23,3 @@ obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \ $(spu-priv1-y) \ $(spu-manage-y) \ spufs/ - -obj-$(CONFIG_PCI_MSI) += axon_msi.o diff --git a/trunk/arch/powerpc/platforms/cell/axon_msi.c b/trunk/arch/powerpc/platforms/cell/axon_msi.c deleted file mode 100644 index 4c9ab5b70bae..000000000000 --- a/trunk/arch/powerpc/platforms/cell/axon_msi.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Copyright 2007, Michael Ellerman, IBM Corporation. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -/* - * MSIC registers, specified as offsets from dcr_base - */ -#define MSIC_CTRL_REG 0x0 - -/* Base Address registers specify FIFO location in BE memory */ -#define MSIC_BASE_ADDR_HI_REG 0x3 -#define MSIC_BASE_ADDR_LO_REG 0x4 - -/* Hold the read/write offsets into the FIFO */ -#define MSIC_READ_OFFSET_REG 0x5 -#define MSIC_WRITE_OFFSET_REG 0x6 - - -/* MSIC control register flags */ -#define MSIC_CTRL_ENABLE 0x0001 -#define MSIC_CTRL_FIFO_FULL_ENABLE 0x0002 -#define MSIC_CTRL_IRQ_ENABLE 0x0008 -#define MSIC_CTRL_FULL_STOP_ENABLE 0x0010 - -/* - * The MSIC can be configured to use a FIFO of 32KB, 64KB, 128KB or 256KB. - * Currently we're using a 64KB FIFO size. - */ -#define MSIC_FIFO_SIZE_SHIFT 16 -#define MSIC_FIFO_SIZE_BYTES (1 << MSIC_FIFO_SIZE_SHIFT) - -/* - * To configure the FIFO size as (1 << n) bytes, we write (n - 15) into bits - * 8-9 of the MSIC control reg. - */ -#define MSIC_CTRL_FIFO_SIZE (((MSIC_FIFO_SIZE_SHIFT - 15) << 8) & 0x300) - -/* - * We need to mask the read/write offsets to make sure they stay within - * the bounds of the FIFO. Also they should always be 16-byte aligned. - */ -#define MSIC_FIFO_SIZE_MASK ((MSIC_FIFO_SIZE_BYTES - 1) & ~0xFu) - -/* Each entry in the FIFO is 16 bytes, the first 4 bytes hold the irq # */ -#define MSIC_FIFO_ENTRY_SIZE 0x10 - - -struct axon_msic { - struct device_node *dn; - struct irq_host *irq_host; - __le32 *fifo; - dcr_host_t dcr_host; - struct list_head list; - u32 read_offset; - u32 dcr_base; -}; - -static LIST_HEAD(axon_msic_list); - -static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val) -{ - pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n); - - dcr_write(msic->dcr_host, msic->dcr_base + dcr_n, val); -} - -static u32 msic_dcr_read(struct axon_msic *msic, unsigned int dcr_n) -{ - return dcr_read(msic->dcr_host, msic->dcr_base + dcr_n); -} - -static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc) -{ - struct axon_msic *msic = get_irq_data(irq); - u32 write_offset, msi; - int idx; - - write_offset = msic_dcr_read(msic, MSIC_WRITE_OFFSET_REG); - pr_debug("axon_msi: original write_offset 0x%x\n", write_offset); - - /* write_offset doesn't wrap properly, so we have to mask it */ - write_offset &= MSIC_FIFO_SIZE_MASK; - - while (msic->read_offset != write_offset) { - idx = msic->read_offset / sizeof(__le32); - msi = le32_to_cpu(msic->fifo[idx]); - msi &= 0xFFFF; - - pr_debug("axon_msi: woff %x roff %x msi %x\n", - write_offset, msic->read_offset, msi); - - msic->read_offset += MSIC_FIFO_ENTRY_SIZE; - msic->read_offset &= MSIC_FIFO_SIZE_MASK; - - if (msi < NR_IRQS && irq_map[msi].host == msic->irq_host) - generic_handle_irq(msi); - else - pr_debug("axon_msi: invalid irq 0x%x!\n", msi); - } - - desc->chip->eoi(irq); -} - -static struct axon_msic *find_msi_translator(struct pci_dev *dev) -{ - struct irq_host *irq_host; - struct device_node *dn, *tmp; - const phandle *ph; - struct axon_msic *msic = NULL; - - dn = pci_device_to_OF_node(dev); - if (!dn) { - dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n"); - return NULL; - } - - for (; dn; tmp = of_get_parent(dn), of_node_put(dn), dn = tmp) { - ph = of_get_property(dn, "msi-translator", NULL); - if (ph) - break; - } - - if (!ph) { - dev_dbg(&dev->dev, - "axon_msi: no msi-translator property found\n"); - goto out_error; - } - - tmp = dn; - dn = of_find_node_by_phandle(*ph); - if (!dn) { - dev_dbg(&dev->dev, - "axon_msi: msi-translator doesn't point to a node\n"); - goto out_error; - } - - irq_host = irq_find_host(dn); - if (!irq_host) { - dev_dbg(&dev->dev, "axon_msi: no irq_host found for node %s\n", - dn->full_name); - goto out_error; - } - - msic = irq_host->host_data; - -out_error: - of_node_put(dn); - of_node_put(tmp); - - return msic; -} - -static int axon_msi_check_device(struct pci_dev *dev, int nvec, int type) -{ - if (!find_msi_translator(dev)) - return -ENODEV; - - return 0; -} - -static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg) -{ - struct device_node *dn, *tmp; - struct msi_desc *entry; - int len; - const u32 *prop; - - dn = pci_device_to_OF_node(dev); - if (!dn) { - dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n"); - return -ENODEV; - } - - entry = list_first_entry(&dev->msi_list, struct msi_desc, list); - - for (; dn; tmp = of_get_parent(dn), of_node_put(dn), dn = tmp) { - if (entry->msi_attrib.is_64) { - prop = of_get_property(dn, "msi-address-64", &len); - if (prop) - break; - } - - prop = of_get_property(dn, "msi-address-32", &len); - if (prop) - break; - } - - if (!prop) { - dev_dbg(&dev->dev, - "axon_msi: no msi-address-(32|64) properties found\n"); - return -ENOENT; - } - - switch (len) { - case 8: - msg->address_hi = prop[0]; - msg->address_lo = prop[1]; - break; - case 4: - msg->address_hi = 0; - msg->address_lo = prop[0]; - break; - default: - dev_dbg(&dev->dev, - "axon_msi: malformed msi-address-(32|64) property\n"); - of_node_put(dn); - return -EINVAL; - } - - of_node_put(dn); - - return 0; -} - -static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) -{ - unsigned int virq, rc; - struct msi_desc *entry; - struct msi_msg msg; - struct axon_msic *msic; - - msic = find_msi_translator(dev); - if (!msic) - return -ENODEV; - - rc = setup_msi_msg_address(dev, &msg); - if (rc) - return rc; - - /* We rely on being able to stash a virq in a u16 */ - BUILD_BUG_ON(NR_IRQS > 65536); - - list_for_each_entry(entry, &dev->msi_list, list) { - virq = irq_create_direct_mapping(msic->irq_host); - if (virq == NO_IRQ) { - dev_warn(&dev->dev, - "axon_msi: virq allocation failed!\n"); - return -1; - } - dev_dbg(&dev->dev, "axon_msi: allocated virq 0x%x\n", virq); - - set_irq_msi(virq, entry); - msg.data = virq; - write_msi_msg(virq, &msg); - } - - return 0; -} - -static void axon_msi_teardown_msi_irqs(struct pci_dev *dev) -{ - struct msi_desc *entry; - - dev_dbg(&dev->dev, "axon_msi: tearing down msi irqs\n"); - - list_for_each_entry(entry, &dev->msi_list, list) { - if (entry->irq == NO_IRQ) - continue; - - set_irq_msi(entry->irq, NULL); - irq_dispose_mapping(entry->irq); - } -} - -static struct irq_chip msic_irq_chip = { - .mask = mask_msi_irq, - .unmask = unmask_msi_irq, - .shutdown = unmask_msi_irq, - .typename = "AXON-MSI", -}; - -static int msic_host_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t hw) -{ - set_irq_chip_and_handler(virq, &msic_irq_chip, handle_simple_irq); - - return 0; -} - -static int msic_host_match(struct irq_host *host, struct device_node *dn) -{ - struct axon_msic *msic = host->host_data; - - return msic->dn == dn; -} - -static struct irq_host_ops msic_host_ops = { - .match = msic_host_match, - .map = msic_host_map, -}; - -static int axon_msi_notify_reboot(struct notifier_block *nb, - unsigned long code, void *data) -{ - struct axon_msic *msic; - u32 tmp; - - list_for_each_entry(msic, &axon_msic_list, list) { - pr_debug("axon_msi: disabling %s\n", msic->dn->full_name); - tmp = msic_dcr_read(msic, MSIC_CTRL_REG); - tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE; - msic_dcr_write(msic, MSIC_CTRL_REG, tmp); - } - - return 0; -} - -static struct notifier_block axon_msi_reboot_notifier = { - .notifier_call = axon_msi_notify_reboot -}; - -static int axon_msi_setup_one(struct device_node *dn) -{ - struct page *page; - struct axon_msic *msic; - unsigned int virq; - int dcr_len; - - pr_debug("axon_msi: setting up dn %s\n", dn->full_name); - - msic = kzalloc(sizeof(struct axon_msic), GFP_KERNEL); - if (!msic) { - printk(KERN_ERR "axon_msi: couldn't allocate msic for %s\n", - dn->full_name); - goto out; - } - - msic->dcr_base = dcr_resource_start(dn, 0); - dcr_len = dcr_resource_len(dn, 0); - - if (msic->dcr_base == 0 || dcr_len == 0) { - printk(KERN_ERR - "axon_msi: couldn't parse dcr properties on %s\n", - dn->full_name); - goto out; - } - - msic->dcr_host = dcr_map(dn, msic->dcr_base, dcr_len); - if (!DCR_MAP_OK(msic->dcr_host)) { - printk(KERN_ERR "axon_msi: dcr_map failed for %s\n", - dn->full_name); - goto out_free_msic; - } - - page = alloc_pages_node(of_node_to_nid(dn), GFP_KERNEL, - get_order(MSIC_FIFO_SIZE_BYTES)); - if (!page) { - printk(KERN_ERR "axon_msi: couldn't allocate fifo for %s\n", - dn->full_name); - goto out_free_msic; - } - - msic->fifo = page_address(page); - - msic->irq_host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, NR_IRQS, - &msic_host_ops, 0); - if (!msic->irq_host) { - printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n", - dn->full_name); - goto out_free_fifo; - } - - msic->irq_host->host_data = msic; - - virq = irq_of_parse_and_map(dn, 0); - if (virq == NO_IRQ) { - printk(KERN_ERR "axon_msi: irq parse and map failed for %s\n", - dn->full_name); - goto out_free_host; - } - - msic->dn = of_node_get(dn); - - set_irq_data(virq, msic); - set_irq_chained_handler(virq, axon_msi_cascade); - pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq); - - /* Enable the MSIC hardware */ - msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, (u64)msic->fifo >> 32); - msic_dcr_write(msic, MSIC_BASE_ADDR_LO_REG, - (u64)msic->fifo & 0xFFFFFFFF); - msic_dcr_write(msic, MSIC_CTRL_REG, - MSIC_CTRL_IRQ_ENABLE | MSIC_CTRL_ENABLE | - MSIC_CTRL_FIFO_SIZE); - - list_add(&msic->list, &axon_msic_list); - - printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name); - - return 0; - -out_free_host: - kfree(msic->irq_host); -out_free_fifo: - __free_pages(virt_to_page(msic->fifo), get_order(MSIC_FIFO_SIZE_BYTES)); -out_free_msic: - kfree(msic); -out: - - return -1; -} - -static int axon_msi_init(void) -{ - struct device_node *dn; - int found = 0; - - pr_debug("axon_msi: initialising ...\n"); - - for_each_compatible_node(dn, NULL, "ibm,axon-msic") { - if (axon_msi_setup_one(dn) == 0) - found++; - } - - if (found) { - ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs; - ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs; - ppc_md.msi_check_device = axon_msi_check_device; - - register_reboot_notifier(&axon_msi_reboot_notifier); - - pr_debug("axon_msi: registered callbacks!\n"); - } - - return 0; -} -arch_initcall(axon_msi_init); diff --git a/trunk/arch/powerpc/platforms/cell/cbe_cpufreq.c b/trunk/arch/powerpc/platforms/cell/cbe_cpufreq.c index 0b6e8ee85ab1..ab511d5b65a4 100644 --- a/trunk/arch/powerpc/platforms/cell/cbe_cpufreq.c +++ b/trunk/arch/powerpc/platforms/cell/cbe_cpufreq.c @@ -1,7 +1,7 @@ /* * cpufreq driver for the cell processor * - * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 * * Author: Christian Krafft * @@ -21,11 +21,18 @@ */ #include +#include + +#include +#include #include -#include +#include #include +#include +#include +#include + #include "cbe_regs.h" -#include "cbe_cpufreq.h" static DEFINE_MUTEX(cbe_switch_mutex); @@ -43,24 +50,159 @@ static struct cpufreq_frequency_table cbe_freqs[] = { {0, CPUFREQ_TABLE_END}, }; +/* to write to MIC register */ +static u64 MIC_Slow_Fast_Timer_table[] = { + [0 ... 7] = 0x007fc00000000000ull, +}; + +/* more values for the MIC */ +static u64 MIC_Slow_Next_Timer_table[] = { + 0x0000240000000000ull, + 0x0000268000000000ull, + 0x000029C000000000ull, + 0x00002D0000000000ull, + 0x0000300000000000ull, + 0x0000334000000000ull, + 0x000039C000000000ull, + 0x00003FC000000000ull, +}; + +static unsigned int pmi_frequency_limit = 0; /* * hardware specific functions */ -static int set_pmode(unsigned int cpu, unsigned int slow_mode) +static struct of_device *pmi_dev; + +#ifdef CONFIG_PPC_PMI +static int set_pmode_pmi(int cpu, unsigned int pmode) { - int rc; + int ret; + pmi_message_t pmi_msg; +#ifdef DEBUG + u64 time; +#endif + + pmi_msg.type = PMI_TYPE_FREQ_CHANGE; + pmi_msg.data1 = cbe_cpu_to_node(cpu); + pmi_msg.data2 = pmode; + +#ifdef DEBUG + time = (u64) get_cycles(); +#endif + + pmi_send_message(pmi_dev, pmi_msg); + ret = pmi_msg.data2; + + pr_debug("PMI returned slow mode %d\n", ret); + +#ifdef DEBUG + time = (u64) get_cycles() - time; /* actual cycles (not cpu cycles!) */ + time = 1000000000 * time / CLOCK_TICK_RATE; /* time in ns (10^-9) */ + pr_debug("had to wait %lu ns for a transition\n", time); +#endif + return ret; +} +#endif + +static int get_pmode(int cpu) +{ + int ret; + struct cbe_pmd_regs __iomem *pmd_regs; + + pmd_regs = cbe_get_cpu_pmd_regs(cpu); + ret = in_be64(&pmd_regs->pmsr) & 0x07; + + return ret; +} + +static int set_pmode_reg(int cpu, unsigned int pmode) +{ + struct cbe_pmd_regs __iomem *pmd_regs; + struct cbe_mic_tm_regs __iomem *mic_tm_regs; + u64 flags; + u64 value; + + local_irq_save(flags); + + mic_tm_regs = cbe_get_cpu_mic_tm_regs(cpu); + pmd_regs = cbe_get_cpu_pmd_regs(cpu); + + pr_debug("pm register is mapped at %p\n", &pmd_regs->pmcr); + pr_debug("mic register is mapped at %p\n", &mic_tm_regs->slow_fast_timer_0); + + out_be64(&mic_tm_regs->slow_fast_timer_0, MIC_Slow_Fast_Timer_table[pmode]); + out_be64(&mic_tm_regs->slow_fast_timer_1, MIC_Slow_Fast_Timer_table[pmode]); + + out_be64(&mic_tm_regs->slow_next_timer_0, MIC_Slow_Next_Timer_table[pmode]); + out_be64(&mic_tm_regs->slow_next_timer_1, MIC_Slow_Next_Timer_table[pmode]); + + value = in_be64(&pmd_regs->pmcr); + /* set bits to zero */ + value &= 0xFFFFFFFFFFFFFFF8ull; + /* set bits to next pmode */ + value |= pmode; + + out_be64(&pmd_regs->pmcr, value); + + /* wait until new pmode appears in status register */ + value = in_be64(&pmd_regs->pmsr) & 0x07; + while(value != pmode) { + cpu_relax(); + value = in_be64(&pmd_regs->pmsr) & 0x07; + } - if (cbe_cpufreq_has_pmi) - rc = cbe_cpufreq_set_pmode_pmi(cpu, slow_mode); + local_irq_restore(flags); + + return 0; +} + +static int set_pmode(int cpu, unsigned int slow_mode) { +#ifdef CONFIG_PPC_PMI + if (pmi_dev) + return set_pmode_pmi(cpu, slow_mode); else - rc = cbe_cpufreq_set_pmode(cpu, slow_mode); +#endif + return set_pmode_reg(cpu, slow_mode); +} + +static void cbe_cpufreq_handle_pmi(struct of_device *dev, pmi_message_t pmi_msg) +{ + u8 cpu; + u8 cbe_pmode_new; - pr_debug("register contains slow mode %d\n", cbe_cpufreq_get_pmode(cpu)); + BUG_ON(pmi_msg.type != PMI_TYPE_FREQ_CHANGE); - return rc; + cpu = cbe_node_to_cpu(pmi_msg.data1); + cbe_pmode_new = pmi_msg.data2; + + pmi_frequency_limit = cbe_freqs[cbe_pmode_new].frequency; + + pr_debug("cbe_handle_pmi: max freq=%d\n", pmi_frequency_limit); } +static int pmi_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct cpufreq_policy *policy = data; + + if (event != CPUFREQ_INCOMPATIBLE) + return 0; + + cpufreq_verify_within_limits(policy, 0, pmi_frequency_limit); + return 0; +} + +static struct notifier_block pmi_notifier_block = { + .notifier_call = pmi_notifier, +}; + +static struct pmi_handler cbe_pmi_handler = { + .type = PMI_TYPE_FREQ_CHANGE, + .handle_pmi_message = cbe_cpufreq_handle_pmi, +}; + + /* * cpufreq functions */ @@ -79,19 +221,8 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) pr_debug("init cpufreq on CPU %d\n", policy->cpu); - /* - * Let's check we can actually get to the CELL regs - */ - if (!cbe_get_cpu_pmd_regs(policy->cpu) || - !cbe_get_cpu_mic_tm_regs(policy->cpu)) { - pr_info("invalid CBE regs pointers for cpufreq\n"); - return -EINVAL; - } - max_freqp = of_get_property(cpu, "clock-frequency", NULL); - of_node_put(cpu); - if (!max_freqp) return -EINVAL; @@ -108,12 +239,10 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) } policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - - /* if DEBUG is enabled set_pmode() measures the latency - * of a transition */ + /* if DEBUG is enabled set_pmode() measures the correct latency of a transition */ policy->cpuinfo.transition_latency = 25000; - cur_pmode = cbe_cpufreq_get_pmode(policy->cpu); + cur_pmode = get_pmode(policy->cpu); pr_debug("current pmode is at %d\n",cur_pmode); policy->cur = cbe_freqs[cur_pmode].frequency; @@ -124,13 +253,21 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu); - /* this ensures that policy->cpuinfo_min - * and policy->cpuinfo_max are set correctly */ + if (pmi_dev) { + /* frequency might get limited later, initialize limit with max_freq */ + pmi_frequency_limit = max_freq; + cpufreq_register_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER); + } + + /* this ensures that policy->cpuinfo_min and policy->cpuinfo_max are set correctly */ return cpufreq_frequency_table_cpuinfo(policy, cbe_freqs); } static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy) { + if (pmi_dev) + cpufreq_unregister_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER); + cpufreq_frequency_table_put_attr(policy->cpu); return 0; } @@ -140,13 +277,13 @@ static int cbe_cpufreq_verify(struct cpufreq_policy *policy) return cpufreq_frequency_table_verify(policy, cbe_freqs); } -static int cbe_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) + +static int cbe_cpufreq_target(struct cpufreq_policy *policy, unsigned int target_freq, + unsigned int relation) { int rc; struct cpufreq_freqs freqs; - unsigned int cbe_pmode_new; + int cbe_pmode_new; cpufreq_frequency_table_target(policy, cbe_freqs, @@ -161,14 +298,12 @@ static int cbe_cpufreq_target(struct cpufreq_policy *policy, mutex_lock(&cbe_switch_mutex); cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - pr_debug("setting frequency for cpu %d to %d kHz, " \ - "1/%d of max frequency\n", + pr_debug("setting frequency for cpu %d to %d kHz, 1/%d of max frequency\n", policy->cpu, cbe_freqs[cbe_pmode_new].frequency, cbe_freqs[cbe_pmode_new].index); rc = set_pmode(policy->cpu, cbe_pmode_new); - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); mutex_unlock(&cbe_switch_mutex); @@ -191,14 +326,28 @@ static struct cpufreq_driver cbe_cpufreq_driver = { static int __init cbe_cpufreq_init(void) { +#ifdef CONFIG_PPC_PMI + struct device_node *np; +#endif if (!machine_is(cell)) return -ENODEV; +#ifdef CONFIG_PPC_PMI + np = of_find_node_by_type(NULL, "ibm,pmi"); + + pmi_dev = of_find_device_by_node(np); + if (pmi_dev) + pmi_register_handler(pmi_dev, &cbe_pmi_handler); +#endif return cpufreq_register_driver(&cbe_cpufreq_driver); } static void __exit cbe_cpufreq_exit(void) { +#ifdef CONFIG_PPC_PMI + if (pmi_dev) + pmi_unregister_handler(pmi_dev, &cbe_pmi_handler); +#endif cpufreq_unregister_driver(&cbe_cpufreq_driver); } diff --git a/trunk/arch/powerpc/platforms/cell/cbe_cpufreq.h b/trunk/arch/powerpc/platforms/cell/cbe_cpufreq.h deleted file mode 100644 index c1d86bfa92ff..000000000000 --- a/trunk/arch/powerpc/platforms/cell/cbe_cpufreq.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * cbe_cpufreq.h - * - * This file contains the definitions used by the cbe_cpufreq driver. - * - * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 - * - * Author: Christian Krafft - * - */ - -#include -#include - -int cbe_cpufreq_set_pmode(int cpu, unsigned int pmode); -int cbe_cpufreq_get_pmode(int cpu); - -int cbe_cpufreq_set_pmode_pmi(int cpu, unsigned int pmode); - -#if defined(CONFIG_CBE_CPUFREQ_PMI) || defined(CONFIG_CBE_CPUFREQ_PMI_MODULE) -extern bool cbe_cpufreq_has_pmi; -#else -#define cbe_cpufreq_has_pmi (0) -#endif diff --git a/trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c b/trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c deleted file mode 100644 index 163263b3e1cd..000000000000 --- a/trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * pervasive backend for the cbe_cpufreq driver - * - * This driver makes use of the pervasive unit to - * engage the desired frequency. - * - * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 - * - * Author: Christian Krafft - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include - -#include "cbe_regs.h" -#include "cbe_cpufreq.h" - -/* to write to MIC register */ -static u64 MIC_Slow_Fast_Timer_table[] = { - [0 ... 7] = 0x007fc00000000000ull, -}; - -/* more values for the MIC */ -static u64 MIC_Slow_Next_Timer_table[] = { - 0x0000240000000000ull, - 0x0000268000000000ull, - 0x000029C000000000ull, - 0x00002D0000000000ull, - 0x0000300000000000ull, - 0x0000334000000000ull, - 0x000039C000000000ull, - 0x00003FC000000000ull, -}; - - -int cbe_cpufreq_set_pmode(int cpu, unsigned int pmode) -{ - struct cbe_pmd_regs __iomem *pmd_regs; - struct cbe_mic_tm_regs __iomem *mic_tm_regs; - u64 flags; - u64 value; -#ifdef DEBUG - long time; -#endif - - local_irq_save(flags); - - mic_tm_regs = cbe_get_cpu_mic_tm_regs(cpu); - pmd_regs = cbe_get_cpu_pmd_regs(cpu); - -#ifdef DEBUG - time = jiffies; -#endif - - out_be64(&mic_tm_regs->slow_fast_timer_0, MIC_Slow_Fast_Timer_table[pmode]); - out_be64(&mic_tm_regs->slow_fast_timer_1, MIC_Slow_Fast_Timer_table[pmode]); - - out_be64(&mic_tm_regs->slow_next_timer_0, MIC_Slow_Next_Timer_table[pmode]); - out_be64(&mic_tm_regs->slow_next_timer_1, MIC_Slow_Next_Timer_table[pmode]); - - value = in_be64(&pmd_regs->pmcr); - /* set bits to zero */ - value &= 0xFFFFFFFFFFFFFFF8ull; - /* set bits to next pmode */ - value |= pmode; - - out_be64(&pmd_regs->pmcr, value); - -#ifdef DEBUG - /* wait until new pmode appears in status register */ - value = in_be64(&pmd_regs->pmsr) & 0x07; - while (value != pmode) { - cpu_relax(); - value = in_be64(&pmd_regs->pmsr) & 0x07; - } - - time = jiffies - time; - time = jiffies_to_msecs(time); - pr_debug("had to wait %lu ms for a transition using " \ - "pervasive unit\n", time); -#endif - local_irq_restore(flags); - - return 0; -} - - -int cbe_cpufreq_get_pmode(int cpu) -{ - int ret; - struct cbe_pmd_regs __iomem *pmd_regs; - - pmd_regs = cbe_get_cpu_pmd_regs(cpu); - ret = in_be64(&pmd_regs->pmsr) & 0x07; - - return ret; -} - diff --git a/trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c b/trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c deleted file mode 100644 index fc6f38982ff4..000000000000 --- a/trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * pmi backend for the cbe_cpufreq driver - * - * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 - * - * Author: Christian Krafft - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include - -#ifdef DEBUG -#include -#endif - -#include "cbe_regs.h" -#include "cbe_cpufreq.h" - -static u8 pmi_slow_mode_limit[MAX_CBE]; - -bool cbe_cpufreq_has_pmi = false; -EXPORT_SYMBOL_GPL(cbe_cpufreq_has_pmi); - -/* - * hardware specific functions - */ - -int cbe_cpufreq_set_pmode_pmi(int cpu, unsigned int pmode) -{ - int ret; - pmi_message_t pmi_msg; -#ifdef DEBUG - long time; -#endif - pmi_msg.type = PMI_TYPE_FREQ_CHANGE; - pmi_msg.data1 = cbe_cpu_to_node(cpu); - pmi_msg.data2 = pmode; - -#ifdef DEBUG - time = jiffies; -#endif - pmi_send_message(pmi_msg); - -#ifdef DEBUG - time = jiffies - time; - time = jiffies_to_msecs(time); - pr_debug("had to wait %lu ms for a transition using " \ - "PMI\n", time); -#endif - ret = pmi_msg.data2; - pr_debug("PMI returned slow mode %d\n", ret); - - return ret; -} -EXPORT_SYMBOL_GPL(cbe_cpufreq_set_pmode_pmi); - - -static void cbe_cpufreq_handle_pmi(pmi_message_t pmi_msg) -{ - u8 node, slow_mode; - - BUG_ON(pmi_msg.type != PMI_TYPE_FREQ_CHANGE); - - node = pmi_msg.data1; - slow_mode = pmi_msg.data2; - - pmi_slow_mode_limit[node] = slow_mode; - - pr_debug("cbe_handle_pmi: node: %d max_freq: %d\n", node, slow_mode); -} - -static int pmi_notifier(struct notifier_block *nb, - unsigned long event, void *data) -{ - struct cpufreq_policy *policy = data; - struct cpufreq_frequency_table *cbe_freqs; - u8 node; - - cbe_freqs = cpufreq_frequency_get_table(policy->cpu); - node = cbe_cpu_to_node(policy->cpu); - - pr_debug("got notified, event=%lu, node=%u\n", event, node); - - if (pmi_slow_mode_limit[node] != 0) { - pr_debug("limiting node %d to slow mode %d\n", - node, pmi_slow_mode_limit[node]); - - cpufreq_verify_within_limits(policy, 0, - - cbe_freqs[pmi_slow_mode_limit[node]].frequency); - } - - return 0; -} - -static struct notifier_block pmi_notifier_block = { - .notifier_call = pmi_notifier, -}; - -static struct pmi_handler cbe_pmi_handler = { - .type = PMI_TYPE_FREQ_CHANGE, - .handle_pmi_message = cbe_cpufreq_handle_pmi, -}; - - - -static int __init cbe_cpufreq_pmi_init(void) -{ - cbe_cpufreq_has_pmi = pmi_register_handler(&cbe_pmi_handler) == 0; - - if (!cbe_cpufreq_has_pmi) - return -ENODEV; - - cpufreq_register_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER); - - return 0; -} - -static void __exit cbe_cpufreq_pmi_exit(void) -{ - cpufreq_unregister_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER); - pmi_unregister_handler(&cbe_pmi_handler); -} - -module_init(cbe_cpufreq_pmi_init); -module_exit(cbe_cpufreq_pmi_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Christian Krafft "); diff --git a/trunk/arch/powerpc/platforms/cell/cbe_regs.c b/trunk/arch/powerpc/platforms/cell/cbe_regs.c index c8f7f0007422..12c9674b4b1f 100644 --- a/trunk/arch/powerpc/platforms/cell/cbe_regs.c +++ b/trunk/arch/powerpc/platforms/cell/cbe_regs.c @@ -174,13 +174,6 @@ static struct device_node *cbe_get_be_node(int cpu_id) cpu_handle = of_get_property(np, "cpus", &len); - /* - * the CAB SLOF tree is non compliant, so we just assume - * there is only one node - */ - if (WARN_ON_ONCE(!cpu_handle)) - return np; - for (i=0; iid); - if (!pmd_regs) { - pr_info("invalid CBE regs pointer for cbe_thermal\n"); - return -EINVAL; - } - out_be64(&pmd_regs->tm_str2, str2); out_be64(&pmd_regs->tm_str1.val, str1.val); out_be64(&pmd_regs->tm_tpr.val, tpr.val); out_be64(&pmd_regs->tm_cr1.val, cr1.val); out_be64(&pmd_regs->tm_cr2, cr2); } - - return 0; } static int __init thermal_init(void) { - int rc = init_default_values(); + init_default_values(); - if (rc == 0) { - spu_add_sysdev_attr_group(&spu_attribute_group); - cpu_add_sysdev_attr_group(&ppe_attribute_group); - } + spu_add_sysdev_attr_group(&spu_attribute_group); + cpu_add_sysdev_attr_group(&ppe_attribute_group); - return rc; + return 0; } module_init(thermal_init); diff --git a/trunk/arch/powerpc/platforms/cell/spu_base.c b/trunk/arch/powerpc/platforms/cell/spu_base.c index 90124228b8f4..96a8f609690c 100644 --- a/trunk/arch/powerpc/platforms/cell/spu_base.c +++ b/trunk/arch/powerpc/platforms/cell/spu_base.c @@ -35,37 +35,18 @@ #include #include #include -#include -#include "spu_priv1_mmio.h" const struct spu_management_ops *spu_management_ops; EXPORT_SYMBOL_GPL(spu_management_ops); const struct spu_priv1_ops *spu_priv1_ops; -EXPORT_SYMBOL_GPL(spu_priv1_ops); - -struct cbe_spu_info cbe_spu_info[MAX_NUMNODES]; -EXPORT_SYMBOL_GPL(cbe_spu_info); - -/* - * Protects cbe_spu_info and spu->number. - */ -static DEFINE_SPINLOCK(spu_lock); -/* - * List of all spus in the system. - * - * This list is iterated by callers from irq context and callers that - * want to sleep. Thus modifications need to be done with both - * spu_full_list_lock and spu_full_list_mutex held, while iterating - * through it requires either of these locks. - * - * In addition spu_full_list_lock protects all assignmens to - * spu->mm. - */ +static struct list_head spu_list[MAX_NUMNODES]; static LIST_HEAD(spu_full_list); -static DEFINE_SPINLOCK(spu_full_list_lock); -static DEFINE_MUTEX(spu_full_list_mutex); +static DEFINE_MUTEX(spu_mutex); +static DEFINE_SPINLOCK(spu_list_lock); + +EXPORT_SYMBOL_GPL(spu_priv1_ops); void spu_invalidate_slbs(struct spu *spu) { @@ -84,12 +65,12 @@ void spu_flush_all_slbs(struct mm_struct *mm) struct spu *spu; unsigned long flags; - spin_lock_irqsave(&spu_full_list_lock, flags); + spin_lock_irqsave(&spu_list_lock, flags); list_for_each_entry(spu, &spu_full_list, full_list) { if (spu->mm == mm) spu_invalidate_slbs(spu); } - spin_unlock_irqrestore(&spu_full_list_lock, flags); + spin_unlock_irqrestore(&spu_list_lock, flags); } /* The hack below stinks... try to do something better one of @@ -107,9 +88,9 @@ void spu_associate_mm(struct spu *spu, struct mm_struct *mm) { unsigned long flags; - spin_lock_irqsave(&spu_full_list_lock, flags); + spin_lock_irqsave(&spu_list_lock, flags); spu->mm = mm; - spin_unlock_irqrestore(&spu_full_list_lock, flags); + spin_unlock_irqrestore(&spu_list_lock, flags); if (mm) mm_needs_global_tlbie(mm); } @@ -409,7 +390,7 @@ static void spu_free_irqs(struct spu *spu) free_irq(spu->irqs[2], spu); } -void spu_init_channels(struct spu *spu) +static void spu_init_channels(struct spu *spu) { static const struct { unsigned channel; @@ -442,7 +423,46 @@ void spu_init_channels(struct spu *spu) out_be64(&priv2->spu_chnlcnt_RW, count_list[i].count); } } -EXPORT_SYMBOL_GPL(spu_init_channels); + +struct spu *spu_alloc_node(int node) +{ + struct spu *spu = NULL; + + mutex_lock(&spu_mutex); + if (!list_empty(&spu_list[node])) { + spu = list_entry(spu_list[node].next, struct spu, list); + list_del_init(&spu->list); + pr_debug("Got SPU %d %d\n", spu->number, spu->node); + } + mutex_unlock(&spu_mutex); + + if (spu) + spu_init_channels(spu); + return spu; +} +EXPORT_SYMBOL_GPL(spu_alloc_node); + +struct spu *spu_alloc(void) +{ + struct spu *spu = NULL; + int node; + + for (node = 0; node < MAX_NUMNODES; node++) { + spu = spu_alloc_node(node); + if (spu) + break; + } + + return spu; +} + +void spu_free(struct spu *spu) +{ + mutex_lock(&spu_mutex); + list_add_tail(&spu->list, &spu_list[spu->node]); + mutex_unlock(&spu_mutex); +} +EXPORT_SYMBOL_GPL(spu_free); static int spu_shutdown(struct sys_device *sysdev) { @@ -461,12 +481,12 @@ struct sysdev_class spu_sysdev_class = { int spu_add_sysdev_attr(struct sysdev_attribute *attr) { struct spu *spu; + mutex_lock(&spu_mutex); - mutex_lock(&spu_full_list_mutex); list_for_each_entry(spu, &spu_full_list, full_list) sysdev_create_file(&spu->sysdev, attr); - mutex_unlock(&spu_full_list_mutex); + mutex_unlock(&spu_mutex); return 0; } EXPORT_SYMBOL_GPL(spu_add_sysdev_attr); @@ -474,12 +494,12 @@ EXPORT_SYMBOL_GPL(spu_add_sysdev_attr); int spu_add_sysdev_attr_group(struct attribute_group *attrs) { struct spu *spu; + mutex_lock(&spu_mutex); - mutex_lock(&spu_full_list_mutex); list_for_each_entry(spu, &spu_full_list, full_list) sysfs_create_group(&spu->sysdev.kobj, attrs); - mutex_unlock(&spu_full_list_mutex); + mutex_unlock(&spu_mutex); return 0; } EXPORT_SYMBOL_GPL(spu_add_sysdev_attr_group); @@ -488,22 +508,24 @@ EXPORT_SYMBOL_GPL(spu_add_sysdev_attr_group); void spu_remove_sysdev_attr(struct sysdev_attribute *attr) { struct spu *spu; + mutex_lock(&spu_mutex); - mutex_lock(&spu_full_list_mutex); list_for_each_entry(spu, &spu_full_list, full_list) sysdev_remove_file(&spu->sysdev, attr); - mutex_unlock(&spu_full_list_mutex); + + mutex_unlock(&spu_mutex); } EXPORT_SYMBOL_GPL(spu_remove_sysdev_attr); void spu_remove_sysdev_attr_group(struct attribute_group *attrs) { struct spu *spu; + mutex_lock(&spu_mutex); - mutex_lock(&spu_full_list_mutex); list_for_each_entry(spu, &spu_full_list, full_list) sysfs_remove_group(&spu->sysdev.kobj, attrs); - mutex_unlock(&spu_full_list_mutex); + + mutex_unlock(&spu_mutex); } EXPORT_SYMBOL_GPL(spu_remove_sysdev_attr_group); @@ -531,19 +553,16 @@ static int __init create_spu(void *data) int ret; static int number; unsigned long flags; - struct timespec ts; ret = -ENOMEM; spu = kzalloc(sizeof (*spu), GFP_KERNEL); if (!spu) goto out; - spu->alloc_state = SPU_FREE; - spin_lock_init(&spu->register_lock); - spin_lock(&spu_lock); + mutex_lock(&spu_mutex); spu->number = number++; - spin_unlock(&spu_lock); + mutex_unlock(&spu_mutex); ret = spu_create_spu(spu, data); @@ -560,22 +579,15 @@ static int __init create_spu(void *data) if (ret) goto out_free_irqs; - mutex_lock(&cbe_spu_info[spu->node].list_mutex); - list_add(&spu->cbe_list, &cbe_spu_info[spu->node].spus); - cbe_spu_info[spu->node].n_spus++; - mutex_unlock(&cbe_spu_info[spu->node].list_mutex); - - mutex_lock(&spu_full_list_mutex); - spin_lock_irqsave(&spu_full_list_lock, flags); + mutex_lock(&spu_mutex); + spin_lock_irqsave(&spu_list_lock, flags); + list_add(&spu->list, &spu_list[spu->node]); list_add(&spu->full_list, &spu_full_list); - spin_unlock_irqrestore(&spu_full_list_lock, flags); - mutex_unlock(&spu_full_list_mutex); - - spu->stats.util_state = SPU_UTIL_IDLE_LOADED; - ktime_get_ts(&ts); - spu->stats.tstamp = timespec_to_ns(&ts); + spin_unlock_irqrestore(&spu_list_lock, flags); + mutex_unlock(&spu_mutex); - INIT_LIST_HEAD(&spu->aff_list); + spu->stats.utilization_state = SPU_UTIL_IDLE; + spu->stats.tstamp = jiffies; goto out; @@ -596,20 +608,12 @@ static const char *spu_state_names[] = { static unsigned long long spu_acct_time(struct spu *spu, enum spu_utilization_state state) { - struct timespec ts; unsigned long long time = spu->stats.times[state]; - /* - * If the spu is idle or the context is stopped, utilization - * statistics are not updated. Apply the time delta from the - * last recorded state of the spu. - */ - if (spu->stats.util_state == state) { - ktime_get_ts(&ts); - time += timespec_to_ns(&ts) - spu->stats.tstamp; - } + if (spu->stats.utilization_state == state) + time += jiffies - spu->stats.tstamp; - return time / NSEC_PER_MSEC; + return jiffies_to_msecs(time); } @@ -619,11 +623,11 @@ static ssize_t spu_stat_show(struct sys_device *sysdev, char *buf) return sprintf(buf, "%s %llu %llu %llu %llu " "%llu %llu %llu %llu %llu %llu %llu %llu\n", - spu_state_names[spu->stats.util_state], + spu_state_names[spu->stats.utilization_state], spu_acct_time(spu, SPU_UTIL_USER), spu_acct_time(spu, SPU_UTIL_SYSTEM), spu_acct_time(spu, SPU_UTIL_IOWAIT), - spu_acct_time(spu, SPU_UTIL_IDLE_LOADED), + spu_acct_time(spu, SPU_UTIL_IDLE), spu->stats.vol_ctx_switch, spu->stats.invol_ctx_switch, spu->stats.slb_flt, @@ -636,146 +640,12 @@ static ssize_t spu_stat_show(struct sys_device *sysdev, char *buf) static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL); -/* Hardcoded affinity idxs for QS20 */ -#define SPES_PER_BE 8 -static int QS20_reg_idxs[SPES_PER_BE] = { 0, 2, 4, 6, 7, 5, 3, 1 }; -static int QS20_reg_memory[SPES_PER_BE] = { 1, 1, 0, 0, 0, 0, 0, 0 }; - -static struct spu *spu_lookup_reg(int node, u32 reg) -{ - struct spu *spu; - - list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) { - if (*(u32 *)get_property(spu_devnode(spu), "reg", NULL) == reg) - return spu; - } - return NULL; -} - -static void init_aff_QS20_harcoded(void) -{ - int node, i; - struct spu *last_spu, *spu; - u32 reg; - - for (node = 0; node < MAX_NUMNODES; node++) { - last_spu = NULL; - for (i = 0; i < SPES_PER_BE; i++) { - reg = QS20_reg_idxs[i]; - spu = spu_lookup_reg(node, reg); - if (!spu) - continue; - spu->has_mem_affinity = QS20_reg_memory[reg]; - if (last_spu) - list_add_tail(&spu->aff_list, - &last_spu->aff_list); - last_spu = spu; - } - } -} - -static int of_has_vicinity(void) -{ - struct spu* spu; - - spu = list_entry(cbe_spu_info[0].spus.next, struct spu, cbe_list); - return of_find_property(spu_devnode(spu), "vicinity", NULL) != NULL; -} - -static struct spu *aff_devnode_spu(int cbe, struct device_node *dn) -{ - struct spu *spu; - - list_for_each_entry(spu, &cbe_spu_info[cbe].spus, cbe_list) - if (spu_devnode(spu) == dn) - return spu; - return NULL; -} - -static struct spu * -aff_node_next_to(int cbe, struct device_node *target, struct device_node *avoid) -{ - struct spu *spu; - const phandle *vic_handles; - int lenp, i; - - list_for_each_entry(spu, &cbe_spu_info[cbe].spus, cbe_list) { - if (spu_devnode(spu) == avoid) - continue; - vic_handles = get_property(spu_devnode(spu), "vicinity", &lenp); - for (i=0; i < (lenp / sizeof(phandle)); i++) { - if (vic_handles[i] == target->linux_phandle) - return spu; - } - } - return NULL; -} - -static void init_aff_fw_vicinity_node(int cbe) -{ - struct spu *spu, *last_spu; - struct device_node *vic_dn, *last_spu_dn; - phandle avoid_ph; - const phandle *vic_handles; - const char *name; - int lenp, i, added, mem_aff; - - last_spu = list_entry(cbe_spu_info[cbe].spus.next, struct spu, cbe_list); - avoid_ph = 0; - for (added = 1; added < cbe_spu_info[cbe].n_spus; added++) { - last_spu_dn = spu_devnode(last_spu); - vic_handles = get_property(last_spu_dn, "vicinity", &lenp); - - for (i = 0; i < (lenp / sizeof(phandle)); i++) { - if (vic_handles[i] == avoid_ph) - continue; - - vic_dn = of_find_node_by_phandle(vic_handles[i]); - if (!vic_dn) - continue; - - name = get_property(vic_dn, "name", NULL); - if (strcmp(name, "spe") == 0) { - spu = aff_devnode_spu(cbe, vic_dn); - avoid_ph = last_spu_dn->linux_phandle; - } - else { - mem_aff = strcmp(name, "mic-tm") == 0; - spu = aff_node_next_to(cbe, vic_dn, last_spu_dn); - if (!spu) - continue; - if (mem_aff) { - last_spu->has_mem_affinity = 1; - spu->has_mem_affinity = 1; - } - avoid_ph = vic_dn->linux_phandle; - } - list_add_tail(&spu->aff_list, &last_spu->aff_list); - last_spu = spu; - break; - } - } -} - -static void init_aff_fw_vicinity(void) -{ - int cbe; - - /* sets has_mem_affinity for each spu, as long as the - * spu->aff_list list, linking each spu to its neighbors - */ - for (cbe = 0; cbe < MAX_NUMNODES; cbe++) - init_aff_fw_vicinity_node(cbe); -} - static int __init init_spu_base(void) { int i, ret = 0; - for (i = 0; i < MAX_NUMNODES; i++) { - mutex_init(&cbe_spu_info[i].list_mutex); - INIT_LIST_HEAD(&cbe_spu_info[i].spus); - } + for (i = 0; i < MAX_NUMNODES; i++) + INIT_LIST_HEAD(&spu_list[i]); if (!spu_management_ops) goto out; @@ -805,25 +675,16 @@ static int __init init_spu_base(void) fb_append_extra_logo(&logo_spe_clut224, ret); } - mutex_lock(&spu_full_list_mutex); xmon_register_spus(&spu_full_list); - crash_register_spus(&spu_full_list); - mutex_unlock(&spu_full_list_mutex); - spu_add_sysdev_attr(&attr_stat); - if (of_has_vicinity()) { - init_aff_fw_vicinity(); - } else { - long root = of_get_flat_dt_root(); - if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) - init_aff_QS20_harcoded(); - } + spu_add_sysdev_attr(&attr_stat); return 0; out_unregister_sysdev_class: sysdev_class_unregister(&spu_sysdev_class); out: + return ret; } module_init(init_spu_base); diff --git a/trunk/arch/powerpc/platforms/cell/spu_syscalls.c b/trunk/arch/powerpc/platforms/cell/spu_syscalls.c index dd2c6688c8aa..261b507a901a 100644 --- a/trunk/arch/powerpc/platforms/cell/spu_syscalls.c +++ b/trunk/arch/powerpc/platforms/cell/spu_syscalls.c @@ -34,27 +34,14 @@ struct spufs_calls spufs_calls = { * this file is not used and the syscalls directly enter the fs code */ asmlinkage long sys_spu_create(const char __user *name, - unsigned int flags, mode_t mode, int neighbor_fd) + unsigned int flags, mode_t mode) { long ret; struct module *owner = spufs_calls.owner; - struct file *neighbor; - int fput_needed; ret = -ENOSYS; if (owner && try_module_get(owner)) { - if (flags & SPU_CREATE_AFFINITY_SPU) { - neighbor = fget_light(neighbor_fd, &fput_needed); - if (neighbor) { - ret = spufs_calls.create_thread(name, flags, - mode, neighbor); - fput_light(neighbor, fput_needed); - } - } - else { - ret = spufs_calls.create_thread(name, flags, - mode, NULL); - } + ret = spufs_calls.create_thread(name, flags, mode); module_put(owner); } return ret; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/context.c b/trunk/arch/powerpc/platforms/cell/spufs/context.c index 6694f86d7000..6d7bd60f5380 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/context.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/context.c @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -56,12 +55,12 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang) ctx->ops = &spu_backing_ops; ctx->owner = get_task_mm(current); INIT_LIST_HEAD(&ctx->rq); - INIT_LIST_HEAD(&ctx->aff_list); if (gang) spu_gang_add_ctx(gang, ctx); ctx->cpus_allowed = current->cpus_allowed; spu_set_timeslice(ctx); - ctx->stats.util_state = SPU_UTIL_IDLE_LOADED; + ctx->stats.execution_state = SPUCTX_UTIL_USER; + ctx->stats.tstamp = jiffies; atomic_inc(&nr_spu_contexts); goto out; @@ -82,8 +81,6 @@ void destroy_spu_context(struct kref *kref) spu_fini_csa(&ctx->csa); if (ctx->gang) spu_gang_remove_ctx(ctx->gang, ctx); - if (ctx->prof_priv_kref) - kref_put(ctx->prof_priv_kref, ctx->prof_priv_release); BUG_ON(!list_empty(&ctx->rq)); atomic_dec(&nr_spu_contexts); kfree(ctx); @@ -169,39 +166,6 @@ int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags) void spu_acquire_saved(struct spu_context *ctx) { spu_acquire(ctx); - if (ctx->state != SPU_STATE_SAVED) { - set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags); + if (ctx->state != SPU_STATE_SAVED) spu_deactivate(ctx); - } -} - -/** - * spu_release_saved - unlock spu context and return it to the runqueue - * @ctx: context to unlock - */ -void spu_release_saved(struct spu_context *ctx) -{ - BUG_ON(ctx->state != SPU_STATE_SAVED); - - if (test_and_clear_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags)) - spu_activate(ctx, 0); - - spu_release(ctx); } - -void spu_set_profile_private_kref(struct spu_context *ctx, - struct kref *prof_info_kref, - void ( * prof_info_release) (struct kref *kref)) -{ - ctx->prof_priv_kref = prof_info_kref; - ctx->prof_priv_release = prof_info_release; -} -EXPORT_SYMBOL_GPL(spu_set_profile_private_kref); - -void *spu_get_profile_private_kref(struct spu_context *ctx) -{ - return ctx->prof_priv_kref; -} -EXPORT_SYMBOL_GPL(spu_get_profile_private_kref); - - diff --git a/trunk/arch/powerpc/platforms/cell/spufs/coredump.c b/trunk/arch/powerpc/platforms/cell/spufs/coredump.c index 5e31799b1e3f..5d9ad5a0307b 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/coredump.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/coredump.c @@ -226,7 +226,7 @@ static void spufs_arch_write_notes(struct file *file) spu_acquire_saved(ctx_info->ctx); for (j = 0; j < spufs_coredump_num_notes; j++) spufs_arch_write_note(ctx_info, j, file); - spu_release_saved(ctx_info->ctx); + spu_release(ctx_info->ctx); list_del(&ctx_info->list); kfree(ctx_info); } diff --git a/trunk/arch/powerpc/platforms/cell/spufs/fault.c b/trunk/arch/powerpc/platforms/cell/spufs/fault.c index 917eab4be486..f53a07437472 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/fault.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/fault.c @@ -179,14 +179,16 @@ int spufs_handle_class1(struct spu_context *ctx) if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))) return 0; - spuctx_switch_state(ctx, SPU_UTIL_IOWAIT); + spuctx_switch_state(ctx, SPUCTX_UTIL_IOWAIT); pr_debug("ctx %p: ea %016lx, dsisr %016lx state %d\n", ctx, ea, dsisr, ctx->state); ctx->stats.hash_flt++; - if (ctx->state == SPU_STATE_RUNNABLE) + if (ctx->state == SPU_STATE_RUNNABLE) { ctx->spu->stats.hash_flt++; + spu_switch_state(ctx->spu, SPU_UTIL_IOWAIT); + } /* we must not hold the lock when entering spu_handle_mm_fault */ spu_release(ctx); @@ -224,7 +226,7 @@ int spufs_handle_class1(struct spu_context *ctx) } else spufs_handle_dma_error(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE); - spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); + spuctx_switch_state(ctx, SPUCTX_UTIL_SYSTEM); return ret; } EXPORT_SYMBOL_GPL(spufs_handle_class1); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/file.c b/trunk/arch/powerpc/platforms/cell/spufs/file.c index 7de4e919687b..c2814ea96af2 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/file.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/file.c @@ -370,7 +370,7 @@ spufs_regs_read(struct file *file, char __user *buffer, spu_acquire_saved(ctx); ret = __spufs_regs_read(ctx, buffer, size, pos); - spu_release_saved(ctx); + spu_release(ctx); return ret; } @@ -392,7 +392,7 @@ spufs_regs_write(struct file *file, const char __user *buffer, ret = copy_from_user(lscsa->gprs + *pos - size, buffer, size) ? -EFAULT : size; - spu_release_saved(ctx); + spu_release(ctx); return ret; } @@ -421,7 +421,7 @@ spufs_fpcr_read(struct file *file, char __user * buffer, spu_acquire_saved(ctx); ret = __spufs_fpcr_read(ctx, buffer, size, pos); - spu_release_saved(ctx); + spu_release(ctx); return ret; } @@ -443,7 +443,7 @@ spufs_fpcr_write(struct file *file, const char __user * buffer, ret = copy_from_user((char *)&lscsa->fpcr + *pos - size, buffer, size) ? -EFAULT : size; - spu_release_saved(ctx); + spu_release(ctx); return ret; } @@ -868,7 +868,7 @@ static ssize_t spufs_signal1_read(struct file *file, char __user *buf, spu_acquire_saved(ctx); ret = __spufs_signal1_read(ctx, buf, len, pos); - spu_release_saved(ctx); + spu_release(ctx); return ret; } @@ -934,13 +934,6 @@ static const struct file_operations spufs_signal1_fops = { .mmap = spufs_signal1_mmap, }; -static const struct file_operations spufs_signal1_nosched_fops = { - .open = spufs_signal1_open, - .release = spufs_signal1_release, - .write = spufs_signal1_write, - .mmap = spufs_signal1_mmap, -}; - static int spufs_signal2_open(struct inode *inode, struct file *file) { struct spufs_inode_info *i = SPUFS_I(inode); @@ -999,7 +992,7 @@ static ssize_t spufs_signal2_read(struct file *file, char __user *buf, spu_acquire_saved(ctx); ret = __spufs_signal2_read(ctx, buf, len, pos); - spu_release_saved(ctx); + spu_release(ctx); return ret; } @@ -1069,13 +1062,6 @@ static const struct file_operations spufs_signal2_fops = { .mmap = spufs_signal2_mmap, }; -static const struct file_operations spufs_signal2_nosched_fops = { - .open = spufs_signal2_open, - .release = spufs_signal2_release, - .write = spufs_signal2_write, - .mmap = spufs_signal2_mmap, -}; - static void spufs_signal1_type_set(void *data, u64 val) { struct spu_context *ctx = data; @@ -1626,7 +1612,7 @@ static void spufs_decr_set(void *data, u64 val) struct spu_lscsa *lscsa = ctx->csa.lscsa; spu_acquire_saved(ctx); lscsa->decr.slot[0] = (u32) val; - spu_release_saved(ctx); + spu_release(ctx); } static u64 __spufs_decr_get(void *data) @@ -1642,7 +1628,7 @@ static u64 spufs_decr_get(void *data) u64 ret; spu_acquire_saved(ctx); ret = __spufs_decr_get(data); - spu_release_saved(ctx); + spu_release(ctx); return ret; } DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set, @@ -1651,21 +1637,17 @@ DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set, static void spufs_decr_status_set(void *data, u64 val) { struct spu_context *ctx = data; + struct spu_lscsa *lscsa = ctx->csa.lscsa; spu_acquire_saved(ctx); - if (val) - ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING; - else - ctx->csa.priv2.mfc_control_RW &= ~MFC_CNTL_DECREMENTER_RUNNING; - spu_release_saved(ctx); + lscsa->decr_status.slot[0] = (u32) val; + spu_release(ctx); } static u64 __spufs_decr_status_get(void *data) { struct spu_context *ctx = data; - if (ctx->csa.priv2.mfc_control_RW & MFC_CNTL_DECREMENTER_RUNNING) - return SPU_DECR_STATUS_RUNNING; - else - return 0; + struct spu_lscsa *lscsa = ctx->csa.lscsa; + return lscsa->decr_status.slot[0]; } static u64 spufs_decr_status_get(void *data) @@ -1674,7 +1656,7 @@ static u64 spufs_decr_status_get(void *data) u64 ret; spu_acquire_saved(ctx); ret = __spufs_decr_status_get(data); - spu_release_saved(ctx); + spu_release(ctx); return ret; } DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get, @@ -1686,7 +1668,7 @@ static void spufs_event_mask_set(void *data, u64 val) struct spu_lscsa *lscsa = ctx->csa.lscsa; spu_acquire_saved(ctx); lscsa->event_mask.slot[0] = (u32) val; - spu_release_saved(ctx); + spu_release(ctx); } static u64 __spufs_event_mask_get(void *data) @@ -1702,7 +1684,7 @@ static u64 spufs_event_mask_get(void *data) u64 ret; spu_acquire_saved(ctx); ret = __spufs_event_mask_get(data); - spu_release_saved(ctx); + spu_release(ctx); return ret; } DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get, @@ -1726,7 +1708,7 @@ static u64 spufs_event_status_get(void *data) spu_acquire_saved(ctx); ret = __spufs_event_status_get(data); - spu_release_saved(ctx); + spu_release(ctx); return ret; } DEFINE_SIMPLE_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get, @@ -1738,7 +1720,7 @@ static void spufs_srr0_set(void *data, u64 val) struct spu_lscsa *lscsa = ctx->csa.lscsa; spu_acquire_saved(ctx); lscsa->srr0.slot[0] = (u32) val; - spu_release_saved(ctx); + spu_release(ctx); } static u64 spufs_srr0_get(void *data) @@ -1748,7 +1730,7 @@ static u64 spufs_srr0_get(void *data) u64 ret; spu_acquire_saved(ctx); ret = lscsa->srr0.slot[0]; - spu_release_saved(ctx); + spu_release(ctx); return ret; } DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set, @@ -1804,7 +1786,7 @@ static u64 spufs_lslr_get(void *data) spu_acquire_saved(ctx); ret = __spufs_lslr_get(data); - spu_release_saved(ctx); + spu_release(ctx); return ret; } @@ -1868,7 +1850,7 @@ static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf, spin_lock(&ctx->csa.register_lock); ret = __spufs_mbox_info_read(ctx, buf, len, pos); spin_unlock(&ctx->csa.register_lock); - spu_release_saved(ctx); + spu_release(ctx); return ret; } @@ -1906,7 +1888,7 @@ static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf, spin_lock(&ctx->csa.register_lock); ret = __spufs_ibox_info_read(ctx, buf, len, pos); spin_unlock(&ctx->csa.register_lock); - spu_release_saved(ctx); + spu_release(ctx); return ret; } @@ -1947,7 +1929,7 @@ static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf, spin_lock(&ctx->csa.register_lock); ret = __spufs_wbox_info_read(ctx, buf, len, pos); spin_unlock(&ctx->csa.register_lock); - spu_release_saved(ctx); + spu_release(ctx); return ret; } @@ -1997,7 +1979,7 @@ static ssize_t spufs_dma_info_read(struct file *file, char __user *buf, spin_lock(&ctx->csa.register_lock); ret = __spufs_dma_info_read(ctx, buf, len, pos); spin_unlock(&ctx->csa.register_lock); - spu_release_saved(ctx); + spu_release(ctx); return ret; } @@ -2048,7 +2030,7 @@ static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf, spin_lock(&ctx->csa.register_lock); ret = __spufs_proxydma_info_read(ctx, buf, len, pos); spin_unlock(&ctx->csa.register_lock); - spu_release_saved(ctx); + spu_release(ctx); return ret; } @@ -2083,26 +2065,14 @@ static const char *ctx_state_names[] = { }; static unsigned long long spufs_acct_time(struct spu_context *ctx, - enum spu_utilization_state state) + enum spuctx_execution_state state) { - struct timespec ts; - unsigned long long time = ctx->stats.times[state]; + unsigned long time = ctx->stats.times[state]; - /* - * In general, utilization statistics are updated by the controlling - * thread as the spu context moves through various well defined - * state transitions, but if the context is lazily loaded its - * utilization statistics are not updated as the controlling thread - * is not tightly coupled with the execution of the spu context. We - * calculate and apply the time delta from the last recorded state - * of the spu context. - */ - if (ctx->spu && ctx->stats.util_state == state) { - ktime_get_ts(&ts); - time += timespec_to_ns(&ts) - ctx->stats.tstamp; - } + if (ctx->stats.execution_state == state) + time += jiffies - ctx->stats.tstamp; - return time / NSEC_PER_MSEC; + return jiffies_to_msecs(time); } static unsigned long long spufs_slb_flts(struct spu_context *ctx) @@ -2137,11 +2107,11 @@ static int spufs_show_stat(struct seq_file *s, void *private) spu_acquire(ctx); seq_printf(s, "%s %llu %llu %llu %llu " "%llu %llu %llu %llu %llu %llu %llu %llu\n", - ctx_state_names[ctx->stats.util_state], - spufs_acct_time(ctx, SPU_UTIL_USER), - spufs_acct_time(ctx, SPU_UTIL_SYSTEM), - spufs_acct_time(ctx, SPU_UTIL_IOWAIT), - spufs_acct_time(ctx, SPU_UTIL_IDLE_LOADED), + ctx_state_names[ctx->stats.execution_state], + spufs_acct_time(ctx, SPUCTX_UTIL_USER), + spufs_acct_time(ctx, SPUCTX_UTIL_SYSTEM), + spufs_acct_time(ctx, SPUCTX_UTIL_IOWAIT), + spufs_acct_time(ctx, SPUCTX_UTIL_LOADED), ctx->stats.vol_ctx_switch, ctx->stats.invol_ctx_switch, spufs_slb_flts(ctx), @@ -2214,8 +2184,8 @@ struct tree_descr spufs_dir_nosched_contents[] = { { "mbox_stat", &spufs_mbox_stat_fops, 0444, }, { "ibox_stat", &spufs_ibox_stat_fops, 0444, }, { "wbox_stat", &spufs_wbox_stat_fops, 0444, }, - { "signal1", &spufs_signal1_nosched_fops, 0222, }, - { "signal2", &spufs_signal2_nosched_fops, 0222, }, + { "signal1", &spufs_signal1_fops, 0666, }, + { "signal2", &spufs_signal2_fops, 0666, }, { "signal1_type", &spufs_signal1_type, 0666, }, { "signal2_type", &spufs_signal2_type, 0666, }, { "mss", &spufs_mss_fops, 0666, }, diff --git a/trunk/arch/powerpc/platforms/cell/spufs/gang.c b/trunk/arch/powerpc/platforms/cell/spufs/gang.c index 71a443253021..212ea78f9051 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/gang.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/gang.c @@ -35,9 +35,7 @@ struct spu_gang *alloc_spu_gang(void) kref_init(&gang->kref); mutex_init(&gang->mutex); - mutex_init(&gang->aff_mutex); INIT_LIST_HEAD(&gang->list); - INIT_LIST_HEAD(&gang->aff_list_head); out: return gang; @@ -75,10 +73,6 @@ void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx) { mutex_lock(&gang->mutex); WARN_ON(ctx->gang != gang); - if (!list_empty(&ctx->aff_list)) { - list_del_init(&ctx->aff_list); - gang->aff_flags &= ~AFF_OFFSETS_SET; - } list_del_init(&ctx->gang_list); gang->contexts--; mutex_unlock(&gang->mutex); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index b3d0dd118dd0..7eb4d6cbcb74 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -316,107 +316,11 @@ static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt) return ret; } -static struct spu_context * -spufs_assert_affinity(unsigned int flags, struct spu_gang *gang, - struct file *filp) -{ - struct spu_context *tmp, *neighbor; - int count, node; - int aff_supp; - - aff_supp = !list_empty(&(list_entry(cbe_spu_info[0].spus.next, - struct spu, cbe_list))->aff_list); - - if (!aff_supp) - return ERR_PTR(-EINVAL); - - if (flags & SPU_CREATE_GANG) - return ERR_PTR(-EINVAL); - - if (flags & SPU_CREATE_AFFINITY_MEM && - gang->aff_ref_ctx && - gang->aff_ref_ctx->flags & SPU_CREATE_AFFINITY_MEM) - return ERR_PTR(-EEXIST); - - if (gang->aff_flags & AFF_MERGED) - return ERR_PTR(-EBUSY); - - neighbor = NULL; - if (flags & SPU_CREATE_AFFINITY_SPU) { - if (!filp || filp->f_op != &spufs_context_fops) - return ERR_PTR(-EINVAL); - - neighbor = get_spu_context( - SPUFS_I(filp->f_dentry->d_inode)->i_ctx); - - if (!list_empty(&neighbor->aff_list) && !(neighbor->aff_head) && - !list_is_last(&neighbor->aff_list, &gang->aff_list_head) && - !list_entry(neighbor->aff_list.next, struct spu_context, - aff_list)->aff_head) - return ERR_PTR(-EEXIST); - - if (gang != neighbor->gang) - return ERR_PTR(-EINVAL); - - count = 1; - list_for_each_entry(tmp, &gang->aff_list_head, aff_list) - count++; - if (list_empty(&neighbor->aff_list)) - count++; - - for (node = 0; node < MAX_NUMNODES; node++) { - if ((cbe_spu_info[node].n_spus - atomic_read( - &cbe_spu_info[node].reserved_spus)) >= count) - break; - } - - if (node == MAX_NUMNODES) - return ERR_PTR(-EEXIST); - } - - return neighbor; -} - -static void -spufs_set_affinity(unsigned int flags, struct spu_context *ctx, - struct spu_context *neighbor) -{ - if (flags & SPU_CREATE_AFFINITY_MEM) - ctx->gang->aff_ref_ctx = ctx; - - if (flags & SPU_CREATE_AFFINITY_SPU) { - if (list_empty(&neighbor->aff_list)) { - list_add_tail(&neighbor->aff_list, - &ctx->gang->aff_list_head); - neighbor->aff_head = 1; - } - - if (list_is_last(&neighbor->aff_list, &ctx->gang->aff_list_head) - || list_entry(neighbor->aff_list.next, struct spu_context, - aff_list)->aff_head) { - list_add(&ctx->aff_list, &neighbor->aff_list); - } else { - list_add_tail(&ctx->aff_list, &neighbor->aff_list); - if (neighbor->aff_head) { - neighbor->aff_head = 0; - ctx->aff_head = 1; - } - } - - if (!ctx->gang->aff_ref_ctx) - ctx->gang->aff_ref_ctx = ctx; - } -} - -static int -spufs_create_context(struct inode *inode, struct dentry *dentry, - struct vfsmount *mnt, int flags, int mode, - struct file *aff_filp) +static int spufs_create_context(struct inode *inode, + struct dentry *dentry, + struct vfsmount *mnt, int flags, int mode) { int ret; - int affinity; - struct spu_gang *gang; - struct spu_context *neighbor; ret = -EPERM; if ((flags & SPU_CREATE_NOSCHED) && @@ -432,29 +336,9 @@ spufs_create_context(struct inode *inode, struct dentry *dentry, if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader) goto out_unlock; - gang = NULL; - neighbor = NULL; - affinity = flags & (SPU_CREATE_AFFINITY_MEM | SPU_CREATE_AFFINITY_SPU); - if (affinity) { - gang = SPUFS_I(inode)->i_gang; - ret = -EINVAL; - if (!gang) - goto out_unlock; - mutex_lock(&gang->aff_mutex); - neighbor = spufs_assert_affinity(flags, gang, aff_filp); - if (IS_ERR(neighbor)) { - ret = PTR_ERR(neighbor); - goto out_aff_unlock; - } - } - ret = spufs_mkdir(inode, dentry, flags, mode & S_IRWXUGO); if (ret) - goto out_aff_unlock; - - if (affinity) - spufs_set_affinity(flags, SPUFS_I(dentry->d_inode)->i_ctx, - neighbor); + goto out_unlock; /* * get references for dget and mntget, will be released @@ -468,9 +352,6 @@ spufs_create_context(struct inode *inode, struct dentry *dentry, goto out; } -out_aff_unlock: - if (affinity) - mutex_unlock(&gang->aff_mutex); out_unlock: mutex_unlock(&inode->i_mutex); out: @@ -569,8 +450,7 @@ static int spufs_create_gang(struct inode *inode, static struct file_system_type spufs_type; -long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode, - struct file *filp) +long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode) { struct dentry *dentry; int ret; @@ -607,7 +487,7 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode, dentry, nd->mnt, mode); else return spufs_create_context(nd->dentry->d_inode, - dentry, nd->mnt, flags, mode, filp); + dentry, nd->mnt, flags, mode); out_dput: dput(dentry); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/run.c b/trunk/arch/powerpc/platforms/cell/spufs/run.c index 0b50fa5cb39d..58ae13b7de84 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/run.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/run.c @@ -18,17 +18,15 @@ void spufs_stop_callback(struct spu *spu) wake_up_all(&ctx->stop_wq); } -static inline int spu_stopped(struct spu_context *ctx, u32 *stat) +static inline int spu_stopped(struct spu_context *ctx, u32 * stat) { struct spu *spu; u64 pte_fault; *stat = ctx->ops->status_read(ctx); - - spu = ctx->spu; - if (ctx->state != SPU_STATE_RUNNABLE || - test_bit(SPU_SCHED_NOTIFY_ACTIVE, &ctx->sched_flags)) + if (ctx->state != SPU_STATE_RUNNABLE) return 1; + spu = ctx->spu; pte_fault = spu->dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED); return (!(*stat & SPU_STATUS_RUNNING) || pte_fault || spu->class_0_pending) ? @@ -126,10 +124,8 @@ static int spu_setup_isolated(struct spu_context *ctx) return ret; } -static int spu_run_init(struct spu_context *ctx, u32 *npc) +static int spu_run_init(struct spu_context *ctx, u32 * npc) { - spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); - if (ctx->flags & SPU_CREATE_ISOLATE) { unsigned long runcntl; @@ -155,20 +151,16 @@ static int spu_run_init(struct spu_context *ctx, u32 *npc) ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE); } - spuctx_switch_state(ctx, SPU_UTIL_USER); - return 0; } -static int spu_run_fini(struct spu_context *ctx, u32 *npc, - u32 *status) +static int spu_run_fini(struct spu_context *ctx, u32 * npc, + u32 * status) { int ret = 0; *status = ctx->ops->status_read(ctx); *npc = ctx->ops->npc_read(ctx); - - spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); spu_release(ctx); if (signal_pending(current)) @@ -297,10 +289,10 @@ static inline int spu_process_events(struct spu_context *ctx) return ret; } -long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event) +long spufs_run_spu(struct file *file, struct spu_context *ctx, + u32 *npc, u32 *event) { int ret; - struct spu *spu; u32 status; if (mutex_lock_interruptible(&ctx->run_mutex)) @@ -336,17 +328,6 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event) ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, &status)); if (unlikely(ret)) break; - spu = ctx->spu; - if (unlikely(test_and_clear_bit(SPU_SCHED_NOTIFY_ACTIVE, - &ctx->sched_flags))) { - if (!(status & SPU_STATUS_STOPPED_BY_STOP)) { - spu_switch_notify(spu, ctx); - continue; - } - } - - spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); - if ((status & SPU_STATUS_STOPPED_BY_STOP) && (status >> SPU_STOP_STATUS_SHIFT == 0x2104)) { ret = spu_process_callback(ctx); @@ -375,7 +356,6 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event) (ctx->state == SPU_STATE_RUNNABLE)) ctx->stats.libassist++; - ctx->ops->master_stop(ctx); ret = spu_run_fini(ctx, npc, &status); spu_yield(ctx); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/sched.c b/trunk/arch/powerpc/platforms/cell/spufs/sched.c index 227968b4779d..e5b4dd1db286 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/sched.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/sched.c @@ -51,6 +51,9 @@ struct spu_prio_array { DECLARE_BITMAP(bitmap, MAX_PRIO); struct list_head runq[MAX_PRIO]; spinlock_t runq_lock; + struct list_head active_list[MAX_NUMNODES]; + struct mutex active_mutex[MAX_NUMNODES]; + int nr_active[MAX_NUMNODES]; int nr_waiting; }; @@ -124,7 +127,7 @@ void __spu_update_sched_info(struct spu_context *ctx) ctx->policy = current->policy; /* - * A lot of places that don't hold list_mutex poke into + * A lot of places that don't hold active_mutex poke into * cpus_allowed, including grab_runnable_context which * already holds the runq_lock. So abuse runq_lock * to protect this field aswell. @@ -138,9 +141,9 @@ void spu_update_sched_info(struct spu_context *ctx) { int node = ctx->spu->node; - mutex_lock(&cbe_spu_info[node].list_mutex); + mutex_lock(&spu_prio->active_mutex[node]); __spu_update_sched_info(ctx); - mutex_unlock(&cbe_spu_info[node].list_mutex); + mutex_unlock(&spu_prio->active_mutex[node]); } static int __node_allowed(struct spu_context *ctx, int node) @@ -166,56 +169,56 @@ static int node_allowed(struct spu_context *ctx, int node) return rval; } -static BLOCKING_NOTIFIER_HEAD(spu_switch_notifier); +/** + * spu_add_to_active_list - add spu to active list + * @spu: spu to add to the active list + */ +static void spu_add_to_active_list(struct spu *spu) +{ + int node = spu->node; -void spu_switch_notify(struct spu *spu, struct spu_context *ctx) + mutex_lock(&spu_prio->active_mutex[node]); + spu_prio->nr_active[node]++; + list_add_tail(&spu->list, &spu_prio->active_list[node]); + mutex_unlock(&spu_prio->active_mutex[node]); +} + +static void __spu_remove_from_active_list(struct spu *spu) { - blocking_notifier_call_chain(&spu_switch_notifier, - ctx ? ctx->object_id : 0, spu); + list_del_init(&spu->list); + spu_prio->nr_active[spu->node]--; } -static void notify_spus_active(void) +/** + * spu_remove_from_active_list - remove spu from active list + * @spu: spu to remove from the active list + */ +static void spu_remove_from_active_list(struct spu *spu) { - int node; + int node = spu->node; - /* - * Wake up the active spu_contexts. - * - * When the awakened processes see their "notify_active" flag is set, - * they will call spu_switch_notify(); - */ - for_each_online_node(node) { - struct spu *spu; + mutex_lock(&spu_prio->active_mutex[node]); + __spu_remove_from_active_list(spu); + mutex_unlock(&spu_prio->active_mutex[node]); +} - mutex_lock(&cbe_spu_info[node].list_mutex); - list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) { - if (spu->alloc_state != SPU_FREE) { - struct spu_context *ctx = spu->ctx; - set_bit(SPU_SCHED_NOTIFY_ACTIVE, - &ctx->sched_flags); - mb(); - wake_up_all(&ctx->stop_wq); - } - } - mutex_unlock(&cbe_spu_info[node].list_mutex); - } +static BLOCKING_NOTIFIER_HEAD(spu_switch_notifier); + +static void spu_switch_notify(struct spu *spu, struct spu_context *ctx) +{ + blocking_notifier_call_chain(&spu_switch_notifier, + ctx ? ctx->object_id : 0, spu); } int spu_switch_event_register(struct notifier_block * n) { - int ret; - ret = blocking_notifier_chain_register(&spu_switch_notifier, n); - if (!ret) - notify_spus_active(); - return ret; + return blocking_notifier_chain_register(&spu_switch_notifier, n); } -EXPORT_SYMBOL_GPL(spu_switch_event_register); int spu_switch_event_unregister(struct notifier_block * n) { return blocking_notifier_chain_unregister(&spu_switch_notifier, n); } -EXPORT_SYMBOL_GPL(spu_switch_event_unregister); /** * spu_bind_context - bind spu context to physical spu @@ -226,12 +229,6 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx) { pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid, spu->number, spu->node); - spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); - - if (ctx->flags & SPU_CREATE_NOSCHED) - atomic_inc(&cbe_spu_info[spu->node].reserved_spus); - if (!list_empty(&ctx->aff_list)) - atomic_inc(&ctx->gang->aff_sched_count); ctx->stats.slb_flt_base = spu->stats.slb_flt; ctx->stats.class2_intr_base = spu->stats.class2_intr; @@ -241,7 +238,6 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx) ctx->spu = spu; ctx->ops = &spu_hw_ops; spu->pid = current->pid; - spu->tgid = current->tgid; spu_associate_mm(spu, ctx->owner); spu->ibox_callback = spufs_ibox_callback; spu->wbox_callback = spufs_wbox_callback; @@ -255,153 +251,7 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx) spu_cpu_affinity_set(spu, raw_smp_processor_id()); spu_switch_notify(spu, ctx); ctx->state = SPU_STATE_RUNNABLE; - - spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); -} - -/* - * Must be used with the list_mutex held. - */ -static inline int sched_spu(struct spu *spu) -{ - BUG_ON(!mutex_is_locked(&cbe_spu_info[spu->node].list_mutex)); - - return (!spu->ctx || !(spu->ctx->flags & SPU_CREATE_NOSCHED)); -} - -static void aff_merge_remaining_ctxs(struct spu_gang *gang) -{ - struct spu_context *ctx; - - list_for_each_entry(ctx, &gang->aff_list_head, aff_list) { - if (list_empty(&ctx->aff_list)) - list_add(&ctx->aff_list, &gang->aff_list_head); - } - gang->aff_flags |= AFF_MERGED; -} - -static void aff_set_offsets(struct spu_gang *gang) -{ - struct spu_context *ctx; - int offset; - - offset = -1; - list_for_each_entry_reverse(ctx, &gang->aff_ref_ctx->aff_list, - aff_list) { - if (&ctx->aff_list == &gang->aff_list_head) - break; - ctx->aff_offset = offset--; - } - - offset = 0; - list_for_each_entry(ctx, gang->aff_ref_ctx->aff_list.prev, aff_list) { - if (&ctx->aff_list == &gang->aff_list_head) - break; - ctx->aff_offset = offset++; - } - - gang->aff_flags |= AFF_OFFSETS_SET; -} - -static struct spu *aff_ref_location(struct spu_context *ctx, int mem_aff, - int group_size, int lowest_offset) -{ - struct spu *spu; - int node, n; - - /* - * TODO: A better algorithm could be used to find a good spu to be - * used as reference location for the ctxs chain. - */ - node = cpu_to_node(raw_smp_processor_id()); - for (n = 0; n < MAX_NUMNODES; n++, node++) { - node = (node < MAX_NUMNODES) ? node : 0; - if (!node_allowed(ctx, node)) - continue; - mutex_lock(&cbe_spu_info[node].list_mutex); - list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) { - if ((!mem_aff || spu->has_mem_affinity) && - sched_spu(spu)) { - mutex_unlock(&cbe_spu_info[node].list_mutex); - return spu; - } - } - mutex_unlock(&cbe_spu_info[node].list_mutex); - } - return NULL; -} - -static void aff_set_ref_point_location(struct spu_gang *gang) -{ - int mem_aff, gs, lowest_offset; - struct spu_context *ctx; - struct spu *tmp; - - mem_aff = gang->aff_ref_ctx->flags & SPU_CREATE_AFFINITY_MEM; - lowest_offset = 0; - gs = 0; - - list_for_each_entry(tmp, &gang->aff_list_head, aff_list) - gs++; - - list_for_each_entry_reverse(ctx, &gang->aff_ref_ctx->aff_list, - aff_list) { - if (&ctx->aff_list == &gang->aff_list_head) - break; - lowest_offset = ctx->aff_offset; - } - - gang->aff_ref_spu = aff_ref_location(ctx, mem_aff, gs, lowest_offset); -} - -static struct spu *ctx_location(struct spu *ref, int offset, int node) -{ - struct spu *spu; - - spu = NULL; - if (offset >= 0) { - list_for_each_entry(spu, ref->aff_list.prev, aff_list) { - BUG_ON(spu->node != node); - if (offset == 0) - break; - if (sched_spu(spu)) - offset--; - } - } else { - list_for_each_entry_reverse(spu, ref->aff_list.next, aff_list) { - BUG_ON(spu->node != node); - if (offset == 0) - break; - if (sched_spu(spu)) - offset++; - } - } - - return spu; -} - -/* - * affinity_check is called each time a context is going to be scheduled. - * It returns the spu ptr on which the context must run. - */ -static int has_affinity(struct spu_context *ctx) -{ - struct spu_gang *gang = ctx->gang; - - if (list_empty(&ctx->aff_list)) - return 0; - - mutex_lock(&gang->aff_mutex); - if (!gang->aff_ref_spu) { - if (!(gang->aff_flags & AFF_MERGED)) - aff_merge_remaining_ctxs(gang); - if (!(gang->aff_flags & AFF_OFFSETS_SET)) - aff_set_offsets(gang); - aff_set_ref_point_location(gang); - } - mutex_unlock(&gang->aff_mutex); - - return gang->aff_ref_spu != NULL; + spu_switch_state(spu, SPU_UTIL_SYSTEM); } /** @@ -413,13 +263,9 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) { pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__, spu->pid, spu->number, spu->node); - spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); - if (spu->ctx->flags & SPU_CREATE_NOSCHED) - atomic_dec(&cbe_spu_info[spu->node].reserved_spus); - if (!list_empty(&ctx->aff_list)) - if (atomic_dec_and_test(&ctx->gang->aff_sched_count)) - ctx->gang->aff_ref_spu = NULL; + spu_switch_state(spu, SPU_UTIL_IDLE); + spu_switch_notify(spu, NULL); spu_unmap_mappings(ctx); spu_save(&ctx->csa, spu); @@ -432,8 +278,8 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) spu->dma_callback = NULL; spu_associate_mm(spu, NULL); spu->pid = 0; - spu->tgid = 0; ctx->ops = &spu_backing_ops; + ctx->spu = NULL; spu->flags = 0; spu->ctx = NULL; @@ -441,10 +287,6 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) (spu->stats.slb_flt - ctx->stats.slb_flt_base); ctx->stats.class2_intr += (spu->stats.class2_intr - ctx->stats.class2_intr_base); - - /* This maps the underlying spu state to idle */ - spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); - ctx->spu = NULL; } /** @@ -510,41 +352,18 @@ static void spu_prio_wait(struct spu_context *ctx) static struct spu *spu_get_idle(struct spu_context *ctx) { - struct spu *spu; - int node, n; - - if (has_affinity(ctx)) { - node = ctx->gang->aff_ref_spu->node; + struct spu *spu = NULL; + int node = cpu_to_node(raw_smp_processor_id()); + int n; - mutex_lock(&cbe_spu_info[node].list_mutex); - spu = ctx_location(ctx->gang->aff_ref_spu, ctx->aff_offset, node); - if (spu && spu->alloc_state == SPU_FREE) - goto found; - mutex_unlock(&cbe_spu_info[node].list_mutex); - return NULL; - } - - node = cpu_to_node(raw_smp_processor_id()); for (n = 0; n < MAX_NUMNODES; n++, node++) { node = (node < MAX_NUMNODES) ? node : 0; if (!node_allowed(ctx, node)) continue; - - mutex_lock(&cbe_spu_info[node].list_mutex); - list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) { - if (spu->alloc_state == SPU_FREE) - goto found; - } - mutex_unlock(&cbe_spu_info[node].list_mutex); + spu = spu_alloc_node(node); + if (spu) + break; } - - return NULL; - - found: - spu->alloc_state = SPU_USED; - mutex_unlock(&cbe_spu_info[node].list_mutex); - pr_debug("Got SPU %d %d\n", spu->number, spu->node); - spu_init_channels(spu); return spu; } @@ -574,15 +393,15 @@ static struct spu *find_victim(struct spu_context *ctx) if (!node_allowed(ctx, node)) continue; - mutex_lock(&cbe_spu_info[node].list_mutex); - list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) { + mutex_lock(&spu_prio->active_mutex[node]); + list_for_each_entry(spu, &spu_prio->active_list[node], list) { struct spu_context *tmp = spu->ctx; if (tmp->prio > ctx->prio && (!victim || tmp->prio > victim->prio)) victim = spu->ctx; } - mutex_unlock(&cbe_spu_info[node].list_mutex); + mutex_unlock(&spu_prio->active_mutex[node]); if (victim) { /* @@ -607,11 +426,7 @@ static struct spu *find_victim(struct spu_context *ctx) victim = NULL; goto restart; } - - mutex_lock(&cbe_spu_info[node].list_mutex); - cbe_spu_info[node].nr_active--; - mutex_unlock(&cbe_spu_info[node].list_mutex); - + spu_remove_from_active_list(spu); spu_unbind_context(spu, victim); victim->stats.invol_ctx_switch++; spu->stats.invol_ctx_switch++; @@ -640,6 +455,8 @@ static struct spu *find_victim(struct spu_context *ctx) */ int spu_activate(struct spu_context *ctx, unsigned long flags) { + spuctx_switch_state(ctx, SPUCTX_UTIL_SYSTEM); + do { struct spu *spu; @@ -660,12 +477,8 @@ int spu_activate(struct spu_context *ctx, unsigned long flags) if (!spu && rt_prio(ctx->prio)) spu = find_victim(ctx); if (spu) { - int node = spu->node; - - mutex_lock(&cbe_spu_info[node].list_mutex); spu_bind_context(spu, ctx); - cbe_spu_info[node].nr_active++; - mutex_unlock(&cbe_spu_info[node].list_mutex); + spu_add_to_active_list(spu); return 0; } @@ -687,7 +500,7 @@ static struct spu_context *grab_runnable_context(int prio, int node) int best; spin_lock(&spu_prio->runq_lock); - best = find_first_bit(spu_prio->bitmap, prio); + best = sched_find_first_bit(spu_prio->bitmap); while (best < prio) { struct list_head *rq = &spu_prio->runq[best]; @@ -714,17 +527,11 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio) if (spu) { new = grab_runnable_context(max_prio, spu->node); if (new || force) { - int node = spu->node; - - mutex_lock(&cbe_spu_info[node].list_mutex); + spu_remove_from_active_list(spu); spu_unbind_context(spu, ctx); - spu->alloc_state = SPU_FREE; - cbe_spu_info[node].nr_active--; - mutex_unlock(&cbe_spu_info[node].list_mutex); - ctx->stats.vol_ctx_switch++; spu->stats.vol_ctx_switch++; - + spu_free(spu); if (new) wake_up(&new->stop_wq); } @@ -743,11 +550,21 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio) */ void spu_deactivate(struct spu_context *ctx) { + /* + * We must never reach this for a nosched context, + * but handle the case gracefull instead of panicing. + */ + if (ctx->flags & SPU_CREATE_NOSCHED) { + WARN_ON(1); + return; + } + __spu_deactivate(ctx, 1, MAX_PRIO); + spuctx_switch_state(ctx, SPUCTX_UTIL_USER); } /** - * spu_yield - yield a physical spu if others are waiting + * spu_yield - yield a physical spu if others are waiting * @ctx: spu context to yield * * Check if there is a higher priority context waiting and if yes @@ -758,12 +575,17 @@ void spu_yield(struct spu_context *ctx) { if (!(ctx->flags & SPU_CREATE_NOSCHED)) { mutex_lock(&ctx->state_mutex); - __spu_deactivate(ctx, 0, MAX_PRIO); + if (__spu_deactivate(ctx, 0, MAX_PRIO)) + spuctx_switch_state(ctx, SPUCTX_UTIL_USER); + else { + spuctx_switch_state(ctx, SPUCTX_UTIL_LOADED); + spu_switch_state(ctx->spu, SPU_UTIL_USER); + } mutex_unlock(&ctx->state_mutex); } } -static noinline void spusched_tick(struct spu_context *ctx) +static void spusched_tick(struct spu_context *ctx) { if (ctx->flags & SPU_CREATE_NOSCHED) return; @@ -774,7 +596,7 @@ static noinline void spusched_tick(struct spu_context *ctx) return; /* - * Unfortunately list_mutex ranks outside of state_mutex, so + * Unfortunately active_mutex ranks outside of state_mutex, so * we have to trylock here. If we fail give the context another * tick and try again. */ @@ -784,11 +606,12 @@ static noinline void spusched_tick(struct spu_context *ctx) new = grab_runnable_context(ctx->prio + 1, spu->node); if (new) { + + __spu_remove_from_active_list(spu); spu_unbind_context(spu, ctx); ctx->stats.invol_ctx_switch++; spu->stats.invol_ctx_switch++; - spu->alloc_state = SPU_FREE; - cbe_spu_info[spu->node].nr_active--; + spu_free(spu); wake_up(&new->stop_wq); /* * We need to break out of the wait loop in @@ -809,7 +632,7 @@ static noinline void spusched_tick(struct spu_context *ctx) * * Return the number of tasks currently running or waiting to run. * - * Note that we don't take runq_lock / list_mutex here. Reading + * Note that we don't take runq_lock / active_mutex here. Reading * a single 32bit value is atomic on powerpc, and we don't care * about memory ordering issues here. */ @@ -818,7 +641,7 @@ static unsigned long count_active_contexts(void) int nr_active = 0, node; for (node = 0; node < MAX_NUMNODES; node++) - nr_active += cbe_spu_info[node].nr_active; + nr_active += spu_prio->nr_active[node]; nr_active += spu_prio->nr_waiting; return nr_active; @@ -858,18 +681,19 @@ static void spusched_wake(unsigned long data) static int spusched_thread(void *unused) { - struct spu *spu; + struct spu *spu, *next; int node; while (!kthread_should_stop()) { set_current_state(TASK_INTERRUPTIBLE); schedule(); for (node = 0; node < MAX_NUMNODES; node++) { - mutex_lock(&cbe_spu_info[node].list_mutex); - list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) - if (spu->ctx) - spusched_tick(spu->ctx); - mutex_unlock(&cbe_spu_info[node].list_mutex); + mutex_lock(&spu_prio->active_mutex[node]); + list_for_each_entry_safe(spu, next, + &spu_prio->active_list[node], + list) + spusched_tick(spu->ctx); + mutex_unlock(&spu_prio->active_mutex[node]); } } @@ -927,9 +751,10 @@ int __init spu_sched_init(void) INIT_LIST_HEAD(&spu_prio->runq[i]); __clear_bit(i, spu_prio->bitmap); } + __set_bit(MAX_PRIO, spu_prio->bitmap); for (i = 0; i < MAX_NUMNODES; i++) { - mutex_init(&cbe_spu_info[i].list_mutex); - INIT_LIST_HEAD(&cbe_spu_info[i].spus); + mutex_init(&spu_prio->active_mutex[i]); + INIT_LIST_HEAD(&spu_prio->active_list[i]); } spin_lock_init(&spu_prio->runq_lock); @@ -958,9 +783,9 @@ int __init spu_sched_init(void) return err; } -void spu_sched_exit(void) +void __exit spu_sched_exit(void) { - struct spu *spu; + struct spu *spu, *tmp; int node; remove_proc_entry("spu_loadavg", NULL); @@ -969,11 +794,13 @@ void spu_sched_exit(void) kthread_stop(spusched_task); for (node = 0; node < MAX_NUMNODES; node++) { - mutex_lock(&cbe_spu_info[node].list_mutex); - list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) - if (spu->alloc_state != SPU_FREE) - spu->alloc_state = SPU_FREE; - mutex_unlock(&cbe_spu_info[node].list_mutex); + mutex_lock(&spu_prio->active_mutex[node]); + list_for_each_entry_safe(spu, tmp, &spu_prio->active_list[node], + list) { + list_del_init(&spu->list); + spu_free(spu); + } + mutex_unlock(&spu_prio->active_mutex[node]); } kfree(spu_prio); } diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spu_restore.c b/trunk/arch/powerpc/platforms/cell/spufs/spu_restore.c index 21a9c952d88b..4e19ed7a0756 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/spu_restore.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/spu_restore.c @@ -84,13 +84,13 @@ static inline void restore_decr(void) unsigned int decr_running; unsigned int decr; - /* Restore, Step 6(moved): + /* Restore, Step 6: * If the LSCSA "decrementer running" flag is set * then write the SPU_WrDec channel with the * decrementer value from LSCSA. */ offset = LSCSA_QW_OFFSET(decr_status); - decr_running = regs_spill[offset].slot[0] & SPU_DECR_STATUS_RUNNING; + decr_running = regs_spill[offset].slot[0]; if (decr_running) { offset = LSCSA_QW_OFFSET(decr); decr = regs_spill[offset].slot[0]; @@ -318,10 +318,10 @@ int main() build_dma_list(lscsa_ea); /* Step 3. */ restore_upper_240kb(lscsa_ea); /* Step 4. */ /* Step 5: done by 'exit'. */ + restore_decr(); /* Step 6. */ enqueue_putllc(lscsa_ea); /* Step 7. */ set_tag_update(); /* Step 8. */ read_tag_status(); /* Step 9. */ - restore_decr(); /* moved Step 6. */ read_llar_status(); /* Step 10. */ write_ppu_mb(); /* Step 11. */ write_ppuint_mb(); /* Step 12. */ diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped b/trunk/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped index f383b027e8bf..15183d209b58 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped +++ b/trunk/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped @@ -10,7 +10,7 @@ static unsigned int spu_restore_code[] __attribute__((__aligned__(128))) = { 0x24fd8081, 0x1cd80081, 0x33001180, -0x42034003, +0x42030003, 0x33800284, 0x1c010204, 0x40200000, @@ -24,22 +24,22 @@ static unsigned int spu_restore_code[] __attribute__((__aligned__(128))) = { 0x23fffd84, 0x1c100183, 0x217ffa85, -0x3080b000, -0x3080b201, -0x3080b402, -0x3080b603, -0x3080b804, -0x3080ba05, -0x3080bc06, -0x3080be07, -0x3080c008, -0x3080c209, -0x3080c40a, -0x3080c60b, -0x3080c80c, -0x3080ca0d, -0x3080cc0e, -0x3080ce0f, +0x3080a000, +0x3080a201, +0x3080a402, +0x3080a603, +0x3080a804, +0x3080aa05, +0x3080ac06, +0x3080ae07, +0x3080b008, +0x3080b209, +0x3080b40a, +0x3080b60b, +0x3080b80c, +0x3080ba0d, +0x3080bc0e, +0x3080be0f, 0x00003ffc, 0x00000000, 0x00000000, @@ -48,18 +48,19 @@ static unsigned int spu_restore_code[] __attribute__((__aligned__(128))) = { 0x3ec00083, 0xb0a14103, 0x01a00204, -0x3ec10083, -0x4202c002, -0xb0a14203, -0x21a00802, -0x3fbf028a, -0x3f20050a, -0x3fbe0502, +0x3ec10082, +0x4202800e, +0x04000703, +0xb0a14202, +0x21a00803, +0x3fbf028d, +0x3f20068d, +0x3fbe0682, 0x3fe30102, 0x21a00882, -0x3f82028b, -0x3fe3058b, -0x3fbf0584, +0x3f82028f, +0x3fe3078f, +0x3fbf0784, 0x3f200204, 0x3fbe0204, 0x3fe30204, @@ -74,285 +75,252 @@ static unsigned int spu_restore_code[] __attribute__((__aligned__(128))) = { 0x21a00083, 0x40800082, 0x21a00b02, -0x10002612, -0x42a00003, -0x42074006, -0x1800c204, -0x40a00008, -0x40800789, -0x1c010305, -0x34000302, +0x10002818, +0x42a00002, +0x32800007, +0x4207000c, +0x18008208, +0x40a0000b, +0x4080020a, +0x40800709, +0x00200000, +0x42070002, +0x3ac30384, 0x1cffc489, -0x3ec00303, -0x3ec00287, -0xb0408403, -0x24000302, -0x34000282, -0x1c020306, -0xb0408207, -0x18020204, -0x24000282, -0x217ffa09, -0x04000402, -0x21a00802, -0x3fbe0504, -0x3fe30204, -0x21a00884, -0x42074002, -0x21a00902, -0x40803c03, -0x21a00983, -0x04000485, -0x21a00a05, +0x00200000, +0x18008383, +0x38830382, +0x4cffc486, +0x3ac28185, +0xb0408584, +0x28830382, +0x1c020387, +0x38828182, +0xb0408405, +0x1802c408, +0x28828182, +0x217ff886, +0x04000583, +0x21a00803, +0x3fbe0682, +0x3fe30102, +0x04000106, +0x21a00886, +0x04000603, +0x21a00903, +0x40803c02, +0x21a00982, +0x40800003, +0x04000184, +0x21a00a04, 0x40802202, 0x21a00a82, -0x21a00805, -0x21a00884, -0x3fbf0582, +0x42028005, +0x34208702, +0x21002282, +0x21a00804, +0x21a00886, +0x3fbf0782, 0x3f200102, 0x3fbe0102, 0x3fe30102, 0x21a00902, 0x40804003, 0x21a00983, -0x21a00a05, +0x21a00a04, 0x40805a02, 0x21a00a82, 0x40800083, 0x21a00b83, 0x01a00c02, -0x30809c03, -0x34000182, -0x14004102, -0x21002082, -0x01a00d82, -0x3080a003, -0x34000182, +0x01a00d83, +0x3420c282, 0x21a00e02, -0x3080a203, -0x34000182, -0x21a00f02, -0x3080a403, -0x34000182, -0x77400100, -0x3080a603, -0x34000182, +0x34210283, +0x21a00f03, +0x34200284, +0x77400200, +0x3421c282, 0x21a00702, -0x3080a803, -0x34000182, -0x21a00082, -0x3080aa03, -0x34000182, +0x34218283, +0x21a00083, +0x34214282, 0x21a00b02, -0x4020007f, -0x3080ae02, -0x42004805, -0x3080ac04, -0x34000103, -0x34000202, -0x1cffc183, -0x3b810106, -0x0f608184, -0x42013802, -0x5c020183, -0x38810102, -0x3b810102, -0x21000e83, +0x4200480c, +0x00200000, +0x1c010286, +0x34220284, +0x34220302, +0x0f608203, +0x5c024204, +0x3b81810b, +0x42013c02, +0x00200000, +0x18008185, +0x38808183, +0x3b814182, +0x21004e84, 0x4020007f, 0x35000100, -0x00000470, -0x000002f8, -0x00000430, +0x000004e0, +0x000002a0, +0x000002e8, +0x00000428, 0x00000360, -0x000002f8, +0x000002e8, +0x000004a0, +0x00000468, 0x000003c8, -0x000004a8, -0x00000298, 0x00000360, -0x00200000, 0x409ffe02, 0x30801203, -0x40800208, -0x3ec40084, -0x40800407, -0x3ac20289, -0xb060c104, -0x3ac1c284, +0x40800204, +0x3ec40085, +0x10009c09, +0x3ac10606, +0xb060c105, +0x4020007f, +0x4020007f, 0x20801203, -0x38820282, -0x41004003, -0xb0408189, -0x28820282, -0x3881c282, -0xb0408304, -0x2881c282, -0x00400000, -0x40800003, -0x35000000, -0x30809e03, -0x34000182, +0x38810602, +0xb0408586, +0x28810602, +0x32004180, +0x34204702, 0x21a00382, 0x4020007f, -0x327fde00, +0x327fdc80, 0x409ffe02, 0x30801203, -0x40800206, -0x3ec40084, -0x40800407, -0x40800608, -0x3ac1828a, -0x3ac20289, -0xb060c104, -0x3ac1c284, +0x40800204, +0x3ec40087, +0x40800405, +0x00200000, +0x40800606, +0x3ac10608, +0x3ac14609, +0x3ac1860a, +0xb060c107, 0x20801203, -0x38818282, 0x41004003, -0xb040818a, -0x10005b0b, -0x41201003, -0x28818282, -0x3881c282, -0xb0408184, -0x41193f83, -0x60ffc003, -0x2881c282, -0x38820282, -0xb0408189, -0x28820282, -0x327fef80, -0x409ffe02, -0x30801203, -0x40800207, -0x3ec40086, -0x4120100b, -0x10005b14, -0x40800404, -0x3ac1c289, -0x40800608, -0xb060c106, -0x3ac10286, -0x3ac2028a, -0x20801203, -0x3881c282, +0x38810602, +0x4020007f, +0xb0408188, +0x4020007f, +0x28810602, +0x41201002, +0x38814603, +0x10009c09, +0xb060c109, +0x4020007f, +0x28814603, 0x41193f83, +0x38818602, 0x60ffc003, -0xb0408589, -0x2881c282, -0x38810282, -0xb0408586, -0x28810282, -0x38820282, 0xb040818a, -0x28820282, -0x4020007f, -0x327fe280, +0x28818602, +0x32003080, 0x409ffe02, 0x30801203, -0x40800207, -0x3ec40084, -0x40800408, -0x10005b14, -0x40800609, -0x3ac1c28a, -0x3ac2028b, -0xb060c104, -0x3ac24284, +0x40800204, +0x3ec40087, +0x41201008, +0x10009c14, +0x40800405, +0x3ac10609, +0x40800606, +0x3ac1460a, +0xb060c107, +0x3ac1860b, 0x20801203, -0x41201003, -0x3881c282, -0xb040830a, -0x2881c282, -0x38820282, -0xb040818b, +0x38810602, +0xb0408409, +0x28810602, +0x38814603, +0xb060c40a, +0x4020007f, +0x28814603, 0x41193f83, +0x38818602, 0x60ffc003, -0x28820282, -0x38824282, -0xb0408184, -0x28824282, +0xb040818b, +0x28818602, +0x32002380, +0x409ffe02, +0x30801204, +0x40800205, +0x3ec40083, +0x40800406, +0x3ac14607, +0x3ac18608, +0xb0810103, +0x41004002, +0x20801204, +0x4020007f, +0x38814603, +0x10009c0b, +0xb060c107, 0x4020007f, -0x327fd580, +0x4020007f, +0x28814603, +0x38818602, +0x4020007f, +0x4020007f, +0xb0408588, +0x28818602, +0x4020007f, +0x32001780, 0x409ffe02, -0x1000658e, -0x40800206, +0x1000640e, +0x40800204, 0x30801203, -0x40800407, -0x3ec40084, -0x40800608, -0x3ac1828a, -0x3ac20289, -0xb060c104, -0x3ac1c284, +0x40800405, +0x3ec40087, +0x40800606, +0x3ac10608, +0x3ac14609, +0x3ac1860a, +0xb060c107, 0x20801203, 0x413d8003, -0x38818282, -0x4020007f, -0x327fd800, -0x409ffe03, -0x30801202, -0x40800207, -0x3ec40084, -0x10005b09, -0x3ac1c288, -0xb0408184, +0x38810602, 0x4020007f, +0x327fd780, +0x409ffe02, +0x10007f0c, +0x40800205, +0x30801204, +0x40800406, +0x3ec40083, +0x3ac14607, +0x3ac18608, +0xb0810103, +0x413d8002, +0x20801204, +0x38814603, 0x4020007f, -0x20801202, -0x3881c282, -0xb0408308, -0x2881c282, -0x327fc680, +0x327feb80, 0x409ffe02, -0x1000588b, -0x40800208, 0x30801203, -0x40800407, -0x3ec40084, -0x3ac20289, -0xb060c104, -0x3ac1c284, +0x40800204, +0x3ec40087, +0x40800405, +0x1000650a, +0x40800606, +0x3ac10608, +0x3ac14609, +0x3ac1860a, +0xb060c107, 0x20801203, -0x413d8003, -0x38820282, -0x327fbd80, -0x00200000, -0x00000da0, -0x00000000, -0x00000000, -0x00000000, -0x00000d90, -0x00000000, -0x00000000, -0x00000000, -0x00000db0, -0x00000000, -0x00000000, -0x00000000, -0x00000dc0, -0x00000000, -0x00000000, -0x00000000, -0x00000d80, -0x00000000, -0x00000000, -0x00000000, -0x00000df0, -0x00000000, -0x00000000, -0x00000000, -0x00000de0, -0x00000000, -0x00000000, -0x00000000, -0x00000dd0, -0x00000000, -0x00000000, -0x00000000, -0x00000e04, -0x00000000, -0x00000000, +0x38810602, +0xb0408588, +0x4020007f, +0x327fc980, +0x00400000, +0x40800003, +0x4020007f, +0x35000000, 0x00000000, -0x00000e00, 0x00000000, 0x00000000, 0x00000000, diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spufs.h b/trunk/arch/powerpc/platforms/cell/spufs/spufs.h index 8b20c0c1556f..08b3530288ac 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/trunk/arch/powerpc/platforms/cell/spufs/spufs.h @@ -40,13 +40,17 @@ enum { struct spu_context_ops; struct spu_gang; -enum { - SPU_SCHED_WAS_ACTIVE, /* was active upon spu_acquire_saved() */ -}; - -/* ctx->sched_flags */ -enum { - SPU_SCHED_NOTIFY_ACTIVE, +/* + * This is the state for spu utilization reporting to userspace. + * Because this state is visible to userspace it must never change and needs + * to be kept strictly separate from any internal state kept by the kernel. + */ +enum spuctx_execution_state { + SPUCTX_UTIL_USER = 0, + SPUCTX_UTIL_SYSTEM, + SPUCTX_UTIL_IOWAIT, + SPUCTX_UTIL_LOADED, + SPUCTX_UTIL_MAX }; struct spu_context { @@ -85,8 +89,6 @@ struct spu_context { struct list_head gang_list; struct spu_gang *gang; - struct kref *prof_priv_kref; - void ( * prof_priv_release) (struct kref *kref); /* owner thread */ pid_t tid; @@ -102,9 +104,9 @@ struct spu_context { /* statistics */ struct { /* updates protected by ctx->state_mutex */ - enum spu_utilization_state util_state; - unsigned long long tstamp; /* time of last state switch */ - unsigned long long times[SPU_UTIL_MAX]; + enum spuctx_execution_state execution_state; + unsigned long tstamp; /* time of last ctx switch */ + unsigned long times[SPUCTX_UTIL_MAX]; unsigned long long vol_ctx_switch; unsigned long long invol_ctx_switch; unsigned long long min_flt; @@ -116,10 +118,6 @@ struct spu_context { unsigned long long class2_intr_base; /* # at last ctx switch */ unsigned long long libassist; } stats; - - struct list_head aff_list; - int aff_head; - int aff_offset; }; struct spu_gang { @@ -127,19 +125,8 @@ struct spu_gang { struct mutex mutex; struct kref kref; int contexts; - - struct spu_context *aff_ref_ctx; - struct list_head aff_list_head; - struct mutex aff_mutex; - int aff_flags; - struct spu *aff_ref_spu; - atomic_t aff_sched_count; }; -/* Flag bits for spu_gang aff_flags */ -#define AFF_OFFSETS_SET 1 -#define AFF_MERGED 2 - struct mfc_dma_command { int32_t pad; /* reserved */ uint32_t lsa; /* local storage address */ @@ -203,9 +190,10 @@ extern struct tree_descr spufs_dir_contents[]; extern struct tree_descr spufs_dir_nosched_contents[]; /* system call implementation */ -long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status); -long spufs_create(struct nameidata *nd, unsigned int flags, - mode_t mode, struct file *filp); +long spufs_run_spu(struct file *file, + struct spu_context *ctx, u32 *npc, u32 *status); +long spufs_create(struct nameidata *nd, + unsigned int flags, mode_t mode); extern const struct file_operations spufs_context_fops; /* gang management */ @@ -218,9 +206,6 @@ void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx); /* fault handling */ int spufs_handle_class1(struct spu_context *ctx); -/* affinity */ -struct spu *affinity_check(struct spu_context *ctx); - /* context management */ extern atomic_t nr_spu_contexts; static inline void spu_acquire(struct spu_context *ctx) @@ -242,17 +227,15 @@ void spu_unmap_mappings(struct spu_context *ctx); void spu_forget(struct spu_context *ctx); int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags); void spu_acquire_saved(struct spu_context *ctx); -void spu_release_saved(struct spu_context *ctx); int spu_activate(struct spu_context *ctx, unsigned long flags); void spu_deactivate(struct spu_context *ctx); void spu_yield(struct spu_context *ctx); -void spu_switch_notify(struct spu *spu, struct spu_context *ctx); void spu_set_timeslice(struct spu_context *ctx); void spu_update_sched_info(struct spu_context *ctx); void __spu_update_sched_info(struct spu_context *ctx); int __init spu_sched_init(void); -void spu_sched_exit(void); +void __exit spu_sched_exit(void); extern char *isolated_loader; @@ -310,34 +293,30 @@ extern int spufs_coredump_num_notes; * line. */ static inline void spuctx_switch_state(struct spu_context *ctx, - enum spu_utilization_state new_state) + enum spuctx_execution_state new_state) { - unsigned long long curtime; - signed long long delta; - struct timespec ts; - struct spu *spu; - enum spu_utilization_state old_state; + WARN_ON(!mutex_is_locked(&ctx->state_mutex)); - ktime_get_ts(&ts); - curtime = timespec_to_ns(&ts); - delta = curtime - ctx->stats.tstamp; + if (ctx->stats.execution_state != new_state) { + unsigned long curtime = jiffies; - WARN_ON(!mutex_is_locked(&ctx->state_mutex)); - WARN_ON(delta < 0); - - spu = ctx->spu; - old_state = ctx->stats.util_state; - ctx->stats.util_state = new_state; - ctx->stats.tstamp = curtime; - - /* - * Update the physical SPU utilization statistics. - */ - if (spu) { - ctx->stats.times[old_state] += delta; - spu->stats.times[old_state] += delta; - spu->stats.util_state = new_state; + ctx->stats.times[ctx->stats.execution_state] += + curtime - ctx->stats.tstamp; + ctx->stats.tstamp = curtime; + ctx->stats.execution_state = new_state; + } +} + +static inline void spu_switch_state(struct spu *spu, + enum spuctx_execution_state new_state) +{ + if (spu->stats.utilization_state != new_state) { + unsigned long curtime = jiffies; + + spu->stats.times[spu->stats.utilization_state] += + curtime - spu->stats.tstamp; spu->stats.tstamp = curtime; + spu->stats.utilization_state = new_state; } } diff --git a/trunk/arch/powerpc/platforms/cell/spufs/switch.c b/trunk/arch/powerpc/platforms/cell/spufs/switch.c index 27ffdae98e5a..9c506ba08cdc 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/switch.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/switch.c @@ -180,7 +180,7 @@ static inline void save_mfc_cntl(struct spu_state *csa, struct spu *spu) case MFC_CNTL_SUSPEND_COMPLETE: if (csa) { csa->priv2.mfc_control_RW = - MFC_CNTL_SUSPEND_MASK | + in_be64(&priv2->mfc_control_RW) | MFC_CNTL_SUSPEND_DMA_QUEUE; } break; @@ -190,7 +190,9 @@ static inline void save_mfc_cntl(struct spu_state *csa, struct spu *spu) MFC_CNTL_SUSPEND_DMA_STATUS_MASK) == MFC_CNTL_SUSPEND_COMPLETE); if (csa) { - csa->priv2.mfc_control_RW = 0; + csa->priv2.mfc_control_RW = + in_be64(&priv2->mfc_control_RW) & + ~MFC_CNTL_SUSPEND_DMA_QUEUE; } break; } @@ -249,8 +251,16 @@ static inline void save_mfc_decr(struct spu_state *csa, struct spu *spu) * Read MFC_CNTL[Ds]. Update saved copy of * CSA.MFC_CNTL[Ds]. */ - csa->priv2.mfc_control_RW |= - in_be64(&priv2->mfc_control_RW) & MFC_CNTL_DECREMENTER_RUNNING; + if (in_be64(&priv2->mfc_control_RW) & MFC_CNTL_DECREMENTER_RUNNING) { + csa->priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING; + csa->suspend_time = get_cycles(); + out_be64(&priv2->spu_chnlcntptr_RW, 7ULL); + eieio(); + csa->spu_chnldata_RW[7] = in_be64(&priv2->spu_chnldata_RW); + eieio(); + } else { + csa->priv2.mfc_control_RW &= ~MFC_CNTL_DECREMENTER_RUNNING; + } } static inline void halt_mfc_decr(struct spu_state *csa, struct spu *spu) @@ -261,8 +271,7 @@ static inline void halt_mfc_decr(struct spu_state *csa, struct spu *spu) * Write MFC_CNTL[Dh] set to a '1' to halt * the decrementer. */ - out_be64(&priv2->mfc_control_RW, - MFC_CNTL_DECREMENTER_HALTED | MFC_CNTL_SUSPEND_MASK); + out_be64(&priv2->mfc_control_RW, MFC_CNTL_DECREMENTER_HALTED); eieio(); } @@ -606,7 +615,7 @@ static inline void save_ppuint_mb(struct spu_state *csa, struct spu *spu) static inline void save_ch_part1(struct spu_state *csa, struct spu *spu) { struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 idx, ch_indices[] = { 0UL, 3UL, 4UL, 24UL, 25UL, 27UL }; + u64 idx, ch_indices[7] = { 0UL, 3UL, 4UL, 24UL, 25UL, 27UL }; int i; /* Save, Step 42: @@ -617,7 +626,7 @@ static inline void save_ch_part1(struct spu_state *csa, struct spu *spu) csa->spu_chnldata_RW[1] = in_be64(&priv2->spu_chnldata_RW); /* Save the following CH: [0,3,4,24,25,27] */ - for (i = 0; i < ARRAY_SIZE(ch_indices); i++) { + for (i = 0; i < 7; i++) { idx = ch_indices[i]; out_be64(&priv2->spu_chnlcntptr_RW, idx); eieio(); @@ -974,13 +983,13 @@ static inline void terminate_spu_app(struct spu_state *csa, struct spu *spu) */ } -static inline void suspend_mfc_and_halt_decr(struct spu_state *csa, - struct spu *spu) +static inline void suspend_mfc(struct spu_state *csa, struct spu *spu) { struct spu_priv2 __iomem *priv2 = spu->priv2; /* Restore, Step 7: - * Write MFC_Cntl[Dh,Sc,Sm]='1','1','0' to suspend + * Restore, Step 47. + * Write MFC_Cntl[Dh,Sc]='1','1' to suspend * the queue and halt the decrementer. */ out_be64(&priv2->mfc_control_RW, MFC_CNTL_SUSPEND_DMA_QUEUE | @@ -1081,7 +1090,7 @@ static inline void clear_spu_status(struct spu_state *csa, struct spu *spu) static inline void reset_ch_part1(struct spu_state *csa, struct spu *spu) { struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 ch_indices[] = { 0UL, 3UL, 4UL, 24UL, 25UL, 27UL }; + u64 ch_indices[7] = { 0UL, 3UL, 4UL, 24UL, 25UL, 27UL }; u64 idx; int i; @@ -1093,7 +1102,7 @@ static inline void reset_ch_part1(struct spu_state *csa, struct spu *spu) out_be64(&priv2->spu_chnldata_RW, 0UL); /* Reset the following CH: [0,3,4,24,25,27] */ - for (i = 0; i < ARRAY_SIZE(ch_indices); i++) { + for (i = 0; i < 7; i++) { idx = ch_indices[i]; out_be64(&priv2->spu_chnlcntptr_RW, idx); eieio(); @@ -1280,15 +1289,7 @@ static inline void setup_decr(struct spu_state *csa, struct spu *spu) cycles_t resume_time = get_cycles(); cycles_t delta_time = resume_time - csa->suspend_time; - csa->lscsa->decr_status.slot[0] = SPU_DECR_STATUS_RUNNING; - if (csa->lscsa->decr.slot[0] < delta_time) { - csa->lscsa->decr_status.slot[0] |= - SPU_DECR_STATUS_WRAPPED; - } - csa->lscsa->decr.slot[0] -= delta_time; - } else { - csa->lscsa->decr_status.slot[0] = 0; } } @@ -1397,18 +1398,6 @@ static inline void restore_ls_16kb(struct spu_state *csa, struct spu *spu) send_mfc_dma(spu, addr, ls_offset, size, tag, rclass, cmd); } -static inline void suspend_mfc(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Restore, Step 47. - * Write MFC_Cntl[Sc,Sm]='1','0' to suspend - * the queue. - */ - out_be64(&priv2->mfc_control_RW, MFC_CNTL_SUSPEND_DMA_QUEUE); - eieio(); -} - static inline void clear_interrupts(struct spu_state *csa, struct spu *spu) { /* Restore, Step 49: @@ -1559,10 +1548,10 @@ static inline void restore_decr_wrapped(struct spu_state *csa, struct spu *spu) * "wrapped" flag is set, OR in a '1' to * CSA.SPU_Event_Status[Tm]. */ - if (csa->lscsa->decr_status.slot[0] & SPU_DECR_STATUS_WRAPPED) { + if (csa->lscsa->decr_status.slot[0] == 1) { csa->spu_chnldata_RW[0] |= 0x20; } - if ((csa->lscsa->decr_status.slot[0] & SPU_DECR_STATUS_WRAPPED) && + if ((csa->lscsa->decr_status.slot[0] == 1) && (csa->spu_chnlcnt_RW[0] == 0 && ((csa->spu_chnldata_RW[2] & 0x20) == 0x0) && ((csa->spu_chnldata_RW[0] & 0x20) != 0x1))) { @@ -1573,13 +1562,18 @@ static inline void restore_decr_wrapped(struct spu_state *csa, struct spu *spu) static inline void restore_ch_part1(struct spu_state *csa, struct spu *spu) { struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 idx, ch_indices[] = { 0UL, 3UL, 4UL, 24UL, 25UL, 27UL }; + u64 idx, ch_indices[7] = { 0UL, 3UL, 4UL, 24UL, 25UL, 27UL }; int i; /* Restore, Step 59: - * Restore the following CH: [0,3,4,24,25,27] */ - for (i = 0; i < ARRAY_SIZE(ch_indices); i++) { + + /* Restore CH 1 without count */ + out_be64(&priv2->spu_chnlcntptr_RW, 1); + out_be64(&priv2->spu_chnldata_RW, csa->spu_chnldata_RW[1]); + + /* Restore the following CH: [0,3,4,24,25,27] */ + for (i = 0; i < 7; i++) { idx = ch_indices[i]; out_be64(&priv2->spu_chnlcntptr_RW, idx); eieio(); @@ -1938,7 +1932,7 @@ static void harvest(struct spu_state *prev, struct spu *spu) set_switch_pending(prev, spu); /* Step 5. */ stop_spu_isolate(spu); /* NEW. */ remove_other_spu_access(prev, spu); /* Step 6. */ - suspend_mfc_and_halt_decr(prev, spu); /* Step 7. */ + suspend_mfc(prev, spu); /* Step 7. */ wait_suspend_mfc_complete(prev, spu); /* Step 8. */ if (!suspend_spe(prev, spu)) /* Step 9. */ clear_spu_status(prev, spu); /* Step 10. */ diff --git a/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c b/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c index 43f0fb88abbc..8e37bdf4dfda 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c @@ -47,7 +47,7 @@ static long do_spu_run(struct file *filp, goto out; i = SPUFS_I(filp->f_path.dentry->d_inode); - ret = spufs_run_spu(i->i_ctx, &npc, &status); + ret = spufs_run_spu(filp, i->i_ctx, &npc, &status); if (put_user(npc, unpc)) ret = -EFAULT; @@ -76,8 +76,8 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus) } #endif -asmlinkage long do_spu_create(const char __user *pathname, unsigned int flags, - mode_t mode, struct file *neighbor) +asmlinkage long sys_spu_create(const char __user *pathname, + unsigned int flags, mode_t mode) { char *tmp; int ret; @@ -90,7 +90,7 @@ asmlinkage long do_spu_create(const char __user *pathname, unsigned int flags, ret = path_lookup(tmp, LOOKUP_PARENT| LOOKUP_OPEN|LOOKUP_CREATE, &nd); if (!ret) { - ret = spufs_create(&nd, flags, mode, neighbor); + ret = spufs_create(&nd, flags, mode); path_release(&nd); } putname(tmp); @@ -99,32 +99,8 @@ asmlinkage long do_spu_create(const char __user *pathname, unsigned int flags, return ret; } -#ifndef MODULE -asmlinkage long sys_spu_create(const char __user *pathname, unsigned int flags, - mode_t mode, int neighbor_fd) -{ - int fput_needed; - struct file *neighbor; - long ret; - - if (flags & SPU_CREATE_AFFINITY_SPU) { - ret = -EBADF; - neighbor = fget_light(neighbor_fd, &fput_needed); - if (neighbor) { - ret = do_spu_create(pathname, flags, mode, neighbor); - fput_light(neighbor, fput_needed); - } - } - else { - ret = do_spu_create(pathname, flags, mode, NULL); - } - - return ret; -} -#endif - struct spufs_calls spufs_calls = { - .create_thread = do_spu_create, + .create_thread = sys_spu_create, .spu_run = do_spu_run, .owner = THIS_MODULE, }; diff --git a/trunk/arch/powerpc/sysdev/Makefile b/trunk/arch/powerpc/sysdev/Makefile index 484eb4e0e9db..f65078c3d3b3 100644 --- a/trunk/arch/powerpc/sysdev/Makefile +++ b/trunk/arch/powerpc/sysdev/Makefile @@ -17,7 +17,6 @@ obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ mv64x60-$(CONFIG_PCI) += mv64x60_pci.o obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o obj-$(CONFIG_RTC_DRV_CMOS) += rtc_cmos_setup.o -obj-$(CONFIG_AXON_RAM) += axonram.o # contains only the suspend handler for time ifeq ($(CONFIG_RTC_CLASS),) diff --git a/trunk/arch/powerpc/sysdev/axonram.c b/trunk/arch/powerpc/sysdev/axonram.c deleted file mode 100644 index 2326d5dc5752..000000000000 --- a/trunk/arch/powerpc/sysdev/axonram.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * (C) Copyright IBM Deutschland Entwicklung GmbH 2006 - * - * Author: Maxim Shchetynin - * - * Axon DDR2 device driver. - * It registers one block device per Axon's DDR2 memory bank found on a system. - * Block devices are called axonram?, their major and minor numbers are - * available in /proc/devices, /proc/partitions or in /sys/block/axonram?/dev. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define AXON_RAM_MODULE_NAME "axonram" -#define AXON_RAM_DEVICE_NAME "axonram" -#define AXON_RAM_MINORS_PER_DISK 16 -#define AXON_RAM_BLOCK_SHIFT PAGE_SHIFT -#define AXON_RAM_BLOCK_SIZE 1 << AXON_RAM_BLOCK_SHIFT -#define AXON_RAM_SECTOR_SHIFT 9 -#define AXON_RAM_SECTOR_SIZE 1 << AXON_RAM_SECTOR_SHIFT -#define AXON_RAM_IRQ_FLAGS IRQF_SHARED | IRQF_TRIGGER_RISING - -struct axon_ram_bank { - struct of_device *device; - struct gendisk *disk; - unsigned int irq_correctable; - unsigned int irq_uncorrectable; - unsigned long ph_addr; - unsigned long io_addr; - unsigned long size; - unsigned long ecc_counter; -}; - -static ssize_t -axon_ram_sysfs_ecc(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct of_device *device = to_of_device(dev); - struct axon_ram_bank *bank = device->dev.platform_data; - - BUG_ON(!bank); - - return sprintf(buf, "%ld\n", bank->ecc_counter); -} - -static DEVICE_ATTR(ecc, S_IRUGO, axon_ram_sysfs_ecc, NULL); - -/** - * axon_ram_irq_handler - interrupt handler for Axon RAM ECC - * @irq: interrupt ID - * @dev: pointer to of_device - */ -static irqreturn_t -axon_ram_irq_handler(int irq, void *dev) -{ - struct of_device *device = dev; - struct axon_ram_bank *bank = device->dev.platform_data; - - BUG_ON(!bank); - - if (irq == bank->irq_correctable) { - dev_err(&device->dev, "Correctable memory error occured\n"); - bank->ecc_counter++; - return IRQ_HANDLED; - } else if (irq == bank->irq_uncorrectable) { - dev_err(&device->dev, "Uncorrectable memory error occured\n"); - panic("Critical ECC error on %s", device->node->full_name); - } - - return IRQ_NONE; -} - -/** - * axon_ram_make_request - make_request() method for block device - * @queue, @bio: see blk_queue_make_request() - */ -static int -axon_ram_make_request(struct request_queue *queue, struct bio *bio) -{ - struct axon_ram_bank *bank = bio->bi_bdev->bd_disk->private_data; - unsigned long phys_mem, phys_end; - void *user_mem; - struct bio_vec *vec; - unsigned int transfered; - unsigned short idx; - int rc = 0; - - phys_mem = bank->io_addr + (bio->bi_sector << AXON_RAM_SECTOR_SHIFT); - phys_end = bank->io_addr + bank->size; - transfered = 0; - bio_for_each_segment(vec, bio, idx) { - if (unlikely(phys_mem + vec->bv_len > phys_end)) { - bio_io_error(bio, bio->bi_size); - rc = -ERANGE; - break; - } - - user_mem = page_address(vec->bv_page) + vec->bv_offset; - if (bio_data_dir(bio) == READ) - memcpy(user_mem, (void *) phys_mem, vec->bv_len); - else - memcpy((void *) phys_mem, user_mem, vec->bv_len); - - phys_mem += vec->bv_len; - transfered += vec->bv_len; - } - bio_endio(bio, transfered, 0); - - return rc; -} - -/** - * axon_ram_direct_access - direct_access() method for block device - * @device, @sector, @data: see block_device_operations method - */ -static int -axon_ram_direct_access(struct block_device *device, sector_t sector, - unsigned long *data) -{ - struct axon_ram_bank *bank = device->bd_disk->private_data; - loff_t offset; - - offset = sector << AXON_RAM_SECTOR_SHIFT; - if (offset >= bank->size) { - dev_err(&bank->device->dev, "Access outside of address space\n"); - return -ERANGE; - } - - *data = bank->ph_addr + offset; - - return 0; -} - -static struct block_device_operations axon_ram_devops = { - .owner = THIS_MODULE, - .direct_access = axon_ram_direct_access -}; - -/** - * axon_ram_probe - probe() method for platform driver - * @device, @device_id: see of_platform_driver method - */ -static int -axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) -{ - static int axon_ram_bank_id = -1; - struct axon_ram_bank *bank; - struct resource resource; - int rc = 0; - - axon_ram_bank_id++; - - dev_info(&device->dev, "Found memory controller on %s\n", - device->node->full_name); - - bank = kzalloc(sizeof(struct axon_ram_bank), GFP_KERNEL); - if (bank == NULL) { - dev_err(&device->dev, "Out of memory\n"); - rc = -ENOMEM; - goto failed; - } - - device->dev.platform_data = bank; - - bank->device = device; - - if (of_address_to_resource(device->node, 0, &resource) != 0) { - dev_err(&device->dev, "Cannot access device tree\n"); - rc = -EFAULT; - goto failed; - } - - bank->size = resource.end - resource.start + 1; - - if (bank->size == 0) { - dev_err(&device->dev, "No DDR2 memory found for %s%d\n", - AXON_RAM_DEVICE_NAME, axon_ram_bank_id); - rc = -ENODEV; - goto failed; - } - - dev_info(&device->dev, "Register DDR2 memory device %s%d with %luMB\n", - AXON_RAM_DEVICE_NAME, axon_ram_bank_id, bank->size >> 20); - - bank->ph_addr = resource.start; - bank->io_addr = (unsigned long) ioremap_flags( - bank->ph_addr, bank->size, _PAGE_NO_CACHE); - if (bank->io_addr == 0) { - dev_err(&device->dev, "ioremap() failed\n"); - rc = -EFAULT; - goto failed; - } - - bank->disk = alloc_disk(AXON_RAM_MINORS_PER_DISK); - if (bank->disk == NULL) { - dev_err(&device->dev, "Cannot register disk\n"); - rc = -EFAULT; - goto failed; - } - - bank->disk->first_minor = 0; - bank->disk->fops = &axon_ram_devops; - bank->disk->private_data = bank; - bank->disk->driverfs_dev = &device->dev; - - sprintf(bank->disk->disk_name, "%s%d", - AXON_RAM_DEVICE_NAME, axon_ram_bank_id); - bank->disk->major = register_blkdev(0, bank->disk->disk_name); - if (bank->disk->major < 0) { - dev_err(&device->dev, "Cannot register block device\n"); - rc = -EFAULT; - goto failed; - } - - bank->disk->queue = blk_alloc_queue(GFP_KERNEL); - if (bank->disk->queue == NULL) { - dev_err(&device->dev, "Cannot register disk queue\n"); - rc = -EFAULT; - goto failed; - } - - set_capacity(bank->disk, bank->size >> AXON_RAM_SECTOR_SHIFT); - blk_queue_make_request(bank->disk->queue, axon_ram_make_request); - blk_queue_hardsect_size(bank->disk->queue, AXON_RAM_SECTOR_SIZE); - add_disk(bank->disk); - - bank->irq_correctable = irq_of_parse_and_map(device->node, 0); - bank->irq_uncorrectable = irq_of_parse_and_map(device->node, 1); - if ((bank->irq_correctable <= 0) || (bank->irq_uncorrectable <= 0)) { - dev_err(&device->dev, "Cannot access ECC interrupt ID\n"); - rc = -EFAULT; - goto failed; - } - - rc = request_irq(bank->irq_correctable, axon_ram_irq_handler, - AXON_RAM_IRQ_FLAGS, bank->disk->disk_name, device); - if (rc != 0) { - dev_err(&device->dev, "Cannot register ECC interrupt handler\n"); - bank->irq_correctable = bank->irq_uncorrectable = 0; - rc = -EFAULT; - goto failed; - } - - rc = request_irq(bank->irq_uncorrectable, axon_ram_irq_handler, - AXON_RAM_IRQ_FLAGS, bank->disk->disk_name, device); - if (rc != 0) { - dev_err(&device->dev, "Cannot register ECC interrupt handler\n"); - bank->irq_uncorrectable = 0; - rc = -EFAULT; - goto failed; - } - - rc = device_create_file(&device->dev, &dev_attr_ecc); - if (rc != 0) { - dev_err(&device->dev, "Cannot create sysfs file\n"); - rc = -EFAULT; - goto failed; - } - - return 0; - -failed: - if (bank != NULL) { - if (bank->irq_uncorrectable > 0) - free_irq(bank->irq_uncorrectable, device); - if (bank->irq_correctable > 0) - free_irq(bank->irq_correctable, device); - if (bank->disk != NULL) { - if (bank->disk->queue != NULL) - blk_cleanup_queue(bank->disk->queue); - if (bank->disk->major > 0) - unregister_blkdev(bank->disk->major, - bank->disk->disk_name); - del_gendisk(bank->disk); - } - device->dev.platform_data = NULL; - if (bank->io_addr != 0) - iounmap((void __iomem *) bank->io_addr); - kfree(bank); - } - - return rc; -} - -/** - * axon_ram_remove - remove() method for platform driver - * @device: see of_platform_driver method - */ -static int -axon_ram_remove(struct of_device *device) -{ - struct axon_ram_bank *bank = device->dev.platform_data; - - BUG_ON(!bank || !bank->disk); - - device_remove_file(&device->dev, &dev_attr_ecc); - free_irq(bank->irq_uncorrectable, device); - free_irq(bank->irq_correctable, device); - blk_cleanup_queue(bank->disk->queue); - unregister_blkdev(bank->disk->major, bank->disk->disk_name); - del_gendisk(bank->disk); - iounmap((void __iomem *) bank->io_addr); - kfree(bank); - - return 0; -} - -static struct of_device_id axon_ram_device_id[] = { - { - .type = "dma-memory" - }, - {} -}; - -static struct of_platform_driver axon_ram_driver = { - .owner = THIS_MODULE, - .name = AXON_RAM_MODULE_NAME, - .match_table = axon_ram_device_id, - .probe = axon_ram_probe, - .remove = axon_ram_remove -}; - -/** - * axon_ram_init - */ -static int __init -axon_ram_init(void) -{ - return of_register_platform_driver(&axon_ram_driver); -} - -/** - * axon_ram_exit - */ -static void __exit -axon_ram_exit(void) -{ - of_unregister_platform_driver(&axon_ram_driver); -} - -module_init(axon_ram_init); -module_exit(axon_ram_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Maxim Shchetynin "); -MODULE_DESCRIPTION("Axon DDR2 RAM device driver for IBM Cell BE"); diff --git a/trunk/arch/powerpc/sysdev/pmi.c b/trunk/arch/powerpc/sysdev/pmi.c index 2f91b55b7754..85a7c99c1003 100644 --- a/trunk/arch/powerpc/sysdev/pmi.c +++ b/trunk/arch/powerpc/sysdev/pmi.c @@ -48,13 +48,15 @@ struct pmi_data { struct work_struct work; }; -static struct pmi_data *data; static int pmi_irq_handler(int irq, void *dev_id) { + struct pmi_data *data; u8 type; int rc; + data = dev_id; + spin_lock(&data->pmi_spinlock); type = ioread8(data->pmi_reg + PMI_READ_TYPE); @@ -109,13 +111,16 @@ MODULE_DEVICE_TABLE(of, pmi_match); static void pmi_notify_handlers(struct work_struct *work) { + struct pmi_data *data; struct pmi_handler *handler; + data = container_of(work, struct pmi_data, work); + spin_lock(&data->handler_spinlock); list_for_each_entry(handler, &data->handler, node) { pr_debug(KERN_INFO "pmi: notifying handler %p\n", handler); if (handler->type == data->msg.type) - handler->handle_pmi_message(data->msg); + handler->handle_pmi_message(data->dev, data->msg); } spin_unlock(&data->handler_spinlock); } @@ -124,14 +129,9 @@ static int pmi_of_probe(struct of_device *dev, const struct of_device_id *match) { struct device_node *np = dev->node; + struct pmi_data *data; int rc; - if (data) { - printk(KERN_ERR "pmi: driver has already been initialized.\n"); - rc = -EBUSY; - goto out; - } - data = kzalloc(sizeof(struct pmi_data), GFP_KERNEL); if (!data) { printk(KERN_ERR "pmi: could not allocate memory.\n"); @@ -154,6 +154,7 @@ static int pmi_of_probe(struct of_device *dev, INIT_WORK(&data->work, pmi_notify_handlers); + dev->dev.driver_data = data; data->dev = dev; data->irq = irq_of_parse_and_map(np, 0); @@ -163,7 +164,7 @@ static int pmi_of_probe(struct of_device *dev, goto error_cleanup_iomap; } - rc = request_irq(data->irq, pmi_irq_handler, 0, "pmi", NULL); + rc = request_irq(data->irq, pmi_irq_handler, 0, "pmi", data); if (rc) { printk(KERN_ERR "pmi: can't request IRQ %d: returned %d\n", data->irq, rc); @@ -186,9 +187,12 @@ static int pmi_of_probe(struct of_device *dev, static int pmi_of_remove(struct of_device *dev) { + struct pmi_data *data; struct pmi_handler *handler, *tmp; - free_irq(data->irq, NULL); + data = dev->dev.driver_data; + + free_irq(data->irq, data); iounmap(data->pmi_reg); spin_lock(&data->handler_spinlock); @@ -198,8 +202,7 @@ static int pmi_of_remove(struct of_device *dev) spin_unlock(&data->handler_spinlock); - kfree(data); - data = NULL; + kfree(dev->dev.driver_data); return 0; } @@ -223,13 +226,13 @@ static void __exit pmi_module_exit(void) } module_exit(pmi_module_exit); -int pmi_send_message(pmi_message_t msg) +void pmi_send_message(struct of_device *device, pmi_message_t msg) { + struct pmi_data *data; unsigned long flags; DECLARE_COMPLETION_ONSTACK(completion); - if (!data) - return -ENODEV; + data = device->dev.driver_data; mutex_lock(&data->msg_mutex); @@ -253,26 +256,30 @@ int pmi_send_message(pmi_message_t msg) data->completion = NULL; mutex_unlock(&data->msg_mutex); - - return 0; } EXPORT_SYMBOL_GPL(pmi_send_message); -int pmi_register_handler(struct pmi_handler *handler) +void pmi_register_handler(struct of_device *device, + struct pmi_handler *handler) { + struct pmi_data *data; + data = device->dev.driver_data; + if (!data) - return -ENODEV; + return; spin_lock(&data->handler_spinlock); list_add_tail(&handler->node, &data->handler); spin_unlock(&data->handler_spinlock); - - return 0; } EXPORT_SYMBOL_GPL(pmi_register_handler); -void pmi_unregister_handler(struct pmi_handler *handler) +void pmi_unregister_handler(struct of_device *device, + struct pmi_handler *handler) { + struct pmi_data *data; + data = device->dev.driver_data; + if (!data) return; diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index f87f429e0b24..d8ed6676ae86 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -178,9 +178,6 @@ config CPU_HAS_PINT_IRQ config CPU_HAS_MASKREG_IRQ bool -config CPU_HAS_INTC_IRQ - bool - config CPU_HAS_INTC2_IRQ bool @@ -212,7 +209,6 @@ config SOLUTION_ENGINE config SH_SOLUTION_ENGINE bool "SolutionEngine" select SOLUTION_ENGINE - select CPU_HAS_IPR_IRQ depends on CPU_SUBTYPE_SH7709 || CPU_SUBTYPE_SH7750 help Select SolutionEngine if configuring for a Hitachi SH7709 @@ -245,7 +241,6 @@ config SH_7722_SOLUTION_ENGINE config SH_7751_SOLUTION_ENGINE bool "SolutionEngine7751" select SOLUTION_ENGINE - select CPU_HAS_IPR_IRQ depends on CPU_SUBTYPE_SH7751 help Select 7751 SolutionEngine if configuring for a Hitachi SH7751 @@ -255,7 +250,6 @@ config SH_7780_SOLUTION_ENGINE bool "SolutionEngine7780" select SOLUTION_ENGINE select SYS_SUPPORTS_PCI - select CPU_HAS_INTC2_IRQ depends on CPU_SUBTYPE_SH7780 help Select 7780 SolutionEngine if configuring for a Renesas SH7780 @@ -323,7 +317,6 @@ config SH_MPC1211 config SH_SH03 bool "Interface CTP/PCI-SH03" depends on CPU_SUBTYPE_SH7751 && BROKEN - select CPU_HAS_IPR_IRQ select SYS_SUPPORTS_PCI help CTP/PCI-SH03 is a CPU module computer that is produced @@ -333,7 +326,6 @@ config SH_SH03 config SH_SECUREEDGE5410 bool "SecureEdge5410" depends on CPU_SUBTYPE_SH7751R - select CPU_HAS_IPR_IRQ select SYS_SUPPORTS_PCI help Select SecureEdge5410 if configuring for a SnapGear SH board. @@ -388,7 +380,6 @@ config SH_LANDISK config SH_TITAN bool "TITAN" depends on CPU_SUBTYPE_SH7751R - select CPU_HAS_IPR_IRQ select SYS_SUPPORTS_PCI help Select Titan if you are configuring for a Nimble Microsystems @@ -397,7 +388,6 @@ config SH_TITAN config SH_SHMIN bool "SHMIN" depends on CPU_SUBTYPE_SH7706 - select CPU_HAS_IPR_IRQ help Select SHMIN if configuring for the SHMIN board. diff --git a/trunk/arch/sh/Makefile b/trunk/arch/sh/Makefile index 0016609d1eba..77fecc62a056 100644 --- a/trunk/arch/sh/Makefile +++ b/trunk/arch/sh/Makefile @@ -121,7 +121,8 @@ core-y += $(addprefix arch/sh/boards/, \ endif # Companion chips -core-$(CONFIG_HD6446X_SERIES) += arch/sh/cchips/hd6446x/ +core-$(CONFIG_HD64461) += arch/sh/cchips/hd6446x/hd64461/ +core-$(CONFIG_HD64465) += arch/sh/cchips/hd6446x/hd64465/ core-$(CONFIG_VOYAGERGX) += arch/sh/cchips/voyagergx/ cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2 diff --git a/trunk/arch/sh/boards/mpc1211/pci.c b/trunk/arch/sh/boards/mpc1211/pci.c index 23849f70f133..4ed1a95c6d56 100644 --- a/trunk/arch/sh/boards/mpc1211/pci.c +++ b/trunk/arch/sh/boards/mpc1211/pci.c @@ -187,7 +187,7 @@ char * __devinit pcibios_setup(char *str) * are examined. */ -void __devinit pcibios_fixup_bus(struct pci_bus *b) +void __init pcibios_fixup_bus(struct pci_bus *b) { pci_read_bridge_bases(b); } diff --git a/trunk/arch/sh/boards/renesas/r7780rp/setup.c b/trunk/arch/sh/boards/renesas/r7780rp/setup.c index adb529d01bae..5afb864a1ec5 100644 --- a/trunk/arch/sh/boards/renesas/r7780rp/setup.c +++ b/trunk/arch/sh/boards/renesas/r7780rp/setup.c @@ -21,58 +21,6 @@ #include #include -static struct resource r8a66597_usb_host_resources[] = { - [0] = { - .name = "r8a66597_hcd", - .start = 0xA4200000, - .end = 0xA42000FF, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "r8a66597_hcd", - .start = 11, /* irq number */ - .end = 11, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device r8a66597_usb_host_device = { - .name = "r8a66597_hcd", - .id = -1, - .dev = { - .dma_mask = NULL, /* don't use dma */ - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(r8a66597_usb_host_resources), - .resource = r8a66597_usb_host_resources, -}; - -static struct resource m66592_usb_peripheral_resources[] = { - [0] = { - .name = "m66592_udc", - .start = 0xb0000000, - .end = 0xb00000FF, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "m66592_udc", - .start = 9, /* irq number */ - .end = 9, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device m66592_usb_peripheral_device = { - .name = "m66592_udc", - .id = -1, - .dev = { - .dma_mask = NULL, /* don't use dma */ - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources), - .resource = m66592_usb_peripheral_resources, -}; - static struct resource cf_ide_resources[] = { [0] = { .start = PA_AREA5_IO + 0x1000, @@ -133,8 +81,6 @@ static struct platform_device heartbeat_device = { }; static struct platform_device *r7780rp_devices[] __initdata = { - &r8a66597_usb_host_device, - &m66592_usb_peripheral_device, &cf_ide_device, &heartbeat_device, }; diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c b/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c index e165d85c03b5..656fda30ef70 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c @@ -86,8 +86,7 @@ static struct plat_serial8250_port uart_platform_data[] = { .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, .regshift = 2, .uartclk = (9600 * 16), - }, - { 0 }, + } }; static struct platform_device uart_device = { diff --git a/trunk/arch/sh/boards/se/7722/irq.c b/trunk/arch/sh/boards/se/7722/irq.c index 0b03f3f610b8..26cff0efda40 100644 --- a/trunk/arch/sh/boards/se/7722/irq.c +++ b/trunk/arch/sh/boards/se/7722/irq.c @@ -16,61 +16,95 @@ #include #include +#define INTC_INTMSK0 0xFFD00044 +#define INTC_INTMSKCLR0 0xFFD00064 + +struct se7722_data { + unsigned char irq; + unsigned char ipr_idx; + unsigned char shift; + unsigned short priority; + unsigned long addr; +}; + + static void disable_se7722_irq(unsigned int irq) { - unsigned int bit = irq - SE7722_FPGA_IRQ_BASE; - ctrl_outw(ctrl_inw(IRQ01_MASK) | 1 << bit, IRQ01_MASK); + struct se7722_data *p = get_irq_chip_data(irq); + ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr ); } static void enable_se7722_irq(unsigned int irq) { - unsigned int bit = irq - SE7722_FPGA_IRQ_BASE; - ctrl_outw(ctrl_inw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK); + struct se7722_data *p = get_irq_chip_data(irq); + ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr ); } static struct irq_chip se7722_irq_chip __read_mostly = { - .name = "SE7722-FPGA", + .name = "SE7722", .mask = disable_se7722_irq, .unmask = enable_se7722_irq, .mask_ack = disable_se7722_irq, }; -static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) -{ - unsigned short intv = ctrl_inw(IRQ01_STS); - struct irq_desc *ext_desc; - unsigned int ext_irq = SE7722_FPGA_IRQ_BASE; +static struct se7722_data ipr_irq_table[] = { + /* irq ,idx,sft, priority , addr */ + { MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } , + { MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } , + { MRSHPC_IRQ2 , 0 , 0 , MRSHPC_BIT2 , IRQ01_MASK } , + { MRSHPC_IRQ3 , 0 , 0 , MRSHPC_BIT3 , IRQ01_MASK } , + { SMC_IRQ , 0 , 0 , SMC_BIT , IRQ01_MASK } , + { EXT_IRQ , 0 , 0 , EXT_BIT , IRQ01_MASK } , +}; - intv &= (1 << SE7722_FPGA_IRQ_NR) - 1; +int se7722_irq_demux(int irq) +{ - while (intv) { - if (intv & 1) { - ext_desc = irq_desc + ext_irq; - handle_level_irq(ext_irq, ext_desc); + if ((irq == IRQ0_IRQ)||(irq == IRQ1_IRQ)) { + volatile unsigned short intv = + *(volatile unsigned short *)IRQ01_STS; + if (irq == IRQ0_IRQ){ + if(intv & SMC_BIT ) { + return SMC_IRQ; + } else if(intv & USB_BIT) { + return USB_IRQ; + } else { + printk("intv =%04x\n", intv); + return SMC_IRQ; + } + } else if(irq == IRQ1_IRQ){ + if(intv & MRSHPC_BIT0) { + return MRSHPC_IRQ0; + } else if(intv & MRSHPC_BIT1) { + return MRSHPC_IRQ1; + } else if(intv & MRSHPC_BIT2) { + return MRSHPC_IRQ2; + } else if(intv & MRSHPC_BIT3) { + return MRSHPC_IRQ3; + } else { + printk("BIT_EXTENTION =%04x\n", intv); + return EXT_IRQ; + } } - intv >>= 1; - ext_irq++; } -} + return irq; +} /* * Initialize IRQ setting */ void __init init_se7722_IRQ(void) { - int i; - - ctrl_outw(0, IRQ01_MASK); /* disable all irqs */ + int i = 0; ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ + ctrl_outl((3 << ((7 - 0) * 4))|(3 << ((7 - 1) * 4)), INTC_INTPRI0); /* irq0 pri=3,irq1,pri=3 */ + ctrl_outw((2 << ((7 - 0) * 2))|(2 << ((7 - 1) * 2)), INTC_ICR1); /* irq0,1 low-level irq */ - for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) - set_irq_chip_and_handler_name(SE7722_FPGA_IRQ_BASE + i, - &se7722_irq_chip, - handle_level_irq, "level"); - - set_irq_chained_handler(IRQ0_IRQ, se7722_irq_demux); - set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); - - set_irq_chained_handler(IRQ1_IRQ, se7722_irq_demux); - set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); + for (i = 0; i < ARRAY_SIZE(ipr_irq_table); i++) { + disable_irq_nosync(ipr_irq_table[i].irq); + set_irq_chip_and_handler_name( ipr_irq_table[i].irq, &se7722_irq_chip, + handle_level_irq, "level"); + set_irq_chip_data( ipr_irq_table[i].irq, &ipr_irq_table[i] ); + disable_se7722_irq(ipr_irq_table[i].irq); + } } diff --git a/trunk/arch/sh/boards/se/7722/setup.c b/trunk/arch/sh/boards/se/7722/setup.c index 495fc7e2b60f..6cca6cbc8069 100644 --- a/trunk/arch/sh/boards/se/7722/setup.c +++ b/trunk/arch/sh/boards/se/7722/setup.c @@ -77,7 +77,6 @@ static struct resource cf_ide_resources[] = { }, [2] = { .start = MRSHPC_IRQ0, - .end = MRSHPC_IRQ0, .flags = IORESOURCE_IRQ, }, }; @@ -141,6 +140,8 @@ static void __init se7722_setup(char **cmdline_p) static struct sh_machine_vector mv_se7722 __initmv = { .mv_name = "Solution Engine 7722" , .mv_setup = se7722_setup , - .mv_nr_irqs = SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_NR, + .mv_nr_irqs = 109 , .mv_init_irq = init_se7722_IRQ, + .mv_irq_demux = se7722_irq_demux, + }; diff --git a/trunk/arch/sh/cchips/hd6446x/Makefile b/trunk/arch/sh/cchips/hd6446x/Makefile deleted file mode 100644 index a106dd9db986..000000000000 --- a/trunk/arch/sh/cchips/hd6446x/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_HD64461) += hd64461.o -obj-$(CONFIG_HD64465) += hd64465/ diff --git a/trunk/arch/sh/cchips/hd6446x/hd64461/Makefile b/trunk/arch/sh/cchips/hd6446x/hd64461/Makefile new file mode 100644 index 000000000000..bff4b92e388c --- /dev/null +++ b/trunk/arch/sh/cchips/hd6446x/hd64461/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the HD64461 +# + +obj-y := setup.o io.o + diff --git a/trunk/arch/sh/cchips/hd6446x/hd64461/io.c b/trunk/arch/sh/cchips/hd6446x/hd64461/io.c new file mode 100644 index 000000000000..7909a1b7b512 --- /dev/null +++ b/trunk/arch/sh/cchips/hd6446x/hd64461/io.c @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2000 YAEGASHI Takeshi + * Typical I/O routines for HD64461 system. + */ + +#include +#include + +#define MEM_BASE (CONFIG_HD64461_IOBASE - HD64461_STBCR) + +static __inline__ unsigned long PORT2ADDR(unsigned long port) +{ + /* 16550A: HD64461 internal */ + if (0x3f8<=port && port<=0x3ff) + return CONFIG_HD64461_IOBASE + 0x8000 + ((port-0x3f8)<<1); + if (0x2f8<=port && port<=0x2ff) + return CONFIG_HD64461_IOBASE + 0x7000 + ((port-0x2f8)<<1); + +#ifdef CONFIG_HD64461_ENABLER + /* NE2000: HD64461 PCMCIA channel 0 (I/O) */ + if (0x300<=port && port<=0x31f) + return 0xba000000 + port; + + /* ide0: HD64461 PCMCIA channel 1 (memory) */ + /* On HP690, CF in slot 1 is configured as a memory card + device. See CF+ and CompactFlash Specification for the + detail of CF's memory mapped addressing. */ + if (0x1f0<=port && port<=0x1f7) return 0xb5000000 + port; + if (port == 0x3f6) return 0xb50001fe; + if (port == 0x3f7) return 0xb50001ff; + + /* ide1 */ + if (0x170<=port && port<=0x177) return 0xba000000 + port; + if (port == 0x376) return 0xba000376; + if (port == 0x377) return 0xba000377; +#endif + + /* ??? */ + if (port < 0xf000) return 0xa0000000 + port; + /* PCMCIA channel 0, I/O (0xba000000) */ + if (port < 0x10000) return 0xba000000 + port - 0xf000; + + /* HD64461 internal devices (0xb0000000) */ + if (port < 0x20000) return CONFIG_HD64461_IOBASE + port - 0x10000; + + /* PCMCIA channel 0, I/O (0xba000000) */ + if (port < 0x30000) return 0xba000000 + port - 0x20000; + + /* PCMCIA channel 1, memory (0xb5000000) */ + if (port < 0x40000) return 0xb5000000 + port - 0x30000; + + /* Whole physical address space (0xa0000000) */ + return 0xa0000000 + (port & 0x1fffffff); +} + +unsigned char hd64461_inb(unsigned long port) +{ + return *(volatile unsigned char*)PORT2ADDR(port); +} + +unsigned char hd64461_inb_p(unsigned long port) +{ + unsigned long v = *(volatile unsigned char*)PORT2ADDR(port); + ctrl_delay(); + return v; +} + +unsigned short hd64461_inw(unsigned long port) +{ + return *(volatile unsigned short*)PORT2ADDR(port); +} + +unsigned int hd64461_inl(unsigned long port) +{ + return *(volatile unsigned long*)PORT2ADDR(port); +} + +void hd64461_outb(unsigned char b, unsigned long port) +{ + *(volatile unsigned char*)PORT2ADDR(port) = b; +} + +void hd64461_outb_p(unsigned char b, unsigned long port) +{ + *(volatile unsigned char*)PORT2ADDR(port) = b; + ctrl_delay(); +} + +void hd64461_outw(unsigned short b, unsigned long port) +{ + *(volatile unsigned short*)PORT2ADDR(port) = b; +} + +void hd64461_outl(unsigned int b, unsigned long port) +{ + *(volatile unsigned long*)PORT2ADDR(port) = b; +} + +void hd64461_insb(unsigned long port, void *buffer, unsigned long count) +{ + volatile unsigned char* addr=(volatile unsigned char*)PORT2ADDR(port); + unsigned char *buf=buffer; + while(count--) *buf++=*addr; +} + +void hd64461_insw(unsigned long port, void *buffer, unsigned long count) +{ + volatile unsigned short* addr=(volatile unsigned short*)PORT2ADDR(port); + unsigned short *buf=buffer; + while(count--) *buf++=*addr; +} + +void hd64461_insl(unsigned long port, void *buffer, unsigned long count) +{ + volatile unsigned long* addr=(volatile unsigned long*)PORT2ADDR(port); + unsigned long *buf=buffer; + while(count--) *buf++=*addr; +} + +void hd64461_outsb(unsigned long port, const void *buffer, unsigned long count) +{ + volatile unsigned char* addr=(volatile unsigned char*)PORT2ADDR(port); + const unsigned char *buf=buffer; + while(count--) *addr=*buf++; +} + +void hd64461_outsw(unsigned long port, const void *buffer, unsigned long count) +{ + volatile unsigned short* addr=(volatile unsigned short*)PORT2ADDR(port); + const unsigned short *buf=buffer; + while(count--) *addr=*buf++; +} + +void hd64461_outsl(unsigned long port, const void *buffer, unsigned long count) +{ + volatile unsigned long* addr=(volatile unsigned long*)PORT2ADDR(port); + const unsigned long *buf=buffer; + while(count--) *addr=*buf++; +} + +unsigned short hd64461_readw(void __iomem *addr) +{ + return ctrl_inw(MEM_BASE+(unsigned long __force)addr); +} + +void hd64461_writew(unsigned short b, void __iomem *addr) +{ + ctrl_outw(b, MEM_BASE+(unsigned long __force)addr); +} + diff --git a/trunk/arch/sh/cchips/hd6446x/hd64461.c b/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c similarity index 98% rename from trunk/arch/sh/cchips/hd6446x/hd64461.c rename to trunk/arch/sh/cchips/hd6446x/hd64461/setup.c index 97f6512aa1b7..4d49b5cbcc13 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64461.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c @@ -1,4 +1,5 @@ /* + * $Id: setup.c,v 1.5 2004/03/16 00:07:50 lethal Exp $ * Copyright (C) 2000 YAEGASHI Takeshi * Hitachi HD64461 companion chip support */ diff --git a/trunk/arch/sh/configs/landisk_defconfig b/trunk/arch/sh/configs/landisk_defconfig index 07310fa03250..e7f8ddb0ada4 100644 --- a/trunk/arch/sh/configs/landisk_defconfig +++ b/trunk/arch/sh/configs/landisk_defconfig @@ -217,7 +217,7 @@ CONFIG_SH_FPU=y # CONFIG_SH_DSP is not set # CONFIG_SH_STORE_QUEUES is not set CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_INTC_IRQ=y +CONFIG_CPU_HAS_IPR_IRQ=y CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_PTEA=y diff --git a/trunk/arch/sh/configs/lboxre2_defconfig b/trunk/arch/sh/configs/lboxre2_defconfig index fa09d68d057a..be86414dcc87 100644 --- a/trunk/arch/sh/configs/lboxre2_defconfig +++ b/trunk/arch/sh/configs/lboxre2_defconfig @@ -222,7 +222,7 @@ CONFIG_SH_FPU=y # CONFIG_SH_DSP is not set # CONFIG_SH_STORE_QUEUES is not set CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_INTC_IRQ=y +CONFIG_CPU_HAS_IPR_IRQ=y CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_PTEA=y diff --git a/trunk/arch/sh/configs/r7780mp_defconfig b/trunk/arch/sh/configs/r7780mp_defconfig index ac4de4973b60..17f7402b31d8 100644 --- a/trunk/arch/sh/configs/r7780mp_defconfig +++ b/trunk/arch/sh/configs/r7780mp_defconfig @@ -191,7 +191,7 @@ CONFIG_SH_FPU=y CONFIG_SH_STORE_QUEUES=y CONFIG_SPECULATIVE_EXECUTION=y CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_INTC_IRQ=y +CONFIG_CPU_HAS_INTC2_IRQ=y CONFIG_CPU_HAS_SR_RB=y # diff --git a/trunk/arch/sh/configs/r7780rp_defconfig b/trunk/arch/sh/configs/r7780rp_defconfig index 12cc01910cf8..48c6a2194c98 100644 --- a/trunk/arch/sh/configs/r7780rp_defconfig +++ b/trunk/arch/sh/configs/r7780rp_defconfig @@ -241,7 +241,7 @@ CONFIG_SH_FPU=y CONFIG_SH_STORE_QUEUES=y CONFIG_SPECULATIVE_EXECUTION=y CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_INTC_IRQ=y +CONFIG_CPU_HAS_INTC2_IRQ=y CONFIG_CPU_HAS_SR_RB=y # diff --git a/trunk/arch/sh/configs/rts7751r2d_defconfig b/trunk/arch/sh/configs/rts7751r2d_defconfig index f1e979b1e495..a59bb78bd071 100644 --- a/trunk/arch/sh/configs/rts7751r2d_defconfig +++ b/trunk/arch/sh/configs/rts7751r2d_defconfig @@ -155,7 +155,7 @@ CONFIG_CPU_SH4=y # CONFIG_CPU_SUBTYPE_SH7091 is not set # CONFIG_CPU_SUBTYPE_SH7750R is not set # CONFIG_CPU_SUBTYPE_SH7750S is not set -# CONFIG_CPU_SUBTYPE_SH7751 is not set +CONFIG_CPU_SUBTYPE_SH7751=y CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set @@ -218,7 +218,7 @@ CONFIG_SH_FPU=y # CONFIG_SH_DSP is not set # CONFIG_SH_STORE_QUEUES is not set CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_INTC_IRQ=y +CONFIG_CPU_HAS_IPR_IRQ=y CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_PTEA=y @@ -280,7 +280,7 @@ CONFIG_ZERO_PAGE_OFFSET=0x00010000 CONFIG_BOOT_LINK_OFFSET=0x00800000 # CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=bios" +CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1" # # Bus options @@ -1323,7 +1323,7 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_SH_STANDARD_BIOS=y +# CONFIG_SH_STANDARD_BIOS is not set CONFIG_EARLY_SCIF_CONSOLE=y CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000 CONFIG_EARLY_PRINTK=y diff --git a/trunk/arch/sh/configs/se7722_defconfig b/trunk/arch/sh/configs/se7722_defconfig index 8e6a6baf5d27..764b813c4051 100644 --- a/trunk/arch/sh/configs/se7722_defconfig +++ b/trunk/arch/sh/configs/se7722_defconfig @@ -200,7 +200,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_SH_DSP=y CONFIG_SH_STORE_QUEUES=y CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_INTC_IRQ=y +CONFIG_CPU_HAS_IPR_IRQ=y CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_PTEA=y @@ -565,7 +565,7 @@ CONFIG_SERIO_LIBPS2=y # Non-8250 serial port support # CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_NR_UARTS=3 +CONFIG_SERIAL_SH_SCI_NR_UARTS=2 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y diff --git a/trunk/arch/sh/configs/se7750_defconfig b/trunk/arch/sh/configs/se7750_defconfig index c60b6fd4fc42..4e6e77fa4ce7 100644 --- a/trunk/arch/sh/configs/se7750_defconfig +++ b/trunk/arch/sh/configs/se7750_defconfig @@ -226,7 +226,7 @@ CONFIG_SH_FPU=y # CONFIG_SH_DSP is not set # CONFIG_SH_STORE_QUEUES is not set CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_INTC_IRQ=y +CONFIG_CPU_HAS_IPR_IRQ=y CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_PTEA=y diff --git a/trunk/arch/sh/configs/se7780_defconfig b/trunk/arch/sh/configs/se7780_defconfig index f68743dc3931..538661e98793 100644 --- a/trunk/arch/sh/configs/se7780_defconfig +++ b/trunk/arch/sh/configs/se7780_defconfig @@ -218,7 +218,6 @@ CONFIG_SH_FPU=y # CONFIG_SH_STORE_QUEUES is not set CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_INTC2_IRQ=y -CONFIG_CPU_HAS_INTC_IRQ=y CONFIG_CPU_HAS_SR_RB=y # diff --git a/trunk/arch/sh/drivers/dma/Kconfig b/trunk/arch/sh/drivers/dma/Kconfig index ee711431e504..333898077c7c 100644 --- a/trunk/arch/sh/drivers/dma/Kconfig +++ b/trunk/arch/sh/drivers/dma/Kconfig @@ -5,13 +5,12 @@ config SH_DMA_API config SH_DMA bool "SuperH on-chip DMA controller (DMAC) support" - depends on CPU_SH3 || CPU_SH4 select SH_DMA_API default n config NR_ONCHIP_DMA_CHANNELS - int depends on SH_DMA + int "Number of on-chip DMAC channels" default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R default "12" if CPU_SUBTYPE_SH7780 default "4" diff --git a/trunk/arch/sh/drivers/heartbeat.c b/trunk/arch/sh/drivers/heartbeat.c index 10c1828c9ff5..23dd6080422f 100644 --- a/trunk/arch/sh/drivers/heartbeat.c +++ b/trunk/arch/sh/drivers/heartbeat.c @@ -78,7 +78,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev) hd->bit_pos[i] = i; } - hd->base = (void __iomem *)(unsigned long)res->start; + hd->base = (void __iomem *)res->start; setup_timer(&hd->timer, heartbeat_timer, (unsigned long)hd); platform_set_drvdata(pdev, hd); diff --git a/trunk/arch/sh/drivers/pci/Makefile b/trunk/arch/sh/drivers/pci/Makefile index 2f65ac72f48a..0e9b532b9fbc 100644 --- a/trunk/arch/sh/drivers/pci/Makefile +++ b/trunk/arch/sh/drivers/pci/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_PCI_AUTO) += pci-auto.o obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o -obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o diff --git a/trunk/arch/sh/drivers/pci/ops-sh4.c b/trunk/arch/sh/drivers/pci/ops-sh4.c index 710a3b0306e5..54232f13e406 100644 --- a/trunk/arch/sh/drivers/pci/ops-sh4.c +++ b/trunk/arch/sh/drivers/pci/ops-sh4.c @@ -153,7 +153,7 @@ static void __init pci_fixup_ide_bases(struct pci_dev *d) } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); -char * __devinit pcibios_setup(char *str) +char * __init pcibios_setup(char *str) { if (!strcmp(str, "off")) { pci_probe = 0; diff --git a/trunk/arch/sh/drivers/pci/pci-st40.c b/trunk/arch/sh/drivers/pci/pci-st40.c index 1502a14386b6..543417ff8314 100644 --- a/trunk/arch/sh/drivers/pci/pci-st40.c +++ b/trunk/arch/sh/drivers/pci/pci-st40.c @@ -328,7 +328,7 @@ int __init st40pci_init(unsigned memStart, unsigned memSize) return 1; } -char * __devinit pcibios_setup(char *str) +char * __init pcibios_setup(char *str) { return str; } diff --git a/trunk/arch/sh/drivers/pci/pci.c b/trunk/arch/sh/drivers/pci/pci.c index ccaba368ac9b..d439336d2e18 100644 --- a/trunk/arch/sh/drivers/pci/pci.c +++ b/trunk/arch/sh/drivers/pci/pci.c @@ -71,7 +71,7 @@ subsys_initcall(pcibios_init); * Called after each bus is probed, but before its children * are examined. */ -void __devinit pcibios_fixup_bus(struct pci_bus *bus) +void __init pcibios_fixup_bus(struct pci_bus *bus) { pci_read_bridge_bases(bus); } diff --git a/trunk/arch/sh/drivers/push-switch.c b/trunk/arch/sh/drivers/push-switch.c index 725be6de589b..b3d20c0e021f 100644 --- a/trunk/arch/sh/drivers/push-switch.c +++ b/trunk/arch/sh/drivers/push-switch.c @@ -138,4 +138,4 @@ module_exit(switch_exit); MODULE_VERSION(DRV_VERSION); MODULE_AUTHOR("Paul Mundt"); -MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPLv2"); diff --git a/trunk/arch/sh/kernel/cpu/clock.c b/trunk/arch/sh/kernel/cpu/clock.c index 92807ffa8e20..63251549e9a8 100644 --- a/trunk/arch/sh/kernel/cpu/clock.c +++ b/trunk/arch/sh/kernel/cpu/clock.c @@ -229,22 +229,6 @@ void clk_recalc_rate(struct clk *clk) } EXPORT_SYMBOL_GPL(clk_recalc_rate); -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - if (likely(clk->ops && clk->ops->round_rate)) { - unsigned long flags, rounded; - - spin_lock_irqsave(&clock_lock, flags); - rounded = clk->ops->round_rate(clk, rate); - spin_unlock_irqrestore(&clock_lock, flags); - - return rounded; - } - - return clk_get_rate(clk); -} -EXPORT_SYMBOL_GPL(clk_round_rate); - /* * Returns a clock. Note that we first try to use device id on the bus * and clock name. If this fails, we try to use clock name only. diff --git a/trunk/arch/sh/kernel/cpu/irq/Makefile b/trunk/arch/sh/kernel/cpu/irq/Makefile index 9ddb446ac930..1c23308cfc25 100644 --- a/trunk/arch/sh/kernel/cpu/irq/Makefile +++ b/trunk/arch/sh/kernel/cpu/irq/Makefile @@ -6,5 +6,4 @@ obj-y += imask.o obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o -obj-$(CONFIG_CPU_HAS_INTC_IRQ) += intc.o obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o diff --git a/trunk/arch/sh/kernel/cpu/irq/intc.c b/trunk/arch/sh/kernel/cpu/irq/intc.c deleted file mode 100644 index 9345a7130e9e..000000000000 --- a/trunk/arch/sh/kernel/cpu/irq/intc.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Shared interrupt handling code for IPR and INTC2 types of IRQs. - * - * Copyright (C) 2007 Magnus Damm - * - * Based on intc2.c and ipr.c - * - * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi - * Copyright (C) 2000 Kazumoto Kojima - * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) - * Copyright (C) 2003 Takashi Kusuda - * Copyright (C) 2005, 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include - -#define _INTC_MK(fn, idx, bit, value) \ - ((fn) << 24 | ((value) << 16) | ((idx) << 8) | (bit)) -#define _INTC_FN(h) (h >> 24) -#define _INTC_VALUE(h) ((h >> 16) & 0xff) -#define _INTC_IDX(h) ((h >> 8) & 0xff) -#define _INTC_BIT(h) (h & 0xff) - -#define _INTC_PTR(desc, member, data) \ - (desc->member + _INTC_IDX(data)) - -static inline struct intc_desc *get_intc_desc(unsigned int irq) -{ - struct irq_chip *chip = get_irq_chip(irq); - return (void *)((char *)chip - offsetof(struct intc_desc, chip)); -} - -static inline unsigned int set_field(unsigned int value, - unsigned int field_value, - unsigned int width, - unsigned int shift) -{ - value &= ~(((1 << width) - 1) << shift); - value |= field_value << shift; - return value; -} - -static inline unsigned int set_prio_field(struct intc_desc *desc, - unsigned int value, - unsigned int priority, - unsigned int data) -{ - unsigned int width = _INTC_PTR(desc, prio_regs, data)->field_width; - - return set_field(value, priority, width, _INTC_BIT(data)); -} - -static void disable_prio_16(struct intc_desc *desc, unsigned int data) -{ - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; - - ctrl_outw(set_prio_field(desc, ctrl_inw(addr), 0, data), addr); -} - -static void enable_prio_16(struct intc_desc *desc, unsigned int data) -{ - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; - unsigned int prio = _INTC_VALUE(data); - - ctrl_outw(set_prio_field(desc, ctrl_inw(addr), prio, data), addr); -} - -static void disable_prio_32(struct intc_desc *desc, unsigned int data) -{ - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; - - ctrl_outl(set_prio_field(desc, ctrl_inl(addr), 0, data), addr); -} - -static void enable_prio_32(struct intc_desc *desc, unsigned int data) -{ - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; - unsigned int prio = _INTC_VALUE(data); - - ctrl_outl(set_prio_field(desc, ctrl_inl(addr), prio, data), addr); -} - -static void disable_mask_8(struct intc_desc *desc, unsigned int data) -{ - ctrl_outb(1 << _INTC_BIT(data), - _INTC_PTR(desc, mask_regs, data)->set_reg); -} - -static void enable_mask_8(struct intc_desc *desc, unsigned int data) -{ - ctrl_outb(1 << _INTC_BIT(data), - _INTC_PTR(desc, mask_regs, data)->clr_reg); -} - -static void disable_mask_32(struct intc_desc *desc, unsigned int data) -{ - ctrl_outl(1 << _INTC_BIT(data), - _INTC_PTR(desc, mask_regs, data)->set_reg); -} - -static void enable_mask_32(struct intc_desc *desc, unsigned int data) -{ - ctrl_outl(1 << _INTC_BIT(data), - _INTC_PTR(desc, mask_regs, data)->clr_reg); -} - -enum { REG_FN_ERROR=0, - REG_FN_MASK_8, REG_FN_MASK_32, - REG_FN_PRIO_16, REG_FN_PRIO_32 }; - -static struct { - void (*enable)(struct intc_desc *, unsigned int); - void (*disable)(struct intc_desc *, unsigned int); -} intc_reg_fns[] = { - [REG_FN_MASK_8] = { enable_mask_8, disable_mask_8 }, - [REG_FN_MASK_32] = { enable_mask_32, disable_mask_32 }, - [REG_FN_PRIO_16] = { enable_prio_16, disable_prio_16 }, - [REG_FN_PRIO_32] = { enable_prio_32, disable_prio_32 }, -}; - -static void intc_enable(unsigned int irq) -{ - struct intc_desc *desc = get_intc_desc(irq); - unsigned int data = (unsigned int) get_irq_chip_data(irq); - - intc_reg_fns[_INTC_FN(data)].enable(desc, data); -} - -static void intc_disable(unsigned int irq) -{ - struct intc_desc *desc = get_intc_desc(irq); - unsigned int data = (unsigned int) get_irq_chip_data(irq); - - intc_reg_fns[_INTC_FN(data)].disable(desc, data); -} - -static void set_sense_16(struct intc_desc *desc, unsigned int data) -{ - unsigned long addr = _INTC_PTR(desc, sense_regs, data)->reg; - unsigned int width = _INTC_PTR(desc, sense_regs, data)->field_width; - unsigned int bit = _INTC_BIT(data); - unsigned int value = _INTC_VALUE(data); - - ctrl_outw(set_field(ctrl_inw(addr), value, width, bit), addr); -} - -static void set_sense_32(struct intc_desc *desc, unsigned int data) -{ - unsigned long addr = _INTC_PTR(desc, sense_regs, data)->reg; - unsigned int width = _INTC_PTR(desc, sense_regs, data)->field_width; - unsigned int bit = _INTC_BIT(data); - unsigned int value = _INTC_VALUE(data); - - ctrl_outl(set_field(ctrl_inl(addr), value, width, bit), addr); -} - -#define VALID(x) (x | 0x80) - -static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { - [IRQ_TYPE_EDGE_FALLING] = VALID(0), - [IRQ_TYPE_EDGE_RISING] = VALID(1), - [IRQ_TYPE_LEVEL_LOW] = VALID(2), - [IRQ_TYPE_LEVEL_HIGH] = VALID(3), -}; - -static int intc_set_sense(unsigned int irq, unsigned int type) -{ - struct intc_desc *desc = get_intc_desc(irq); - unsigned char value = intc_irq_sense_table[type & IRQ_TYPE_SENSE_MASK]; - unsigned int i, j, data, bit; - intc_enum enum_id = 0; - - for (i = 0; i < desc->nr_vectors; i++) { - struct intc_vect *vect = desc->vectors + i; - - if (evt2irq(vect->vect) != irq) - continue; - - enum_id = vect->enum_id; - break; - } - - if (!enum_id || !value) - return -EINVAL; - - value ^= VALID(0); - - for (i = 0; i < desc->nr_sense_regs; i++) { - struct intc_sense_reg *sr = desc->sense_regs + i; - - for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) { - if (sr->enum_ids[j] != enum_id) - continue; - - bit = sr->reg_width - ((j + 1) * sr->field_width); - data = _INTC_MK(0, i, bit, value); - - switch(sr->reg_width) { - case 16: - set_sense_16(desc, data); - break; - case 32: - set_sense_32(desc, data); - break; - } - - return 0; - } - } - - return -EINVAL; -} - -static unsigned int __init intc_find_mask_handler(unsigned int width) -{ - switch (width) { - case 8: - return REG_FN_MASK_8; - case 32: - return REG_FN_MASK_32; - } - - BUG(); - return REG_FN_ERROR; -} - -static unsigned int __init intc_find_prio_handler(unsigned int width) -{ - switch (width) { - case 16: - return REG_FN_PRIO_16; - case 32: - return REG_FN_PRIO_32; - } - - BUG(); - return REG_FN_ERROR; -} - -static intc_enum __init intc_grp_id(struct intc_desc *desc, intc_enum enum_id) -{ - struct intc_group *g = desc->groups; - unsigned int i, j; - - for (i = 0; g && enum_id && i < desc->nr_groups; i++) { - g = desc->groups + i; - - for (j = 0; g->enum_ids[j]; j++) { - if (g->enum_ids[j] != enum_id) - continue; - - return g->enum_id; - } - } - - return 0; -} - -static unsigned int __init intc_prio_value(struct intc_desc *desc, - intc_enum enum_id, int do_grps) -{ - struct intc_prio *p = desc->priorities; - unsigned int i; - - for (i = 0; p && enum_id && i < desc->nr_priorities; i++) { - p = desc->priorities + i; - - if (p->enum_id != enum_id) - continue; - - return p->priority; - } - - if (do_grps) - return intc_prio_value(desc, intc_grp_id(desc, enum_id), 0); - - /* default to the lowest priority possible if no priority is set - * - this needs to be at least 2 for 5-bit priorities on 7780 - */ - - return 2; -} - -static unsigned int __init intc_mask_data(struct intc_desc *desc, - intc_enum enum_id, int do_grps) -{ - struct intc_mask_reg *mr = desc->mask_regs; - unsigned int i, j, fn; - - for (i = 0; mr && enum_id && i < desc->nr_mask_regs; i++) { - mr = desc->mask_regs + i; - - for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) { - if (mr->enum_ids[j] != enum_id) - continue; - - fn = intc_find_mask_handler(mr->reg_width); - if (fn == REG_FN_ERROR) - return 0; - - return _INTC_MK(fn, i, (mr->reg_width - 1) - j, 0); - } - } - - if (do_grps) - return intc_mask_data(desc, intc_grp_id(desc, enum_id), 0); - - return 0; -} - -static unsigned int __init intc_prio_data(struct intc_desc *desc, - intc_enum enum_id, int do_grps) -{ - struct intc_prio_reg *pr = desc->prio_regs; - unsigned int i, j, fn, bit, prio; - - for (i = 0; pr && enum_id && i < desc->nr_prio_regs; i++) { - pr = desc->prio_regs + i; - - for (j = 0; j < ARRAY_SIZE(pr->enum_ids); j++) { - if (pr->enum_ids[j] != enum_id) - continue; - - fn = intc_find_prio_handler(pr->reg_width); - if (fn == REG_FN_ERROR) - return 0; - - prio = intc_prio_value(desc, enum_id, 1); - bit = pr->reg_width - ((j + 1) * pr->field_width); - - BUG_ON(bit < 0); - - return _INTC_MK(fn, i, bit, prio); - } - } - - if (do_grps) - return intc_prio_data(desc, intc_grp_id(desc, enum_id), 0); - - return 0; -} - -static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id, - unsigned int irq) -{ - unsigned int data[2], primary; - - /* Prefer single interrupt source bitmap over other combinations: - * 1. bitmap, single interrupt source - * 2. priority, single interrupt source - * 3. bitmap, multiple interrupt sources (groups) - * 4. priority, multiple interrupt sources (groups) - */ - - data[0] = intc_mask_data(desc, enum_id, 0); - data[1] = intc_prio_data(desc, enum_id, 0); - - primary = 0; - if (!data[0] && data[1]) - primary = 1; - - data[0] = data[0] ? data[0] : intc_mask_data(desc, enum_id, 1); - data[1] = data[1] ? data[1] : intc_prio_data(desc, enum_id, 1); - - if (!data[primary]) - primary ^= 1; - - BUG_ON(!data[primary]); /* must have primary masking method */ - - disable_irq_nosync(irq); - set_irq_chip_and_handler_name(irq, &desc->chip, - handle_level_irq, "level"); - set_irq_chip_data(irq, (void *)data[primary]); - - /* enable secondary masking method if present */ - if (data[!primary]) - intc_reg_fns[_INTC_FN(data[!primary])].enable(desc, - data[!primary]); - - /* irq should be disabled by default */ - desc->chip.mask(irq); -} - -void __init register_intc_controller(struct intc_desc *desc) -{ - unsigned int i; - - desc->chip.mask = intc_disable; - desc->chip.unmask = intc_enable; - desc->chip.mask_ack = intc_disable; - desc->chip.set_type = intc_set_sense; - - for (i = 0; i < desc->nr_vectors; i++) { - struct intc_vect *vect = desc->vectors + i; - - intc_register_irq(desc, vect->enum_id, evt2irq(vect->vect)); - } -} diff --git a/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c index a979b981e6a3..1a107fe22dde 100644 --- a/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -88,7 +88,7 @@ static struct ipr_desc ipr_irq_desc = { }, }; -void __init plat_irq_setup(void) +void __init init_IRQ_ipr(void) { register_ipr_controller(&ipr_irq_desc); } diff --git a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index deab16500167..b6e3a6351fa6 100644 --- a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -107,7 +107,7 @@ static struct ipr_desc ipr_irq_desc = { }, }; -void __init plat_irq_setup(void) +void __init init_IRQ_ipr(void) { register_ipr_controller(&ipr_irq_desc); } diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c index ebd9d06d8bdd..a55b8ce2c54c 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -92,7 +92,7 @@ static struct ipr_desc ipr_irq_desc = { }, }; -void __init plat_irq_setup(void) +void __init init_IRQ_ipr(void) { register_ipr_controller(&ipr_irq_desc); } diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7709.c index 086f8e2545af..d79ec0c0522f 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7709.c +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7709.c @@ -139,7 +139,7 @@ static struct ipr_desc ipr_irq_desc = { }, }; -void __init plat_irq_setup(void) +void __init init_IRQ_ipr(void) { register_ipr_controller(&ipr_irq_desc); } diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 132284893373..f40e6dac337d 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -101,7 +101,7 @@ static struct ipr_desc ipr_irq_desc = { }, }; -void __init plat_irq_setup(void) +void __init init_IRQ_ipr(void) { register_ipr_controller(&ipr_irq_desc); } diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c index f2286de22bd5..da153bcdfeb2 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -82,213 +82,88 @@ static int __init sh7750_devices_setup(void) } __initcall(sh7750_devices_setup); -enum { - UNUSED = 0, - - /* interrupt sources */ - IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */ - HUDI, GPIOI, - DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3, - DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7, - DMAC_DMAE, - PCIC0_PCISERR, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON, - PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3, - TMU3, TMU4, TMU0, TMU1, TMU2_TUNI, TMU2_TICPI, - RTC_ATI, RTC_PRI, RTC_CUI, - SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI, - SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI, - WDT, - REF_RCMI, REF_ROVI, - - /* interrupt groups */ - DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF, -}; - -static struct intc_vect vectors[] = { - INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620), - INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), - INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460), - INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), - INTC_VECT(RTC_CUI, 0x4c0), - INTC_VECT(SCI1_ERI, 0x4e0), INTC_VECT(SCI1_RXI, 0x500), - INTC_VECT(SCI1_TXI, 0x520), INTC_VECT(SCI1_TEI, 0x540), - INTC_VECT(SCIF_ERI, 0x700), INTC_VECT(SCIF_RXI, 0x720), - INTC_VECT(SCIF_BRI, 0x740), INTC_VECT(SCIF_TXI, 0x760), - INTC_VECT(WDT, 0x560), - INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0), -}; - -static struct intc_group groups[] = { - INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI), - INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), - INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI), - INTC_GROUP(SCIF, SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI), - INTC_GROUP(REF, REF_RCMI, REF_ROVI), -}; - -static struct intc_prio priorities[] = { - INTC_PRIO(SCIF, 3), - INTC_PRIO(SCI1, 3), - INTC_PRIO(DMAC, 7), -}; - -static struct intc_prio_reg prio_registers[] = { - { 0xffd00004, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, - { 0xffd00008, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } }, - { 0xffd0000c, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } }, - { 0xffd00010, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } }, - { 0xfe080000, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0, - TMU4, TMU3, - PCIC1, PCIC0_PCISERR } }, -}; - -static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups, - priorities, NULL, prio_registers, NULL); - -/* SH7750, SH7750S, SH7751 and SH7091 all have 4-channel DMA controllers */ -#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \ - defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ - defined(CONFIG_CPU_SUBTYPE_SH7751) || \ - defined(CONFIG_CPU_SUBTYPE_SH7091) -static struct intc_vect vectors_dma4[] = { - INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660), - INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0), - INTC_VECT(DMAC_DMAE, 0x6c0), -}; - -static struct intc_group groups_dma4[] = { - INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, - DMAC_DMTE3, DMAC_DMAE), -}; - -static DECLARE_INTC_DESC(intc_desc_dma4, "sh7750_dma4", - vectors_dma4, groups_dma4, - priorities, NULL, prio_registers, NULL); -#endif - -/* SH7750R and SH7751R both have 8-channel DMA controllers */ -#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || defined(CONFIG_CPU_SUBTYPE_SH7751R) -static struct intc_vect vectors_dma8[] = { - INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660), - INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0), - INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0), - INTC_VECT(DMAC_DMTE6, 0x7c0), INTC_VECT(DMAC_DMTE7, 0x7e0), - INTC_VECT(DMAC_DMAE, 0x6c0), -}; - -static struct intc_group groups_dma8[] = { - INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, - DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5, - DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE), -}; - -static DECLARE_INTC_DESC(intc_desc_dma8, "sh7750_dma8", - vectors_dma8, groups_dma8, - priorities, NULL, prio_registers, NULL); -#endif - -/* SH7750R, SH7751 and SH7751R all have two extra timer channels */ -#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ - defined(CONFIG_CPU_SUBTYPE_SH7751) || \ - defined(CONFIG_CPU_SUBTYPE_SH7751R) -static struct intc_vect vectors_tmu34[] = { - INTC_VECT(TMU3, 0xb00), INTC_VECT(TMU4, 0xb80), -}; - -static struct intc_mask_reg mask_registers[] = { - { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, TMU4, TMU3, - PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON, - PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, - PCIC1_PCIDMA3, PCIC0_PCISERR } }, +static struct ipr_data ipr_irq_table[] = { + /* IRQ, IPR-idx, shift, priority */ + { 16, 0, 12, 2 }, /* TMU0 TUNI*/ + { 17, 0, 12, 2 }, /* TMU1 TUNI */ + { 18, 0, 4, 2 }, /* TMU2 TUNI */ + { 19, 0, 4, 2 }, /* TMU2 TIPCI */ + { 27, 1, 12, 2 }, /* WDT ITI */ + { 20, 0, 0, 2 }, /* RTC ATI (alarm) */ + { 21, 0, 0, 2 }, /* RTC PRI (period) */ + { 22, 0, 0, 2 }, /* RTC CUI (carry) */ + { 23, 1, 4, 3 }, /* SCI ERI */ + { 24, 1, 4, 3 }, /* SCI RXI */ + { 25, 1, 4, 3 }, /* SCI TXI */ + { 40, 2, 4, 3 }, /* SCIF ERI */ + { 41, 2, 4, 3 }, /* SCIF RXI */ + { 42, 2, 4, 3 }, /* SCIF BRI */ + { 43, 2, 4, 3 }, /* SCIF TXI */ + { 34, 2, 8, 7 }, /* DMAC DMTE0 */ + { 35, 2, 8, 7 }, /* DMAC DMTE1 */ + { 36, 2, 8, 7 }, /* DMAC DMTE2 */ + { 37, 2, 8, 7 }, /* DMAC DMTE3 */ + { 38, 2, 8, 7 }, /* DMAC DMAE */ +}; + +static unsigned long ipr_offsets[] = { + 0xffd00004UL, /* 0: IPRA */ + 0xffd00008UL, /* 1: IPRB */ + 0xffd0000cUL, /* 2: IPRC */ + 0xffd00010UL, /* 3: IPRD */ +}; + +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + + .chip = { + .name = "IPR-sh7750", + }, }; -static DECLARE_INTC_DESC(intc_desc_tmu34, "sh7750_tmu34", - vectors_tmu34, NULL, priorities, - mask_registers, prio_registers, NULL); -#endif - -/* SH7750S, SH7750R, SH7751 and SH7751R all have IRLM priority registers */ -static struct intc_vect vectors_irlm[] = { - INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0), - INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360), +#ifdef CONFIG_CPU_SUBTYPE_SH7751 +static struct ipr_data ipr_irq_table_sh7751[] = { + { 44, 2, 8, 7 }, /* DMAC DMTE4 */ + { 45, 2, 8, 7 }, /* DMAC DMTE5 */ + { 46, 2, 8, 7 }, /* DMAC DMTE6 */ + { 47, 2, 8, 7 }, /* DMAC DMTE7 */ + /* The following use INTC_INPRI00 for masking, which is a 32-bit + register, not a 16-bit register like the IPRx registers, so it + would need special support */ + /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */ + /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */ }; -static DECLARE_INTC_DESC(intc_desc_irlm, "sh7750_irlm", vectors_irlm, NULL, - priorities, NULL, prio_registers, NULL); +static struct ipr_desc ipr_irq_desc_sh7751 = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), -/* SH7751 and SH7751R both have PCI */ -#if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7751R) -static struct intc_vect vectors_pci[] = { - INTC_VECT(PCIC0_PCISERR, 0xa00), INTC_VECT(PCIC1_PCIERR, 0xae0), - INTC_VECT(PCIC1_PCIPWDWN, 0xac0), INTC_VECT(PCIC1_PCIPWON, 0xaa0), - INTC_VECT(PCIC1_PCIDMA0, 0xa80), INTC_VECT(PCIC1_PCIDMA1, 0xa60), - INTC_VECT(PCIC1_PCIDMA2, 0xa40), INTC_VECT(PCIC1_PCIDMA3, 0xa20), -}; + .ipr_data = ipr_irq_table_sh7751, + .nr_irqs = ARRAY_SIZE(ipr_irq_table_sh7751), -static struct intc_group groups_pci[] = { - INTC_GROUP(PCIC1, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON, - PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3), + .chip = { + .name = "IPR-sh7751", + }, }; - -static DECLARE_INTC_DESC(intc_desc_pci, "sh7750_pci", vectors_pci, groups_pci, - priorities, mask_registers, prio_registers, NULL); #endif -#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \ - defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ - defined(CONFIG_CPU_SUBTYPE_SH7091) -void __init plat_irq_setup(void) +void __init init_IRQ_ipr(void) { - /* - * same vectors for SH7750, SH7750S and SH7091 except for IRLM, - * see below.. - */ - register_intc_controller(&intc_desc); - register_intc_controller(&intc_desc_dma4); -} + register_ipr_controller(&ipr_irq_desc); +#ifdef CONFIG_CPU_SUBTYPE_SH7751 + register_ipr_controller(&ipr_irq_desc_sh7751); #endif - -#if defined(CONFIG_CPU_SUBTYPE_SH7750R) -void __init plat_irq_setup(void) -{ - register_intc_controller(&intc_desc); - register_intc_controller(&intc_desc_dma8); - register_intc_controller(&intc_desc_tmu34); } -#endif - -#if defined(CONFIG_CPU_SUBTYPE_SH7751) -void __init plat_irq_setup(void) -{ - register_intc_controller(&intc_desc); - register_intc_controller(&intc_desc_dma4); - register_intc_controller(&intc_desc_tmu34); - register_intc_controller(&intc_desc_pci); -} -#endif - -#if defined(CONFIG_CPU_SUBTYPE_SH7751R) -void __init plat_irq_setup(void) -{ - register_intc_controller(&intc_desc); - register_intc_controller(&intc_desc_dma8); - register_intc_controller(&intc_desc_tmu34); - register_intc_controller(&intc_desc_pci); -} -#endif #define INTC_ICR 0xffd00000UL #define INTC_ICR_IRLM (1<<7) /* enable individual interrupt mode for external interupts */ -void __init ipr_irq_enable_irlm(void) +void ipr_irq_enable_irlm(void) { -#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7091) - BUG(); /* impossible to mask interrupts on SH7750 and SH7091 */ -#endif - register_intc_controller(&intc_desc_irlm); - ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); } diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 47fa27056253..3df169755673 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -109,6 +109,11 @@ static struct intc2_desc intc2_irq_desc __read_mostly = { }, }; +void __init init_IRQ_intc2(void) +{ + register_intc2_controller(&intc2_irq_desc); +} + static struct ipr_data ipr_irq_table[] = { /* IRQ, IPR-idx, shift, priority */ { 16, 0, 12, 2 }, /* TMU0 TUNI*/ @@ -158,8 +163,7 @@ static struct ipr_desc ipr_irq_desc = { }, }; -void __init plat_irq_setup(void) +void __init init_IRQ_ipr(void) { - register_intc2_controller(&intc2_irq_desc); register_ipr_controller(&ipr_irq_desc); } diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index a0fd8bb21f7c..51b386d454de 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -387,24 +387,9 @@ static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate, return err; } -static long sh7722_frqcr_round_rate(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk->parent->rate; - int div; - - /* look for multiplier/divisor pair */ - div = sh7722_find_divisors(parent_rate, rate); - if (div < 0) - return clk->rate; - - /* calculate new value of clock rate */ - return parent_rate * 2 / div; -} - static struct clk_ops sh7722_frqcr_clk_ops = { .recalc = sh7722_frqcr_recalc, .set_rate = sh7722_frqcr_set_rate, - .round_rate = sh7722_frqcr_round_rate, }; /* diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 25b913e07e2c..a3e159ef6dfe 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -19,21 +19,8 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, - }, - { - .mapbase = 0xffe10000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 81, 81, 81, 81 }, - }, - { - .mapbase = 0xffe20000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 82, 82, 82, 82 }, - }, - { + .irqs = { 80, 81, 83, 82 }, + }, { .flags = 0, } }; @@ -57,145 +44,46 @@ static int __init sh7722_devices_setup(void) } __initcall(sh7722_devices_setup); -enum { - UNUSED=0, - - /* interrupt sources */ - IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, - HUDI, - SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI, - RTC_ATI, RTC_PRI, RTC_CUI, - DMAC0, DMAC1, DMAC2, DMAC3, - VIO_CEUI, VIO_BEUI, VIO_VEUI, VOU, - VPU, TPU, - USB_USBI0, USB_USBI1, - DMAC4, DMAC5, DMAC_DADERR, - KEYSC, - SCIF0, SCIF1, SCIF2, SIOF0, SIOF1, SIO, - FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I, - I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI, - SDHI0, SDHI1, SDHI2, SDHI3, - CMT, TSIF, SIU, TWODG, - TMU0, TMU1, TMU2, - IRDA, JPU, LCDC, - - /* interrupt groups */ - - SIM, RTC, DMAC0123, VIOVOU, USB, DMAC45, FLCTL, I2C, SDHI, -}; - -static struct intc_vect vectors[] = { - INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), - INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), - INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), - INTC_VECT(IRQ6, 0x6c0), INTC_VECT(IRQ7, 0x6e0), - INTC_VECT(SIM_ERI, 0x700), INTC_VECT(SIM_RXI, 0x720), - INTC_VECT(SIM_TXI, 0x740), INTC_VECT(SIM_TEI, 0x760), - INTC_VECT(RTC_ATI, 0x780), INTC_VECT(RTC_PRI, 0x7a0), - INTC_VECT(RTC_CUI, 0x7c0), - INTC_VECT(DMAC0, 0x800), INTC_VECT(DMAC1, 0x820), - INTC_VECT(DMAC2, 0x840), INTC_VECT(DMAC3, 0x860), - INTC_VECT(VIO_CEUI, 0x880), INTC_VECT(VIO_BEUI, 0x8a0), - INTC_VECT(VIO_VEUI, 0x8c0), INTC_VECT(VOU, 0x8e0), - INTC_VECT(VPU, 0x980), INTC_VECT(TPU, 0x9a0), - INTC_VECT(USB_USBI0, 0xa20), INTC_VECT(USB_USBI1, 0xa40), - INTC_VECT(DMAC4, 0xb80), INTC_VECT(DMAC5, 0xba0), - INTC_VECT(DMAC_DADERR, 0xbc0), INTC_VECT(KEYSC, 0xbe0), - INTC_VECT(SCIF0, 0xc00), INTC_VECT(SCIF1, 0xc20), - INTC_VECT(SCIF2, 0xc40), INTC_VECT(SIOF0, 0xc80), - INTC_VECT(SIOF1, 0xca0), INTC_VECT(SIO, 0xd00), - INTC_VECT(FLCTL_FLSTEI, 0xd80), INTC_VECT(FLCTL_FLENDI, 0xda0), - INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0), - INTC_VECT(I2C_ALI, 0xe00), INTC_VECT(I2C_TACKI, 0xe20), - INTC_VECT(I2C_WAITI, 0xe40), INTC_VECT(I2C_DTEI, 0xe60), - INTC_VECT(SDHI0, 0xe80), INTC_VECT(SDHI1, 0xea0), - INTC_VECT(SDHI2, 0xec0), INTC_VECT(SDHI3, 0xee0), - INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20), - INTC_VECT(SIU, 0xf80), INTC_VECT(TWODG, 0xfa0), - INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), - INTC_VECT(TMU2, 0x440), INTC_VECT(IRDA, 0x480), - INTC_VECT(JPU, 0x560), INTC_VECT(LCDC, 0x580), -}; - -static struct intc_group groups[] = { - INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI), - INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), - INTC_GROUP(DMAC0123, DMAC0, DMAC1, DMAC2, DMAC3), - INTC_GROUP(VIOVOU, VIO_CEUI, VIO_BEUI, VIO_VEUI, VOU), - INTC_GROUP(USB, USB_USBI0, USB_USBI1), - INTC_GROUP(DMAC45, DMAC4, DMAC5, DMAC_DADERR), - INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLENDI, - FLCTL_FLTREQ0I, FLCTL_FLTREQ1I), - INTC_GROUP(I2C, I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI), - INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3), +static struct ipr_data ipr_irq_table[] = { + /* IRQ, IPR-idx, shift, prio */ + { 16, 0, 12, 2 }, /* TMU0 */ + { 17, 0, 8, 2 }, /* TMU1 */ + { 80, 6, 12, 3 }, /* SCIF ERI */ + { 81, 6, 12, 3 }, /* SCIF RXI */ + { 82, 6, 12, 3 }, /* SCIF BRI */ + { 83, 6, 12, 3 }, /* SCIF TXI */ }; -static struct intc_prio priorities[] = { - INTC_PRIO(SCIF0, 3), - INTC_PRIO(SCIF1, 3), - INTC_PRIO(SCIF2, 3), - INTC_PRIO(TMU0, 2), - INTC_PRIO(TMU1, 2), +static unsigned long ipr_offsets[] = { + 0xa4080000, /* 0: IPRA */ + 0xa4080004, /* 1: IPRB */ + 0xa4080008, /* 2: IPRC */ + 0xa408000c, /* 3: IPRD */ + 0xa4080010, /* 4: IPRE */ + 0xa4080014, /* 5: IPRF */ + 0xa4080018, /* 6: IPRG */ + 0xa408001c, /* 7: IPRH */ + 0xa4080020, /* 8: IPRI */ + 0xa4080024, /* 9: IPRJ */ + 0xa4080028, /* 10: IPRK */ + 0xa408002c, /* 11: IPRL */ }; -static struct intc_mask_reg mask_registers[] = { - { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ - { } }, - { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ - { VOU, VIO_VEUI, VIO_BEUI, VIO_CEUI, DMAC3, DMAC2, DMAC1, DMAC0 } }, - { 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */ - { 0, 0, 0, VPU, } }, - { 0xa408008c, 0xa40800cc, 8, /* IMR3 / IMCR3 */ - { SIM_TEI, SIM_TXI, SIM_RXI, SIM_ERI, 0, 0, 0, IRDA } }, - { 0xa4080090, 0xa40800d0, 8, /* IMR4 / IMCR4 */ - { 0, TMU2, TMU1, TMU0, JPU, 0, 0, LCDC } }, - { 0xa4080094, 0xa40800d4, 8, /* IMR5 / IMCR5 */ - { KEYSC, DMAC_DADERR, DMAC5, DMAC4, 0, SCIF2, SCIF1, SCIF0 } }, - { 0xa4080098, 0xa40800d8, 8, /* IMR6 / IMCR6 */ - { 0, 0, 0, SIO, 0, 0, SIOF1, SIOF0 } }, - { 0xa408009c, 0xa40800dc, 8, /* IMR7 / IMCR7 */ - { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, - FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } }, - { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ - { SDHI3, SDHI2, SDHI1, SDHI0, 0, 0, TWODG, SIU } }, - { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ - { 0, 0, 0, CMT, 0, USB_USBI1, USB_USBI0, } }, - { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ - { } }, - { 0xa40800ac, 0xa40800ec, 8, /* IMR11 / IMCR11 */ - { 0, RTC_CUI, RTC_PRI, RTC_ATI, 0, TPU, 0, TSIF } }, - { 0xa4140044, 0xa4140064, 8, /* INTMSK00 / INTMSKCLR00 */ - { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, -}; +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), -static struct intc_prio_reg prio_registers[] = { - { 0xa4080000, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, IRDA } }, - { 0xa4080004, 16, 4, /* IPRB */ { JPU, LCDC, SIM } }, - { 0xa4080008, 16, 4, /* IPRC */ { } }, - { 0xa408000c, 16, 4, /* IPRD */ { } }, - { 0xa4080010, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, 0, VPU } }, - { 0xa4080014, 16, 4, /* IPRF */ { KEYSC, DMAC45, USB, CMT } }, - { 0xa4080018, 16, 4, /* IPRG */ { SCIF0, SCIF1, SCIF2 } }, - { 0xa408001c, 16, 4, /* IPRH */ { SIOF0, SIOF1, FLCTL, I2C } }, - { 0xa4080020, 16, 4, /* IPRI */ { SIO, 0, TSIF, RTC } }, - { 0xa4080024, 16, 4, /* IPRJ */ { 0, 0, SIU } }, - { 0xa4080028, 16, 4, /* IPRK */ { 0, 0, 0, SDHI } }, - { 0xa408002c, 16, 4, /* IPRL */ { TWODG, 0, TPU } }, - { 0xa4140010, 32, 4, /* INTPRI00 */ - { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, -}; + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), -static struct intc_sense_reg sense_registers[] = { - { 0xa414001c, 16, 2, /* ICR1 */ - { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, + .chip = { + .name = "IPR-sh7722", + }, }; -static DECLARE_INTC_DESC(intc_desc, "sh7722", vectors, groups, priorities, - mask_registers, prio_registers, sense_registers); - -void __init plat_irq_setup(void) +void __init init_IRQ_ipr(void) { - register_intc_controller(&intc_desc); + register_ipr_controller(&ipr_irq_desc); } void __init plat_mem_setup(void) diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index a4127ec15203..b57c760bffde 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -30,7 +30,7 @@ static struct resource rtc_resources[] = { }, [3] = { /* Alarm IRQ */ - .start = 20, + .start = 23, .flags = IORESOURCE_IRQ, }, }; @@ -78,205 +78,44 @@ static int __init sh7780_devices_setup(void) } __initcall(sh7780_devices_setup); -enum { - UNUSED = 0, +static struct intc2_data intc2_irq_table[] = { + { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ - /* interrupt sources */ + { 21, 1, 0, 0, 2, 2 }, + { 22, 1, 1, 0, 2, 2 }, + { 23, 1, 2, 0, 2, 2 }, - IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, - IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, - IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, - IRL_HHLL, IRL_HHLH, IRL_HHHL, + { 40, 8, 24, 0, 3, 3 }, /* SCIF0 ERI */ + { 41, 8, 24, 0, 3, 3 }, /* SCIF0 RXI */ + { 42, 8, 24, 0, 3, 3 }, /* SCIF0 BRI */ + { 43, 8, 24, 0, 3, 3 }, /* SCIF0 TXI */ - IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, - RTC_ATI, RTC_PRI, RTC_CUI, - WDT, - TMU0, TMU1, TMU2, TMU2_TICPI, - HUDI, - DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3, DMAC0_DMAE, - SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI, - DMAC0_DMINT4, DMAC0_DMINT5, DMAC1_DMINT6, DMAC1_DMINT7, - CMT, HAC, - PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, - PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0, - SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI, - SIOF, HSPI, - MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY, - DMAC1_DMINT8, DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11, - TMU3, TMU4, TMU5, - SSI, - FLCTL_FLSTE, FLCTL_FLEND, FLCTL_FLTRQ0, FLCTL_FLTRQ1, - GPIOI0, GPIOI1, GPIOI2, GPIOI3, + { 76, 8, 16, 0, 4, 3 }, /* SCIF1 ERI */ + { 77, 8, 16, 0, 4, 3 }, /* SCIF1 RXI */ + { 78, 8, 16, 0, 4, 3 }, /* SCIF1 BRI */ + { 79, 8, 16, 0, 4, 3 }, /* SCIF1 TXI */ - /* interrupt groups */ - - RTC, TMU012, DMAC0, SCIF0, DMAC45, DMAC1, - PCIC5, SCIF1, MMCIF, TMU345, FLCTL, GPIO, -}; - -static struct intc_vect vectors[] = { - INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), - INTC_VECT(RTC_CUI, 0x4c0), - INTC_VECT(WDT, 0x560), - INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0), - INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0), - INTC_VECT(HUDI, 0x600), - INTC_VECT(DMAC0_DMINT0, 0x640), INTC_VECT(DMAC0_DMINT1, 0x660), - INTC_VECT(DMAC0_DMINT2, 0x680), INTC_VECT(DMAC0_DMINT3, 0x6a0), - INTC_VECT(DMAC0_DMAE, 0x6c0), - INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720), - INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760), - INTC_VECT(DMAC0_DMINT4, 0x780), INTC_VECT(DMAC0_DMINT5, 0x7a0), - INTC_VECT(DMAC1_DMINT6, 0x7c0), INTC_VECT(DMAC1_DMINT7, 0x7e0), - INTC_VECT(CMT, 0x900), INTC_VECT(HAC, 0x980), - INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20), - INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60), - INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0), - INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0), - INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20), - INTC_VECT(SCIF1_ERI, 0xb80), INTC_VECT(SCIF1_RXI, 0xba0), - INTC_VECT(SCIF1_BRI, 0xbc0), INTC_VECT(SCIF1_TXI, 0xbe0), - INTC_VECT(SIOF, 0xc00), INTC_VECT(HSPI, 0xc80), - INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20), - INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60), - INTC_VECT(DMAC1_DMINT8, 0xd80), INTC_VECT(DMAC1_DMINT9, 0xda0), - INTC_VECT(DMAC1_DMINT10, 0xdc0), INTC_VECT(DMAC1_DMINT11, 0xde0), - INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20), - INTC_VECT(TMU5, 0xe40), - INTC_VECT(SSI, 0xe80), - INTC_VECT(FLCTL_FLSTE, 0xf00), INTC_VECT(FLCTL_FLEND, 0xf20), - INTC_VECT(FLCTL_FLTRQ0, 0xf40), INTC_VECT(FLCTL_FLTRQ1, 0xf60), - INTC_VECT(GPIOI0, 0xf80), INTC_VECT(GPIOI1, 0xfa0), - INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0), -}; - -static struct intc_group groups[] = { - INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), - INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI), - INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, - DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE), - INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI), - INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, - DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11), - INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0), - INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI), - INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY), - INTC_GROUP(TMU345, TMU3, TMU4, TMU5), - INTC_GROUP(FLCTL, FLCTL_FLSTE, FLCTL_FLEND, - FLCTL_FLTRQ0, FLCTL_FLTRQ1), - INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3), -}; - -static struct intc_prio priorities[] = { - INTC_PRIO(SCIF0, 3), - INTC_PRIO(SCIF1, 3), -}; - -static struct intc_mask_reg mask_registers[] = { - { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */ - { 0, 0, 0, 0, 0, 0, GPIO, FLCTL, - SSI, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB, - PCIINTA, PCISERR, HAC, CMT, 0, 0, DMAC1, DMAC0, - HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } }, -}; - -static struct intc_prio_reg prio_registers[] = { - { 0xffd40000, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, TMU2, TMU2_TICPI } }, - { 0xffd40004, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } }, - { 0xffd40008, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } }, - { 0xffd4000c, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } }, - { 0xffd40010, 32, 8, /* INT2PRI4 */ { CMT, HAC, PCISERR, PCIINTA, } }, - { 0xffd40014, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC, - PCIINTD, PCIC5 } }, - { 0xffd40018, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } }, - { 0xffd4001c, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } }, -}; - -static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities, - mask_registers, prio_registers, NULL); - -/* Support for external interrupt pins in IRQ mode */ - -static struct intc_vect irq_vectors[] = { - INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), - INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), - INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380), - INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200), -}; - -static struct intc_mask_reg irq_mask_registers[] = { - { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */ - { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, -}; - -static struct intc_prio_reg irq_prio_registers[] = { - { 0xffd00010, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, - IRQ4, IRQ5, IRQ6, IRQ7 } }, -}; - -static struct intc_sense_reg irq_sense_registers[] = { - { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3, - IRQ4, IRQ5, IRQ6, IRQ7 } }, + { 64, 0x10, 8, 0, 14, 2 }, /* PCIC0 */ + { 65, 0x10, 0, 0, 15, 2 }, /* PCIC1 */ + { 66, 0x14, 24, 0, 16, 2 }, /* PCIC2 */ + { 67, 0x14, 16, 0, 17, 2 }, /* PCIC3 */ + { 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */ }; -static DECLARE_INTC_DESC(intc_irq_desc, "sh7780-irq", irq_vectors, - NULL, NULL, irq_mask_registers, irq_prio_registers, - irq_sense_registers); - -/* External interrupt pins in IRL mode */ - -static struct intc_vect irl_vectors[] = { - INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220), - INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260), - INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0), - INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0), - INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320), - INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360), - INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0), - INTC_VECT(IRL_HHHL, 0x3c0), -}; +static struct intc2_desc intc2_irq_desc __read_mostly = { + .prio_base = 0xffd40000, + .msk_base = 0xffd40038, + .mskclr_base = 0xffd4003c, -static struct intc_mask_reg irl3210_mask_registers[] = { - { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */ - { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, - IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, - IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, - IRL_HHLL, IRL_HHLH, IRL_HHHL, } }, -}; + .intc2_data = intc2_irq_table, + .nr_irqs = ARRAY_SIZE(intc2_irq_table), -static struct intc_mask_reg irl7654_mask_registers[] = { - { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, - IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, - IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, - IRL_HHLL, IRL_HHLH, IRL_HHHL, } }, + .chip = { + .name = "INTC2-sh7780", + }, }; -static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors, - NULL, NULL, irl7654_mask_registers, NULL, NULL); - -static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors, - NULL, NULL, irl3210_mask_registers, NULL, NULL); - -void __init plat_irq_setup(void) +void __init init_IRQ_intc2(void) { - register_intc_controller(&intc_desc); -} - -void __init plat_irq_setup_pins(int mode) -{ - switch (mode) { - case IRQ_MODE_IRQ: - register_intc_controller(&intc_irq_desc); - break; - case IRQ_MODE_IRL7654: - register_intc_controller(&intc_irl7654_desc); - break; - case IRQ_MODE_IRL3210: - register_intc_controller(&intc_irl3210_desc); - break; - default: - BUG(); - } + register_intc2_controller(&intc2_irq_desc); } diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index cf047562e43f..ce10ec5d6914 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -110,7 +110,7 @@ static struct intc2_desc intc2_irq_desc __read_mostly = { }, }; -void __init plat_irq_setup(void) +void __init init_IRQ_intc2(void) { register_intc2_controller(&intc2_irq_desc); } diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 704c064f70dc..70683ea12b83 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -79,7 +79,7 @@ static struct intc2_desc intc2_irq_desc __read_mostly = { }, }; -void __init plat_irq_setup(void) +void __init init_IRQ_intc2(void) { register_intc2_controller(&intc2_irq_desc); } diff --git a/trunk/arch/sh/kernel/cpufreq.c b/trunk/arch/sh/kernel/cpufreq.c index e61890217c50..47abf6e49dfb 100644 --- a/trunk/arch/sh/kernel/cpufreq.c +++ b/trunk/arch/sh/kernel/cpufreq.c @@ -3,46 +3,89 @@ * * cpufreq driver for the SuperH processors. * - * Copyright (C) 2002 - 2007 Paul Mundt + * Copyright (C) 2002, 2003, 2004, 2005 Paul Mundt * Copyright (C) 2002 M. R. Brown * - * Clock framework bits from arch/avr32/mach-at32ap/cpufreq.c - * - * Copyright (C) 2004-2007 Atmel Corporation - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. */ #include #include #include #include +#include #include -#include +#include #include #include #include /* set_cpus_allowed() */ -#include -static struct clk *cpuclk; +#include +#include +#include +#include + +/* + * For SuperH, each policy change requires that we change the IFC, BFC, and + * PFC at the same time. Here we define sane values that won't trash the + * system. + * + * Note the max set is computed at runtime, we use the divisors that we booted + * with to setup our maximum operating frequencies. + */ +struct clock_set { + unsigned int ifc; + unsigned int bfc; + unsigned int pfc; +} clock_sets[] = { +#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH2) + { 0, 0, 0 }, /* not implemented yet */ +#elif defined(CONFIG_CPU_SH4) + { 4, 8, 8 }, /* min - IFC: 1/4, BFC: 1/8, PFC: 1/8 */ + { 1, 2, 2 }, /* max - IFC: 1, BFC: 1/2, PFC: 1/2 */ +#endif +}; + +#define MIN_CLOCK_SET 0 +#define MAX_CLOCK_SET (ARRAY_SIZE(clock_sets) - 1) + +/* + * For the time being, we only support two frequencies, which in turn are + * aimed at the POWERSAVE and PERFORMANCE policies, which in turn are derived + * directly from the respective min/max clock sets. Technically we could + * support a wider range of frequencies, but these vary far too much for each + * CPU subtype (and we'd have to construct a frequency table for each subtype). + * + * Maybe something to implement in the future.. + */ +#define SH_FREQ_MAX 0 +#define SH_FREQ_MIN 1 + +static struct cpufreq_frequency_table sh_freqs[] = { + { SH_FREQ_MAX, 0 }, + { SH_FREQ_MIN, 0 }, + { 0, CPUFREQ_TABLE_END }, +}; -static unsigned int sh_cpufreq_get(unsigned int cpu) +static void sh_cpufreq_update_clocks(unsigned int set) { - return (clk_get_rate(cpuclk) + 500) / 1000; + current_cpu_data.cpu_clock = current_cpu_data.master_clock / clock_sets[set].ifc; + current_cpu_data.bus_clock = current_cpu_data.master_clock / clock_sets[set].bfc; + current_cpu_data.module_clock = current_cpu_data.master_clock / clock_sets[set].pfc; + current_cpu_data.loops_per_jiffy = loops_per_jiffy; } +/* XXX: This needs to be split out per CPU and CPU subtype. */ /* * Here we notify other drivers of the proposed change and the final change. */ -static int sh_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int sh_cpufreq_setstate(unsigned int cpu, unsigned int set) { - unsigned int cpu = policy->cpu; + unsigned short frqcr = ctrl_inw(FRQCR); cpumask_t cpus_allowed; struct cpufreq_freqs freqs; - long freq; if (!cpu_online(cpu)) return -ENODEV; @@ -52,109 +95,125 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy, BUG_ON(smp_processor_id() != cpu); - /* Convert target_freq from kHz to Hz */ - freq = clk_round_rate(cpuclk, target_freq * 1000); - - if (freq < (policy->min * 1000) || freq > (policy->max * 1000)) - return -EINVAL; - - pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000); - - freqs.cpu = cpu; - freqs.old = sh_cpufreq_get(cpu); - freqs.new = (freq + 500) / 1000; - freqs.flags = 0; + freqs.cpu = cpu; + freqs.old = current_cpu_data.cpu_clock / 1000; + freqs.new = (current_cpu_data.master_clock / clock_sets[set].ifc) / 1000; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); +#if defined(CONFIG_CPU_SH3) + frqcr |= (newstate & 0x4000) << 14; + frqcr |= (newstate & 0x000c) << 2; +#elif defined(CONFIG_CPU_SH4) + /* + * FRQCR.PLL2EN is 1, we need to allow the PLL to stabilize by + * initializing the WDT. + */ + if (frqcr & (1 << 9)) { + __u8 csr; + + /* + * Set the overflow period to the highest available, + * in this case a 1/4096 division ratio yields a 5.25ms + * overflow period. See asm-sh/watchdog.h for more + * information and a range of other divisors. + */ + csr = sh_wdt_read_csr(); + csr |= WTCSR_CKS_4096; + sh_wdt_write_csr(csr); + + sh_wdt_write_cnt(0); + } + frqcr &= 0x0e00; /* Clear ifc, bfc, pfc */ + frqcr |= get_ifc_value(clock_sets[set].ifc) << 6; + frqcr |= get_bfc_value(clock_sets[set].bfc) << 3; + frqcr |= get_pfc_value(clock_sets[set].pfc); +#endif + ctrl_outw(frqcr, FRQCR); + sh_cpufreq_update_clocks(set); + set_cpus_allowed(current, cpus_allowed); - clk_set_rate(cpuclk, freq); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - pr_debug("cpufreq: set frequency %lu Hz\n", freq); - return 0; } static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy) { - printk(KERN_INFO "cpufreq: SuperH CPU frequency driver.\n"); + unsigned int min_freq, max_freq; + unsigned int ifc, bfc, pfc; if (!cpu_online(policy->cpu)) return -ENODEV; - cpuclk = clk_get(NULL, "cpu_clk"); - if (IS_ERR(cpuclk)) { - printk(KERN_ERR "cpufreq: couldn't get CPU clk\n"); - return PTR_ERR(cpuclk); - } + /* Update our maximum clock set */ + get_current_frequency_divisors(&ifc, &bfc, &pfc); + clock_sets[MAX_CLOCK_SET].ifc = ifc; + clock_sets[MAX_CLOCK_SET].bfc = bfc; + clock_sets[MAX_CLOCK_SET].pfc = pfc; + + /* Convert from Hz to kHz */ + max_freq = current_cpu_data.cpu_clock / 1000; + min_freq = (current_cpu_data.master_clock / clock_sets[MIN_CLOCK_SET].ifc) / 1000; + + sh_freqs[SH_FREQ_MAX].frequency = max_freq; + sh_freqs[SH_FREQ_MIN].frequency = min_freq; /* cpuinfo and default policy values */ - policy->cpuinfo.min_freq = (clk_round_rate(cpuclk, 1) + 500) / 1000; - policy->cpuinfo.max_freq = (clk_round_rate(cpuclk, ~0UL) + 500) / 1000; + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; + policy->cur = max_freq; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - policy->cur = sh_cpufreq_get(policy->cpu); - policy->min = policy->cpuinfo.min_freq; - policy->max = policy->cpuinfo.max_freq; - - - /* - * Catch the cases where the clock framework hasn't been wired up - * properly to support scaling. - */ - if (unlikely(policy->min == policy->max)) { - printk(KERN_ERR "cpufreq: clock framework rate rounding " - "not supported on this CPU.\n"); - - clk_put(cpuclk); - return -EINVAL; - } - - printk(KERN_INFO "cpufreq: Frequencies - Minimum %u.%03u MHz, " - "Maximum %u.%03u MHz.\n", - policy->min / 1000, policy->min % 1000, - policy->max / 1000, policy->max % 1000); - - return 0; + return cpufreq_frequency_table_cpuinfo(policy, &sh_freqs[0]); } static int sh_cpufreq_verify(struct cpufreq_policy *policy) { - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); - return 0; + return cpufreq_frequency_table_verify(policy, &sh_freqs[0]); } -static int sh_cpufreq_exit(struct cpufreq_policy *policy) +static int sh_cpufreq_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) { - clk_put(cpuclk); + unsigned int set, idx = 0; + + if (cpufreq_frequency_table_target(policy, &sh_freqs[0], target_freq, relation, &idx)) + return -EINVAL; + + set = (idx == SH_FREQ_MIN) ? MIN_CLOCK_SET : MAX_CLOCK_SET; + + sh_cpufreq_setstate(policy->cpu, set); + return 0; } static struct cpufreq_driver sh_cpufreq_driver = { .owner = THIS_MODULE, - .name = "sh", + .name = "SH cpufreq", .init = sh_cpufreq_cpu_init, .verify = sh_cpufreq_verify, .target = sh_cpufreq_target, - .get = sh_cpufreq_get, - .exit = sh_cpufreq_exit, }; -static int __init sh_cpufreq_module_init(void) +static int __init sh_cpufreq_init(void) { - return cpufreq_register_driver(&sh_cpufreq_driver); + if (!current_cpu_data.cpu_clock) + return -EINVAL; + if (cpufreq_register_driver(&sh_cpufreq_driver)) + return -EINVAL; + + return 0; } -static void __exit sh_cpufreq_module_exit(void) +static void __exit sh_cpufreq_exit(void) { cpufreq_unregister_driver(&sh_cpufreq_driver); } -module_init(sh_cpufreq_module_init); -module_exit(sh_cpufreq_module_exit); +module_init(sh_cpufreq_init); +module_exit(sh_cpufreq_exit); MODULE_AUTHOR("Paul Mundt "); MODULE_DESCRIPTION("cpufreq driver for SuperH"); MODULE_LICENSE("GPL"); + diff --git a/trunk/arch/sh/kernel/head.S b/trunk/arch/sh/kernel/head.S index 0bccc0ca5a0f..71a3ad7d283e 100644 --- a/trunk/arch/sh/kernel/head.S +++ b/trunk/arch/sh/kernel/head.S @@ -36,8 +36,7 @@ ENTRY(empty_zero_page) 1: .skip PAGE_SIZE - empty_zero_page - 1b - .section .text.head, "ax" - + .text /* * Condition at the entry of _stext: * diff --git a/trunk/arch/sh/kernel/irq.c b/trunk/arch/sh/kernel/irq.c index 03404987528d..27897798867a 100644 --- a/trunk/arch/sh/kernel/irq.c +++ b/trunk/arch/sh/kernel/irq.c @@ -253,7 +253,14 @@ void __init init_IRQ(void) #ifdef CONFIG_CPU_HAS_PINT_IRQ init_IRQ_pint(); #endif - plat_irq_setup(); + +#ifdef CONFIG_CPU_HAS_INTC2_IRQ + init_IRQ_intc2(); +#endif + +#ifdef CONFIG_CPU_HAS_IPR_IRQ + init_IRQ_ipr(); +#endif /* Perform the machine specific initialisation */ if (sh_mv.mv_init_irq) diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index c14a3e95d0b1..de8e6e2f2c87 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -79,11 +78,7 @@ static char __initdata command_line[COMMAND_LINE_SIZE] = { 0, }; static struct resource code_resource = { .name = "Kernel code", }; static struct resource data_resource = { .name = "Kernel data", }; -unsigned long memory_start; -EXPORT_SYMBOL(memory_start); - -unsigned long memory_end; -EXPORT_SYMBOL(memory_end); +unsigned long memory_start, memory_end; static int __init early_parse_mem(char *p) { diff --git a/trunk/arch/sh/kernel/sh_bios.c b/trunk/arch/sh/kernel/sh_bios.c index d1bcac4fa269..5b53e10bb9cd 100644 --- a/trunk/arch/sh/kernel/sh_bios.c +++ b/trunk/arch/sh/kernel/sh_bios.c @@ -5,7 +5,7 @@ * Copyright (C) 2000 Greg Banks, Mitch Davis * */ -#include + #include #define BIOS_CALL_CONSOLE_WRITE 0 @@ -63,7 +63,6 @@ void sh_bios_gdb_detach(void) { sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0); } -EXPORT_SYMBOL(sh_bios_gdb_detach); void sh_bios_get_node_addr (unsigned char *node_addr) { diff --git a/trunk/arch/sh/kernel/sh_ksyms.c b/trunk/arch/sh/kernel/sh_ksyms.c index 37aef0a85197..c968dcf09eee 100644 --- a/trunk/arch/sh/kernel/sh_ksyms.c +++ b/trunk/arch/sh/kernel/sh_ksyms.c @@ -63,43 +63,10 @@ EXPORT_SYMBOL(__const_udelay); /* These symbols are generated by the compiler itself */ DECLARE_EXPORT(__udivsi3); DECLARE_EXPORT(__sdivsi3); -DECLARE_EXPORT(__ashrsi3); -DECLARE_EXPORT(__ashlsi3); DECLARE_EXPORT(__ashrdi3); DECLARE_EXPORT(__ashldi3); -DECLARE_EXPORT(__ashiftrt_r4_6); -DECLARE_EXPORT(__ashiftrt_r4_7); -DECLARE_EXPORT(__ashiftrt_r4_8); -DECLARE_EXPORT(__ashiftrt_r4_9); -DECLARE_EXPORT(__ashiftrt_r4_10); -DECLARE_EXPORT(__ashiftrt_r4_11); -DECLARE_EXPORT(__ashiftrt_r4_12); -DECLARE_EXPORT(__ashiftrt_r4_13); -DECLARE_EXPORT(__ashiftrt_r4_14); -DECLARE_EXPORT(__ashiftrt_r4_15); -DECLARE_EXPORT(__ashiftrt_r4_20); -DECLARE_EXPORT(__ashiftrt_r4_21); -DECLARE_EXPORT(__ashiftrt_r4_22); -DECLARE_EXPORT(__ashiftrt_r4_23); -DECLARE_EXPORT(__ashiftrt_r4_24); -DECLARE_EXPORT(__ashiftrt_r4_27); -DECLARE_EXPORT(__ashiftrt_r4_30); -DECLARE_EXPORT(__lshrsi3); DECLARE_EXPORT(__lshrdi3); -DECLARE_EXPORT(__movstrSI8); -DECLARE_EXPORT(__movstrSI12); DECLARE_EXPORT(__movstrSI16); -DECLARE_EXPORT(__movstrSI20); -DECLARE_EXPORT(__movstrSI24); -DECLARE_EXPORT(__movstrSI28); -DECLARE_EXPORT(__movstrSI32); -DECLARE_EXPORT(__movstrSI36); -DECLARE_EXPORT(__movstrSI40); -DECLARE_EXPORT(__movstrSI44); -DECLARE_EXPORT(__movstrSI48); -DECLARE_EXPORT(__movstrSI52); -DECLARE_EXPORT(__movstrSI56); -DECLARE_EXPORT(__movstrSI60); #if __GNUC__ == 4 DECLARE_EXPORT(__movmem); #else @@ -148,9 +115,7 @@ EXPORT_SYMBOL(synchronize_irq); #endif EXPORT_SYMBOL(csum_partial); -EXPORT_SYMBOL(csum_partial_copy_generic); #ifdef CONFIG_IPV6 EXPORT_SYMBOL(csum_ipv6_magic); #endif EXPORT_SYMBOL(clear_page); -EXPORT_SYMBOL(__clear_user); diff --git a/trunk/arch/sh/kernel/syscalls.S b/trunk/arch/sh/kernel/syscalls.S index 91fb7024e06f..ff5656e60c05 100644 --- a/trunk/arch/sh/kernel/syscalls.S +++ b/trunk/arch/sh/kernel/syscalls.S @@ -358,4 +358,3 @@ ENTRY(sys_call_table) .long sys_signalfd .long sys_timerfd .long sys_eventfd - .long sys_fallocate diff --git a/trunk/arch/sh/kernel/vmlinux.lds.S b/trunk/arch/sh/kernel/vmlinux.lds.S index 9cb95af7b090..5ba216180b30 100644 --- a/trunk/arch/sh/kernel/vmlinux.lds.S +++ b/trunk/arch/sh/kernel/vmlinux.lds.S @@ -22,7 +22,6 @@ SECTIONS *(.empty_zero_page) } = 0 .text : { - *(.text.head) TEXT_TEXT SCHED_TEXT LOCK_TEXT diff --git a/trunk/arch/sh/mm/Kconfig b/trunk/arch/sh/mm/Kconfig index 70da1c8d407e..28d79a474cde 100644 --- a/trunk/arch/sh/mm/Kconfig +++ b/trunk/arch/sh/mm/Kconfig @@ -120,14 +120,14 @@ config CPU_SUBTYPE_SH7712 config CPU_SUBTYPE_SH7750 bool "Support SH7750 processor" select CPU_SH4 - select CPU_HAS_INTC_IRQ + select CPU_HAS_IPR_IRQ help Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. config CPU_SUBTYPE_SH7091 bool "Support SH7091 processor" select CPU_SH4 - select CPU_HAS_INTC_IRQ + select CPU_HAS_IPR_IRQ help Select SH7091 if you have an SH-4 based Sega device (such as the Dreamcast, Naomi, and Naomi 2). @@ -135,17 +135,17 @@ config CPU_SUBTYPE_SH7091 config CPU_SUBTYPE_SH7750R bool "Support SH7750R processor" select CPU_SH4 - select CPU_HAS_INTC_IRQ + select CPU_HAS_IPR_IRQ config CPU_SUBTYPE_SH7750S bool "Support SH7750S processor" select CPU_SH4 - select CPU_HAS_INTC_IRQ + select CPU_HAS_IPR_IRQ config CPU_SUBTYPE_SH7751 bool "Support SH7751 processor" select CPU_SH4 - select CPU_HAS_INTC_IRQ + select CPU_HAS_IPR_IRQ help Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU, or if you have a HD6417751R CPU. @@ -153,7 +153,7 @@ config CPU_SUBTYPE_SH7751 config CPU_SUBTYPE_SH7751R bool "Support SH7751R processor" select CPU_SH4 - select CPU_HAS_INTC_IRQ + select CPU_HAS_IPR_IRQ config CPU_SUBTYPE_SH7760 bool "Support SH7760 processor" @@ -189,7 +189,7 @@ config CPU_SUBTYPE_SH7770 config CPU_SUBTYPE_SH7780 bool "Support SH7780 processor" select CPU_SH4A - select CPU_HAS_INTC_IRQ + select CPU_HAS_INTC2_IRQ config CPU_SUBTYPE_SH7785 bool "Support SH7785 processor" @@ -217,7 +217,7 @@ config CPU_SUBTYPE_SH7722 bool "Support SH7722 processor" select CPU_SH4AL_DSP select CPU_SHX2 - select CPU_HAS_INTC_IRQ + select CPU_HAS_IPR_IRQ select ARCH_SPARSEMEM_ENABLE select SYS_SUPPORTS_NUMA diff --git a/trunk/arch/sh64/configs/cayman_defconfig b/trunk/arch/sh64/configs/cayman_defconfig index 784434143343..ed035084b053 100644 --- a/trunk/arch/sh64/configs/cayman_defconfig +++ b/trunk/arch/sh64/configs/cayman_defconfig @@ -1,12 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22 -# Fri Jul 20 12:28:34 2007 +# Linux kernel version: 2.6.22-rc1 +# Mon May 14 08:43:31 2007 # CONFIG_SUPERH=y CONFIG_SUPERH64=y CONFIG_MMU=y -CONFIG_QUICKLIST=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y @@ -33,7 +32,7 @@ CONFIG_SWAP=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 @@ -67,12 +66,19 @@ CONFIG_SLAB=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# # CONFIG_MODULES is not set + +# +# Block layer +# CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -150,8 +156,6 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=1 -CONFIG_VIRT_TO_BUS=y # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -171,6 +175,7 @@ CONFIG_SH_PCIDMA_NONCOHERENT=y # Executable file formats # CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_FLAT is not set # CONFIG_BINFMT_MISC is not set # @@ -220,8 +225,20 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# # CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# # CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -257,7 +274,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set # # Device Drivers @@ -272,10 +288,26 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# # CONFIG_CONNECTOR is not set # CONFIG_MTD is not set + +# +# Parallel port support +# # CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -291,11 +323,18 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y + +# +# Misc devices +# # CONFIG_PHANTOM is not set -# CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set +# CONFIG_BLINK is not set + +# +# ATA/ATAPI/MFM/RLL support +# # CONFIG_IDE is not set # @@ -303,7 +342,6 @@ CONFIG_MISC_DEVICES=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -CONFIG_SCSI_DMA=y # CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -372,8 +410,13 @@ CONFIG_SCSI_SYM53C8XX_MMIO=y # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_ESP_CORE is not set # CONFIG_SCSI_SRP is not set # CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# # CONFIG_MD is not set # @@ -389,16 +432,30 @@ CONFIG_SCSI_SYM53C8XX_MMIO=y # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set + +# +# I2O device support +# # CONFIG_I2O is not set + +# +# Network device support +# CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set + +# +# ARCnet devices +# # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# CONFIG_NET_ETHERNET=y # CONFIG_MII is not set # CONFIG_STNIC is not set @@ -407,6 +464,10 @@ CONFIG_NET_ETHERNET=y # CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_SMC91X is not set + +# +# Tulip family network device support +# CONFIG_NET_TULIP=y # CONFIG_DE2104X is not set CONFIG_TULIP=y @@ -449,6 +510,7 @@ CONFIG_NETDEV_1000=y # CONFIG_SIS190 is not set # CONFIG_SKGE is not set # CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set @@ -462,6 +524,11 @@ CONFIG_NETDEV_10000=y # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_MLX4_CORE is not set +CONFIG_MLX4_DEBUG=y + +# +# Token Ring devices +# # CONFIG_TR is not set # @@ -479,7 +546,15 @@ CONFIG_NETDEV_10000=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# # CONFIG_ISDN is not set + +# +# Telephony Support +# # CONFIG_PHONE is not set # @@ -487,7 +562,6 @@ CONFIG_NETDEV_10000=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -564,6 +638,10 @@ CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# # CONFIG_IPMI_HANDLER is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -580,10 +658,15 @@ CONFIG_WATCHDOG=y # CONFIG_PCIPCWATCHDOG is not set # CONFIG_WDTPCI is not set CONFIG_HW_RANDOM=y +# CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# # CONFIG_TCG_TPM is not set CONFIG_DEVPORT=y # CONFIG_I2C is not set @@ -593,24 +676,20 @@ CONFIG_DEVPORT=y # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# # CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ABITUGURU3 is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set # CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set # @@ -660,6 +739,7 @@ CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set +# CONFIG_FB_EPSON1355 is not set # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set @@ -685,7 +765,6 @@ CONFIG_FB_KYRO=y # CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_FONTS=y # CONFIG_FONT_8x8 is not set @@ -710,10 +789,16 @@ CONFIG_LOGO_SUPERH_CLUT224=y # Sound # # CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y + +# +# HID Devices +# CONFIG_HID=y # CONFIG_HID_DEBUG is not set -CONFIG_USB_SUPPORT=y + +# +# USB support +# CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y @@ -741,8 +826,16 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # LED Triggers # + +# +# InfiniBand support +# # CONFIG_INFINIBAND is not set +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + # # Real Time Clock # @@ -761,11 +854,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # DMA Devices # -# -# Userspace I/O -# -# CONFIG_UIO is not set - # # File systems # @@ -862,6 +950,7 @@ CONFIG_SUNRPC=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -912,7 +1001,6 @@ CONFIG_DEBUG_FS=y CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y -CONFIG_SCHED_DEBUG=y CONFIG_SCHEDSTATS=y # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set @@ -929,6 +1017,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_LIST is not set CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_EARLY_PRINTK is not set # CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set @@ -944,6 +1033,10 @@ CONFIG_SH64_SR_WATCH=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set + +# +# Cryptographic options +# # CONFIG_CRYPTO is not set # @@ -954,7 +1047,6 @@ CONFIG_BITREVERSE=y # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y -# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y diff --git a/trunk/arch/sh64/kernel/head.S b/trunk/arch/sh64/kernel/head.S index 186406d3ad9c..f3740ddbc471 100644 --- a/trunk/arch/sh64/kernel/head.S +++ b/trunk/arch/sh64/kernel/head.S @@ -124,7 +124,7 @@ empty_bad_pte_table: fpu_in_use: .quad 0 - .section .text.head, "ax" + .section .text, "ax" .balign L1_CACHE_BYTES /* * Condition at the entry of __stext: diff --git a/trunk/arch/sh64/kernel/pci_sh5.c b/trunk/arch/sh64/kernel/pci_sh5.c index 388bb711f1b0..3334f99b5835 100644 --- a/trunk/arch/sh64/kernel/pci_sh5.c +++ b/trunk/arch/sh64/kernel/pci_sh5.c @@ -48,7 +48,7 @@ static void __init pci_fixup_ide_bases(struct pci_dev *d) } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); -char * __devinit pcibios_setup(char *str) +char * __init pcibios_setup(char *str) { return str; } @@ -497,7 +497,7 @@ static int __init pcibios_init(void) subsys_initcall(pcibios_init); -void __devinit pcibios_fixup_bus(struct pci_bus *bus) +void __init pcibios_fixup_bus(struct pci_bus *bus) { struct pci_dev *dev = bus->self; int i; diff --git a/trunk/arch/sh64/kernel/syscalls.S b/trunk/arch/sh64/kernel/syscalls.S index abb94c05d07a..a5c680d29384 100644 --- a/trunk/arch/sh64/kernel/syscalls.S +++ b/trunk/arch/sh64/kernel/syscalls.S @@ -378,4 +378,3 @@ sys_call_table: .long sys_signalfd .long sys_timerfd /* 350 */ .long sys_eventfd - .long sys_fallocate diff --git a/trunk/arch/sh64/kernel/vmlinux.lds.S b/trunk/arch/sh64/kernel/vmlinux.lds.S index 267b4f9af2e1..8ac9c7c5f848 100644 --- a/trunk/arch/sh64/kernel/vmlinux.lds.S +++ b/trunk/arch/sh64/kernel/vmlinux.lds.S @@ -54,7 +54,6 @@ SECTIONS } = 0 .text : C_PHYS(.text) { - *(.text.head) TEXT_TEXT *(.text64) *(.text..SHmedia32) diff --git a/trunk/arch/sh64/mm/ioremap.c b/trunk/arch/sh64/mm/ioremap.c index 990857756d44..ff26c02511aa 100644 --- a/trunk/arch/sh64/mm/ioremap.c +++ b/trunk/arch/sh64/mm/ioremap.c @@ -242,7 +242,7 @@ static void shmedia_free_io(struct resource *res) release_resource(res); } -static __init_refok void *sh64_get_page(void) +static void *sh64_get_page(void) { extern int after_bootmem; void *page; diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index 9d327ec59759..603d83ad65c8 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -24,9 +24,6 @@ config GENERIC_ISA_DMA config ARCH_NO_VIRT_TO_BUS def_bool y -config OF - def_bool y - source "init/Kconfig" menu "General machine setup" diff --git a/trunk/arch/sparc/kernel/ebus.c b/trunk/arch/sparc/kernel/ebus.c index ac352eb6dff3..7bb86b9cdaa3 100644 --- a/trunk/arch/sparc/kernel/ebus.c +++ b/trunk/arch/sparc/kernel/ebus.c @@ -148,7 +148,6 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d { const struct linux_prom_registers *regs; struct linux_ebus_child *child; - struct dev_archdata *sd; const int *irqs; int i, n, len; unsigned long baseaddr; @@ -235,10 +234,6 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d } } - sd = &dev->ofdev.dev.archdata; - sd->prom_node = dp; - sd->op = &dev->ofdev; - dev->ofdev.node = dp; dev->ofdev.dev.parent = &dev->bus->ofdev.dev; dev->ofdev.dev.bus = &ebus_bus_type; diff --git a/trunk/arch/sparc/kernel/of_device.c b/trunk/arch/sparc/kernel/of_device.c index 36383f73d685..fd7f8cb668a3 100644 --- a/trunk/arch/sparc/kernel/of_device.c +++ b/trunk/arch/sparc/kernel/of_device.c @@ -1,13 +1,132 @@ #include #include -#include #include #include #include #include -#include -#include -#include + +#include +#include + +/** + * of_match_device - Tell if an of_device structure has a matching + * of_match structure + * @ids: array of of device match structures to search in + * @dev: the of device structure to match against + * + * Used by a driver to check whether an of_device present in the + * system is in its list of supported devices. + */ +const struct of_device_id *of_match_device(const struct of_device_id *matches, + const struct of_device *dev) +{ + if (!dev->node) + return NULL; + while (matches->name[0] || matches->type[0] || matches->compatible[0]) { + int match = 1; + if (matches->name[0]) + match &= dev->node->name + && !strcmp(matches->name, dev->node->name); + if (matches->type[0]) + match &= dev->node->type + && !strcmp(matches->type, dev->node->type); + if (matches->compatible[0]) + match &= of_device_is_compatible(dev->node, + matches->compatible); + if (match) + return matches; + matches++; + } + return NULL; +} + +static int of_platform_bus_match(struct device *dev, struct device_driver *drv) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * of_drv = to_of_platform_driver(drv); + const struct of_device_id * matches = of_drv->match_table; + + if (!matches) + return 0; + + return of_match_device(matches, of_dev) != NULL; +} + +struct of_device *of_dev_get(struct of_device *dev) +{ + struct device *tmp; + + if (!dev) + return NULL; + tmp = get_device(&dev->dev); + if (tmp) + return to_of_device(tmp); + else + return NULL; +} + +void of_dev_put(struct of_device *dev) +{ + if (dev) + put_device(&dev->dev); +} + + +static int of_device_probe(struct device *dev) +{ + int error = -ENODEV; + struct of_platform_driver *drv; + struct of_device *of_dev; + const struct of_device_id *match; + + drv = to_of_platform_driver(dev->driver); + of_dev = to_of_device(dev); + + if (!drv->probe) + return error; + + of_dev_get(of_dev); + + match = of_match_device(drv->match_table, of_dev); + if (match) + error = drv->probe(of_dev, match); + if (error) + of_dev_put(of_dev); + + return error; +} + +static int of_device_remove(struct device *dev) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + + if (dev->driver && drv->remove) + drv->remove(of_dev); + return 0; +} + +static int of_device_suspend(struct device *dev, pm_message_t state) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + int error = 0; + + if (dev->driver && drv->suspend) + error = drv->suspend(of_dev, state); + return error; +} + +static int of_device_resume(struct device * dev) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + int error = 0; + + if (dev->driver && drv->resume) + error = drv->resume(of_dev); + return error; +} static int node_match(struct device *dev, void *data) { @@ -19,7 +138,7 @@ static int node_match(struct device *dev, void *data) struct of_device *of_find_device_by_node(struct device_node *dp) { - struct device *dev = bus_find_device(&of_platform_bus_type, NULL, + struct device *dev = bus_find_device(&of_bus_type, NULL, dp, node_match); if (dev) @@ -30,17 +149,38 @@ struct of_device *of_find_device_by_node(struct device_node *dp) EXPORT_SYMBOL(of_find_device_by_node); #ifdef CONFIG_PCI -struct bus_type ebus_bus_type; +struct bus_type ebus_bus_type = { + .name = "ebus", + .match = of_platform_bus_match, + .probe = of_device_probe, + .remove = of_device_remove, + .suspend = of_device_suspend, + .resume = of_device_resume, +}; EXPORT_SYMBOL(ebus_bus_type); #endif #ifdef CONFIG_SBUS -struct bus_type sbus_bus_type; +struct bus_type sbus_bus_type = { + .name = "sbus", + .match = of_platform_bus_match, + .probe = of_device_probe, + .remove = of_device_remove, + .suspend = of_device_suspend, + .resume = of_device_resume, +}; EXPORT_SYMBOL(sbus_bus_type); #endif -struct bus_type of_platform_bus_type; -EXPORT_SYMBOL(of_platform_bus_type); +struct bus_type of_bus_type = { + .name = "of", + .match = of_platform_bus_match, + .probe = of_device_probe, + .remove = of_device_remove, + .suspend = of_device_suspend, + .resume = of_device_resume, +}; +EXPORT_SYMBOL(of_bus_type); static inline u64 of_read_addr(const u32 *cell, int size) { @@ -420,16 +560,11 @@ static struct of_device * __init scan_one_device(struct device_node *dp, { struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); const struct linux_prom_irqs *intr; - struct dev_archdata *sd; int len, i; if (!op) return NULL; - sd = &op->dev.archdata; - sd->prom_node = dp; - sd->op = op; - op->node = dp; op->clock_freq = of_getintprop_default(dp, "clock-frequency", @@ -511,7 +646,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, build_device_resources(op, parent); op->dev.parent = parent; - op->dev.bus = &of_platform_bus_type; + op->dev.bus = &of_bus_type; if (!parent) strcpy(op->dev.bus_id, "root"); else @@ -555,14 +690,14 @@ static int __init of_bus_driver_init(void) { int err; - err = of_bus_type_init(&of_platform_bus_type, "of"); + err = bus_register(&of_bus_type); #ifdef CONFIG_PCI if (!err) - err = of_bus_type_init(&ebus_bus_type, "ebus"); + err = bus_register(&ebus_bus_type); #endif #ifdef CONFIG_SBUS if (!err) - err = of_bus_type_init(&sbus_bus_type, "sbus"); + err = bus_register(&sbus_bus_type); #endif if (!err) @@ -600,6 +735,56 @@ void of_unregister_driver(struct of_platform_driver *drv) driver_unregister(&drv->driver); } + +static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct of_device *ofdev; + + ofdev = to_of_device(dev); + return sprintf(buf, "%s", ofdev->node->full_name); +} + +static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); + +/** + * of_release_dev - free an of device structure when all users of it are finished. + * @dev: device that's been disconnected + * + * Will be called only by the device core when all users of this of device are + * done. + */ +void of_release_dev(struct device *dev) +{ + struct of_device *ofdev; + + ofdev = to_of_device(dev); + + kfree(ofdev); +} + +int of_device_register(struct of_device *ofdev) +{ + int rc; + + BUG_ON(ofdev->node == NULL); + + rc = device_register(&ofdev->dev); + if (rc) + return rc; + + rc = device_create_file(&ofdev->dev, &dev_attr_devspec); + if (rc) + device_unregister(&ofdev->dev); + + return rc; +} + +void of_device_unregister(struct of_device *ofdev) +{ + device_remove_file(&ofdev->dev, &dev_attr_devspec); + device_unregister(&ofdev->dev); +} + struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id, struct device *parent, @@ -625,6 +810,12 @@ struct of_device* of_platform_device_create(struct device_node *np, return dev; } +EXPORT_SYMBOL(of_match_device); EXPORT_SYMBOL(of_register_driver); EXPORT_SYMBOL(of_unregister_driver); +EXPORT_SYMBOL(of_device_register); +EXPORT_SYMBOL(of_device_unregister); +EXPORT_SYMBOL(of_dev_get); +EXPORT_SYMBOL(of_dev_put); EXPORT_SYMBOL(of_platform_device_create); +EXPORT_SYMBOL(of_release_dev); diff --git a/trunk/arch/sparc/kernel/process.c b/trunk/arch/sparc/kernel/process.c index 33f7a3ddb104..8c37f8f5adb7 100644 --- a/trunk/arch/sparc/kernel/process.c +++ b/trunk/arch/sparc/kernel/process.c @@ -39,7 +39,6 @@ #include #include #include -#include #include /* @@ -151,7 +150,7 @@ void machine_halt(void) local_irq_enable(); mdelay(8); local_irq_disable(); - if (prom_palette) + if (!serial_console && prom_palette) prom_palette (1); prom_halt(); panic("Halt failed!"); @@ -167,7 +166,7 @@ void machine_restart(char * cmd) p = strchr (reboot_command, '\n'); if (p) *p = 0; - if (prom_palette) + if (!serial_console && prom_palette) prom_palette (1); if (cmd) prom_reboot(cmd); @@ -180,8 +179,7 @@ void machine_restart(char * cmd) void machine_power_off(void) { #ifdef CONFIG_SUN_AUXIO - if (auxio_power_register && - (strcmp(of_console_device->type, "serial") || scons_pwroff)) + if (auxio_power_register && (!serial_console || scons_pwroff)) *auxio_power_register |= AUXIO_POWER_OFF; #endif machine_halt(); diff --git a/trunk/arch/sparc/kernel/prom.c b/trunk/arch/sparc/kernel/prom.c index e3a537650db1..eed140b3c739 100644 --- a/trunk/arch/sparc/kernel/prom.c +++ b/trunk/arch/sparc/kernel/prom.c @@ -25,9 +25,73 @@ #include #include -extern struct device_node *allnodes; /* temporary while merging */ +static struct device_node *allnodes; -extern rwlock_t devtree_lock; /* temporary while merging */ +/* use when traversing tree through the allnext, child, sibling, + * or parent members of struct device_node. + */ +static DEFINE_RWLOCK(devtree_lock); + +int of_device_is_compatible(const struct device_node *device, + const char *compat) +{ + const char* cp; + int cplen, l; + + cp = of_get_property(device, "compatible", &cplen); + if (cp == NULL) + return 0; + while (cplen > 0) { + if (strncmp(cp, compat, strlen(compat)) == 0) + return 1; + l = strlen(cp) + 1; + cp += l; + cplen -= l; + } + + return 0; +} +EXPORT_SYMBOL(of_device_is_compatible); + +struct device_node *of_get_parent(const struct device_node *node) +{ + struct device_node *np; + + if (!node) + return NULL; + + np = node->parent; + + return np; +} +EXPORT_SYMBOL(of_get_parent); + +struct device_node *of_get_next_child(const struct device_node *node, + struct device_node *prev) +{ + struct device_node *next; + + next = prev ? prev->sibling : node->child; + for (; next != 0; next = next->sibling) { + break; + } + + return next; +} +EXPORT_SYMBOL(of_get_next_child); + +struct device_node *of_find_node_by_path(const char *path) +{ + struct device_node *np = allnodes; + + for (; np != 0; np = np->allnext) { + if (np->full_name != 0 && strcmp(np->full_name, path) == 0) + break; + } + + return np; +} +EXPORT_SYMBOL(of_find_node_by_path); struct device_node *of_find_node_by_phandle(phandle handle) { @@ -41,6 +105,81 @@ struct device_node *of_find_node_by_phandle(phandle handle) } EXPORT_SYMBOL(of_find_node_by_phandle); +struct device_node *of_find_node_by_name(struct device_node *from, + const char *name) +{ + struct device_node *np; + + np = from ? from->allnext : allnodes; + for (; np != NULL; np = np->allnext) + if (np->name != NULL && strcmp(np->name, name) == 0) + break; + + return np; +} +EXPORT_SYMBOL(of_find_node_by_name); + +struct device_node *of_find_node_by_type(struct device_node *from, + const char *type) +{ + struct device_node *np; + + np = from ? from->allnext : allnodes; + for (; np != 0; np = np->allnext) + if (np->type != 0 && strcmp(np->type, type) == 0) + break; + + return np; +} +EXPORT_SYMBOL(of_find_node_by_type); + +struct device_node *of_find_compatible_node(struct device_node *from, + const char *type, const char *compatible) +{ + struct device_node *np; + + np = from ? from->allnext : allnodes; + for (; np != 0; np = np->allnext) { + if (type != NULL + && !(np->type != 0 && strcmp(np->type, type) == 0)) + continue; + if (of_device_is_compatible(np, compatible)) + break; + } + + return np; +} +EXPORT_SYMBOL(of_find_compatible_node); + +struct property *of_find_property(const struct device_node *np, + const char *name, + int *lenp) +{ + struct property *pp; + + for (pp = np->properties; pp != 0; pp = pp->next) { + if (strcasecmp(pp->name, name) == 0) { + if (lenp != 0) + *lenp = pp->length; + break; + } + } + return pp; +} +EXPORT_SYMBOL(of_find_property); + +/* + * Find a property with a given name for a given node + * and return the value. + */ +const void *of_get_property(const struct device_node *np, const char *name, + int *lenp) +{ + struct property *pp = of_find_property(np,name,lenp); + return pp ? pp->value : NULL; +} +EXPORT_SYMBOL(of_get_property); + int of_getintprop_default(struct device_node *np, const char *name, int def) { struct property *prop; @@ -54,6 +193,36 @@ int of_getintprop_default(struct device_node *np, const char *name, int def) } EXPORT_SYMBOL(of_getintprop_default); +int of_n_addr_cells(struct device_node *np) +{ + const int* ip; + do { + if (np->parent) + np = np->parent; + ip = of_get_property(np, "#address-cells", NULL); + if (ip != NULL) + return *ip; + } while (np->parent); + /* No #address-cells property for the root node, default to 2 */ + return 2; +} +EXPORT_SYMBOL(of_n_addr_cells); + +int of_n_size_cells(struct device_node *np) +{ + const int* ip; + do { + if (np->parent) + np = np->parent; + ip = of_get_property(np, "#size-cells", NULL); + if (ip != NULL) + return *ip; + } while (np->parent); + /* No #size-cells property for the root node, default to 1 */ + return 1; +} +EXPORT_SYMBOL(of_n_size_cells); + int of_set_property(struct device_node *dp, const char *name, void *val, int len) { struct property **prevp; @@ -397,135 +566,6 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl return dp; } -struct device_node *of_console_device; -EXPORT_SYMBOL(of_console_device); - -char *of_console_path; -EXPORT_SYMBOL(of_console_path); - -char *of_console_options; -EXPORT_SYMBOL(of_console_options); - -extern void restore_current(void); - -static void __init of_console_init(void) -{ - char *msg = "OF stdout device is: %s\n"; - struct device_node *dp; - unsigned long flags; - const char *type; - phandle node; - int skip, fd; - - of_console_path = prom_early_alloc(256); - - switch (prom_vers) { - case PROM_V0: - case PROM_SUN4: - skip = 0; - switch (*romvec->pv_stdout) { - case PROMDEV_SCREEN: - type = "display"; - break; - - case PROMDEV_TTYB: - skip = 1; - /* FALLTHRU */ - - case PROMDEV_TTYA: - type = "serial"; - break; - - default: - prom_printf("Invalid PROM_V0 stdout value %u\n", - *romvec->pv_stdout); - prom_halt(); - } - - for_each_node_by_type(dp, type) { - if (!skip--) - break; - } - if (!dp) { - prom_printf("Cannot find PROM_V0 console node.\n"); - prom_halt(); - } - of_console_device = dp; - - strcpy(of_console_path, dp->full_name); - if (!strcmp(type, "serial")) { - strcat(of_console_path, - (skip ? ":b" : ":a")); - } - break; - - default: - case PROM_V2: - case PROM_V3: - fd = *romvec->pv_v2bootargs.fd_stdout; - - spin_lock_irqsave(&prom_lock, flags); - node = (*romvec->pv_v2devops.v2_inst2pkg)(fd); - restore_current(); - spin_unlock_irqrestore(&prom_lock, flags); - - if (!node) { - prom_printf("Cannot resolve stdout node from " - "instance %08x.\n", fd); - prom_halt(); - } - dp = of_find_node_by_phandle(node); - type = of_get_property(dp, "device_type", NULL); - - if (!type) { - prom_printf("Console stdout lacks " - "device_type property.\n"); - prom_halt(); - } - - if (strcmp(type, "display") && strcmp(type, "serial")) { - prom_printf("Console device_type is neither display " - "nor serial.\n"); - prom_halt(); - } - - of_console_device = dp; - - if (prom_vers == PROM_V2) { - strcpy(of_console_path, dp->full_name); - switch (*romvec->pv_stdout) { - case PROMDEV_TTYA: - strcat(of_console_path, ":a"); - break; - case PROMDEV_TTYB: - strcat(of_console_path, ":b"); - break; - } - } else { - const char *path; - - dp = of_find_node_by_path("/"); - path = of_get_property(dp, "stdout-path", NULL); - if (!path) { - prom_printf("No stdout-path in root node.\n"); - prom_halt(); - } - strcpy(of_console_path, path); - } - break; - } - - of_console_options = strrchr(of_console_path, ':'); - if (of_console_options) { - of_console_options++; - if (*of_console_options == '\0') - of_console_options = NULL; - } - - prom_printf(msg, of_console_path); - printk(msg, of_console_path); -} - void __init prom_build_devicetree(void) { struct device_node **nextp; @@ -538,8 +578,6 @@ void __init prom_build_devicetree(void) allnodes->child = build_tree(allnodes, prom_getchild(allnodes->node), &nextp); - of_console_init(); - printk("PROM: Built device tree with %u bytes of memory.\n", prom_early_allocated); } diff --git a/trunk/arch/sparc/kernel/setup.c b/trunk/arch/sparc/kernel/setup.c index f8228383895a..64c0ed98820a 100644 --- a/trunk/arch/sparc/kernel/setup.c +++ b/trunk/arch/sparc/kernel/setup.c @@ -146,6 +146,31 @@ static void __init process_switch(char c) } } +static void __init process_console(char *commands) +{ + serial_console = 0; + commands += 8; + /* Linux-style serial */ + if (!strncmp(commands, "ttyS", 4)) + serial_console = simple_strtoul(commands + 4, NULL, 10) + 1; + else if (!strncmp(commands, "tty", 3)) { + char c = *(commands + 3); + /* Solaris-style serial */ + if (c == 'a' || c == 'b') + serial_console = c - 'a' + 1; + /* else Linux-style fbcon, not serial */ + } +#if defined(CONFIG_PROM_CONSOLE) + if (!strncmp(commands, "prom", 4)) { + char *p; + + for (p = commands - 8; *p && *p != ' '; p++) + *p = ' '; + conswitchp = &prom_con; + } +#endif +} + static void __init boot_flags_init(char *commands) { while (*commands) { @@ -162,7 +187,9 @@ static void __init boot_flags_init(char *commands) process_switch(*commands++); continue; } - if (!strncmp(commands, "mem=", 4)) { + if (!strncmp(commands, "console=", 8)) { + process_console(commands); + } else if (!strncmp(commands, "mem=", 4)) { /* * "mem=XXX[kKmM] overrides the PROM-reported * memory size. @@ -314,6 +341,41 @@ void __init setup_arch(char **cmdline_p) smp_setup_cpu_possible_map(); } +static int __init set_preferred_console(void) +{ + int idev, odev; + + /* The user has requested a console so this is already set up. */ + if (serial_console >= 0) + return -EBUSY; + + idev = prom_query_input_device(); + odev = prom_query_output_device(); + if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) { + serial_console = 0; + } else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) { + serial_console = 1; + } else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) { + serial_console = 2; + } else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OTTYA) { + prom_printf("MrCoffee ttya\n"); + serial_console = 1; + } else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OSCREEN) { + serial_console = 0; + prom_printf("MrCoffee keyboard\n"); + } else { + prom_printf("Confusing console (idev %d, odev %d)\n", + idev, odev); + serial_console = 1; + } + + if (serial_console) + return add_preferred_console("ttyS", serial_console - 1, NULL); + + return -ENODEV; +} +console_initcall(set_preferred_console); + extern char *sparc_cpu_type; extern char *sparc_fpu_type; @@ -399,6 +461,7 @@ void sun_do_break(void) prom_cmdline(); } +int serial_console = -1; int stop_a_enabled = 1; static int __init topology_init(void) diff --git a/trunk/arch/sparc/kernel/systbls.S b/trunk/arch/sparc/kernel/systbls.S index 55722840859c..90b52d4dab9a 100644 --- a/trunk/arch/sparc/kernel/systbls.S +++ b/trunk/arch/sparc/kernel/systbls.S @@ -1,7 +1,8 @@ -/* systbls.S: System call entry point tables for OS compatibility. +/* $Id: systbls.S,v 1.103 2002/02/08 03:57:14 davem Exp $ + * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * - * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * * Based upon preliminary work which is: * @@ -79,7 +80,7 @@ sys_call_table: /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare /*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy /*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait -/*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd, sys_fallocate +/*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd #ifdef CONFIG_SUNOS_EMUL /* Now the SunOS syscall table. */ @@ -197,6 +198,6 @@ sunos_sys_table: .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys /*310*/ .long sunos_nosys, sunos_nosys, sunos_nosys - .long sunos_nosys, sunos_nosys + .long sunos_nosys #endif diff --git a/trunk/arch/sparc/kernel/time.c b/trunk/arch/sparc/kernel/time.c index f2fdbb3664d3..7b4612da74a6 100644 --- a/trunk/arch/sparc/kernel/time.c +++ b/trunk/arch/sparc/kernel/time.c @@ -354,7 +354,7 @@ static struct of_platform_driver clock_driver = { /* Probe for the mostek real time clock chip. */ static int __init clock_init(void) { - return of_register_driver(&clock_driver, &of_platform_bus_type); + return of_register_driver(&clock_driver, &of_bus_type); } /* Must be after subsys_initcall() so that busses are probed. Must diff --git a/trunk/arch/sparc/prom/console.c b/trunk/arch/sparc/prom/console.c index 8d1cfb0d5068..4e6e41d3291d 100644 --- a/trunk/arch/sparc/prom/console.c +++ b/trunk/arch/sparc/prom/console.c @@ -102,3 +102,119 @@ prom_putchar(char c) while(prom_nbputchar(c) == -1) ; return; } + +/* Query for input device type */ +enum prom_input_device +prom_query_input_device(void) +{ + unsigned long flags; + int st_p; + char propb[64]; + char *p; + int propl; + + switch(prom_vers) { + case PROM_V0: + case PROM_V2: + case PROM_SUN4: + default: + switch(*romvec->pv_stdin) { + case PROMDEV_KBD: return PROMDEV_IKBD; + case PROMDEV_TTYA: return PROMDEV_ITTYA; + case PROMDEV_TTYB: return PROMDEV_ITTYB; + default: + return PROMDEV_I_UNK; + }; + case PROM_V3: + spin_lock_irqsave(&prom_lock, flags); + st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin); + restore_current(); + spin_unlock_irqrestore(&prom_lock, flags); + if(prom_node_has_property(st_p, "keyboard")) + return PROMDEV_IKBD; + if (prom_getproperty(st_p, "name", propb, sizeof(propb)) != -1) { + if(strncmp(propb, "keyboard", sizeof("serial")) == 0) + return PROMDEV_IKBD; + } + if (prom_getproperty(st_p, "device_type", propb, sizeof(propb)) != -1) { + if(strncmp(propb, "serial", sizeof("serial"))) + return PROMDEV_I_UNK; + } + propl = prom_getproperty(prom_root_node, "stdin-path", propb, sizeof(propb)); + if(propl > 2) { + p = propb; + while(*p) p++; p -= 2; + if(p[0] == ':') { + if(p[1] == 'a') + return PROMDEV_ITTYA; + else if(p[1] == 'b') + return PROMDEV_ITTYB; + } + } + return PROMDEV_I_UNK; + } +} + +/* Query for output device type */ + +enum prom_output_device +prom_query_output_device(void) +{ + unsigned long flags; + int st_p; + char propb[64]; + char *p; + int propl; + + switch(prom_vers) { + case PROM_V0: + case PROM_SUN4: + switch(*romvec->pv_stdin) { + case PROMDEV_SCREEN: return PROMDEV_OSCREEN; + case PROMDEV_TTYA: return PROMDEV_OTTYA; + case PROMDEV_TTYB: return PROMDEV_OTTYB; + }; + break; + case PROM_V2: + case PROM_V3: + spin_lock_irqsave(&prom_lock, flags); + st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout); + restore_current(); + spin_unlock_irqrestore(&prom_lock, flags); + propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb)); + if (propl == sizeof("display") && + strncmp("display", propb, sizeof("display")) == 0) + { + return PROMDEV_OSCREEN; + } + if(prom_vers == PROM_V3) { + if(propl >= 0 && + strncmp("serial", propb, sizeof("serial")) != 0) + return PROMDEV_O_UNK; + propl = prom_getproperty(prom_root_node, "stdout-path", + propb, sizeof(propb)); + if(propl == CON_SIZE_JMC && + strncmp(propb, con_name_jmc, CON_SIZE_JMC) == 0) + return PROMDEV_OTTYA; + if(propl > 2) { + p = propb; + while(*p) p++; p-= 2; + if(p[0]==':') { + if(p[1] == 'a') + return PROMDEV_OTTYA; + else if(p[1] == 'b') + return PROMDEV_OTTYB; + } + } + } else { + switch(*romvec->pv_stdin) { + case PROMDEV_TTYA: return PROMDEV_OTTYA; + case PROMDEV_TTYB: return PROMDEV_OTTYB; + }; + } + break; + default: + ; + }; + return PROMDEV_O_UNK; +} diff --git a/trunk/arch/sparc/prom/misc.c b/trunk/arch/sparc/prom/misc.c index 37cff5f54704..1942c7c05cb1 100644 --- a/trunk/arch/sparc/prom/misc.c +++ b/trunk/arch/sparc/prom/misc.c @@ -58,7 +58,7 @@ prom_cmdline(void) extern void install_linux_ticker(void); unsigned long flags; - if (prom_palette) + if(!serial_console && prom_palette) prom_palette (1); spin_lock_irqsave(&prom_lock, flags); install_obp_ticker(); @@ -69,7 +69,7 @@ prom_cmdline(void) #ifdef CONFIG_SUN_AUXIO set_auxio(AUXIO_LED, 0); #endif - if (prom_palette) + if(!serial_console && prom_palette) prom_palette (0); } diff --git a/trunk/arch/sparc64/Kconfig b/trunk/arch/sparc64/Kconfig index f1cc55677ff2..df6ee71894d1 100644 --- a/trunk/arch/sparc64/Kconfig +++ b/trunk/arch/sparc64/Kconfig @@ -65,9 +65,6 @@ config AUDIT_ARCH config ARCH_NO_VIRT_TO_BUS def_bool y -config OF - def_bool y - choice prompt "Kernel page size" default SPARC64_PAGE_SIZE_8KB diff --git a/trunk/arch/sparc64/defconfig b/trunk/arch/sparc64/defconfig index 10e301970a44..45ebf91a280c 100644 --- a/trunk/arch/sparc64/defconfig +++ b/trunk/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.22 -# Thu Jul 19 21:30:37 2007 +# Tue Jul 17 01:19:52 2007 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -16,7 +16,6 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_AUDIT_ARCH=y -CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_SPARC64_PAGE_SIZE_8KB=y # CONFIG_SPARC64_PAGE_SIZE_64KB is not set # CONFIG_SPARC64_PAGE_SIZE_512KB is not set @@ -149,6 +148,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_RESOURCES_64BIT=y CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=1 +CONFIG_VIRT_TO_BUS=y CONFIG_SBUS=y CONFIG_SBUSCHAR=y CONFIG_SUN_AUXIO=y @@ -317,6 +317,7 @@ CONFIG_CONNECTOR=m # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set @@ -469,6 +470,10 @@ CONFIG_ISCSI_TCP=m # CONFIG_SCSI_SUNESP is not set # CONFIG_SCSI_SRP is not set # CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# CONFIG_MD=y CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m @@ -605,6 +610,10 @@ CONFIG_SLHC=m # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -773,7 +782,6 @@ CONFIG_I2C_ALGOBIT=y CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ABITUGURU3 is not set # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set @@ -800,13 +808,11 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set @@ -900,7 +906,6 @@ CONFIG_FB_RADEON_I2C=y # CONFIG_PROM_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_FONTS=y # CONFIG_FONT_8x8 is not set @@ -1190,11 +1195,6 @@ CONFIG_USB_STORAGE=m # DMA Devices # -# -# Userspace I/O -# -# CONFIG_UIO is not set - # # Misc Linux/SPARC drivers # @@ -1385,7 +1385,6 @@ CONFIG_SCHEDSTATS=y # CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_LOCK_ALLOC is not set # CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1462,7 +1461,6 @@ CONFIG_CRC_CCITT=m CONFIG_CRC16=m # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y -# CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/trunk/arch/sparc64/kernel/auxio.c b/trunk/arch/sparc64/kernel/auxio.c index 7b379761e9f8..826118ee53d5 100644 --- a/trunk/arch/sparc64/kernel/auxio.c +++ b/trunk/arch/sparc64/kernel/auxio.c @@ -155,7 +155,7 @@ static struct of_platform_driver auxio_driver = { static int __init auxio_init(void) { - return of_register_driver(&auxio_driver, &of_platform_bus_type); + return of_register_driver(&auxio_driver, &of_bus_type); } /* Must be after subsys_initcall() so that busses are probed. Must diff --git a/trunk/arch/sparc64/kernel/ds.c b/trunk/arch/sparc64/kernel/ds.c index 9f472a79d37e..fa1f04d756a2 100644 --- a/trunk/arch/sparc64/kernel/ds.c +++ b/trunk/arch/sparc64/kernel/ds.c @@ -13,11 +13,11 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -124,11 +124,10 @@ struct ds_data_nack { __u64 result; }; -struct ds_info; struct ds_cap_state { __u64 handle; - void (*data)(struct ds_info *dp, + void (*data)(struct ldc_channel *lp, struct ds_cap_state *cp, void *buf, int len); @@ -140,27 +139,27 @@ struct ds_cap_state { #define CAP_STATE_REGISTERED 0x02 }; -static void md_update_data(struct ds_info *dp, struct ds_cap_state *cp, +static void md_update_data(struct ldc_channel *lp, struct ds_cap_state *cp, void *buf, int len); -static void domain_shutdown_data(struct ds_info *dp, +static void domain_shutdown_data(struct ldc_channel *lp, struct ds_cap_state *cp, void *buf, int len); -static void domain_panic_data(struct ds_info *dp, +static void domain_panic_data(struct ldc_channel *lp, struct ds_cap_state *cp, void *buf, int len); #ifdef CONFIG_HOTPLUG_CPU -static void dr_cpu_data(struct ds_info *dp, +static void dr_cpu_data(struct ldc_channel *lp, struct ds_cap_state *cp, void *buf, int len); #endif -static void ds_pri_data(struct ds_info *dp, +static void ds_pri_data(struct ldc_channel *lp, struct ds_cap_state *cp, void *buf, int len); -static void ds_var_data(struct ds_info *dp, +static void ds_var_data(struct ldc_channel *lp, struct ds_cap_state *cp, void *buf, int len); -struct ds_cap_state ds_states_template[] = { +struct ds_cap_state ds_states[] = { { .service_id = "md-update", .data = md_update_data, @@ -201,38 +200,30 @@ struct ds_info { #define DS_HS_START 0x01 #define DS_HS_DONE 0x02 - u64 id; - void *rcv_buf; int rcv_buf_len; - - struct ds_cap_state *ds_states; - int num_ds_states; - - struct ds_info *next; }; -static struct ds_info *ds_info_list; +static struct ds_info *ds_info; -static struct ds_cap_state *find_cap(struct ds_info *dp, u64 handle) +static struct ds_cap_state *find_cap(u64 handle) { unsigned int index = handle >> 32; - if (index >= dp->num_ds_states) + if (index >= ARRAY_SIZE(ds_states)) return NULL; - return &dp->ds_states[index]; + return &ds_states[index]; } -static struct ds_cap_state *find_cap_by_string(struct ds_info *dp, - const char *name) +static struct ds_cap_state *find_cap_by_string(const char *name) { int i; - for (i = 0; i < dp->num_ds_states; i++) { - if (strcmp(dp->ds_states[i].service_id, name)) + for (i = 0; i < ARRAY_SIZE(ds_states); i++) { + if (strcmp(ds_states[i].service_id, name)) continue; - return &dp->ds_states[i]; + return &ds_states[i]; } return NULL; } @@ -273,11 +264,10 @@ struct ds_md_update_res { __u32 result; }; -static void md_update_data(struct ds_info *dp, - struct ds_cap_state *cp, +static void md_update_data(struct ldc_channel *lp, + struct ds_cap_state *dp, void *buf, int len) { - struct ldc_channel *lp = dp->lp; struct ds_data *dpkt = buf; struct ds_md_update_req *rp; struct { @@ -287,14 +277,14 @@ static void md_update_data(struct ds_info *dp, rp = (struct ds_md_update_req *) (dpkt + 1); - printk(KERN_INFO "ds-%lu: Machine description update.\n", dp->id); + printk(KERN_INFO PFX "Machine description update.\n"); mdesc_update(); memset(&pkt, 0, sizeof(pkt)); pkt.data.tag.type = DS_DATA; pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag); - pkt.data.handle = cp->handle; + pkt.data.handle = dp->handle; pkt.res.req_num = rp->req_num; pkt.res.result = DS_OK; @@ -312,11 +302,10 @@ struct ds_shutdown_res { char reason[1]; }; -static void domain_shutdown_data(struct ds_info *dp, - struct ds_cap_state *cp, +static void domain_shutdown_data(struct ldc_channel *lp, + struct ds_cap_state *dp, void *buf, int len) { - struct ldc_channel *lp = dp->lp; struct ds_data *dpkt = buf; struct ds_shutdown_req *rp; struct { @@ -326,20 +315,20 @@ static void domain_shutdown_data(struct ds_info *dp, rp = (struct ds_shutdown_req *) (dpkt + 1); - printk(KERN_ALERT "ds-%lu: Shutdown request from " - "LDOM manager received.\n", dp->id); + printk(KERN_ALERT PFX "Shutdown request from " + "LDOM manager received.\n"); memset(&pkt, 0, sizeof(pkt)); pkt.data.tag.type = DS_DATA; pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag); - pkt.data.handle = cp->handle; + pkt.data.handle = dp->handle; pkt.res.req_num = rp->req_num; pkt.res.result = DS_OK; pkt.res.reason[0] = 0; ds_send(lp, &pkt, sizeof(pkt)); - orderly_poweroff(true); + wake_up_powerd(); } struct ds_panic_req { @@ -352,11 +341,10 @@ struct ds_panic_res { char reason[1]; }; -static void domain_panic_data(struct ds_info *dp, - struct ds_cap_state *cp, +static void domain_panic_data(struct ldc_channel *lp, + struct ds_cap_state *dp, void *buf, int len) { - struct ldc_channel *lp = dp->lp; struct ds_data *dpkt = buf; struct ds_panic_req *rp; struct { @@ -366,13 +354,13 @@ static void domain_panic_data(struct ds_info *dp, rp = (struct ds_panic_req *) (dpkt + 1); - printk(KERN_ALERT "ds-%lu: Panic request from " - "LDOM manager received.\n", dp->id); + printk(KERN_ALERT PFX "Panic request from " + "LDOM manager received.\n"); memset(&pkt, 0, sizeof(pkt)); pkt.data.tag.type = DS_DATA; pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag); - pkt.data.handle = cp->handle; + pkt.data.handle = dp->handle; pkt.res.req_num = rp->req_num; pkt.res.result = DS_OK; pkt.res.reason[0] = 0; @@ -415,11 +403,10 @@ struct dr_cpu_resp_entry { __u32 str_off; }; -static void __dr_cpu_send_error(struct ds_info *dp, - struct ds_cap_state *cp, - struct ds_data *data) +static void __dr_cpu_send_error(struct ds_cap_state *cp, struct ds_data *data) { struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1); + struct ds_info *dp = ds_info; struct { struct ds_data data; struct dr_cpu_tag tag; @@ -441,14 +428,12 @@ static void __dr_cpu_send_error(struct ds_info *dp, __ds_send(dp->lp, &pkt, msg_len); } -static void dr_cpu_send_error(struct ds_info *dp, - struct ds_cap_state *cp, - struct ds_data *data) +static void dr_cpu_send_error(struct ds_cap_state *cp, struct ds_data *data) { unsigned long flags; spin_lock_irqsave(&ds_lock, flags); - __dr_cpu_send_error(dp, cp, data); + __dr_cpu_send_error(cp, data); spin_unlock_irqrestore(&ds_lock, flags); } @@ -526,9 +511,7 @@ static void dr_cpu_mark(struct ds_data *resp, int cpu, int ncpus, } } -static int dr_cpu_configure(struct ds_info *dp, - struct ds_cap_state *cp, - u64 req_num, +static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num, cpumask_t *mask) { struct ds_data *resp; @@ -550,8 +533,7 @@ static int dr_cpu_configure(struct ds_info *dp, for_each_cpu_mask(cpu, *mask) { int err; - printk(KERN_INFO "ds-%lu: Starting cpu %d...\n", - dp->id, cpu); + printk(KERN_INFO PFX "Starting cpu %d...\n", cpu); err = cpu_up(cpu); if (err) { __u32 res = DR_CPU_RES_FAILURE; @@ -566,14 +548,14 @@ static int dr_cpu_configure(struct ds_info *dp, res = DR_CPU_RES_CPU_NOT_RESPONDING; } - printk(KERN_INFO "ds-%lu: CPU startup failed err=%d\n", - dp->id, err); + printk(KERN_INFO PFX "CPU startup failed err=%d\n", + err); dr_cpu_mark(resp, cpu, ncpus, res, stat); } } spin_lock_irqsave(&ds_lock, flags); - __ds_send(dp->lp, resp, resp_len); + __ds_send(ds_info->lp, resp, resp_len); spin_unlock_irqrestore(&ds_lock, flags); kfree(resp); @@ -584,9 +566,7 @@ static int dr_cpu_configure(struct ds_info *dp, return 0; } -static int dr_cpu_unconfigure(struct ds_info *dp, - struct ds_cap_state *cp, - u64 req_num, +static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num, cpumask_t *mask) { struct ds_data *resp; @@ -606,8 +586,8 @@ static int dr_cpu_unconfigure(struct ds_info *dp, for_each_cpu_mask(cpu, *mask) { int err; - printk(KERN_INFO "ds-%lu: Shutting down cpu %d...\n", - dp->id, cpu); + printk(KERN_INFO PFX "CPU[%d]: Shutting down cpu %d...\n", + smp_processor_id(), cpu); err = cpu_down(cpu); if (err) dr_cpu_mark(resp, cpu, ncpus, @@ -616,7 +596,7 @@ static int dr_cpu_unconfigure(struct ds_info *dp, } spin_lock_irqsave(&ds_lock, flags); - __ds_send(dp->lp, resp, resp_len); + __ds_send(ds_info->lp, resp, resp_len); spin_unlock_irqrestore(&ds_lock, flags); kfree(resp); @@ -624,7 +604,7 @@ static int dr_cpu_unconfigure(struct ds_info *dp, return 0; } -static void dr_cpu_data(struct ds_info *dp, +static void dr_cpu_data(struct ldc_channel *lp, struct ds_cap_state *cp, void *buf, int len) { @@ -643,7 +623,7 @@ static void dr_cpu_data(struct ds_info *dp, break; default: - dr_cpu_send_error(dp, cp, data); + dr_cpu_send_error(cp, data); return; } @@ -659,12 +639,12 @@ static void dr_cpu_data(struct ds_info *dp, } if (tag->type == DR_CPU_CONFIGURE) - err = dr_cpu_configure(dp, cp, req_num, &mask); + err = dr_cpu_configure(cp, req_num, &mask); else - err = dr_cpu_unconfigure(dp, cp, req_num, &mask); + err = dr_cpu_unconfigure(cp, req_num, &mask); if (err) - dr_cpu_send_error(dp, cp, data); + dr_cpu_send_error(cp, data); } #endif /* CONFIG_HOTPLUG_CPU */ @@ -676,8 +656,8 @@ struct ds_pri_msg { #define DS_PRI_UPDATE 0x02 }; -static void ds_pri_data(struct ds_info *dp, - struct ds_cap_state *cp, +static void ds_pri_data(struct ldc_channel *lp, + struct ds_cap_state *dp, void *buf, int len) { struct ds_data *dpkt = buf; @@ -685,8 +665,8 @@ static void ds_pri_data(struct ds_info *dp, rp = (struct ds_pri_msg *) (dpkt + 1); - printk(KERN_INFO "ds-%lu: PRI REQ [%lx:%lx], len=%d\n", - dp->id, rp->req_num, rp->type, len); + printk(KERN_INFO PFX "PRI REQ [%lx:%lx], len=%d\n", + rp->req_num, rp->type, len); } struct ds_var_hdr { @@ -721,8 +701,8 @@ static DEFINE_MUTEX(ds_var_mutex); static int ds_var_doorbell; static int ds_var_response; -static void ds_var_data(struct ds_info *dp, - struct ds_cap_state *cp, +static void ds_var_data(struct ldc_channel *lp, + struct ds_cap_state *dp, void *buf, int len) { struct ds_data *dpkt = buf; @@ -741,35 +721,14 @@ static void ds_var_data(struct ds_info *dp, void ldom_set_var(const char *var, const char *value) { + struct ds_info *dp = ds_info; struct ds_cap_state *cp; - struct ds_info *dp; - unsigned long flags; - spin_lock_irqsave(&ds_lock, flags); - cp = NULL; - for (dp = ds_info_list; dp; dp = dp->next) { - struct ds_cap_state *tmp; + cp = find_cap_by_string("var-config"); + if (cp->state != CAP_STATE_REGISTERED) + cp = find_cap_by_string("var-config-backup"); - tmp = find_cap_by_string(dp, "var-config"); - if (tmp && tmp->state == CAP_STATE_REGISTERED) { - cp = tmp; - break; - } - } - if (!cp) { - for (dp = ds_info_list; dp; dp = dp->next) { - struct ds_cap_state *tmp; - - tmp = find_cap_by_string(dp, "var-config-backup"); - if (tmp && tmp->state == CAP_STATE_REGISTERED) { - cp = tmp; - break; - } - } - } - spin_unlock_irqrestore(&ds_lock, flags); - - if (cp) { + if (cp->state == CAP_STATE_REGISTERED) { union { struct { struct ds_data data; @@ -777,6 +736,7 @@ void ldom_set_var(const char *var, const char *value) } header; char all[512]; } pkt; + unsigned long flags; char *base, *p; int msg_len, loops; @@ -817,9 +777,9 @@ void ldom_set_var(const char *var, const char *value) if (ds_var_doorbell == 0 || ds_var_response != DS_VAR_SUCCESS) - printk(KERN_ERR "ds-%lu: var-config [%s:%s] " + printk(KERN_ERR PFX "var-config [%s:%s] " "failed, response(%d).\n", - dp->id, var, value, + var, value, ds_var_response); } else { printk(KERN_ERR PFX "var-config not registered so " @@ -851,8 +811,8 @@ void ldom_power_off(void) static void ds_conn_reset(struct ds_info *dp) { - printk(KERN_ERR "ds-%lu: ds_conn_reset() from %p\n", - dp->id, __builtin_return_address(0)); + printk(KERN_ERR PFX "ds_conn_reset() from %p\n", + __builtin_return_address(0)); } static int register_services(struct ds_info *dp) @@ -860,12 +820,12 @@ static int register_services(struct ds_info *dp) struct ldc_channel *lp = dp->lp; int i; - for (i = 0; i < dp->num_ds_states; i++) { + for (i = 0; i < ARRAY_SIZE(ds_states); i++) { struct { struct ds_reg_req req; u8 id_buf[256]; } pbuf; - struct ds_cap_state *cp = &dp->ds_states[i]; + struct ds_cap_state *cp = &ds_states[i]; int err, msg_len; u64 new_count; @@ -910,26 +870,28 @@ static int ds_handshake(struct ds_info *dp, struct ds_msg_tag *pkt) if (pkt->type == DS_REG_ACK) { struct ds_reg_ack *ap = (struct ds_reg_ack *) pkt; - struct ds_cap_state *cp = find_cap(dp, ap->handle); + struct ds_cap_state *cp = find_cap(ap->handle); if (!cp) { - printk(KERN_ERR "ds-%lu: REG ACK for unknown " - "handle %lx\n", dp->id, ap->handle); + printk(KERN_ERR PFX "REG ACK for unknown handle %lx\n", + ap->handle); return 0; } - printk(KERN_INFO "ds-%lu: Registered %s service.\n", - dp->id, cp->service_id); + printk(KERN_INFO PFX "Registered %s service.\n", + cp->service_id); cp->state = CAP_STATE_REGISTERED; } else if (pkt->type == DS_REG_NACK) { struct ds_reg_nack *np = (struct ds_reg_nack *) pkt; - struct ds_cap_state *cp = find_cap(dp, np->handle); + struct ds_cap_state *cp = find_cap(np->handle); if (!cp) { - printk(KERN_ERR "ds-%lu: REG NACK for " + printk(KERN_ERR PFX "REG NACK for " "unknown handle %lx\n", - dp->id, np->handle); + np->handle); return 0; } + printk(KERN_INFO PFX "Could not register %s service\n", + cp->service_id); cp->state = CAP_STATE_UNKNOWN; } @@ -960,7 +922,6 @@ static DECLARE_WAIT_QUEUE_HEAD(ds_wait); struct ds_queue_entry { struct list_head list; - struct ds_info *dp; int req_len; int __pad; u64 req[0]; @@ -969,6 +930,7 @@ struct ds_queue_entry { static void process_ds_work(void) { struct ds_queue_entry *qp, *tmp; + static struct ds_info *dp; unsigned long flags; LIST_HEAD(todo); @@ -977,22 +939,22 @@ static void process_ds_work(void) INIT_LIST_HEAD(&ds_work_list); spin_unlock_irqrestore(&ds_lock, flags); + dp = ds_info; + list_for_each_entry_safe(qp, tmp, &todo, list) { struct ds_data *dpkt = (struct ds_data *) qp->req; - struct ds_info *dp = qp->dp; - struct ds_cap_state *cp = find_cap(dp, dpkt->handle); + struct ds_cap_state *cp = find_cap(dpkt->handle); int req_len = qp->req_len; if (!cp) { - printk(KERN_ERR "ds-%lu: Data for unknown " - "handle %lu\n", - dp->id, dpkt->handle); + printk(KERN_ERR PFX "Data for unknown handle %lu\n", + dpkt->handle); spin_lock_irqsave(&ds_lock, flags); __send_ds_nack(dp, dpkt->handle); spin_unlock_irqrestore(&ds_lock, flags); } else { - cp->data(dp, cp, dpkt, req_len); + cp->data(dp->lp, cp, dpkt, req_len); } list_del(&qp->list); @@ -1028,7 +990,6 @@ static int ds_data(struct ds_info *dp, struct ds_msg_tag *pkt, int len) if (!qp) { __send_ds_nack(dp, dpkt->handle); } else { - qp->dp = dp; memcpy(&qp->req, pkt, len); list_add_tail(&qp->list, &ds_work_list); wake_up(&ds_wait); @@ -1058,8 +1019,8 @@ static void ds_reset(struct ds_info *dp) dp->hs_state = 0; - for (i = 0; i < dp->num_ds_states; i++) { - struct ds_cap_state *cp = &dp->ds_states[i]; + for (i = 0; i < ARRAY_SIZE(ds_states); i++) { + struct ds_cap_state *cp = &ds_states[i]; cp->state = CAP_STATE_UNKNOWN; } @@ -1087,8 +1048,7 @@ static void ds_event(void *arg, int event) } if (event != LDC_EVENT_DATA_READY) { - printk(KERN_WARNING "ds-%lu: Unexpected LDC event %d\n", - dp->id, event); + printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event); spin_unlock_irqrestore(&ds_lock, flags); return; } @@ -1139,11 +1099,9 @@ static int __devinit ds_probe(struct vio_dev *vdev, .mtu = 4096, .mode = LDC_MODE_STREAM, }; - struct mdesc_handle *hp; struct ldc_channel *lp; struct ds_info *dp; - const u64 *val; - int err, i; + int err; if (ds_version_printed++ == 0) printk(KERN_INFO "%s", version); @@ -1153,37 +1111,19 @@ static int __devinit ds_probe(struct vio_dev *vdev, if (!dp) goto out_err; - hp = mdesc_grab(); - val = mdesc_get_property(hp, vdev->mp, "id", NULL); - if (val) - dp->id = *val; - mdesc_release(hp); - dp->rcv_buf = kzalloc(4096, GFP_KERNEL); if (!dp->rcv_buf) goto out_free_dp; dp->rcv_buf_len = 4096; - dp->ds_states = kzalloc(sizeof(ds_states_template), - GFP_KERNEL); - if (!dp->ds_states) - goto out_free_rcv_buf; - - memcpy(dp->ds_states, ds_states_template, - sizeof(ds_states_template)); - dp->num_ds_states = ARRAY_SIZE(ds_states_template); - - for (i = 0; i < dp->num_ds_states; i++) - dp->ds_states[i].handle = ((u64)i << 32); - ds_cfg.tx_irq = vdev->tx_irq; ds_cfg.rx_irq = vdev->rx_irq; lp = ldc_alloc(vdev->channel_id, &ds_cfg, dp); if (IS_ERR(lp)) { err = PTR_ERR(lp); - goto out_free_ds_states; + goto out_free_rcv_buf; } dp->lp = lp; @@ -1191,19 +1131,15 @@ static int __devinit ds_probe(struct vio_dev *vdev, if (err) goto out_free_ldc; - spin_lock_irq(&ds_lock); - dp->next = ds_info_list; - ds_info_list = dp; - spin_unlock_irq(&ds_lock); + ds_info = dp; + + start_powerd(); return err; out_free_ldc: ldc_free(dp->lp); -out_free_ds_states: - kfree(dp->ds_states); - out_free_rcv_buf: kfree(dp->rcv_buf); @@ -1238,6 +1174,11 @@ static struct vio_driver ds_driver = { static int __init ds_init(void) { + int i; + + for (i = 0; i < ARRAY_SIZE(ds_states); i++) + ds_states[i].handle = ((u64)i << 32); + kthread_run(ds_thread, NULL, "kldomd"); return vio_register_driver(&ds_driver); diff --git a/trunk/arch/sparc64/kernel/ebus.c b/trunk/arch/sparc64/kernel/ebus.c index 6d2956179cde..ad55a9bb50dd 100644 --- a/trunk/arch/sparc64/kernel/ebus.c +++ b/trunk/arch/sparc64/kernel/ebus.c @@ -362,7 +362,6 @@ static int __init child_regs_nonstandard(struct linux_ebus_device *dev) static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev) { struct linux_ebus_child *child; - struct dev_archdata *sd; struct of_device *op; int i, len; @@ -388,10 +387,6 @@ static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_de dev->irqs[i] = op->irqs[i]; } - sd = &dev->ofdev.dev.archdata; - sd->prom_node = dp; - sd->op = &dev->ofdev; - dev->ofdev.node = dp; dev->ofdev.dev.parent = &dev->bus->ofdev.dev; dev->ofdev.dev.bus = &ebus_bus_type; diff --git a/trunk/arch/sparc64/kernel/head.S b/trunk/arch/sparc64/kernel/head.S index 35feacb6b8ec..77259526cb15 100644 --- a/trunk/arch/sparc64/kernel/head.S +++ b/trunk/arch/sparc64/kernel/head.S @@ -458,6 +458,7 @@ tlb_fixup_done: or %g6, %lo(init_thread_union), %g6 ldx [%g6 + TI_TASK], %g4 mov %sp, %l6 + mov %o4, %l7 wr %g0, ASI_P, %asi mov 1, %g1 diff --git a/trunk/arch/sparc64/kernel/irq.c b/trunk/arch/sparc64/kernel/irq.c index db31bf6b42db..8cb3358674f5 100644 --- a/trunk/arch/sparc64/kernel/irq.c +++ b/trunk/arch/sparc64/kernel/irq.c @@ -87,11 +87,7 @@ struct ino_bucket ivector_table[NUM_IVECS] __attribute__ ((aligned (SMP_CACHE_BY */ #define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist) -static struct { - unsigned int irq; - unsigned int dev_handle; - unsigned int dev_ino; -} virt_to_real_irq_table[NR_IRQS]; +static unsigned int virt_to_real_irq_table[NR_IRQS]; static unsigned char virt_irq_alloc(unsigned int real_irq) { @@ -100,7 +96,7 @@ static unsigned char virt_irq_alloc(unsigned int real_irq) BUILD_BUG_ON(NR_IRQS >= 256); for (ent = 1; ent < NR_IRQS; ent++) { - if (!virt_to_real_irq_table[ent].irq) + if (!virt_to_real_irq_table[ent]) break; } if (ent >= NR_IRQS) { @@ -108,7 +104,7 @@ static unsigned char virt_irq_alloc(unsigned int real_irq) return 0; } - virt_to_real_irq_table[ent].irq = real_irq; + virt_to_real_irq_table[ent] = real_irq; return ent; } @@ -121,8 +117,8 @@ static void virt_irq_free(unsigned int virt_irq) if (virt_irq >= NR_IRQS) return; - real_irq = virt_to_real_irq_table[virt_irq].irq; - virt_to_real_irq_table[virt_irq].irq = 0; + real_irq = virt_to_real_irq_table[virt_irq]; + virt_to_real_irq_table[virt_irq] = 0; __bucket(real_irq)->virt_irq = 0; } @@ -130,7 +126,7 @@ static void virt_irq_free(unsigned int virt_irq) static unsigned int virt_to_real_irq(unsigned char virt_irq) { - return virt_to_real_irq_table[virt_irq].irq; + return virt_to_real_irq_table[virt_irq]; } /* @@ -340,15 +336,15 @@ static void sun4v_irq_enable(unsigned int virt_irq) err = sun4v_intr_settarget(ino, cpuid); if (err != HV_EOK) - printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): " - "err(%d)\n", ino, cpuid, err); + printk("sun4v_intr_settarget(%x,%lu): err(%d)\n", + ino, cpuid, err); err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); if (err != HV_EOK) - printk(KERN_ERR "sun4v_intr_setstate(%x): " + printk("sun4v_intr_setstate(%x): " "err(%d)\n", ino, err); err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED); if (err != HV_EOK) - printk(KERN_ERR "sun4v_intr_setenabled(%x): err(%d)\n", + printk("sun4v_intr_setenabled(%x): err(%d)\n", ino, err); } } @@ -366,8 +362,8 @@ static void sun4v_set_affinity(unsigned int virt_irq, cpumask_t mask) err = sun4v_intr_settarget(ino, cpuid); if (err != HV_EOK) - printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): " - "err(%d)\n", ino, cpuid, err); + printk("sun4v_intr_settarget(%x,%lu): err(%d)\n", + ino, cpuid, err); } } @@ -381,7 +377,7 @@ static void sun4v_irq_disable(unsigned int virt_irq) err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED); if (err != HV_EOK) - printk(KERN_ERR "sun4v_intr_setenabled(%x): " + printk("sun4v_intr_setenabled(%x): " "err(%d)\n", ino, err); } } @@ -414,7 +410,7 @@ static void sun4v_irq_end(unsigned int virt_irq) err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); if (err != HV_EOK) - printk(KERN_ERR "sun4v_intr_setstate(%x): " + printk("sun4v_intr_setstate(%x): " "err(%d)\n", ino, err); } } @@ -422,6 +418,7 @@ static void sun4v_irq_end(unsigned int virt_irq) static void sun4v_virq_enable(unsigned int virt_irq) { struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); + unsigned int ino = bucket - &ivector_table[0]; if (likely(bucket)) { unsigned long cpuid, dev_handle, dev_ino; @@ -429,24 +426,24 @@ static void sun4v_virq_enable(unsigned int virt_irq) cpuid = irq_choose_cpu(virt_irq); - dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; - dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; + dev_handle = ino & IMAP_IGN; + dev_ino = ino & IMAP_INO; err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); if (err != HV_EOK) - printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): " + printk("sun4v_vintr_set_target(%lx,%lx,%lu): " "err(%d)\n", dev_handle, dev_ino, cpuid, err); err = sun4v_vintr_set_state(dev_handle, dev_ino, HV_INTR_STATE_IDLE); if (err != HV_EOK) - printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," + printk("sun4v_vintr_set_state(%lx,%lx," "HV_INTR_STATE_IDLE): err(%d)\n", dev_handle, dev_ino, err); err = sun4v_vintr_set_valid(dev_handle, dev_ino, HV_INTR_ENABLED); if (err != HV_EOK) - printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," + printk("sun4v_vintr_set_state(%lx,%lx," "HV_INTR_ENABLED): err(%d)\n", dev_handle, dev_ino, err); } @@ -455,6 +452,7 @@ static void sun4v_virq_enable(unsigned int virt_irq) static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask) { struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); + unsigned int ino = bucket - &ivector_table[0]; if (likely(bucket)) { unsigned long cpuid, dev_handle, dev_ino; @@ -462,12 +460,12 @@ static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask) cpuid = irq_choose_cpu(virt_irq); - dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; - dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; + dev_handle = ino & IMAP_IGN; + dev_ino = ino & IMAP_INO; err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); if (err != HV_EOK) - printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): " + printk("sun4v_vintr_set_target(%lx,%lx,%lu): " "err(%d)\n", dev_handle, dev_ino, cpuid, err); } @@ -476,18 +474,19 @@ static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask) static void sun4v_virq_disable(unsigned int virt_irq) { struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); + unsigned int ino = bucket - &ivector_table[0]; if (likely(bucket)) { unsigned long dev_handle, dev_ino; int err; - dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; - dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; + dev_handle = ino & IMAP_IGN; + dev_ino = ino & IMAP_INO; err = sun4v_vintr_set_valid(dev_handle, dev_ino, HV_INTR_DISABLED); if (err != HV_EOK) - printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," + printk("sun4v_vintr_set_state(%lx,%lx," "HV_INTR_DISABLED): err(%d)\n", dev_handle, dev_ino, err); } @@ -496,6 +495,7 @@ static void sun4v_virq_disable(unsigned int virt_irq) static void sun4v_virq_end(unsigned int virt_irq) { struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); + unsigned int ino = bucket - &ivector_table[0]; struct irq_desc *desc = irq_desc + virt_irq; if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -505,13 +505,13 @@ static void sun4v_virq_end(unsigned int virt_irq) unsigned long dev_handle, dev_ino; int err; - dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; - dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; + dev_handle = ino & IMAP_IGN; + dev_ino = ino & IMAP_INO; err = sun4v_vintr_set_state(dev_handle, dev_ino, HV_INTR_STATE_IDLE); if (err != HV_EOK) - printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," + printk("sun4v_vintr_set_state(%lx,%lx," "HV_INTR_STATE_IDLE): err(%d)\n", dev_handle, dev_ino, err); } @@ -700,12 +700,11 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) { unsigned long sysino, hv_err; - unsigned int virq; - BUG_ON(devhandle & devino); + BUG_ON(devhandle & ~IMAP_IGN); + BUG_ON(devino & ~IMAP_INO); sysino = devhandle | devino; - BUG_ON(sysino & ~(IMAP_IGN | IMAP_INO)); hv_err = sun4v_vintr_set_cookie(devhandle, devino, sysino); if (hv_err) { @@ -714,12 +713,7 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) prom_halt(); } - virq = sun4v_build_common(sysino, &sun4v_virq); - - virt_to_real_irq_table[virq].dev_handle = devhandle; - virt_to_real_irq_table[virq].dev_ino = devino; - - return virq; + return sun4v_build_common(sysino, &sun4v_virq); } #ifdef CONFIG_PCI_MSI diff --git a/trunk/arch/sparc64/kernel/isa.c b/trunk/arch/sparc64/kernel/isa.c index 1a1043fcf97d..6a6882e57ff2 100644 --- a/trunk/arch/sparc64/kernel/isa.c +++ b/trunk/arch/sparc64/kernel/isa.c @@ -79,7 +79,6 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) while (dp) { struct sparc_isa_device *isa_dev; - struct dev_archdata *sd; isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL); if (!isa_dev) { @@ -87,10 +86,6 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) return; } - sd = &isa_dev->ofdev.dev.archdata; - sd->prom_node = dp; - sd->op = &isa_dev->ofdev; - isa_dev->ofdev.node = dp; isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev; isa_dev->ofdev.dev.bus = &isa_bus_type; diff --git a/trunk/arch/sparc64/kernel/mdesc.c b/trunk/arch/sparc64/kernel/mdesc.c index cce4d0ddf5d5..302ba5e5a0bb 100644 --- a/trunk/arch/sparc64/kernel/mdesc.c +++ b/trunk/arch/sparc64/kernel/mdesc.c @@ -83,7 +83,7 @@ static void mdesc_handle_init(struct mdesc_handle *hp, hp->handle_size = handle_size; } -static struct mdesc_handle * __init mdesc_bootmem_alloc(unsigned int mdesc_size) +static struct mdesc_handle *mdesc_bootmem_alloc(unsigned int mdesc_size) { struct mdesc_handle *hp; unsigned int handle_size, alloc_size; @@ -123,7 +123,7 @@ static void mdesc_bootmem_free(struct mdesc_handle *hp) } } -static struct mdesc_mem_ops bootmem_mdesc_ops = { +static struct mdesc_mem_ops bootmem_mdesc_memops = { .alloc = mdesc_bootmem_alloc, .free = mdesc_bootmem_free, }; @@ -231,25 +231,6 @@ void mdesc_register_notifier(struct mdesc_notifier_client *client) mutex_unlock(&mdesc_mutex); } -static const u64 *parent_cfg_handle(struct mdesc_handle *hp, u64 node) -{ - const u64 *id; - u64 a; - - id = NULL; - mdesc_for_each_arc(a, hp, node, MDESC_ARC_TYPE_BACK) { - u64 target; - - target = mdesc_arc_target(hp, a); - id = mdesc_get_property(hp, target, - "cfg-handle", NULL); - if (id) - break; - } - - return id; -} - /* Run 'func' on nodes which are in A but not in B. */ static void invoke_on_missing(const char *name, struct mdesc_handle *a, @@ -259,42 +240,13 @@ static void invoke_on_missing(const char *name, u64 node; mdesc_for_each_node_by_name(a, node, name) { - int found = 0, is_vdc_port = 0; - const char *name_prop; - const u64 *id; + const u64 *id = mdesc_get_property(a, node, "id", NULL); + int found = 0; u64 fnode; - name_prop = mdesc_get_property(a, node, "name", NULL); - if (name_prop && !strcmp(name_prop, "vdc-port")) { - is_vdc_port = 1; - id = parent_cfg_handle(a, node); - } else - id = mdesc_get_property(a, node, "id", NULL); - - if (!id) { - printk(KERN_ERR "MD: Cannot find ID for %s node.\n", - (name_prop ? name_prop : name)); - continue; - } - mdesc_for_each_node_by_name(b, fnode, name) { - const u64 *fid; - - if (is_vdc_port) { - name_prop = mdesc_get_property(b, fnode, - "name", NULL); - if (!name_prop || - strcmp(name_prop, "vdc-port")) - continue; - fid = parent_cfg_handle(b, fnode); - if (!fid) { - printk(KERN_ERR "MD: Cannot find ID " - "for vdc-port node.\n"); - continue; - } - } else - fid = mdesc_get_property(b, fnode, - "id", NULL); + const u64 *fid = mdesc_get_property(b, fnode, + "id", NULL); if (*id == *fid) { found = 1; @@ -860,7 +812,7 @@ void __init sun4v_mdesc_init(void) printk("MDESC: Size is %lu bytes.\n", len); - hp = mdesc_alloc(len, &bootmem_mdesc_ops); + hp = mdesc_alloc(len, &bootmem_mdesc_memops); if (hp == NULL) { prom_printf("MDESC: alloc of %lu bytes failed.\n", len); prom_halt(); diff --git a/trunk/arch/sparc64/kernel/of_device.c b/trunk/arch/sparc64/kernel/of_device.c index 4cc77485f536..6676b93219dc 100644 --- a/trunk/arch/sparc64/kernel/of_device.c +++ b/trunk/arch/sparc64/kernel/of_device.c @@ -1,13 +1,132 @@ #include #include -#include #include #include #include #include -#include -#include -#include + +#include +#include + +/** + * of_match_device - Tell if an of_device structure has a matching + * of_match structure + * @ids: array of of device match structures to search in + * @dev: the of device structure to match against + * + * Used by a driver to check whether an of_device present in the + * system is in its list of supported devices. + */ +const struct of_device_id *of_match_device(const struct of_device_id *matches, + const struct of_device *dev) +{ + if (!dev->node) + return NULL; + while (matches->name[0] || matches->type[0] || matches->compatible[0]) { + int match = 1; + if (matches->name[0]) + match &= dev->node->name + && !strcmp(matches->name, dev->node->name); + if (matches->type[0]) + match &= dev->node->type + && !strcmp(matches->type, dev->node->type); + if (matches->compatible[0]) + match &= of_device_is_compatible(dev->node, + matches->compatible); + if (match) + return matches; + matches++; + } + return NULL; +} + +static int of_platform_bus_match(struct device *dev, struct device_driver *drv) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * of_drv = to_of_platform_driver(drv); + const struct of_device_id * matches = of_drv->match_table; + + if (!matches) + return 0; + + return of_match_device(matches, of_dev) != NULL; +} + +struct of_device *of_dev_get(struct of_device *dev) +{ + struct device *tmp; + + if (!dev) + return NULL; + tmp = get_device(&dev->dev); + if (tmp) + return to_of_device(tmp); + else + return NULL; +} + +void of_dev_put(struct of_device *dev) +{ + if (dev) + put_device(&dev->dev); +} + + +static int of_device_probe(struct device *dev) +{ + int error = -ENODEV; + struct of_platform_driver *drv; + struct of_device *of_dev; + const struct of_device_id *match; + + drv = to_of_platform_driver(dev->driver); + of_dev = to_of_device(dev); + + if (!drv->probe) + return error; + + of_dev_get(of_dev); + + match = of_match_device(drv->match_table, of_dev); + if (match) + error = drv->probe(of_dev, match); + if (error) + of_dev_put(of_dev); + + return error; +} + +static int of_device_remove(struct device *dev) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + + if (dev->driver && drv->remove) + drv->remove(of_dev); + return 0; +} + +static int of_device_suspend(struct device *dev, pm_message_t state) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + int error = 0; + + if (dev->driver && drv->suspend) + error = drv->suspend(of_dev, state); + return error; +} + +static int of_device_resume(struct device * dev) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + int error = 0; + + if (dev->driver && drv->resume) + error = drv->resume(of_dev); + return error; +} void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name) { @@ -44,7 +163,7 @@ static int node_match(struct device *dev, void *data) struct of_device *of_find_device_by_node(struct device_node *dp) { - struct device *dev = bus_find_device(&of_platform_bus_type, NULL, + struct device *dev = bus_find_device(&of_bus_type, NULL, dp, node_match); if (dev) @@ -55,20 +174,48 @@ struct of_device *of_find_device_by_node(struct device_node *dp) EXPORT_SYMBOL(of_find_device_by_node); #ifdef CONFIG_PCI -struct bus_type isa_bus_type; +struct bus_type isa_bus_type = { + .name = "isa", + .match = of_platform_bus_match, + .probe = of_device_probe, + .remove = of_device_remove, + .suspend = of_device_suspend, + .resume = of_device_resume, +}; EXPORT_SYMBOL(isa_bus_type); -struct bus_type ebus_bus_type; +struct bus_type ebus_bus_type = { + .name = "ebus", + .match = of_platform_bus_match, + .probe = of_device_probe, + .remove = of_device_remove, + .suspend = of_device_suspend, + .resume = of_device_resume, +}; EXPORT_SYMBOL(ebus_bus_type); #endif #ifdef CONFIG_SBUS -struct bus_type sbus_bus_type; +struct bus_type sbus_bus_type = { + .name = "sbus", + .match = of_platform_bus_match, + .probe = of_device_probe, + .remove = of_device_remove, + .suspend = of_device_suspend, + .resume = of_device_resume, +}; EXPORT_SYMBOL(sbus_bus_type); #endif -struct bus_type of_platform_bus_type; -EXPORT_SYMBOL(of_platform_bus_type); +struct bus_type of_bus_type = { + .name = "of", + .match = of_platform_bus_match, + .probe = of_device_probe, + .remove = of_device_remove, + .suspend = of_device_suspend, + .resume = of_device_resume, +}; +EXPORT_SYMBOL(of_bus_type); static inline u64 of_read_addr(const u32 *cell, int size) { @@ -752,16 +899,11 @@ static struct of_device * __init scan_one_device(struct device_node *dp, { struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); const unsigned int *irq; - struct dev_archdata *sd; int len, i; if (!op) return NULL; - sd = &op->dev.archdata; - sd->prom_node = dp; - sd->op = op; - op->node = dp; op->clock_freq = of_getintprop_default(dp, "clock-frequency", @@ -791,7 +933,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]); op->dev.parent = parent; - op->dev.bus = &of_platform_bus_type; + op->dev.bus = &of_bus_type; if (!parent) strcpy(op->dev.bus_id, "root"); else @@ -835,16 +977,16 @@ static int __init of_bus_driver_init(void) { int err; - err = of_bus_type_init(&of_platform_bus_type, "of"); + err = bus_register(&of_bus_type); #ifdef CONFIG_PCI if (!err) - err = of_bus_type_init(&isa_bus_type, "isa"); + err = bus_register(&isa_bus_type); if (!err) - err = of_bus_type_init(&ebus_bus_type, "ebus"); + err = bus_register(&ebus_bus_type); #endif #ifdef CONFIG_SBUS if (!err) - err = of_bus_type_init(&sbus_bus_type, "sbus"); + err = bus_register(&sbus_bus_type); #endif if (!err) @@ -878,13 +1020,61 @@ int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) /* register with core */ return driver_register(&drv->driver); } -EXPORT_SYMBOL(of_register_driver); void of_unregister_driver(struct of_platform_driver *drv) { driver_unregister(&drv->driver); } -EXPORT_SYMBOL(of_unregister_driver); + + +static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct of_device *ofdev; + + ofdev = to_of_device(dev); + return sprintf(buf, "%s", ofdev->node->full_name); +} + +static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); + +/** + * of_release_dev - free an of device structure when all users of it are finished. + * @dev: device that's been disconnected + * + * Will be called only by the device core when all users of this of device are + * done. + */ +void of_release_dev(struct device *dev) +{ + struct of_device *ofdev; + + ofdev = to_of_device(dev); + + kfree(ofdev); +} + +int of_device_register(struct of_device *ofdev) +{ + int rc; + + BUG_ON(ofdev->node == NULL); + + rc = device_register(&ofdev->dev); + if (rc) + return rc; + + rc = device_create_file(&ofdev->dev, &dev_attr_devspec); + if (rc) + device_unregister(&ofdev->dev); + + return rc; +} + +void of_device_unregister(struct of_device *ofdev) +{ + device_remove_file(&ofdev->dev, &dev_attr_devspec); + device_unregister(&ofdev->dev); +} struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id, @@ -910,4 +1100,13 @@ struct of_device* of_platform_device_create(struct device_node *np, return dev; } + +EXPORT_SYMBOL(of_match_device); +EXPORT_SYMBOL(of_register_driver); +EXPORT_SYMBOL(of_unregister_driver); +EXPORT_SYMBOL(of_device_register); +EXPORT_SYMBOL(of_device_unregister); +EXPORT_SYMBOL(of_dev_get); +EXPORT_SYMBOL(of_dev_put); EXPORT_SYMBOL(of_platform_device_create); +EXPORT_SYMBOL(of_release_dev); diff --git a/trunk/arch/sparc64/kernel/pci_sun4v.c b/trunk/arch/sparc64/kernel/pci_sun4v.c index 639cf06ca372..6b3fe2c1d65e 100644 --- a/trunk/arch/sparc64/kernel/pci_sun4v.c +++ b/trunk/arch/sparc64/kernel/pci_sun4v.c @@ -1129,7 +1129,7 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) } #endif /* !(CONFIG_PCI_MSI) */ -static void __init pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle) +static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle) { struct pci_pbm_info *pbm; @@ -1163,7 +1163,7 @@ static void __init pci_sun4v_pbm_init(struct pci_controller_info *p, struct devi pci_sun4v_msi_init(pbm); } -void __init sun4v_pci_init(struct device_node *dp, char *model_name) +void sun4v_pci_init(struct device_node *dp, char *model_name) { static int hvapi_negotiated = 0; struct pci_controller_info *p; diff --git a/trunk/arch/sparc64/kernel/power.c b/trunk/arch/sparc64/kernel/power.c index 881a09ee4c4c..8dd4294ad21e 100644 --- a/trunk/arch/sparc64/kernel/power.c +++ b/trunk/arch/sparc64/kernel/power.c @@ -12,13 +12,13 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include @@ -31,9 +31,20 @@ int scons_pwroff = 1; static void __iomem *power_reg; +static DECLARE_WAIT_QUEUE_HEAD(powerd_wait); +static int button_pressed; + +void wake_up_powerd(void) +{ + if (button_pressed == 0) { + button_pressed = 1; + wake_up(&powerd_wait); + } +} + static irqreturn_t power_handler(int irq, void *dev_id) { - orderly_poweroff(true); + wake_up_powerd(); /* FIXME: Check registers for status... */ return IRQ_HANDLED; @@ -46,7 +57,7 @@ static void (*poweroff_method)(void) = machine_alt_power_off; void machine_power_off(void) { sstate_poweroff(); - if (strcmp(of_console_device->type, "serial") || scons_pwroff) { + if (!serial_console || scons_pwroff) { if (power_reg) { /* Both register bits seem to have the * same effect, so until I figure out @@ -66,6 +77,48 @@ void machine_power_off(void) void (*pm_power_off)(void) = machine_power_off; EXPORT_SYMBOL(pm_power_off); +static int powerd(void *__unused) +{ + static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; + char *argv[] = { "/sbin/shutdown", "-h", "now", NULL }; + DECLARE_WAITQUEUE(wait, current); + + daemonize("powerd"); + + add_wait_queue(&powerd_wait, &wait); + + for (;;) { + set_task_state(current, TASK_INTERRUPTIBLE); + if (button_pressed) + break; + flush_signals(current); + schedule(); + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&powerd_wait, &wait); + + /* Ok, down we go... */ + button_pressed = 0; + if (kernel_execve("/sbin/shutdown", argv, envp) < 0) { + printk(KERN_ERR "powerd: shutdown execution failed\n"); + machine_power_off(); + } + return 0; +} + +int start_powerd(void) +{ + int err; + + err = kernel_thread(powerd, NULL, CLONE_FS); + if (err < 0) + printk(KERN_ERR "power: Failed to start power daemon.\n"); + else + printk(KERN_INFO "power: powerd running.\n"); + + return err; +} + static int __init has_button_interrupt(unsigned int irq, struct device_node *dp) { if (irq == 0xffffffff) @@ -83,15 +136,20 @@ static int __devinit power_probe(struct of_device *op, const struct of_device_id power_reg = of_ioremap(res, 0, 0x4, "power"); - printk(KERN_INFO "%s: Control reg at %lx\n", + printk("%s: Control reg at %lx ... ", op->node->name, res->start); poweroff_method = machine_halt; /* able to use the standard halt */ if (has_button_interrupt(irq, op->node)) { + if (start_powerd() < 0) + return 0; + if (request_irq(irq, power_handler, 0, "power", NULL) < 0) printk(KERN_ERR "power: Cannot setup IRQ handler.\n"); + } else { + printk(KERN_INFO "power: Not using powerd.\n"); } return 0; @@ -112,6 +170,6 @@ static struct of_platform_driver power_driver = { void __init power_init(void) { - of_register_driver(&power_driver, &of_platform_bus_type); + of_register_driver(&power_driver, &of_bus_type); return; } diff --git a/trunk/arch/sparc64/kernel/process.c b/trunk/arch/sparc64/kernel/process.c index fd7899ba1d70..93557507ec9f 100644 --- a/trunk/arch/sparc64/kernel/process.c +++ b/trunk/arch/sparc64/kernel/process.c @@ -119,7 +119,7 @@ extern void (*prom_keyboard)(void); void machine_halt(void) { sstate_halt(); - if (prom_palette) + if (!serial_console && prom_palette) prom_palette (1); if (prom_keyboard) prom_keyboard(); @@ -130,7 +130,7 @@ void machine_halt(void) void machine_alt_power_off(void) { sstate_poweroff(); - if (prom_palette) + if (!serial_console && prom_palette) prom_palette(1); if (prom_keyboard) prom_keyboard(); @@ -145,7 +145,7 @@ void machine_restart(char * cmd) sstate_reboot(); p = strchr (reboot_command, '\n'); if (p) *p = 0; - if (prom_palette) + if (!serial_console && prom_palette) prom_palette (1); if (prom_keyboard) prom_keyboard(); diff --git a/trunk/arch/sparc64/kernel/prom.c b/trunk/arch/sparc64/kernel/prom.c index f4e0a9ad9be3..5d220302cd50 100644 --- a/trunk/arch/sparc64/kernel/prom.c +++ b/trunk/arch/sparc64/kernel/prom.c @@ -30,9 +30,73 @@ #include #include -extern struct device_node *allnodes; /* temporary while merging */ +static struct device_node *allnodes; -extern rwlock_t devtree_lock; /* temporary while merging */ +/* use when traversing tree through the allnext, child, sibling, + * or parent members of struct device_node. + */ +static DEFINE_RWLOCK(devtree_lock); + +int of_device_is_compatible(const struct device_node *device, + const char *compat) +{ + const char* cp; + int cplen, l; + + cp = of_get_property(device, "compatible", &cplen); + if (cp == NULL) + return 0; + while (cplen > 0) { + if (strncmp(cp, compat, strlen(compat)) == 0) + return 1; + l = strlen(cp) + 1; + cp += l; + cplen -= l; + } + + return 0; +} +EXPORT_SYMBOL(of_device_is_compatible); + +struct device_node *of_get_parent(const struct device_node *node) +{ + struct device_node *np; + + if (!node) + return NULL; + + np = node->parent; + + return np; +} +EXPORT_SYMBOL(of_get_parent); + +struct device_node *of_get_next_child(const struct device_node *node, + struct device_node *prev) +{ + struct device_node *next; + + next = prev ? prev->sibling : node->child; + for (; next != 0; next = next->sibling) { + break; + } + + return next; +} +EXPORT_SYMBOL(of_get_next_child); + +struct device_node *of_find_node_by_path(const char *path) +{ + struct device_node *np = allnodes; + + for (; np != 0; np = np->allnext) { + if (np->full_name != 0 && strcmp(np->full_name, path) == 0) + break; + } + + return np; +} +EXPORT_SYMBOL(of_find_node_by_path); struct device_node *of_find_node_by_phandle(phandle handle) { @@ -46,6 +110,81 @@ struct device_node *of_find_node_by_phandle(phandle handle) } EXPORT_SYMBOL(of_find_node_by_phandle); +struct device_node *of_find_node_by_name(struct device_node *from, + const char *name) +{ + struct device_node *np; + + np = from ? from->allnext : allnodes; + for (; np != NULL; np = np->allnext) + if (np->name != NULL && strcmp(np->name, name) == 0) + break; + + return np; +} +EXPORT_SYMBOL(of_find_node_by_name); + +struct device_node *of_find_node_by_type(struct device_node *from, + const char *type) +{ + struct device_node *np; + + np = from ? from->allnext : allnodes; + for (; np != 0; np = np->allnext) + if (np->type != 0 && strcmp(np->type, type) == 0) + break; + + return np; +} +EXPORT_SYMBOL(of_find_node_by_type); + +struct device_node *of_find_compatible_node(struct device_node *from, + const char *type, const char *compatible) +{ + struct device_node *np; + + np = from ? from->allnext : allnodes; + for (; np != 0; np = np->allnext) { + if (type != NULL + && !(np->type != 0 && strcmp(np->type, type) == 0)) + continue; + if (of_device_is_compatible(np, compatible)) + break; + } + + return np; +} +EXPORT_SYMBOL(of_find_compatible_node); + +struct property *of_find_property(const struct device_node *np, + const char *name, + int *lenp) +{ + struct property *pp; + + for (pp = np->properties; pp != 0; pp = pp->next) { + if (strcasecmp(pp->name, name) == 0) { + if (lenp != 0) + *lenp = pp->length; + break; + } + } + return pp; +} +EXPORT_SYMBOL(of_find_property); + +/* + * Find a property with a given name for a given node + * and return the value. + */ +const void *of_get_property(const struct device_node *np, const char *name, + int *lenp) +{ + struct property *pp = of_find_property(np,name,lenp); + return pp ? pp->value : NULL; +} +EXPORT_SYMBOL(of_get_property); + int of_getintprop_default(struct device_node *np, const char *name, int def) { struct property *prop; @@ -59,6 +198,36 @@ int of_getintprop_default(struct device_node *np, const char *name, int def) } EXPORT_SYMBOL(of_getintprop_default); +int of_n_addr_cells(struct device_node *np) +{ + const int* ip; + do { + if (np->parent) + np = np->parent; + ip = of_get_property(np, "#address-cells", NULL); + if (ip != NULL) + return *ip; + } while (np->parent); + /* No #address-cells property for the root node, default to 2 */ + return 2; +} +EXPORT_SYMBOL(of_n_addr_cells); + +int of_n_size_cells(struct device_node *np) +{ + const int* ip; + do { + if (np->parent) + np = np->parent; + ip = of_get_property(np, "#size-cells", NULL); + if (ip != NULL) + return *ip; + } while (np->parent); + /* No #size-cells property for the root node, default to 1 */ + return 1; +} +EXPORT_SYMBOL(of_n_size_cells); + int of_set_property(struct device_node *dp, const char *name, void *val, int len) { struct property **prevp; @@ -1646,60 +1815,6 @@ static void __init of_fill_in_cpu_data(void) smp_fill_in_sib_core_maps(); } -struct device_node *of_console_device; -EXPORT_SYMBOL(of_console_device); - -char *of_console_path; -EXPORT_SYMBOL(of_console_path); - -char *of_console_options; -EXPORT_SYMBOL(of_console_options); - -static void __init of_console_init(void) -{ - char *msg = "OF stdout device is: %s\n"; - struct device_node *dp; - const char *type; - phandle node; - - of_console_path = prom_early_alloc(256); - if (prom_ihandle2path(prom_stdout, of_console_path, 256) < 0) { - prom_printf("Cannot obtain path of stdout.\n"); - prom_halt(); - } - of_console_options = strrchr(of_console_path, ':'); - if (of_console_options) { - of_console_options++; - if (*of_console_options == '\0') - of_console_options = NULL; - } - - node = prom_inst2pkg(prom_stdout); - if (!node) { - prom_printf("Cannot resolve stdout node from " - "instance %08x.\n", prom_stdout); - prom_halt(); - } - - dp = of_find_node_by_phandle(node); - type = of_get_property(dp, "device_type", NULL); - if (!type) { - prom_printf("Console stdout lacks device_type property.\n"); - prom_halt(); - } - - if (strcmp(type, "display") && strcmp(type, "serial")) { - prom_printf("Console device_type is neither display " - "nor serial.\n"); - prom_halt(); - } - - of_console_device = dp; - - prom_printf(msg, of_console_path); - printk(msg, of_console_path); -} - void __init prom_build_devicetree(void) { struct device_node **nextp; @@ -1712,8 +1827,6 @@ void __init prom_build_devicetree(void) allnodes->child = build_tree(allnodes, prom_getchild(allnodes->node), &nextp); - of_console_init(); - printk("PROM: Built device tree with %u bytes of memory.\n", prom_early_allocated); diff --git a/trunk/arch/sparc64/kernel/setup.c b/trunk/arch/sparc64/kernel/setup.c index 0f5be828ee92..aafde3dd9fd4 100644 --- a/trunk/arch/sparc64/kernel/setup.c +++ b/trunk/arch/sparc64/kernel/setup.c @@ -133,6 +133,33 @@ static void __init process_switch(char c) } } +static void __init process_console(char *commands) +{ + serial_console = 0; + commands += 8; + /* Linux-style serial */ + if (!strncmp(commands, "ttyS", 4)) + serial_console = simple_strtoul(commands + 4, NULL, 10) + 1; + else if (!strncmp(commands, "tty", 3)) { + char c = *(commands + 3); + /* Solaris-style serial */ + if (c == 'a' || c == 'b') { + serial_console = c - 'a' + 1; + prom_printf ("Using /dev/tty%c as console.\n", c); + } + /* else Linux-style fbcon, not serial */ + } +#if defined(CONFIG_PROM_CONSOLE) + if (!strncmp(commands, "prom", 4)) { + char *p; + + for (p = commands - 8; *p && *p != ' '; p++) + *p = ' '; + conswitchp = &prom_con; + } +#endif +} + static void __init boot_flags_init(char *commands) { while (*commands) { @@ -149,7 +176,9 @@ static void __init boot_flags_init(char *commands) process_switch(*commands++); continue; } - if (!strncmp(commands, "mem=", 4)) { + if (!strncmp(commands, "console=", 8)) { + process_console(commands); + } else if (!strncmp(commands, "mem=", 4)) { /* * "mem=XXX[kKmM]" overrides the PROM-reported * memory size. @@ -349,6 +378,44 @@ void __init setup_arch(char **cmdline_p) paging_init(); } +static int __init set_preferred_console(void) +{ + int idev, odev; + + /* The user has requested a console so this is already set up. */ + if (serial_console >= 0) + return -EBUSY; + + idev = prom_query_input_device(); + odev = prom_query_output_device(); + if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) { + serial_console = 0; + } else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) { + serial_console = 1; + } else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) { + serial_console = 2; + } else if (idev == PROMDEV_IRSC && odev == PROMDEV_ORSC) { + serial_console = 3; + } else if (idev == PROMDEV_IVCONS && odev == PROMDEV_OVCONS) { + /* sunhv_console_init() doesn't check the serial_console + * value anyways... + */ + serial_console = 4; + return add_preferred_console("ttyHV", 0, NULL); + } else { + prom_printf("Inconsistent console: " + "input %d, output %d\n", + idev, odev); + prom_halt(); + } + + if (serial_console) + return add_preferred_console("ttyS", serial_console - 1, NULL); + + return -ENODEV; +} +console_initcall(set_preferred_console); + /* BUFFER is PAGE_SIZE bytes long. */ extern char *sparc_cpu_type; @@ -441,4 +508,5 @@ void sun_do_break(void) prom_cmdline(); } +int serial_console = -1; int stop_a_enabled = 1; diff --git a/trunk/arch/sparc64/kernel/sparc64_ksyms.c b/trunk/arch/sparc64/kernel/sparc64_ksyms.c index 7d36531aa5b9..719d676c2ddc 100644 --- a/trunk/arch/sparc64/kernel/sparc64_ksyms.c +++ b/trunk/arch/sparc64/kernel/sparc64_ksyms.c @@ -330,6 +330,7 @@ EXPORT_SYMBOL(VISenter); /* for input/keybdev */ EXPORT_SYMBOL(sun_do_break); +EXPORT_SYMBOL(serial_console); EXPORT_SYMBOL(stop_a_enabled); #ifdef CONFIG_DEBUG_BUGVERBOSE diff --git a/trunk/arch/sparc64/kernel/sys_sparc32.c b/trunk/arch/sparc64/kernel/sys_sparc32.c index e8dce90d05d4..abd83129b2e7 100644 --- a/trunk/arch/sparc64/kernel/sys_sparc32.c +++ b/trunk/arch/sparc64/kernel/sys_sparc32.c @@ -1,7 +1,8 @@ -/* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. +/* $Id: sys_sparc32.c,v 1.184 2002/02/09 19:49:31 davem Exp $ + * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - * Copyright (C) 1997, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) * * These routines maintain argument size conversion between 32bit and 64bit * environment. @@ -1027,10 +1028,3 @@ long compat_sync_file_range(int fd, unsigned long off_high, unsigned long off_lo (nb_high << 32) | nb_low, flags); } - -asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo, - u32 lenhi, u32 lenlo) -{ - return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo, - ((loff_t)lenhi << 32) | lenlo); -} diff --git a/trunk/arch/sparc64/kernel/systbls.S b/trunk/arch/sparc64/kernel/systbls.S index 06d10907d8ce..8765e32155a0 100644 --- a/trunk/arch/sparc64/kernel/systbls.S +++ b/trunk/arch/sparc64/kernel/systbls.S @@ -1,7 +1,8 @@ -/* systbls.S: System call entry point tables for OS compatibility. +/* $Id: systbls.S,v 1.81 2002/02/08 03:57:14 davem Exp $ + * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * - * Copyright (C) 1995, 1996, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) * * Based upon preliminary work which is: @@ -80,7 +81,7 @@ sys_call_table32: .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare /*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait -/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, compat_sys_timerfd, sys_eventfd, compat_sys_fallocate +/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, compat_sys_timerfd, sys_eventfd #endif /* CONFIG_COMPAT */ @@ -152,7 +153,7 @@ sys_call_table: .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare /*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait -/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd, sys_fallocate +/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ defined(CONFIG_SOLARIS_EMUL_MODULE) @@ -271,6 +272,6 @@ sunos_sys_table: .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys /*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys + .word sunos_nosys #endif diff --git a/trunk/arch/sparc64/kernel/time.c b/trunk/arch/sparc64/kernel/time.c index e340eb401fb9..62e316ab1339 100644 --- a/trunk/arch/sparc64/kernel/time.c +++ b/trunk/arch/sparc64/kernel/time.c @@ -835,7 +835,7 @@ static int __init clock_init(void) return 0; } - return of_register_driver(&clock_driver, &of_platform_bus_type); + return of_register_driver(&clock_driver, &of_bus_type); } /* Must be after subsys_initcall() so that busses are probed. Must @@ -1434,78 +1434,6 @@ static int bq4802_set_rtc_time(struct rtc_time *time) return 0; } - -static void cmos_get_rtc_time(struct rtc_time *rtc_tm) -{ - unsigned char ctrl; - - rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); - rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); - rtc_tm->tm_hour = CMOS_READ(RTC_HOURS); - rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH); - rtc_tm->tm_mon = CMOS_READ(RTC_MONTH); - rtc_tm->tm_year = CMOS_READ(RTC_YEAR); - rtc_tm->tm_wday = CMOS_READ(RTC_DAY_OF_WEEK); - - ctrl = CMOS_READ(RTC_CONTROL); - if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BCD_TO_BIN(rtc_tm->tm_sec); - BCD_TO_BIN(rtc_tm->tm_min); - BCD_TO_BIN(rtc_tm->tm_hour); - BCD_TO_BIN(rtc_tm->tm_mday); - BCD_TO_BIN(rtc_tm->tm_mon); - BCD_TO_BIN(rtc_tm->tm_year); - BCD_TO_BIN(rtc_tm->tm_wday); - } - - if (rtc_tm->tm_year <= 69) - rtc_tm->tm_year += 100; - - rtc_tm->tm_mon--; -} - -static int cmos_set_rtc_time(struct rtc_time *rtc_tm) -{ - unsigned char mon, day, hrs, min, sec; - unsigned char save_control, save_freq_select; - unsigned int yrs; - - yrs = rtc_tm->tm_year; - mon = rtc_tm->tm_mon + 1; - day = rtc_tm->tm_mday; - hrs = rtc_tm->tm_hour; - min = rtc_tm->tm_min; - sec = rtc_tm->tm_sec; - - if (yrs >= 100) - yrs -= 100; - - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(sec); - BIN_TO_BCD(min); - BIN_TO_BCD(hrs); - BIN_TO_BCD(day); - BIN_TO_BCD(mon); - BIN_TO_BCD(yrs); - } - - save_control = CMOS_READ(RTC_CONTROL); - CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); - - CMOS_WRITE(yrs, RTC_YEAR); - CMOS_WRITE(mon, RTC_MONTH); - CMOS_WRITE(day, RTC_DAY_OF_MONTH); - CMOS_WRITE(hrs, RTC_HOURS); - CMOS_WRITE(min, RTC_MINUTES); - CMOS_WRITE(sec, RTC_SECONDS); - - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - - return 0; -} #endif /* CONFIG_PCI */ struct mini_rtc_ops { @@ -1528,11 +1456,6 @@ static struct mini_rtc_ops bq4802_rtc_ops = { .get_rtc_time = bq4802_get_rtc_time, .set_rtc_time = bq4802_set_rtc_time, }; - -static struct mini_rtc_ops cmos_rtc_ops = { - .get_rtc_time = cmos_get_rtc_time, - .set_rtc_time = cmos_set_rtc_time, -}; #endif /* CONFIG_PCI */ static struct mini_rtc_ops *mini_rtc_ops; @@ -1660,8 +1583,6 @@ static int __init rtc_mini_init(void) #ifdef CONFIG_PCI else if (bq4802_regs) mini_rtc_ops = &bq4802_rtc_ops; - else if (ds1287_regs) - mini_rtc_ops = &cmos_rtc_ops; #endif /* CONFIG_PCI */ else return -ENODEV; diff --git a/trunk/arch/sparc64/kernel/vio.c b/trunk/arch/sparc64/kernel/vio.c index 3685daf5157f..8d3cc4fdb557 100644 --- a/trunk/arch/sparc64/kernel/vio.c +++ b/trunk/arch/sparc64/kernel/vio.c @@ -103,9 +103,9 @@ static ssize_t devspec_show(struct device *dev, struct vio_dev *vdev = to_vio_dev(dev); const char *str = "none"; - if (!strcmp(vdev->type, "vnet-port")) + if (!strcmp(vdev->type, "network")) str = "vnet"; - else if (!strcmp(vdev->type, "vdc-port")) + else if (!strcmp(vdev->type, "block")) str = "vdisk"; return sprintf(buf, "%s\n", str); @@ -205,8 +205,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, struct device_node *dp; struct vio_dev *vdev; int err, tlen, clen; - const u64 *id, *cfg_handle; - u64 a; + const u64 *id; type = mdesc_get_property(hp, mp, "device-type", &tlen); if (!type) { @@ -222,19 +221,6 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, return NULL; } - id = mdesc_get_property(hp, mp, "id", NULL); - - cfg_handle = NULL; - mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) { - u64 target; - - target = mdesc_arc_target(hp, a); - cfg_handle = mdesc_get_property(hp, target, - "cfg-handle", NULL); - if (cfg_handle) - break; - } - bus_id_name = type; if (!strcmp(type, "domain-services-port")) bus_id_name = "ds"; @@ -274,19 +260,13 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, vio_fill_channel_info(hp, mp, vdev); - if (!id) { + id = mdesc_get_property(hp, mp, "id", NULL); + if (!id) snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s", bus_id_name); - vdev->dev_no = ~(u64)0; - } else if (!cfg_handle) { + else snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu", bus_id_name, *id); - vdev->dev_no = *id; - } else { - snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu-%lu", - bus_id_name, *cfg_handle, *id); - vdev->dev_no = *cfg_handle; - } vdev->dev.parent = parent; vdev->dev.bus = &vio_bus_type; diff --git a/trunk/arch/sparc64/prom/console.c b/trunk/arch/sparc64/prom/console.c index 3fafa9a8b50b..7c25c54cefdc 100644 --- a/trunk/arch/sparc64/prom/console.c +++ b/trunk/arch/sparc64/prom/console.c @@ -73,3 +73,88 @@ prom_puts(const char *s, int len) P1275_INOUT(3,1), prom_stdout, s, P1275_SIZE(len)); } + +/* Query for input device type */ +enum prom_input_device +prom_query_input_device(void) +{ + int st_p; + char propb[64]; + + st_p = prom_inst2pkg(prom_stdin); + if(prom_node_has_property(st_p, "keyboard")) + return PROMDEV_IKBD; + prom_getproperty(st_p, "device_type", propb, sizeof(propb)); + if(strncmp(propb, "serial", 6)) + return PROMDEV_I_UNK; + /* FIXME: Is there any better way how to find out? */ + memset(propb, 0, sizeof(propb)); + st_p = prom_finddevice ("/options"); + prom_getproperty(st_p, "input-device", propb, sizeof(propb)); + + /* + * If we get here with propb == 'keyboard', we are on ttya, as + * the PROM defaulted to this due to 'no input device'. + */ + if (!strncmp(propb, "keyboard", 8)) + return PROMDEV_ITTYA; + + if (!strncmp (propb, "rsc", 3)) + return PROMDEV_IRSC; + + if (!strncmp (propb, "virtual-console", 3)) + return PROMDEV_IVCONS; + + if (strncmp (propb, "tty", 3) || !propb[3]) + return PROMDEV_I_UNK; + + switch (propb[3]) { + case 'a': return PROMDEV_ITTYA; + case 'b': return PROMDEV_ITTYB; + default: return PROMDEV_I_UNK; + } +} + +/* Query for output device type */ + +enum prom_output_device +prom_query_output_device(void) +{ + int st_p; + char propb[64]; + int propl; + + st_p = prom_inst2pkg(prom_stdout); + propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb)); + if (propl >= 0 && propl == sizeof("display") && + strncmp("display", propb, sizeof("display")) == 0) + return PROMDEV_OSCREEN; + if(strncmp("serial", propb, 6)) + return PROMDEV_O_UNK; + /* FIXME: Is there any better way how to find out? */ + memset(propb, 0, sizeof(propb)); + st_p = prom_finddevice ("/options"); + prom_getproperty(st_p, "output-device", propb, sizeof(propb)); + + /* + * If we get here with propb == 'screen', we are on ttya, as + * the PROM defaulted to this due to 'no input device'. + */ + if (!strncmp(propb, "screen", 6)) + return PROMDEV_OTTYA; + + if (!strncmp (propb, "rsc", 3)) + return PROMDEV_ORSC; + + if (!strncmp (propb, "virtual-console", 3)) + return PROMDEV_OVCONS; + + if (strncmp (propb, "tty", 3) || !propb[3]) + return PROMDEV_O_UNK; + + switch (propb[3]) { + case 'a': return PROMDEV_OTTYA; + case 'b': return PROMDEV_OTTYB; + default: return PROMDEV_O_UNK; + } +} diff --git a/trunk/arch/sparc64/prom/misc.c b/trunk/arch/sparc64/prom/misc.c index 68c83ad04ad9..33c5b7da31e5 100644 --- a/trunk/arch/sparc64/prom/misc.c +++ b/trunk/arch/sparc64/prom/misc.c @@ -72,7 +72,7 @@ void prom_cmdline(void) local_irq_save(flags); - if (prom_palette) + if (!serial_console && prom_palette) prom_palette(1); #ifdef CONFIG_SMP @@ -85,7 +85,7 @@ void prom_cmdline(void) smp_release(); #endif - if (prom_palette) + if (!serial_console && prom_palette) prom_palette(0); local_irq_restore(flags); diff --git a/trunk/arch/sparc64/prom/tree.c b/trunk/arch/sparc64/prom/tree.c index b2c5b12c9818..17b7ecfe7ca9 100644 --- a/trunk/arch/sparc64/prom/tree.c +++ b/trunk/arch/sparc64/prom/tree.c @@ -304,11 +304,3 @@ prom_pathtoinode(const char *path) if (node == -1) return 0; return node; } - -int prom_ihandle2path(int handle, char *buffer, int bufsize) -{ - return p1275_cmd("instance-to-path", - P1275_ARG(1,P1275_ARG_OUT_BUF)| - P1275_INOUT(3, 1), - handle, buffer, P1275_SIZE(bufsize)); -} diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index d148ccbc36d1..9755a3cfad26 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -92,11 +92,7 @@ struct cfq_data { struct cfq_queue *active_queue; struct cfq_io_context *active_cic; - /* - * async queue for each priority case - */ - struct cfq_queue *async_cfqq[2][IOPRIO_BE_NR]; - struct cfq_queue *async_idle_cfqq; + struct cfq_queue *async_cfqq[IOPRIO_BE_NR]; struct timer_list idle_class_timer; @@ -115,6 +111,9 @@ struct cfq_data { unsigned int cfq_slice_idle; struct list_head cic_list; + + sector_t new_seek_mean; + u64 new_seek_total; }; /* @@ -154,6 +153,8 @@ struct cfq_queue { /* various state flags, see below */ unsigned int flags; + + sector_t last_request_pos; }; enum cfqq_state_flags { @@ -1413,44 +1414,24 @@ cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync, return cfqq; } -static struct cfq_queue ** -cfq_async_queue_prio(struct cfq_data *cfqd, int ioprio_class, int ioprio) -{ - switch(ioprio_class) { - case IOPRIO_CLASS_RT: - return &cfqd->async_cfqq[0][ioprio]; - case IOPRIO_CLASS_BE: - return &cfqd->async_cfqq[1][ioprio]; - case IOPRIO_CLASS_IDLE: - return &cfqd->async_idle_cfqq; - default: - BUG(); - } -} - static struct cfq_queue * cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk, gfp_t gfp_mask) { const int ioprio = task_ioprio(tsk); - const int ioprio_class = task_ioprio_class(tsk); - struct cfq_queue **async_cfqq = NULL; struct cfq_queue *cfqq = NULL; - if (!is_sync) { - async_cfqq = cfq_async_queue_prio(cfqd, ioprio_class, ioprio); - cfqq = *async_cfqq; - } - + if (!is_sync) + cfqq = cfqd->async_cfqq[ioprio]; if (!cfqq) cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask); /* * pin the queue now that it's allocated, scheduler exit will prune it */ - if (!is_sync && !(*async_cfqq)) { + if (!is_sync && !cfqd->async_cfqq[ioprio]) { atomic_inc(&cfqq->ref); - *async_cfqq = cfqq; + cfqd->async_cfqq[ioprio] = cfqq; } atomic_inc(&cfqq->ref); @@ -1616,6 +1597,11 @@ cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_io_context *cic, else sdist = cic->last_request_pos - rq->sector; + if (!cic->seek_samples) { + cfqd->new_seek_total = (7*cic->seek_total + (u64)256*sdist) / 8; + cfqd->new_seek_mean = cfqd->new_seek_total / 256; + } + /* * Don't allow the seek distance to get too large from the * odd fragment, pagein, etc @@ -1751,6 +1737,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, cfq_update_idle_window(cfqd, cfqq, cic); cic->last_request_pos = rq->sector + rq->nr_sectors; + cfqq->last_request_pos = cic->last_request_pos; if (cfqq == cfqd->active_queue) { /* @@ -2055,24 +2042,11 @@ static void cfq_shutdown_timer_wq(struct cfq_data *cfqd) blk_sync_queue(cfqd->queue); } -static void cfq_put_async_queues(struct cfq_data *cfqd) -{ - int i; - - for (i = 0; i < IOPRIO_BE_NR; i++) { - if (cfqd->async_cfqq[0][i]) - cfq_put_queue(cfqd->async_cfqq[0][i]); - if (cfqd->async_cfqq[1][i]) - cfq_put_queue(cfqd->async_cfqq[1][i]); - if (cfqd->async_idle_cfqq) - cfq_put_queue(cfqd->async_idle_cfqq); - } -} - static void cfq_exit_queue(elevator_t *e) { struct cfq_data *cfqd = e->elevator_data; request_queue_t *q = cfqd->queue; + int i; cfq_shutdown_timer_wq(cfqd); @@ -2089,7 +2063,12 @@ static void cfq_exit_queue(elevator_t *e) __cfq_exit_single_io_context(cfqd, cic); } - cfq_put_async_queues(cfqd); + /* + * Put the async queues + */ + for (i = 0; i < IOPRIO_BE_NR; i++) + if (cfqd->async_cfqq[i]) + cfq_put_queue(cfqd->async_cfqq[i]); spin_unlock_irq(q->queue_lock); diff --git a/trunk/crypto/async_tx/async_memcpy.c b/trunk/crypto/async_tx/async_memcpy.c index 047e533fcc5b..a973f4ef897d 100644 --- a/trunk/crypto/async_tx/async_memcpy.c +++ b/trunk/crypto/async_tx/async_memcpy.c @@ -36,6 +36,7 @@ * @offset: offset in pages to start transaction * @len: length in bytes * @flags: ASYNC_TX_ASSUME_COHERENT, ASYNC_TX_ACK, ASYNC_TX_DEP_ACK, + * ASYNC_TX_KMAP_SRC, ASYNC_TX_KMAP_DST * @depend_tx: memcpy depends on the result of this transaction * @cb_fn: function to call when the memcpy completes * @cb_param: parameter to pass to the callback routine @@ -87,13 +88,23 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset, __FUNCTION__); } - dest_buf = kmap_atomic(dest, KM_USER0) + dest_offset; - src_buf = kmap_atomic(src, KM_USER1) + src_offset; + if (flags & ASYNC_TX_KMAP_DST) + dest_buf = kmap_atomic(dest, KM_USER0) + dest_offset; + else + dest_buf = page_address(dest) + dest_offset; + + if (flags & ASYNC_TX_KMAP_SRC) + src_buf = kmap_atomic(src, KM_USER0) + src_offset; + else + src_buf = page_address(src) + src_offset; memcpy(dest_buf, src_buf, len); - kunmap_atomic(dest_buf, KM_USER0); - kunmap_atomic(src_buf, KM_USER1); + if (flags & ASYNC_TX_KMAP_DST) + kunmap_atomic(dest_buf, KM_USER0); + + if (flags & ASYNC_TX_KMAP_SRC) + kunmap_atomic(src_buf, KM_USER0); async_tx_sync_epilog(flags, depend_tx, cb_fn, cb_param); } diff --git a/trunk/drivers/Kconfig b/trunk/drivers/Kconfig index 3e1c442deff9..707650ab77a7 100644 --- a/trunk/drivers/Kconfig +++ b/trunk/drivers/Kconfig @@ -8,8 +8,6 @@ source "drivers/connector/Kconfig" source "drivers/mtd/Kconfig" -source "drivers/of/Kconfig" - source "drivers/parport/Kconfig" source "drivers/pnp/Kconfig" diff --git a/trunk/drivers/Makefile b/trunk/drivers/Makefile index a9e4c5f922a0..0ea8e3237c0d 100644 --- a/trunk/drivers/Makefile +++ b/trunk/drivers/Makefile @@ -86,4 +86,3 @@ obj-$(CONFIG_GENERIC_TIME) += clocksource/ obj-$(CONFIG_DMA_ENGINE) += dma/ obj-$(CONFIG_HID) += hid/ obj-$(CONFIG_PPC_PS3) += ps3/ -obj-$(CONFIG_OF) += of/ diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index bb5d23be4260..80ffc7829916 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -475,7 +475,7 @@ static void acpi_processor_idle(void) /* Get end time (ticks) */ t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); -#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) +#ifdef CONFIG_GENERIC_TIME /* TSC halts in C2, so notify users */ mark_tsc_unstable("possible TSC halt in C2"); #endif @@ -517,7 +517,7 @@ static void acpi_processor_idle(void) acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); } -#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) +#ifdef CONFIG_GENERIC_TIME /* TSC halts in C3, so notify users */ mark_tsc_unstable("TSC halts in C3"); #endif diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index 06f212ff2b4f..11e4eb9f304e 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -99,7 +99,6 @@ enum { HOST_CAP_SSC = (1 << 14), /* Slumber capable */ HOST_CAP_CLO = (1 << 24), /* Command List Override support */ HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ - HOST_CAP_SNTF = (1 << 29), /* SNotification register */ HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ @@ -114,11 +113,11 @@ enum { PORT_TFDATA = 0x20, /* taskfile data */ PORT_SIG = 0x24, /* device TF signature */ PORT_CMD_ISSUE = 0x38, /* command issue */ + PORT_SCR = 0x28, /* SATA phy register block */ PORT_SCR_STAT = 0x28, /* SATA phy register: SStatus */ PORT_SCR_CTL = 0x2c, /* SATA phy register: SControl */ PORT_SCR_ERR = 0x30, /* SATA phy register: SError */ PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */ - PORT_SCR_NTF = 0x3c, /* SATA phy register: SNotification */ /* PORT_IRQ_{STAT,MASK} bits */ PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */ @@ -217,8 +216,8 @@ struct ahci_port_priv { unsigned int ncq_saw_sdb:1; }; -static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); static void ahci_irq_clear(struct ata_port *ap); @@ -418,10 +417,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { /* ATI */ { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ - { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700 IDE */ - { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb600 }, /* ATI SB700 AHCI */ - { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb600 }, /* ATI SB700 nraid5 */ - { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb600 }, /* ATI SB700 raid5 */ + { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700 */ /* VIA */ { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */ @@ -549,19 +545,13 @@ static void ahci_save_initial_config(struct pci_dev *pdev, hpriv->saved_cap = cap = readl(mmio + HOST_CAP); hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL); - /* some chips have errata preventing 64bit use */ + /* some chips lie about 64bit support */ if ((cap & HOST_CAP_64) && (pi->flags & AHCI_FLAG_32BIT_ONLY)) { dev_printk(KERN_INFO, &pdev->dev, "controller can't do 64bit DMA, forcing 32bit\n"); cap &= ~HOST_CAP_64; } - if ((cap & HOST_CAP_NCQ) && (pi->flags & AHCI_FLAG_NO_NCQ)) { - dev_printk(KERN_INFO, &pdev->dev, - "controller can't do NCQ, turning off CAP_NCQ\n"); - cap &= ~HOST_CAP_NCQ; - } - /* fixup zero port_map */ if (!port_map) { port_map = (1 << ahci_nr_ports(cap)) - 1; @@ -635,45 +625,38 @@ static void ahci_restore_initial_config(struct ata_host *host) (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ } -static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg) +static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) { - static const int offset[] = { - [SCR_STATUS] = PORT_SCR_STAT, - [SCR_CONTROL] = PORT_SCR_CTL, - [SCR_ERROR] = PORT_SCR_ERR, - [SCR_ACTIVE] = PORT_SCR_ACT, - [SCR_NOTIFICATION] = PORT_SCR_NTF, - }; - struct ahci_host_priv *hpriv = ap->host->private_data; + unsigned int sc_reg; + + switch (sc_reg_in) { + case SCR_STATUS: sc_reg = 0; break; + case SCR_CONTROL: sc_reg = 1; break; + case SCR_ERROR: sc_reg = 2; break; + case SCR_ACTIVE: sc_reg = 3; break; + default: + return 0xffffffffU; + } - if (sc_reg < ARRAY_SIZE(offset) && - (sc_reg != SCR_NOTIFICATION || (hpriv->cap & HOST_CAP_SNTF))) - return offset[sc_reg]; - return 0; + return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); } -static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) -{ - void __iomem *port_mmio = ahci_port_base(ap); - int offset = ahci_scr_offset(ap, sc_reg); - - if (offset) { - *val = readl(port_mmio + offset); - return 0; - } - return -EINVAL; -} -static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, + u32 val) { - void __iomem *port_mmio = ahci_port_base(ap); - int offset = ahci_scr_offset(ap, sc_reg); - - if (offset) { - writel(val, port_mmio + offset); - return 0; + unsigned int sc_reg; + + switch (sc_reg_in) { + case SCR_STATUS: sc_reg = 0; break; + case SCR_CONTROL: sc_reg = 1; break; + case SCR_ERROR: sc_reg = 2; break; + case SCR_ACTIVE: sc_reg = 3; break; + default: + return; } - return -EINVAL; + + writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); } static void ahci_start_engine(struct ata_port *ap) @@ -965,87 +948,37 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); } -static int ahci_kick_engine(struct ata_port *ap, int force_restart) +static int ahci_clo(struct ata_port *ap) { void __iomem *port_mmio = ap->ioaddr.cmd_addr; struct ahci_host_priv *hpriv = ap->host->private_data; u32 tmp; - int busy, rc; - - /* do we need to kick the port? */ - busy = ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ); - if (!busy && !force_restart) - return 0; - - /* stop engine */ - rc = ahci_stop_engine(ap); - if (rc) - goto out_restart; - /* need to do CLO? */ - if (!busy) { - rc = 0; - goto out_restart; - } + if (!(hpriv->cap & HOST_CAP_CLO)) + return -EOPNOTSUPP; - if (!(hpriv->cap & HOST_CAP_CLO)) { - rc = -EOPNOTSUPP; - goto out_restart; - } - - /* perform CLO */ tmp = readl(port_mmio + PORT_CMD); tmp |= PORT_CMD_CLO; writel(tmp, port_mmio + PORT_CMD); - rc = 0; tmp = ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_CLO, PORT_CMD_CLO, 1, 500); if (tmp & PORT_CMD_CLO) - rc = -EIO; + return -EIO; - /* restart engine */ - out_restart: - ahci_start_engine(ap); - return rc; + return 0; } -static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp, - struct ata_taskfile *tf, int is_cmd, u16 flags, - unsigned long timeout_msec) +static int ahci_softreset(struct ata_port *ap, unsigned int *class, + unsigned long deadline) { - const u32 cmd_fis_len = 5; /* five dwords */ struct ahci_port_priv *pp = ap->private_data; void __iomem *port_mmio = ahci_port_base(ap); - u8 *fis = pp->cmd_tbl; - u32 tmp; - - /* prep the command */ - ata_tf_to_fis(tf, pmp, is_cmd, fis); - ahci_fill_cmd_slot(pp, 0, cmd_fis_len | flags | (pmp << 12)); - - /* issue & wait */ - writel(1, port_mmio + PORT_CMD_ISSUE); - - if (timeout_msec) { - tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, - 1, timeout_msec); - if (tmp & 0x1) { - ahci_kick_engine(ap, 1); - return -EBUSY; - } - } else - readl(port_mmio + PORT_CMD_ISSUE); /* flush */ - - return 0; -} - -static int ahci_do_softreset(struct ata_port *ap, unsigned int *class, - int pmp, unsigned long deadline) -{ + const u32 cmd_fis_len = 5; /* five dwords */ const char *reason = NULL; - unsigned long now, msecs; struct ata_taskfile tf; + u32 tmp; + u8 *fis; int rc; DPRINTK("ENTER\n"); @@ -1057,22 +990,43 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class, } /* prepare for SRST (AHCI-1.1 10.4.1) */ - rc = ahci_kick_engine(ap, 1); - if (rc) - ata_port_printk(ap, KERN_WARNING, - "failed to reset engine (errno=%d)", rc); + rc = ahci_stop_engine(ap); + if (rc) { + reason = "failed to stop engine"; + goto fail_restart; + } + + /* check BUSY/DRQ, perform Command List Override if necessary */ + if (ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ)) { + rc = ahci_clo(ap); + + if (rc == -EOPNOTSUPP) { + reason = "port busy but CLO unavailable"; + goto fail_restart; + } else if (rc) { + reason = "port busy but CLO failed"; + goto fail_restart; + } + } + + /* restart engine */ + ahci_start_engine(ap); ata_tf_init(ap->device, &tf); + fis = pp->cmd_tbl; /* issue the first D2H Register FIS */ - msecs = 0; - now = jiffies; - if (time_after(now, deadline)) - msecs = jiffies_to_msecs(deadline - now); + ahci_fill_cmd_slot(pp, 0, + cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY); tf.ctl |= ATA_SRST; - if (ahci_exec_polled_cmd(ap, pmp, &tf, 0, - AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY, msecs)) { + ata_tf_to_fis(&tf, fis, 0); + fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ + + writel(1, port_mmio + PORT_CMD_ISSUE); + + tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1, 500); + if (tmp & 0x1) { rc = -EIO; reason = "1st FIS failed"; goto fail; @@ -1082,8 +1036,14 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class, msleep(1); /* issue the second D2H Register FIS */ + ahci_fill_cmd_slot(pp, 0, cmd_fis_len); + tf.ctl &= ~ATA_SRST; - ahci_exec_polled_cmd(ap, pmp, &tf, 0, 0, 0); + ata_tf_to_fis(&tf, fis, 0); + fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ + + writel(1, port_mmio + PORT_CMD_ISSUE); + readl(port_mmio + PORT_CMD_ISSUE); /* flush */ /* spec mandates ">= 2ms" before checking status. * We wait 150ms, because that was the magic delay used for @@ -1106,17 +1066,13 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class, DPRINTK("EXIT, class=%u\n", *class); return 0; + fail_restart: + ahci_start_engine(ap); fail: ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason); return rc; } -static int ahci_softreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) -{ - return ahci_do_softreset(ap, class, 0, deadline); -} - static int ahci_hardreset(struct ata_port *ap, unsigned int *class, unsigned long deadline) { @@ -1132,7 +1088,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class, /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(ap->device, &tf); tf.command = 0x80; - ata_tf_to_fis(&tf, 0, 0, d2h_fis); + ata_tf_to_fis(&tf, d2h_fis, 0); rc = sata_std_hardreset(ap, class, deadline); @@ -1150,7 +1106,6 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class, static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class, unsigned long deadline) { - u32 serror; int rc; DPRINTK("ENTER\n"); @@ -1161,8 +1116,7 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class, deadline); /* vt8251 needs SError cleared for the port to operate */ - ahci_scr_read(ap, SCR_ERROR, &serror); - ahci_scr_write(ap, SCR_ERROR, serror); + ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR)); ahci_start_engine(ap); @@ -1251,7 +1205,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) */ cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ; - ata_tf_to_fis(&qc->tf, 0, 1, cmd_tbl); + ata_tf_to_fis(&qc->tf, cmd_tbl, 0); if (is_atapi) { memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len); @@ -1284,7 +1238,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) ata_ehi_clear_desc(ehi); /* AHCI needs SError cleared; otherwise, it might lock up */ - ahci_scr_read(ap, SCR_ERROR, &serror); + serror = ahci_scr_read(ap, SCR_ERROR); ahci_scr_write(ap, SCR_ERROR, serror); /* analyze @irq_stat */ @@ -1308,12 +1262,12 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) if (irq_stat & PORT_IRQ_IF_ERR) { err_mask |= AC_ERR_ATA_BUS; action |= ATA_EH_SOFTRESET; - ata_ehi_push_desc(ehi, "interface fatal error"); + ata_ehi_push_desc(ehi, ", interface fatal error"); } if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) { ata_ehi_hotplugged(ehi); - ata_ehi_push_desc(ehi, "%s", irq_stat & PORT_IRQ_CONNECT ? + ata_ehi_push_desc(ehi, ", %s", irq_stat & PORT_IRQ_CONNECT ? "connection status changed" : "PHY RDY changed"); } @@ -1322,7 +1276,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) err_mask |= AC_ERR_HSM; action |= ATA_EH_SOFTRESET; - ata_ehi_push_desc(ehi, "unknown FIS %08x %08x %08x %08x", + ata_ehi_push_desc(ehi, ", unknown FIS %08x %08x %08x %08x", unk[0], unk[1], unk[2], unk[3]); } @@ -1558,17 +1512,11 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - /* make DMA engine forget about the failed command */ - if (qc->flags & ATA_QCFLAG_FAILED) - ahci_kick_engine(ap, 1); -} - -static int ahci_port_resume(struct ata_port *ap) -{ - ahci_power_up(ap); - ahci_start_port(ap); - - return 0; + if (qc->flags & ATA_QCFLAG_FAILED) { + /* make DMA engine forget about the failed command */ + ahci_stop_engine(ap); + ahci_start_engine(ap); + } } #ifdef CONFIG_PM @@ -1588,6 +1536,14 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) return rc; } +static int ahci_port_resume(struct ata_port *ap) +{ + ahci_power_up(ap); + ahci_start_port(ap); + + return 0; +} + static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { struct ata_host *host = dev_get_drvdata(&pdev->dev); @@ -1778,13 +1734,12 @@ static void ahci_print_info(struct ata_host *host) dev_printk(KERN_INFO, &pdev->dev, "flags: " - "%s%s%s%s%s%s%s" - "%s%s%s%s%s%s%s\n" + "%s%s%s%s%s%s" + "%s%s%s%s%s%s%s\n" , cap & (1 << 31) ? "64bit " : "", cap & (1 << 30) ? "ncq " : "", - cap & (1 << 29) ? "sntf " : "", cap & (1 << 28) ? "ilck " : "", cap & (1 << 27) ? "stag " : "", cap & (1 << 26) ? "pm " : "", @@ -1839,7 +1794,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ahci_save_initial_config(pdev, &pi, hpriv); /* prepare host */ - if (hpriv->cap & HOST_CAP_NCQ) + if (!(pi.flags & AHCI_FLAG_NO_NCQ) && (hpriv->cap & HOST_CAP_NCQ)) pi.flags |= ATA_FLAG_NCQ; host = ata_host_alloc_pinfo(&pdev->dev, ppi, fls(hpriv->port_map)); @@ -1853,8 +1808,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) void __iomem *port_mmio = ahci_port_base(ap); /* standard SATA port setup */ - if (hpriv->port_map & (1 << i)) + if (hpriv->port_map & (1 << i)) { ap->ioaddr.cmd_addr = port_mmio; + ap->ioaddr.scr_addr = port_mmio + PORT_SCR; + } /* disabled/not-implemented port */ else diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 6001aae0b884..88e2dd0983b5 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -111,9 +111,8 @@ MODULE_VERSION(DRV_VERSION); /** * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure * @tf: Taskfile to convert - * @pmp: Port multiplier port - * @is_cmd: This FIS is for command * @fis: Buffer into which data will output + * @pmp: Port multiplier port * * Converts a standard ATA taskfile to a Serial ATA * FIS structure (Register - Host to Device). @@ -121,13 +120,12 @@ MODULE_VERSION(DRV_VERSION); * LOCKING: * Inherited from caller. */ -void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis) -{ - fis[0] = 0x27; /* Register - Host to Device FIS */ - fis[1] = pmp & 0xf; /* Port multiplier number*/ - if (is_cmd) - fis[1] |= (1 << 7); /* bit 7 indicates Command FIS */ +void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp) +{ + fis[0] = 0x27; /* Register - Host to Device FIS */ + fis[1] = (pmp & 0xf) | (1 << 7); /* Port multiplier number, + bit 7 indicates Command FIS */ fis[2] = tf->command; fis[3] = tf->feature; @@ -2389,35 +2387,21 @@ int sata_down_spd_limit(struct ata_port *ap) u32 sstatus, spd, mask; int rc, highbit; - if (!sata_scr_valid(ap)) - return -EOPNOTSUPP; - - /* If SCR can be read, use it to determine the current SPD. - * If not, use cached value in ap->sata_spd. - */ rc = sata_scr_read(ap, SCR_STATUS, &sstatus); - if (rc == 0) - spd = (sstatus >> 4) & 0xf; - else - spd = ap->sata_spd; + if (rc) + return rc; mask = ap->sata_spd_limit; if (mask <= 1) return -EINVAL; - - /* unconditionally mask off the highest bit */ highbit = fls(mask) - 1; mask &= ~(1 << highbit); - /* Mask off all speeds higher than or equal to the current - * one. Force 1.5Gbps if current SPD is not available. - */ - if (spd > 1) - mask &= (1 << (spd - 1)) - 1; - else - mask &= 1; - - /* were we already at the bottom? */ + spd = (sstatus >> 4) & 0xf; + if (spd <= 1) + return -EINVAL; + spd--; + mask &= (1 << spd) - 1; if (!mask) return -EINVAL; @@ -3267,11 +3251,9 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params, last = cur; last_jiffies = jiffies; - /* Check deadline. If debouncing failed, return - * -EPIPE to tell upper layer to lower link speed. - */ + /* check deadline */ if (time_after(jiffies, deadline)) - return -EPIPE; + return -EBUSY; } } @@ -3787,7 +3769,6 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, }, { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, }, { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, }, - { "ST9160821AS", "3.CLF", ATA_HORKAGE_NONCQ, }, /* Devices with NCQ limits */ @@ -5748,8 +5729,10 @@ int sata_scr_valid(struct ata_port *ap) */ int sata_scr_read(struct ata_port *ap, int reg, u32 *val) { - if (sata_scr_valid(ap)) - return ap->ops->scr_read(ap, reg, val); + if (sata_scr_valid(ap)) { + *val = ap->ops->scr_read(ap, reg); + return 0; + } return -EOPNOTSUPP; } @@ -5771,8 +5754,10 @@ int sata_scr_read(struct ata_port *ap, int reg, u32 *val) */ int sata_scr_write(struct ata_port *ap, int reg, u32 val) { - if (sata_scr_valid(ap)) - return ap->ops->scr_write(ap, reg, val); + if (sata_scr_valid(ap)) { + ap->ops->scr_write(ap, reg, val); + return 0; + } return -EOPNOTSUPP; } @@ -5793,13 +5778,10 @@ int sata_scr_write(struct ata_port *ap, int reg, u32 val) */ int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val) { - int rc; - if (sata_scr_valid(ap)) { - rc = ap->ops->scr_write(ap, reg, val); - if (rc == 0) - rc = ap->ops->scr_read(ap, reg, &val); - return rc; + ap->ops->scr_write(ap, reg, val); + ap->ops->scr_read(ap, reg); + return 0; } return -EOPNOTSUPP; } @@ -6011,7 +5993,6 @@ void ata_dev_init(struct ata_device *dev) /* SATA spd limit is bound to the first device */ ap->sata_spd_limit = ap->hw_sata_spd_limit; - ap->sata_spd = 0; /* High bits of dev->flags are used to record warm plug * requests which occur asynchronously. Synchronize using @@ -6077,9 +6058,6 @@ struct ata_port *ata_port_alloc(struct ata_host *host) INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); INIT_LIST_HEAD(&ap->eh_done_q); init_waitqueue_head(&ap->eh_wait_q); - init_timer_deferrable(&ap->fastdrain_timer); - ap->fastdrain_timer.function = ata_eh_fastdrain_timerfn; - ap->fastdrain_timer.data = (unsigned long)ap; ap->cbl = ATA_CBL_NONE; @@ -6456,7 +6434,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; - ata_scsi_scan_host(ap, 1); + ata_scsi_scan_host(ap); } return 0; @@ -6964,9 +6942,6 @@ EXPORT_SYMBOL_GPL(ata_pci_default_filter); EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); #endif /* CONFIG_PCI */ -EXPORT_SYMBOL_GPL(__ata_ehi_push_desc); -EXPORT_SYMBOL_GPL(ata_ehi_push_desc); -EXPORT_SYMBOL_GPL(ata_ehi_clear_desc); EXPORT_SYMBOL_GPL(ata_eng_timeout); EXPORT_SYMBOL_GPL(ata_port_schedule_eh); EXPORT_SYMBOL_GPL(ata_port_abort); diff --git a/trunk/drivers/ata/libata-eh.c b/trunk/drivers/ata/libata-eh.c index ac6ceed4bb60..9aa62a0754f6 100644 --- a/trunk/drivers/ata/libata-eh.c +++ b/trunk/drivers/ata/libata-eh.c @@ -56,7 +56,6 @@ enum { */ enum { ATA_EH_PRERESET_TIMEOUT = 10 * HZ, - ATA_EH_FASTDRAIN_INTERVAL = 3 * HZ, }; /* The following table determines how we sequence resets. Each entry @@ -86,71 +85,6 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) { } #endif /* CONFIG_PM */ -static void __ata_ehi_pushv_desc(struct ata_eh_info *ehi, const char *fmt, - va_list args) -{ - ehi->desc_len += vscnprintf(ehi->desc + ehi->desc_len, - ATA_EH_DESC_LEN - ehi->desc_len, - fmt, args); -} - -/** - * __ata_ehi_push_desc - push error description without adding separator - * @ehi: target EHI - * @fmt: printf format string - * - * Format string according to @fmt and append it to @ehi->desc. - * - * LOCKING: - * spin_lock_irqsave(host lock) - */ -void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - __ata_ehi_pushv_desc(ehi, fmt, args); - va_end(args); -} - -/** - * ata_ehi_push_desc - push error description with separator - * @ehi: target EHI - * @fmt: printf format string - * - * Format string according to @fmt and append it to @ehi->desc. - * If @ehi->desc is not empty, ", " is added in-between. - * - * LOCKING: - * spin_lock_irqsave(host lock) - */ -void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) -{ - va_list args; - - if (ehi->desc_len) - __ata_ehi_push_desc(ehi, ", "); - - va_start(args, fmt); - __ata_ehi_pushv_desc(ehi, fmt, args); - va_end(args); -} - -/** - * ata_ehi_clear_desc - clean error description - * @ehi: target EHI - * - * Clear @ehi->desc. - * - * LOCKING: - * spin_lock_irqsave(host lock) - */ -void ata_ehi_clear_desc(struct ata_eh_info *ehi) -{ - ehi->desc[0] = '\0'; - ehi->desc_len = 0; -} - static void ata_ering_record(struct ata_ering *ering, int is_io, unsigned int err_mask) { @@ -362,9 +296,6 @@ void ata_scsi_error(struct Scsi_Host *host) repeat: /* invoke error handler */ if (ap->ops->error_handler) { - /* kill fast drain timer */ - del_timer_sync(&ap->fastdrain_timer); - /* process port resume request */ ata_eh_handle_port_resume(ap); @@ -580,94 +511,6 @@ void ata_eng_timeout(struct ata_port *ap) DPRINTK("EXIT\n"); } -static int ata_eh_nr_in_flight(struct ata_port *ap) -{ - unsigned int tag; - int nr = 0; - - /* count only non-internal commands */ - for (tag = 0; tag < ATA_MAX_QUEUE - 1; tag++) - if (ata_qc_from_tag(ap, tag)) - nr++; - - return nr; -} - -void ata_eh_fastdrain_timerfn(unsigned long arg) -{ - struct ata_port *ap = (void *)arg; - unsigned long flags; - int cnt; - - spin_lock_irqsave(ap->lock, flags); - - cnt = ata_eh_nr_in_flight(ap); - - /* are we done? */ - if (!cnt) - goto out_unlock; - - if (cnt == ap->fastdrain_cnt) { - unsigned int tag; - - /* No progress during the last interval, tag all - * in-flight qcs as timed out and freeze the port. - */ - for (tag = 0; tag < ATA_MAX_QUEUE - 1; tag++) { - struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag); - if (qc) - qc->err_mask |= AC_ERR_TIMEOUT; - } - - ata_port_freeze(ap); - } else { - /* some qcs have finished, give it another chance */ - ap->fastdrain_cnt = cnt; - ap->fastdrain_timer.expires = - jiffies + ATA_EH_FASTDRAIN_INTERVAL; - add_timer(&ap->fastdrain_timer); - } - - out_unlock: - spin_unlock_irqrestore(ap->lock, flags); -} - -/** - * ata_eh_set_pending - set ATA_PFLAG_EH_PENDING and activate fast drain - * @ap: target ATA port - * @fastdrain: activate fast drain - * - * Set ATA_PFLAG_EH_PENDING and activate fast drain if @fastdrain - * is non-zero and EH wasn't pending before. Fast drain ensures - * that EH kicks in in timely manner. - * - * LOCKING: - * spin_lock_irqsave(host lock) - */ -static void ata_eh_set_pending(struct ata_port *ap, int fastdrain) -{ - int cnt; - - /* already scheduled? */ - if (ap->pflags & ATA_PFLAG_EH_PENDING) - return; - - ap->pflags |= ATA_PFLAG_EH_PENDING; - - if (!fastdrain) - return; - - /* do we have in-flight qcs? */ - cnt = ata_eh_nr_in_flight(ap); - if (!cnt) - return; - - /* activate fast drain */ - ap->fastdrain_cnt = cnt; - ap->fastdrain_timer.expires = jiffies + ATA_EH_FASTDRAIN_INTERVAL; - add_timer(&ap->fastdrain_timer); -} - /** * ata_qc_schedule_eh - schedule qc for error handling * @qc: command to schedule error handling for @@ -685,7 +528,7 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc) WARN_ON(!ap->ops->error_handler); qc->flags |= ATA_QCFLAG_FAILED; - ata_eh_set_pending(ap, 1); + qc->ap->pflags |= ATA_PFLAG_EH_PENDING; /* The following will fail if timeout has already expired. * ata_scsi_error() takes care of such scmds on EH entry. @@ -712,7 +555,7 @@ void ata_port_schedule_eh(struct ata_port *ap) if (ap->pflags & ATA_PFLAG_INITIALIZING) return; - ata_eh_set_pending(ap, 1); + ap->pflags |= ATA_PFLAG_EH_PENDING; scsi_schedule_eh(ap->scsi_host); DPRINTK("port EH scheduled\n"); @@ -736,9 +579,6 @@ int ata_port_abort(struct ata_port *ap) WARN_ON(!ap->ops->error_handler); - /* we're gonna abort all commands, no need for fast drain */ - ata_eh_set_pending(ap, 0); - for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag); @@ -1290,7 +1130,7 @@ static void ata_eh_analyze_ncq_error(struct ata_port *ap) /* we've got the perpetrator, condemn it */ qc = __ata_qc_from_tag(ap, tag); memcpy(&qc->result_tf, &tf, sizeof(tf)); - qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; + qc->err_mask |= AC_ERR_DEV; ehc->i.err_mask &= ~AC_ERR_DEV; } @@ -1573,12 +1413,8 @@ static void ata_eh_autopsy(struct ata_port *ap) if (rc == 0) { ehc->i.serror |= serror; ata_eh_analyze_serror(ap); - } else if (rc != -EOPNOTSUPP) { - /* SError read failed, force hardreset and probing */ - ata_ehi_schedule_probe(&ehc->i); + } else if (rc != -EOPNOTSUPP) ehc->i.action |= ATA_EH_HARDRESET; - ehc->i.err_mask |= AC_ERR_OTHER; - } /* analyze NCQ failure */ ata_eh_analyze_ncq_error(ap); @@ -1688,14 +1524,14 @@ static void ata_eh_report(struct ata_port *ap) ehc->i.err_mask, ap->sactive, ehc->i.serror, ehc->i.action, frozen); if (desc) - ata_dev_printk(ehc->i.dev, KERN_ERR, "%s\n", desc); + ata_dev_printk(ehc->i.dev, KERN_ERR, "(%s)\n", desc); } else { ata_port_printk(ap, KERN_ERR, "exception Emask 0x%x " "SAct 0x%x SErr 0x%x action 0x%x%s\n", ehc->i.err_mask, ap->sactive, ehc->i.serror, ehc->i.action, frozen); if (desc) - ata_port_printk(ap, KERN_ERR, "%s\n", desc); + ata_port_printk(ap, KERN_ERR, "(%s)\n", desc); } for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { @@ -1715,7 +1551,7 @@ static void ata_eh_report(struct ata_port *ap) "cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x " "tag %d cdb 0x%x data %u %s\n " "res %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x " - "Emask 0x%x (%s)%s\n", + "Emask 0x%x (%s)\n", cmd->command, cmd->feature, cmd->nsect, cmd->lbal, cmd->lbam, cmd->lbah, cmd->hob_feature, cmd->hob_nsect, @@ -1726,8 +1562,7 @@ static void ata_eh_report(struct ata_port *ap) res->lbal, res->lbam, res->lbah, res->hob_feature, res->hob_nsect, res->hob_lbal, res->hob_lbam, res->hob_lbah, - res->device, qc->err_mask, ata_err_string(qc->err_mask), - qc->err_mask & AC_ERR_NCQ ? " " : ""); + res->device, qc->err_mask, ata_err_string(qc->err_mask)); } } @@ -1813,7 +1648,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, } else ata_port_printk(ap, KERN_ERR, "prereset failed (errno=%d)\n", rc); - goto out; + return rc; } } @@ -1826,8 +1661,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, /* prereset told us not to reset, bang classes and return */ for (i = 0; i < ATA_MAX_DEVICES; i++) classes[i] = ATA_DEV_NONE; - rc = 0; - goto out; + return 0; } /* did prereset() screw up? if so, fix up to avoid oopsing */ @@ -1863,8 +1697,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, ata_port_printk(ap, KERN_ERR, "follow-up softreset required " "but no softreset avaliable\n"); - rc = -EINVAL; - goto out; + return -EINVAL; } ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK); @@ -1874,8 +1707,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, classes[0] == ATA_DEV_UNKNOWN) { ata_port_printk(ap, KERN_ERR, "classification failed\n"); - rc = -EINVAL; - goto out; + return -EINVAL; } } @@ -1892,7 +1724,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, schedule_timeout_uninterruptible(delta); } - if (rc == -EPIPE || + if (reset == hardreset && try == ARRAY_SIZE(ata_eh_reset_timeouts) - 1) sata_down_spd_limit(ap); if (hardreset) @@ -1901,18 +1733,12 @@ static int ata_eh_reset(struct ata_port *ap, int classify, } if (rc == 0) { - u32 sstatus; - /* After the reset, the device state is PIO 0 and the * controller state is undefined. Record the mode. */ for (i = 0; i < ATA_MAX_DEVICES; i++) ap->device[i].pio_mode = XFER_PIO_0; - /* record current link speed */ - if (sata_scr_read(ap, SCR_STATUS, &sstatus) == 0) - ap->sata_spd = (sstatus >> 4) & 0xf; - if (postreset) postreset(ap, classes); @@ -1920,9 +1746,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, ata_eh_done(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); ehc->i.action |= ATA_EH_REVALIDATE; } - out: - /* clear hotplug flag */ - ehc->i.flags &= ~ATA_EHI_HOTPLUGGED; + return rc; } diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index 12ac0b511f79..cfde22da07ac 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -2947,22 +2947,17 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) return rc; } -void ata_scsi_scan_host(struct ata_port *ap, int sync) +void ata_scsi_scan_host(struct ata_port *ap) { - int tries = 5; - struct ata_device *last_failed_dev = NULL; - struct ata_device *dev; unsigned int i; if (ap->flags & ATA_FLAG_DISABLED) return; - repeat: for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *dev = &ap->device[i]; struct scsi_device *sdev; - dev = &ap->device[i]; - if (!ata_dev_enabled(dev) || dev->sdev) continue; @@ -2972,45 +2967,6 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync) scsi_device_put(sdev); } } - - /* If we scanned while EH was in progress or allocation - * failure occurred, scan would have failed silently. Check - * whether all devices are attached. - */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->device[i]; - if (ata_dev_enabled(dev) && !dev->sdev) - break; - } - if (i == ATA_MAX_DEVICES) - return; - - /* we're missing some SCSI devices */ - if (sync) { - /* If caller requested synchrnous scan && we've made - * any progress, sleep briefly and repeat. - */ - if (dev != last_failed_dev) { - msleep(100); - last_failed_dev = dev; - goto repeat; - } - - /* We might be failing to detect boot device, give it - * a few more chances. - */ - if (--tries) { - msleep(100); - goto repeat; - } - - ata_port_printk(ap, KERN_ERR, "WARNING: synchronous SCSI scan " - "failed without making any progress,\n" - " switching to async\n"); - } - - queue_delayed_work(ata_aux_wq, &ap->hotplug_task, - round_jiffies_relative(HZ)); } /** @@ -3137,7 +3093,20 @@ void ata_scsi_hotplug(struct work_struct *work) } /* scan for new ones */ - ata_scsi_scan_host(ap, 0); + ata_scsi_scan_host(ap); + + /* If we scanned while EH was in progress, scan would have + * failed silently. Requeue if there are enabled but + * unattached devices. + */ + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *dev = &ap->device[i]; + if (ata_dev_enabled(dev) && !dev->sdev) { + queue_delayed_work(ata_aux_wq, &ap->hotplug_task, + round_jiffies_relative(HZ)); + break; + } + } DPRINTK("EXIT\n"); } diff --git a/trunk/drivers/ata/libata-sff.c b/trunk/drivers/ata/libata-sff.c index 6c289c7b1322..ca7d2245d684 100644 --- a/trunk/drivers/ata/libata-sff.c +++ b/trunk/drivers/ata/libata-sff.c @@ -1,5 +1,5 @@ /* - * libata-sff.c - helper library for PCI IDE BMDMA + * libata-bmdma.c - helper library for PCI IDE BMDMA * * Maintained by: Jeff Garzik * Please ALWAYS copy linux-ide@vger.kernel.org @@ -211,8 +211,6 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) tf->hob_lbal = ioread8(ioaddr->lbal_addr); tf->hob_lbam = ioread8(ioaddr->lbam_addr); tf->hob_lbah = ioread8(ioaddr->lbah_addr); - iowrite8(tf->ctl, ioaddr->ctl_addr); - ap->last_ctl = tf->ctl; } } diff --git a/trunk/drivers/ata/libata.h b/trunk/drivers/ata/libata.h index 564cd234c805..ba17fc5f2e99 100644 --- a/trunk/drivers/ata/libata.h +++ b/trunk/drivers/ata/libata.h @@ -112,7 +112,7 @@ static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } /* libata-scsi.c */ extern int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht); -extern void ata_scsi_scan_host(struct ata_port *ap, int sync); +extern void ata_scsi_scan_host(struct ata_port *ap); extern int ata_scsi_offline_dev(struct ata_device *dev); extern void ata_scsi_hotplug(struct work_struct *work); extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, @@ -151,7 +151,6 @@ extern int ata_bus_probe(struct ata_port *ap); extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); extern void ata_scsi_error(struct Scsi_Host *host); extern void ata_port_wait_eh(struct ata_port *ap); -extern void ata_eh_fastdrain_timerfn(unsigned long arg); extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc); /* libata-sff.c */ diff --git a/trunk/drivers/ata/pata_cs5520.c b/trunk/drivers/ata/pata_cs5520.c index 7dc76e71bd55..6bf037d82b5a 100644 --- a/trunk/drivers/ata/pata_cs5520.c +++ b/trunk/drivers/ata/pata_cs5520.c @@ -275,7 +275,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi for (i = 0; i < 2; i++) { static const int irq[] = { 14, 15 }; - struct ata_port *ap = host->ports[i]; + struct ata_port *ap = host->ports[0]; if (ata_port_is_dummy(ap)) continue; diff --git a/trunk/drivers/ata/pata_platform.c b/trunk/drivers/ata/pata_platform.c index a909f793ffc1..79f841bca593 100644 --- a/trunk/drivers/ata/pata_platform.c +++ b/trunk/drivers/ata/pata_platform.c @@ -213,9 +213,8 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) pata_platform_setup_port(&ap->ioaddr, pp_info); /* activate */ - return ata_host_activate(host, platform_get_irq(pdev, 0), - ata_interrupt, pp_info ? pp_info->irq_flags - : 0, &pata_platform_sht); + return ata_host_activate(host, platform_get_irq(pdev, 0), ata_interrupt, + pp_info->irq_flags, &pata_platform_sht); } /** diff --git a/trunk/drivers/ata/pata_scc.c b/trunk/drivers/ata/pata_scc.c index 36cdbd2b0bd5..c55667e0eb65 100644 --- a/trunk/drivers/ata/pata_scc.c +++ b/trunk/drivers/ata/pata_scc.c @@ -238,6 +238,12 @@ static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev) else offset = 0; /* 100MHz */ + /* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */ + if (adev->class == ATA_DEV_ATAPI && speed > XFER_UDMA_4) { + printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME); + speed = XFER_UDMA_4; + } + if (speed >= XFER_UDMA_0) idx = speed - XFER_UDMA_0; else @@ -258,17 +264,6 @@ static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev) JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]); } -unsigned long scc_mode_filter(struct ata_device *adev, unsigned long mask) -{ - /* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */ - if (adev->class == ATA_DEV_ATAPI && - (mask & (0xE0 << ATA_SHIFT_UDMA))) { - printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME); - mask &= ~(0xE0 << ATA_SHIFT_UDMA); - } - return ata_pci_default_filter(adev, mask); -} - /** * scc_tf_load - send taskfile registers to host controller * @ap: Port to which output is sent @@ -363,8 +358,6 @@ static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf) tf->hob_lbal = in_be32(ioaddr->lbal_addr); tf->hob_lbam = in_be32(ioaddr->lbam_addr); tf->hob_lbah = in_be32(ioaddr->lbah_addr); - out_be32(ioaddr->ctl_addr, tf->ctl); - ap->last_ctl = tf->ctl; } } @@ -748,7 +741,7 @@ static u8 scc_bmdma_status (struct ata_port *ap) return host_stat; /* errata A252,A308 workaround: Step4 */ - if ((ata_altstatus(ap) & ATA_ERR) && (int_status & INTSTS_INTRQ)) + if (ata_altstatus(ap) & ATA_ERR && int_status & INTSTS_INTRQ) return (host_stat | ATA_DMA_INTR); /* errata A308 workaround Step5 */ @@ -759,11 +752,11 @@ static u8 scc_bmdma_status (struct ata_port *ap) if ((qc->tf.protocol == ATA_PROT_DMA && qc->dev->xfer_mode > XFER_UDMA_4)) { if (!(int_status & INTSTS_ACTEINT)) { - printk(KERN_WARNING "ata%u: operation failed (transfer data loss)\n", - ap->print_id); + printk(KERN_WARNING "ata%u: data lost occurred. (ACTEINT==0, retry:%d)\n", + ap->print_id, retry); host_stat |= ATA_DMA_ERR; if (retry++) - ap->udma_mask &= ~(1 << qc->dev->xfer_mode); + ap->udma_mask >>= 1; } else retry = 0; } @@ -1023,7 +1016,7 @@ static const struct ata_port_operations scc_pata_ops = { .port_disable = ata_port_disable, .set_piomode = scc_set_piomode, .set_dmamode = scc_set_dmamode, - .mode_filter = scc_mode_filter, + .mode_filter = ata_pci_default_filter, .tf_load = scc_tf_load, .tf_read = scc_tf_read, diff --git a/trunk/drivers/ata/sata_inic162x.c b/trunk/drivers/ata/sata_inic162x.c index a9c948d7604a..3de183461c3c 100644 --- a/trunk/drivers/ata/sata_inic162x.c +++ b/trunk/drivers/ata/sata_inic162x.c @@ -190,34 +190,34 @@ static void inic_reset_port(void __iomem *port_base) writew(ctl, idma_ctl); } -static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val) +static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg) { void __iomem *scr_addr = ap->ioaddr.scr_addr; void __iomem *addr; + u32 val; if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) - return -EINVAL; + return 0xffffffffU; addr = scr_addr + scr_map[sc_reg] * 4; - *val = readl(scr_addr + scr_map[sc_reg] * 4); + val = readl(scr_addr + scr_map[sc_reg] * 4); /* this controller has stuck DIAG.N, ignore it */ if (sc_reg == SCR_ERROR) - *val &= ~SERR_PHYRDY_CHG; - return 0; + val &= ~SERR_PHYRDY_CHG; + return val; } -static int inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) +static void inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) { void __iomem *scr_addr = ap->ioaddr.scr_addr; void __iomem *addr; if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) - return -EINVAL; + return; addr = scr_addr + scr_map[sc_reg] * 4; writel(val, scr_addr + scr_map[sc_reg] * 4); - return 0; } /* diff --git a/trunk/drivers/ata/sata_mv.c b/trunk/drivers/ata/sata_mv.c index 8ec520885b95..fb8a749423ca 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -35,6 +35,8 @@ 6) Add port multiplier support (intermediate) + 7) Test and verify 3.0 Gbps support + 8) Develop a low-power-consumption strategy, and implement it. 9) [Experiment, low priority] See if ATAPI can be supported using @@ -225,26 +227,26 @@ enum { EDMA_ERR_IRQ_CAUSE_OFS = 0x8, EDMA_ERR_IRQ_MASK_OFS = 0xc, - EDMA_ERR_D_PAR = (1 << 0), /* UDMA data parity err */ - EDMA_ERR_PRD_PAR = (1 << 1), /* UDMA PRD parity err */ - EDMA_ERR_DEV = (1 << 2), /* device error */ - EDMA_ERR_DEV_DCON = (1 << 3), /* device disconnect */ - EDMA_ERR_DEV_CON = (1 << 4), /* device connected */ - EDMA_ERR_SERR = (1 << 5), /* SError bits [WBDST] raised */ + EDMA_ERR_D_PAR = (1 << 0), + EDMA_ERR_PRD_PAR = (1 << 1), + EDMA_ERR_DEV = (1 << 2), + EDMA_ERR_DEV_DCON = (1 << 3), + EDMA_ERR_DEV_CON = (1 << 4), + EDMA_ERR_SERR = (1 << 5), EDMA_ERR_SELF_DIS = (1 << 7), /* Gen II/IIE self-disable */ EDMA_ERR_SELF_DIS_5 = (1 << 8), /* Gen I self-disable */ - EDMA_ERR_BIST_ASYNC = (1 << 8), /* BIST FIS or Async Notify */ + EDMA_ERR_BIST_ASYNC = (1 << 8), EDMA_ERR_TRANS_IRQ_7 = (1 << 8), /* Gen IIE transprt layer irq */ - EDMA_ERR_CRQB_PAR = (1 << 9), /* CRQB parity error */ - EDMA_ERR_CRPB_PAR = (1 << 10), /* CRPB parity error */ - EDMA_ERR_INTRL_PAR = (1 << 11), /* internal parity error */ - EDMA_ERR_IORDY = (1 << 12), /* IORdy timeout */ - EDMA_ERR_LNK_CTRL_RX = (0xf << 13), /* link ctrl rx error */ + EDMA_ERR_CRBQ_PAR = (1 << 9), + EDMA_ERR_CRPB_PAR = (1 << 10), + EDMA_ERR_INTRL_PAR = (1 << 11), + EDMA_ERR_IORDY = (1 << 12), + EDMA_ERR_LNK_CTRL_RX = (0xf << 13), EDMA_ERR_LNK_CTRL_RX_2 = (1 << 15), - EDMA_ERR_LNK_DATA_RX = (0xf << 17), /* link data rx error */ - EDMA_ERR_LNK_CTRL_TX = (0x1f << 21), /* link ctrl tx error */ - EDMA_ERR_LNK_DATA_TX = (0x1f << 26), /* link data tx error */ - EDMA_ERR_TRANS_PROTO = (1 << 31), /* transport protocol error */ + EDMA_ERR_LNK_DATA_RX = (0xf << 17), + EDMA_ERR_LNK_CTRL_TX = (0x1f << 21), + EDMA_ERR_LNK_DATA_TX = (0x1f << 26), + EDMA_ERR_TRANS_PROTO = (1 << 31), EDMA_ERR_OVERRUN_5 = (1 << 5), EDMA_ERR_UNDERRUN_5 = (1 << 6), EDMA_EH_FREEZE = EDMA_ERR_D_PAR | @@ -253,7 +255,7 @@ enum { EDMA_ERR_DEV_CON | EDMA_ERR_SERR | EDMA_ERR_SELF_DIS | - EDMA_ERR_CRQB_PAR | + EDMA_ERR_CRBQ_PAR | EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR | EDMA_ERR_IORDY | @@ -268,7 +270,7 @@ enum { EDMA_ERR_OVERRUN_5 | EDMA_ERR_UNDERRUN_5 | EDMA_ERR_SELF_DIS_5 | - EDMA_ERR_CRQB_PAR | + EDMA_ERR_CRBQ_PAR | EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR | EDMA_ERR_IORDY, @@ -284,10 +286,10 @@ enum { EDMA_RSP_Q_OUT_PTR_OFS = 0x24, /* also contains BASE_LO */ EDMA_RSP_Q_PTR_SHIFT = 3, - EDMA_CMD_OFS = 0x28, /* EDMA command register */ - EDMA_EN = (1 << 0), /* enable EDMA */ - EDMA_DS = (1 << 1), /* disable EDMA; self-negated */ - ATA_RST = (1 << 2), /* reset trans/link/phy */ + EDMA_CMD_OFS = 0x28, + EDMA_EN = (1 << 0), + EDMA_DS = (1 << 1), + ATA_RST = (1 << 2), EDMA_IORDY_TMOUT = 0x34, EDMA_ARB_CFG = 0x38, @@ -299,13 +301,14 @@ enum { MV_HP_ERRATA_60X1B2 = (1 << 3), MV_HP_ERRATA_60X1C0 = (1 << 4), MV_HP_ERRATA_XX42A0 = (1 << 5), - MV_HP_GEN_I = (1 << 6), /* Generation I: 50xx */ - MV_HP_GEN_II = (1 << 7), /* Generation II: 60xx */ - MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */ + MV_HP_GEN_I = (1 << 6), + MV_HP_GEN_II = (1 << 7), + MV_HP_GEN_IIE = (1 << 8), /* Port private flags (pp_flags) */ - MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */ - MV_PP_FLAG_HAD_A_RESET = (1 << 2), /* 1st hard reset complete? */ + MV_PP_FLAG_EDMA_EN = (1 << 0), + MV_PP_FLAG_EDMA_DS_ACT = (1 << 1), + MV_PP_FLAG_HAD_A_RESET = (1 << 2), }; #define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I) @@ -315,12 +318,8 @@ enum { enum { MV_DMA_BOUNDARY = 0xffffffffU, - /* mask of register bits containing lower 32 bits - * of EDMA request queue DMA address - */ EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U, - /* ditto, for response queue */ EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U, }; @@ -404,10 +403,10 @@ struct mv_host_priv { }; static void mv_irq_clear(struct ata_port *ap); -static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val); -static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); -static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val); -static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); +static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in); +static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); +static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in); +static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); static int mv_port_start(struct ata_port *ap); static void mv_port_stop(struct ata_port *ap); static void mv_qc_prep(struct ata_queued_cmd *qc); @@ -824,7 +823,7 @@ static void mv_start_dma(void __iomem *base, struct mv_host_priv *hpriv, } /** - * __mv_stop_dma - Disable eDMA engine + * mv_stop_dma - Disable eDMA engine * @ap: ATA channel to manipulate * * Verify the local cache of the eDMA state is accurate with a @@ -833,7 +832,7 @@ static void mv_start_dma(void __iomem *base, struct mv_host_priv *hpriv, * LOCKING: * Inherited from caller. */ -static int __mv_stop_dma(struct ata_port *ap) +static int mv_stop_dma(struct ata_port *ap) { void __iomem *port_mmio = mv_ap_base(ap); struct mv_port_priv *pp = ap->private_data; @@ -866,18 +865,6 @@ static int __mv_stop_dma(struct ata_port *ap) return err; } -static int mv_stop_dma(struct ata_port *ap) -{ - unsigned long flags; - int rc; - - spin_lock_irqsave(&ap->host->lock, flags); - rc = __mv_stop_dma(ap); - spin_unlock_irqrestore(&ap->host->lock, flags); - - return rc; -} - #ifdef ATA_DEBUG static void mv_dump_mem(void __iomem *start, unsigned bytes) { @@ -974,26 +961,22 @@ static unsigned int mv_scr_offset(unsigned int sc_reg_in) return ofs; } -static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val) +static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in) { unsigned int ofs = mv_scr_offset(sc_reg_in); - if (ofs != 0xffffffffU) { - *val = readl(mv_ap_base(ap) + ofs); - return 0; - } else - return -EINVAL; + if (0xffffffffU != ofs) + return readl(mv_ap_base(ap) + ofs); + else + return (u32) ofs; } -static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) +static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) { unsigned int ofs = mv_scr_offset(sc_reg_in); - if (ofs != 0xffffffffU) { + if (0xffffffffU != ofs) writelfl(val, mv_ap_base(ap) + ofs); - return 0; - } else - return -EINVAL; } static void mv_edma_cfg(struct ata_port *ap, struct mv_host_priv *hpriv, @@ -1046,7 +1029,6 @@ static int mv_port_start(struct ata_port *ap) void __iomem *port_mmio = mv_ap_base(ap); void *mem; dma_addr_t mem_dma; - unsigned long flags; int rc; pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); @@ -1085,14 +1067,10 @@ static int mv_port_start(struct ata_port *ap) pp->sg_tbl = mem; pp->sg_tbl_dma = mem_dma; - spin_lock_irqsave(&ap->host->lock, flags); - mv_edma_cfg(ap, hpriv, port_mmio); mv_set_edma_ptrs(port_mmio, hpriv, pp); - spin_unlock_irqrestore(&ap->host->lock, flags); - /* Don't turn on EDMA here...do it before DMA commands only. Else * we'll be unable to send non-data, PIO, etc due to restricted access * to shadow regs. @@ -1112,7 +1090,11 @@ static int mv_port_start(struct ata_port *ap) */ static void mv_port_stop(struct ata_port *ap) { + unsigned long flags; + + spin_lock_irqsave(&ap->host->lock, flags); mv_stop_dma(ap); + spin_unlock_irqrestore(&ap->host->lock, flags); } /** @@ -1343,7 +1325,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) * port. Turn off EDMA so there won't be problems accessing * shadow block, etc registers. */ - __mv_stop_dma(ap); + mv_stop_dma(ap); return ata_qc_issue_prot(qc); } @@ -1411,16 +1393,16 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) if (edma_err_cause & EDMA_ERR_DEV) err_mask |= AC_ERR_DEV; if (edma_err_cause & (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR | - EDMA_ERR_CRQB_PAR | EDMA_ERR_CRPB_PAR | + EDMA_ERR_CRBQ_PAR | EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR)) { err_mask |= AC_ERR_ATA_BUS; action |= ATA_EH_HARDRESET; - ata_ehi_push_desc(ehi, "parity error"); + ata_ehi_push_desc(ehi, ", parity error"); } if (edma_err_cause & (EDMA_ERR_DEV_DCON | EDMA_ERR_DEV_CON)) { ata_ehi_hotplugged(ehi); ata_ehi_push_desc(ehi, edma_err_cause & EDMA_ERR_DEV_DCON ? - "dev disconnect" : "dev connect"); + ", dev disconnect" : ", dev connect"); } if (IS_GEN_I(hpriv)) { @@ -1429,7 +1411,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) if (edma_err_cause & EDMA_ERR_SELF_DIS_5) { struct mv_port_priv *pp = ap->private_data; pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; - ata_ehi_push_desc(ehi, "EDMA self-disable"); + ata_ehi_push_desc(ehi, ", EDMA self-disable"); } } else { eh_freeze_mask = EDMA_EH_FREEZE; @@ -1437,7 +1419,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) if (edma_err_cause & EDMA_ERR_SELF_DIS) { struct mv_port_priv *pp = ap->private_data; pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; - ata_ehi_push_desc(ehi, "EDMA self-disable"); + ata_ehi_push_desc(ehi, ", EDMA self-disable"); } if (edma_err_cause & EDMA_ERR_SERR) { @@ -1507,30 +1489,33 @@ static void mv_intr_edma(struct ata_port *ap) while (1) { u16 status; - unsigned int tag; /* get s/w response queue last-read pointer, and compare */ out_index = pp->resp_idx & MV_MAX_Q_DEPTH_MASK; if (in_index == out_index) break; + /* 50xx: get active ATA command */ - if (IS_GEN_I(hpriv)) - tag = ap->active_tag; + if (IS_GEN_I(hpriv)) + qc = ata_qc_from_tag(ap, ap->active_tag); - /* Gen II/IIE: get active ATA command via tag, to enable - * support for queueing. this works transparently for - * queued and non-queued modes. + /* 60xx: get active ATA command via tag, to enable support + * for queueing. this works transparently for queued and + * non-queued modes. */ - else if (IS_GEN_II(hpriv)) - tag = (le16_to_cpu(pp->crpb[out_index].id) - >> CRPB_IOID_SHIFT_6) & 0x3f; + else { + unsigned int tag; - else /* IS_GEN_IIE */ - tag = (le16_to_cpu(pp->crpb[out_index].id) - >> CRPB_IOID_SHIFT_7) & 0x3f; + if (IS_GEN_II(hpriv)) + tag = (le16_to_cpu(pp->crpb[out_index].id) + >> CRPB_IOID_SHIFT_6) & 0x3f; + else + tag = (le16_to_cpu(pp->crpb[out_index].id) + >> CRPB_IOID_SHIFT_7) & 0x3f; - qc = ata_qc_from_tag(ap, tag); + qc = ata_qc_from_tag(ap, tag); + } /* lower 8 bits of status are EDMA_ERR_IRQ_CAUSE_OFS * bits (WARNING: might not necessarily be associated @@ -1550,7 +1535,7 @@ static void mv_intr_edma(struct ata_port *ap) ata_qc_complete(qc); } - /* advance software response queue pointer, to + /* advance software response queue pointer, to * indicate (after the loop completes) to hardware * that we have consumed a response queue entry. */ @@ -1756,30 +1741,26 @@ static unsigned int mv5_scr_offset(unsigned int sc_reg_in) return ofs; } -static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val) +static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in) { void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; void __iomem *addr = mv5_phy_base(mmio, ap->port_no); unsigned int ofs = mv5_scr_offset(sc_reg_in); - if (ofs != 0xffffffffU) { - *val = readl(addr + ofs); - return 0; - } else - return -EINVAL; + if (ofs != 0xffffffffU) + return readl(addr + ofs); + else + return (u32) ofs; } -static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) +static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) { void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; void __iomem *addr = mv5_phy_base(mmio, ap->port_no); unsigned int ofs = mv5_scr_offset(sc_reg_in); - if (ofs != 0xffffffffU) { + if (ofs != 0xffffffffU) writelfl(val, addr + ofs); - return 0; - } else - return -EINVAL; } static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio) @@ -2157,17 +2138,9 @@ static void mv_phy_reset(struct ata_port *ap, unsigned int *class, VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio); -#ifdef DEBUG - { - u32 sstatus, serror, scontrol; - - mv_scr_read(ap, SCR_STATUS, &sstatus); - mv_scr_read(ap, SCR_ERROR, &serror); - mv_scr_read(ap, SCR_CONTROL, &scontrol); - DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x " - "SCtrl 0x%08x\n", status, serror, scontrol); - } -#endif + DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x " + "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), + mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); /* Issue COMRESET via SControl */ comreset_retry: @@ -2191,17 +2164,9 @@ static void mv_phy_reset(struct ata_port *ap, unsigned int *class, (retry-- > 0)) goto comreset_retry; -#ifdef DEBUG - { - u32 sstatus, serror, scontrol; - - mv_scr_read(ap, SCR_STATUS, &sstatus); - mv_scr_read(ap, SCR_ERROR, &serror); - mv_scr_read(ap, SCR_CONTROL, &scontrol); - DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x " - "SCtrl 0x%08x\n", sstatus, serror, scontrol); - } -#endif + DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x " + "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), + mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); if (ata_port_offline(ap)) { *class = ATA_DEV_NONE; @@ -2244,7 +2209,7 @@ static int mv_prereset(struct ata_port *ap, unsigned long deadline) struct mv_port_priv *pp = ap->private_data; struct ata_eh_context *ehc = &ap->eh_context; int rc; - + rc = mv_stop_dma(ap); if (rc) ehc->i.action |= ATA_EH_HARDRESET; diff --git a/trunk/drivers/ata/sata_nv.c b/trunk/drivers/ata/sata_nv.c index 0b58c4df6fd2..db81e3efa5ec 100644 --- a/trunk/drivers/ata/sata_nv.c +++ b/trunk/drivers/ata/sata_nv.c @@ -236,8 +236,8 @@ static void nv_ck804_host_stop(struct ata_host *host); static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance); static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance); static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance); -static int nv_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void nv_nf2_freeze(struct ata_port *ap); static void nv_nf2_thaw(struct ata_port *ap); @@ -715,20 +715,19 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err) int freeze = 0; ata_ehi_clear_desc(ehi); - __ata_ehi_push_desc(ehi, "CPB resp_flags 0x%x: ", flags ); + ata_ehi_push_desc(ehi, "CPB resp_flags 0x%x", flags ); if (flags & NV_CPB_RESP_ATA_ERR) { - ata_ehi_push_desc(ehi, "ATA error"); + ata_ehi_push_desc(ehi, ": ATA error"); ehi->err_mask |= AC_ERR_DEV; } else if (flags & NV_CPB_RESP_CMD_ERR) { - ata_ehi_push_desc(ehi, "CMD error"); + ata_ehi_push_desc(ehi, ": CMD error"); ehi->err_mask |= AC_ERR_DEV; } else if (flags & NV_CPB_RESP_CPB_ERR) { - ata_ehi_push_desc(ehi, "CPB error"); + ata_ehi_push_desc(ehi, ": CPB error"); ehi->err_mask |= AC_ERR_SYSTEM; freeze = 1; } else { /* notifier error, but no error in CPB flags? */ - ata_ehi_push_desc(ehi, "unknown"); ehi->err_mask |= AC_ERR_OTHER; freeze = 1; } @@ -855,21 +854,20 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) struct ata_eh_info *ehi = &ap->eh_info; ata_ehi_clear_desc(ehi); - __ata_ehi_push_desc(ehi, "ADMA status 0x%08x: ", status ); + ata_ehi_push_desc(ehi, "ADMA status 0x%08x", status ); if (status & NV_ADMA_STAT_TIMEOUT) { ehi->err_mask |= AC_ERR_SYSTEM; - ata_ehi_push_desc(ehi, "timeout"); + ata_ehi_push_desc(ehi, ": timeout"); } else if (status & NV_ADMA_STAT_HOTPLUG) { ata_ehi_hotplugged(ehi); - ata_ehi_push_desc(ehi, "hotplug"); + ata_ehi_push_desc(ehi, ": hotplug"); } else if (status & NV_ADMA_STAT_HOTUNPLUG) { ata_ehi_hotplugged(ehi); - ata_ehi_push_desc(ehi, "hot unplug"); + ata_ehi_push_desc(ehi, ": hot unplug"); } else if (status & NV_ADMA_STAT_SERROR) { /* let libata analyze SError and figure out the cause */ - ata_ehi_push_desc(ehi, "SError"); - } else - ata_ehi_push_desc(ehi, "unknown"); + ata_ehi_push_desc(ehi, ": SError"); + } ata_port_freeze(ap); continue; } @@ -1393,22 +1391,20 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance) return ret; } -static int nv_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return 0xffffffffU; - *val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; + return ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); } -static int nv_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return; iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; } static void nv_nf2_freeze(struct ata_port *ap) diff --git a/trunk/drivers/ata/sata_promise.c b/trunk/drivers/ata/sata_promise.c index d39ebc23c4a9..d2fcb9a6bec2 100644 --- a/trunk/drivers/ata/sata_promise.c +++ b/trunk/drivers/ata/sata_promise.c @@ -128,8 +128,8 @@ struct pdc_port_priv { dma_addr_t pkt_dma; }; -static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int pdc_common_port_start(struct ata_port *ap); static int pdc_sata_port_start(struct ata_port *ap); @@ -427,20 +427,19 @@ static int pdc_sata_cable_detect(struct ata_port *ap) return ATA_CBL_SATA; } -static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) - return -EINVAL; - *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; + return 0xffffffffU; + return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); } -static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, + u32 val) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return; writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; } static void pdc_atapi_pkt(struct ata_queued_cmd *qc) @@ -643,12 +642,8 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, | PDC_PCI_SYS_ERR | PDC1_PCI_PARITY_ERR)) ac_err_mask |= AC_ERR_HOST_BUS; - if (sata_scr_valid(ap)) { - u32 serror; - - pdc_sata_scr_read(ap, SCR_ERROR, &serror); - ehi->serror |= serror; - } + if (sata_scr_valid(ap)) + ehi->serror |= pdc_sata_scr_read(ap, SCR_ERROR); qc->err_mask |= ac_err_mask; diff --git a/trunk/drivers/ata/sata_qstor.c b/trunk/drivers/ata/sata_qstor.c index c8f9242e7f44..9ab554da89bf 100644 --- a/trunk/drivers/ata/sata_qstor.c +++ b/trunk/drivers/ata/sata_qstor.c @@ -111,8 +111,8 @@ struct qs_port_priv { qs_state_t state; }; -static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int qs_port_start(struct ata_port *ap); static void qs_host_stop(struct ata_host *host); @@ -255,20 +255,18 @@ static void qs_eng_timeout(struct ata_port *ap) ata_eng_timeout(ap); } -static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) - return -EINVAL; - *val = readl(ap->ioaddr.scr_addr + (sc_reg * 8)); - return 0; + return ~0U; + return readl(ap->ioaddr.scr_addr + (sc_reg * 8)); } -static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return; writel(val, ap->ioaddr.scr_addr + (sc_reg * 8)); - return 0; } static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) @@ -339,7 +337,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) buf[28] = dflags; /* frame information structure (FIS) */ - ata_tf_to_fis(&qc->tf, 0, 1, &buf[32]); + ata_tf_to_fis(&qc->tf, &buf[32], 0); } static inline void qs_packet_start(struct ata_queued_cmd *qc) diff --git a/trunk/drivers/ata/sata_sil.c b/trunk/drivers/ata/sata_sil.c index db6763758952..2a86dc4598d0 100644 --- a/trunk/drivers/ata/sata_sil.c +++ b/trunk/drivers/ata/sata_sil.c @@ -115,8 +115,8 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int sil_pci_device_resume(struct pci_dev *pdev); #endif static void sil_dev_config(struct ata_device *dev); -static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed); static void sil_freeze(struct ata_port *ap); static void sil_thaw(struct ata_port *ap); @@ -350,26 +350,19 @@ static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_re return NULL; } -static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg) { void __iomem *mmio = sil_scr_addr(ap, sc_reg); - - if (mmio) { - *val = readl(mmio); - return 0; - } - return -EINVAL; + if (mmio) + return readl(mmio); + return 0xffffffffU; } -static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { void __iomem *mmio = sil_scr_addr(ap, sc_reg); - - if (mmio) { + if (mmio) writel(val, mmio); - return 0; - } - return -EINVAL; } static void sil_host_intr(struct ata_port *ap, u32 bmdma2) @@ -385,7 +378,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) * controllers continue to assert IRQ as long as * SError bits are pending. Clear SError immediately. */ - sil_scr_read(ap, SCR_ERROR, &serror); + serror = sil_scr_read(ap, SCR_ERROR); sil_scr_write(ap, SCR_ERROR, serror); /* Trigger hotplug and accumulate SError only if the diff --git a/trunk/drivers/ata/sata_sil24.c b/trunk/drivers/ata/sata_sil24.c index 46fbbe7f121c..ac43a30ebe29 100644 --- a/trunk/drivers/ata/sata_sil24.c +++ b/trunk/drivers/ata/sata_sil24.c @@ -326,8 +326,8 @@ struct sil24_port_priv { static void sil24_dev_config(struct ata_device *dev); static u8 sil24_check_status(struct ata_port *ap); -static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val); -static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); +static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg); +static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf); static void sil24_qc_prep(struct ata_queued_cmd *qc); static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); @@ -464,15 +464,15 @@ static void sil24_dev_config(struct ata_device *dev) writel(PORT_CS_CDB16, port + PORT_CTRL_CLR); } -static void sil24_read_tf(struct ata_port *ap, int tag, struct ata_taskfile *tf) +static inline void sil24_update_tf(struct ata_port *ap) { + struct sil24_port_priv *pp = ap->private_data; void __iomem *port = ap->ioaddr.cmd_addr; - struct sil24_prb __iomem *prb; + struct sil24_prb __iomem *prb = port; u8 fis[6 * 4]; - prb = port + PORT_LRAM + sil24_tag(tag) * PORT_LRAM_SLOT_SZ; - memcpy_fromio(fis, prb->fis, sizeof(fis)); - ata_tf_from_fis(fis, tf); + memcpy_fromio(fis, prb->fis, 6 * 4); + ata_tf_from_fis(fis, &pp->tf); } static u8 sil24_check_status(struct ata_port *ap) @@ -488,30 +488,25 @@ static int sil24_scr_map[] = { [SCR_ACTIVE] = 3, }; -static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val) +static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg) { void __iomem *scr_addr = ap->ioaddr.scr_addr; - if (sc_reg < ARRAY_SIZE(sil24_scr_map)) { void __iomem *addr; addr = scr_addr + sil24_scr_map[sc_reg] * 4; - *val = readl(scr_addr + sil24_scr_map[sc_reg] * 4); - return 0; + return readl(scr_addr + sil24_scr_map[sc_reg] * 4); } - return -EINVAL; + return 0xffffffffU; } -static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) +static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) { void __iomem *scr_addr = ap->ioaddr.scr_addr; - if (sc_reg < ARRAY_SIZE(sil24_scr_map)) { void __iomem *addr; addr = scr_addr + sil24_scr_map[sc_reg] * 4; writel(val, scr_addr + sil24_scr_map[sc_reg] * 4); - return 0; } - return -EINVAL; } static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf) @@ -536,60 +531,15 @@ static int sil24_init_port(struct ata_port *ap) return 0; } -static int sil24_exec_polled_cmd(struct ata_port *ap, int pmp, - const struct ata_taskfile *tf, - int is_cmd, u32 ctrl, - unsigned long timeout_msec) +static int sil24_softreset(struct ata_port *ap, unsigned int *class, + unsigned long deadline) { void __iomem *port = ap->ioaddr.cmd_addr; struct sil24_port_priv *pp = ap->private_data; struct sil24_prb *prb = &pp->cmd_block[0].ata.prb; dma_addr_t paddr = pp->cmd_block_dma; - u32 irq_enabled, irq_mask, irq_stat; - int rc; - - prb->ctrl = cpu_to_le16(ctrl); - ata_tf_to_fis(tf, pmp, is_cmd, prb->fis); - - /* temporarily plug completion and error interrupts */ - irq_enabled = readl(port + PORT_IRQ_ENABLE_SET); - writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR, port + PORT_IRQ_ENABLE_CLR); - - writel((u32)paddr, port + PORT_CMD_ACTIVATE); - writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); - - irq_mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT; - irq_stat = ata_wait_register(port + PORT_IRQ_STAT, irq_mask, 0x0, - 10, timeout_msec); - - writel(irq_mask, port + PORT_IRQ_STAT); /* clear IRQs */ - irq_stat >>= PORT_IRQ_RAW_SHIFT; - - if (irq_stat & PORT_IRQ_COMPLETE) - rc = 0; - else { - /* force port into known state */ - sil24_init_port(ap); - - if (irq_stat & PORT_IRQ_ERROR) - rc = -EIO; - else - rc = -EBUSY; - } - - /* restore IRQ enabled */ - writel(irq_enabled, port + PORT_IRQ_ENABLE_SET); - - return rc; -} - -static int sil24_do_softreset(struct ata_port *ap, unsigned int *class, - int pmp, unsigned long deadline) -{ - unsigned long timeout_msec = 0; - struct ata_taskfile tf; + u32 mask, irq_stat; const char *reason; - int rc; DPRINTK("ENTER\n"); @@ -606,22 +556,29 @@ static int sil24_do_softreset(struct ata_port *ap, unsigned int *class, } /* do SRST */ - if (time_after(deadline, jiffies)) - timeout_msec = jiffies_to_msecs(deadline - jiffies); - - ata_tf_init(ap->device, &tf); /* doesn't really matter */ - rc = sil24_exec_polled_cmd(ap, pmp, &tf, 0, PRB_CTRL_SRST, - timeout_msec); - if (rc == -EBUSY) { - reason = "timeout"; - goto err; - } else if (rc) { - reason = "SRST command error"; + prb->ctrl = cpu_to_le16(PRB_CTRL_SRST); + prb->fis[1] = 0; /* no PMP yet */ + + writel((u32)paddr, port + PORT_CMD_ACTIVATE); + writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); + + mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT; + irq_stat = ata_wait_register(port + PORT_IRQ_STAT, mask, 0x0, + 100, jiffies_to_msecs(deadline - jiffies)); + + writel(irq_stat, port + PORT_IRQ_STAT); /* clear IRQs */ + irq_stat >>= PORT_IRQ_RAW_SHIFT; + + if (!(irq_stat & PORT_IRQ_COMPLETE)) { + if (irq_stat & PORT_IRQ_ERROR) + reason = "SRST command error"; + else + reason = "timeout"; goto err; } - sil24_read_tf(ap, 0, &tf); - *class = ata_dev_classify(&tf); + sil24_update_tf(ap); + *class = ata_dev_classify(&pp->tf); if (*class == ATA_DEV_UNKNOWN) *class = ATA_DEV_NONE; @@ -635,12 +592,6 @@ static int sil24_do_softreset(struct ata_port *ap, unsigned int *class, return -EIO; } -static int sil24_softreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) -{ - return sil24_do_softreset(ap, class, 0, deadline); -} - static int sil24_hardreset(struct ata_port *ap, unsigned int *class, unsigned long deadline) { @@ -748,7 +699,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) } prb->ctrl = cpu_to_le16(ctrl); - ata_tf_to_fis(&qc->tf, 0, 1, prb->fis); + ata_tf_to_fis(&qc->tf, prb->fis, 0); if (qc->flags & ATA_QCFLAG_DMAMAP) sil24_fill_sg(qc, sge); @@ -803,7 +754,6 @@ static void sil24_thaw(struct ata_port *ap) static void sil24_error_intr(struct ata_port *ap) { void __iomem *port = ap->ioaddr.cmd_addr; - struct sil24_port_priv *pp = ap->private_data; struct ata_eh_info *ehi = &ap->eh_info; int freeze = 0; u32 irq_stat; @@ -819,16 +769,16 @@ static void sil24_error_intr(struct ata_port *ap) if (irq_stat & (PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG)) { ata_ehi_hotplugged(ehi); - ata_ehi_push_desc(ehi, "%s", - irq_stat & PORT_IRQ_PHYRDY_CHG ? - "PHY RDY changed" : "device exchanged"); + ata_ehi_push_desc(ehi, ", %s", + irq_stat & PORT_IRQ_PHYRDY_CHG ? + "PHY RDY changed" : "device exchanged"); freeze = 1; } if (irq_stat & PORT_IRQ_UNK_FIS) { ehi->err_mask |= AC_ERR_HSM; ehi->action |= ATA_EH_SOFTRESET; - ata_ehi_push_desc(ehi, "unknown FIS"); + ata_ehi_push_desc(ehi , ", unknown FIS"); freeze = 1; } @@ -847,18 +797,18 @@ static void sil24_error_intr(struct ata_port *ap) if (ci && ci->desc) { err_mask |= ci->err_mask; action |= ci->action; - ata_ehi_push_desc(ehi, "%s", ci->desc); + ata_ehi_push_desc(ehi, ", %s", ci->desc); } else { err_mask |= AC_ERR_OTHER; action |= ATA_EH_SOFTRESET; - ata_ehi_push_desc(ehi, "unknown command error %d", + ata_ehi_push_desc(ehi, ", unknown command error %d", cerr); } /* record error info */ qc = ata_qc_from_tag(ap, ap->active_tag); if (qc) { - sil24_read_tf(ap, qc->tag, &pp->tf); + sil24_update_tf(ap); qc->err_mask |= err_mask; } else ehi->err_mask |= err_mask; @@ -875,11 +825,8 @@ static void sil24_error_intr(struct ata_port *ap) static void sil24_finish_qc(struct ata_queued_cmd *qc) { - struct ata_port *ap = qc->ap; - struct sil24_port_priv *pp = ap->private_data; - if (qc->flags & ATA_QCFLAG_RESULT_TF) - sil24_read_tf(ap, qc->tag, &pp->tf); + sil24_update_tf(qc->ap); } static inline void sil24_host_intr(struct ata_port *ap) diff --git a/trunk/drivers/ata/sata_sis.c b/trunk/drivers/ata/sata_sis.c index 31a2f55aae66..33716b00c6b7 100644 --- a/trunk/drivers/ata/sata_sis.c +++ b/trunk/drivers/ata/sata_sis.c @@ -64,8 +64,8 @@ enum { }; static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static int sis_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static const struct pci_device_id sis_pci_tbl[] = { { PCI_VDEVICE(SI, 0x0180), sis_180 }, /* SiS 964/180 */ @@ -207,37 +207,36 @@ static void sis_scr_cfg_write (struct ata_port *ap, unsigned int sc_reg, u32 val pci_write_config_dword(pdev, cfg_addr+0x10, val); } -static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u32 val, val2 = 0; u8 pmr; if (sc_reg > SCR_CONTROL) - return -EINVAL; + return 0xffffffffU; if (ap->flags & SIS_FLAG_CFGSCR) return sis_scr_cfg_read(ap, sc_reg); pci_read_config_byte(pdev, SIS_PMR, &pmr); - *val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); + val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) - *val |= ioread32(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10); - - *val &= 0xfffffffb; + val2 = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10); - return 0; + return (val | val2) & 0xfffffffb; } -static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 pmr; if (sc_reg > SCR_CONTROL) - return -EINVAL; + return; pci_read_config_byte(pdev, SIS_PMR, &pmr); @@ -249,7 +248,6 @@ static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10); } - return 0; } static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) diff --git a/trunk/drivers/ata/sata_svw.c b/trunk/drivers/ata/sata_svw.c index 92e877075037..63fe99afd59f 100644 --- a/trunk/drivers/ata/sata_svw.c +++ b/trunk/drivers/ata/sata_svw.c @@ -103,21 +103,20 @@ static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc) return 0; } -static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) - return -EINVAL; - *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; + return 0xffffffffU; + return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); } -static int k2_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void k2_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, + u32 val) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return; writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; } diff --git a/trunk/drivers/ata/sata_uli.c b/trunk/drivers/ata/sata_uli.c index 78c28512f01c..b52f83ab056a 100644 --- a/trunk/drivers/ata/sata_uli.c +++ b/trunk/drivers/ata/sata_uli.c @@ -57,8 +57,8 @@ struct uli_priv { }; static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static int uli_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static const struct pci_device_id uli_pci_tbl[] = { { PCI_VDEVICE(AL, 0x5289), uli_5289 }, @@ -164,22 +164,20 @@ static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val) pci_write_config_dword(pdev, cfg_addr, val); } -static int uli_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return 0xffffffffU; - *val = uli_scr_cfg_read(ap, sc_reg); - return 0; + return uli_scr_cfg_read(ap, sc_reg); } -static int uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) +static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { if (sc_reg > SCR_CONTROL) //SCR_CONTROL=2, SCR_ERROR=1, SCR_STATUS=0 - return -EINVAL; + return; uli_scr_cfg_write(ap, sc_reg, val); - return 0; } static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) diff --git a/trunk/drivers/ata/sata_via.c b/trunk/drivers/ata/sata_via.c index 86b7bfc17324..c4124475f754 100644 --- a/trunk/drivers/ata/sata_via.c +++ b/trunk/drivers/ata/sata_via.c @@ -72,8 +72,8 @@ enum { }; static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static int svia_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void svia_noop_freeze(struct ata_port *ap); static void vt6420_error_handler(struct ata_port *ap); static int vt6421_pata_cable_detect(struct ata_port *ap); @@ -249,20 +249,18 @@ MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, svia_pci_tbl); MODULE_VERSION(DRV_VERSION); -static int svia_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) - return -EINVAL; - *val = ioread32(ap->ioaddr.scr_addr + (4 * sc_reg)); - return 0; + return 0xffffffffU; + return ioread32(ap->ioaddr.scr_addr + (4 * sc_reg)); } -static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return; iowrite32(val, ap->ioaddr.scr_addr + (4 * sc_reg)); - return 0; } static void svia_noop_freeze(struct ata_port *ap) @@ -307,19 +305,18 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline) /* Resume phy. This is the old SATA resume sequence */ svia_scr_write(ap, SCR_CONTROL, 0x300); - svia_scr_read(ap, SCR_CONTROL, &scontrol); /* flush */ + svia_scr_read(ap, SCR_CONTROL); /* flush */ /* wait for phy to become ready, if necessary */ do { msleep(200); - svia_scr_read(ap, SCR_STATUS, &sstatus); - if ((sstatus & 0xf) != 1) + if ((svia_scr_read(ap, SCR_STATUS) & 0xf) != 1) break; } while (time_before(jiffies, timeout)); /* open code sata_print_link_status() */ - svia_scr_read(ap, SCR_STATUS, &sstatus); - svia_scr_read(ap, SCR_CONTROL, &scontrol); + sstatus = svia_scr_read(ap, SCR_STATUS); + scontrol = svia_scr_read(ap, SCR_CONTROL); online = (sstatus & 0xf) == 0x3; @@ -328,7 +325,7 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline) online ? "up" : "down", sstatus, scontrol); /* SStatus is read one more time */ - svia_scr_read(ap, SCR_STATUS, &sstatus); + svia_scr_read(ap, SCR_STATUS); if (!online) { /* tell EH to bail */ diff --git a/trunk/drivers/ata/sata_vsc.c b/trunk/drivers/ata/sata_vsc.c index 24344d0d0575..1b5d81faa102 100644 --- a/trunk/drivers/ata/sata_vsc.c +++ b/trunk/drivers/ata/sata_vsc.c @@ -98,21 +98,20 @@ enum { VSC_SATA_INT_PHY_CHANGE), }; -static int vsc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) - return -EINVAL; - *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; + return 0xffffffffU; + return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); } -static int vsc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void vsc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, + u32 val) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return; writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; } diff --git a/trunk/drivers/block/sunvdc.c b/trunk/drivers/block/sunvdc.c index d50b82381155..2288b55d916f 100644 --- a/trunk/drivers/block/sunvdc.c +++ b/trunk/drivers/block/sunvdc.c @@ -64,6 +64,7 @@ struct vdc_port { u64 operations; u32 vdisk_size; u8 vdisk_type; + u8 dev_no; char disk_name[32]; @@ -702,7 +703,7 @@ static int probe_disk(struct vdc_port *port) blk_queue_max_phys_segments(q, port->ring_cookies); blk_queue_max_sectors(q, port->max_xfer_size); g->major = vdc_major; - g->first_minor = port->vio.vdev->dev_no << PARTITION_SHIFT; + g->first_minor = port->dev_no << PARTITION_SHIFT; strcpy(g->disk_name, port->disk_name); g->fops = &vdc_fops; @@ -746,16 +747,21 @@ static int __devinit vdc_port_probe(struct vio_dev *vdev, { struct mdesc_handle *hp; struct vdc_port *port; + const u64 *port_id; int err; print_version(); hp = mdesc_grab(); + port_id = mdesc_get_property(hp, vdev->mp, "id", NULL); err = -ENODEV; - if ((vdev->dev_no << PARTITION_SHIFT) & ~(u64)MINORMASK) { - printk(KERN_ERR PFX "Port id [%lu] too large.\n", - vdev->dev_no); + if (!port_id) { + printk(KERN_ERR PFX "Port lacks id property.\n"); + goto err_out_release_mdesc; + } + if ((*port_id << PARTITION_SHIFT) & ~(u64)MINORMASK) { + printk(KERN_ERR PFX "Port id [%lu] too large.\n", *port_id); goto err_out_release_mdesc; } @@ -766,14 +772,16 @@ static int __devinit vdc_port_probe(struct vio_dev *vdev, goto err_out_release_mdesc; } - if (vdev->dev_no >= 26) + port->dev_no = *port_id; + + if (port->dev_no >= 26) snprintf(port->disk_name, sizeof(port->disk_name), VDCBLK_NAME "%c%c", - 'a' + ((int)vdev->dev_no / 26) - 1, - 'a' + ((int)vdev->dev_no % 26)); + 'a' + (port->dev_no / 26) - 1, + 'a' + (port->dev_no % 26)); else snprintf(port->disk_name, sizeof(port->disk_name), - VDCBLK_NAME "%c", 'a' + ((int)vdev->dev_no % 26)); + VDCBLK_NAME "%c", 'a' + (port->dev_no % 26)); err = vio_driver_init(&port->vio, vdev, VDEV_DISK, vdc_versions, ARRAY_SIZE(vdc_versions), @@ -841,7 +849,7 @@ static struct vio_device_id vdc_port_match[] = { }, {}, }; -MODULE_DEVICE_TABLE(vio, vdc_port_match); +MODULE_DEVICE_TABLE(vio, vdc_match); static struct vio_driver vdc_port_driver = { .id_table = vdc_port_match, diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index c8dfd18bea44..9e8f21410d2d 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -185,7 +185,7 @@ config ESPSERIAL config MOXA_INTELLIO tristate "Moxa Intellio support" - depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) + depends on SERIAL_NONSTANDARD help Say Y here if you have a Moxa Intellio multiport serial card. @@ -241,7 +241,7 @@ config SYNCLINK config SYNCLINKMP tristate "SyncLink Multiport support" - depends on SERIAL_NONSTANDARD && PCI + depends on SERIAL_NONSTANDARD help Enable support for the SyncLink Multiport (2 or 4 ports) serial adapter, running asynchronous and HDLC communications up @@ -726,7 +726,7 @@ config NVRAM config RTC tristate "Enhanced Real Time Clock Support" - depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC64 && (!SPARC32 || PCI) && !FRV && !ARM && !SUPERH && !S390 + depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM && !SUPERH && !S390 ---help--- If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you diff --git a/trunk/drivers/char/hpet.c b/trunk/drivers/char/hpet.c index ba0e74ad74bb..0be700f4e8fd 100644 --- a/trunk/drivers/char/hpet.c +++ b/trunk/drivers/char/hpet.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -52,34 +51,8 @@ #define HPET_RANGE_SIZE 1024 /* from HPET spec */ -#if BITS_PER_LONG == 64 -#define write_counter(V, MC) writeq(V, MC) -#define read_counter(MC) readq(MC) -#else -#define write_counter(V, MC) writel(V, MC) -#define read_counter(MC) readl(MC) -#endif - static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ; -static void __iomem *hpet_mctr; - -static cycle_t read_hpet(void) -{ - return (cycle_t)read_counter((void __iomem *)hpet_mctr); -} - -static struct clocksource clocksource_hpet = { - .name = "hpet", - .rating = 250, - .read = read_hpet, - .mask = 0xffffffffffffffff, - .mult = 0, /*to be caluclated*/ - .shift = 10, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; -static struct clocksource *hpet_clocksource; - /* A lock for concurrent access by app and isr hpet activity. */ static DEFINE_SPINLOCK(hpet_lock); /* A lock for concurrent intermodule access to hpet and isr hpet activity. */ @@ -106,7 +79,7 @@ struct hpets { struct hpets *hp_next; struct hpet __iomem *hp_hpet; unsigned long hp_hpet_phys; - struct clocksource *hp_clocksource; + struct time_interpolator *hp_interpolator; unsigned long long hp_tick_freq; unsigned long hp_delta; unsigned int hp_ntimer; @@ -121,6 +94,13 @@ static struct hpets *hpets; #define HPET_PERIODIC 0x0004 #define HPET_SHARED_IRQ 0x0008 +#if BITS_PER_LONG == 64 +#define write_counter(V, MC) writeq(V, MC) +#define read_counter(MC) readq(MC) +#else +#define write_counter(V, MC) writel(V, MC) +#define read_counter(MC) readl(MC) +#endif #ifndef readq static inline unsigned long long readq(void __iomem *addr) @@ -757,6 +737,27 @@ static ctl_table dev_root[] = { static struct ctl_table_header *sysctl_header; +static void hpet_register_interpolator(struct hpets *hpetp) +{ +#ifdef CONFIG_TIME_INTERPOLATION + struct time_interpolator *ti; + + ti = kzalloc(sizeof(*ti), GFP_KERNEL); + if (!ti) + return; + + ti->source = TIME_SOURCE_MMIO64; + ti->shift = 10; + ti->addr = &hpetp->hp_hpet->hpet_mc; + ti->frequency = hpetp->hp_tick_freq; + ti->drift = HPET_DRIFT; + ti->mask = -1; + + hpetp->hp_interpolator = ti; + register_time_interpolator(ti); +#endif +} + /* * Adjustment for when arming the timer with * initial conditions. That is, main counter @@ -908,16 +909,7 @@ int hpet_alloc(struct hpet_data *hdp) } hpetp->hp_delta = hpet_calibrate(hpetp); - - if (!hpet_clocksource) { - hpet_mctr = (void __iomem *)&hpetp->hp_hpet->hpet_mc; - CLKSRC_FSYS_MMIO_SET(clocksource_hpet.fsys_mmio, hpet_mctr); - clocksource_hpet.mult = clocksource_hz2mult(hpetp->hp_tick_freq, - clocksource_hpet.shift); - clocksource_register(&clocksource_hpet); - hpetp->hp_clocksource = &clocksource_hpet; - hpet_clocksource = &clocksource_hpet; - } + hpet_register_interpolator(hpetp); return 0; } @@ -1003,7 +995,7 @@ static int hpet_acpi_add(struct acpi_device *device) static int hpet_acpi_remove(struct acpi_device *device, int type) { - /* XXX need to unregister clocksource, dealloc mem, etc */ + /* XXX need to unregister interpolator, dealloc mem, etc */ return -EINVAL; } diff --git a/trunk/drivers/char/rtc.c b/trunk/drivers/char/rtc.c index 30c3f54c7666..22cf7aa56cc4 100644 --- a/trunk/drivers/char/rtc.c +++ b/trunk/drivers/char/rtc.c @@ -86,9 +86,12 @@ #include #endif -#ifdef CONFIG_SPARC32 +#ifdef __sparc__ #include #include +#ifdef __sparc_v9__ +#include +#endif static unsigned long rtc_port; static int rtc_irq = PCI_IRQ_NONE; @@ -927,9 +930,13 @@ static int __init rtc_init(void) unsigned int year, ctrl; char *guess = NULL; #endif -#ifdef CONFIG_SPARC32 +#ifdef __sparc__ struct linux_ebus *ebus; struct linux_ebus_device *edev; +#ifdef __sparc_v9__ + struct sparc_isa_bridge *isa_br; + struct sparc_isa_device *isa_dev; +#endif #else void *r; #ifdef RTC_IRQ @@ -937,7 +944,7 @@ static int __init rtc_init(void) #endif #endif -#ifdef CONFIG_SPARC32 +#ifdef __sparc__ for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { if(strcmp(edev->prom_node->name, "rtc") == 0) { @@ -947,6 +954,17 @@ static int __init rtc_init(void) } } } +#ifdef __sparc_v9__ + for_each_isa(isa_br) { + for_each_isadev(isa_dev, isa_br) { + if (strcmp(isa_dev->prom_node->name, "rtc") == 0) { + rtc_port = isa_dev->resource.start; + rtc_irq = isa_dev->irq; + goto found; + } + } + } +#endif rtc_has_irq = 0; printk(KERN_ERR "rtc_init: no PC rtc found\n"); return -EIO; @@ -1002,7 +1020,7 @@ static int __init rtc_init(void) #endif -#endif /* CONFIG_SPARC32 vs. others */ +#endif /* __sparc__ vs. others */ if (misc_register(&rtc_dev)) { #ifdef RTC_IRQ @@ -1087,7 +1105,7 @@ static void __exit rtc_exit (void) remove_proc_entry ("driver/rtc", NULL); misc_deregister(&rtc_dev); -#ifdef CONFIG_SPARC32 +#ifdef __sparc__ if (rtc_has_irq) free_irq (rtc_irq, &rtc_port); #else @@ -1099,7 +1117,7 @@ static void __exit rtc_exit (void) if (rtc_has_irq) free_irq (RTC_IRQ, NULL); #endif -#endif /* CONFIG_SPARC32 */ +#endif /* __sparc__ */ } module_init(rtc_init); diff --git a/trunk/drivers/char/serial167.c b/trunk/drivers/char/serial167.c index f1497cecffd8..c585b4738f86 100644 --- a/trunk/drivers/char/serial167.c +++ b/trunk/drivers/char/serial167.c @@ -2573,10 +2573,16 @@ static struct tty_driver *serial167_console_device(struct console *c, return cy_serial_driver; } +static int __init serial167_console_setup(struct console *co, char *options) +{ + return 0; +} + static struct console sercons = { .name = "ttyS", .write = serial167_console_write, .device = serial167_console_device, + .setup = serial167_console_setup, .flags = CON_PRINTBUFFER, .index = -1, }; diff --git a/trunk/drivers/char/tpm/tpm_bios.c b/trunk/drivers/char/tpm/tpm_bios.c index 8677fc6a545e..4eba32b23b29 100644 --- a/trunk/drivers/char/tpm/tpm_bios.c +++ b/trunk/drivers/char/tpm/tpm_bios.c @@ -427,7 +427,7 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode, return -ENOMEM; if ((err = read_log(log))) - goto out_free; + return err; /* now register seq file */ err = seq_open(file, &tpm_ascii_b_measurments_seqops); @@ -435,15 +435,10 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode, seq = file->private_data; seq->private = log; } else { - goto out_free; + kfree(log->bios_event_log); + kfree(log); } - -out: return err; -out_free: - kfree(log->bios_event_log); - kfree(log); - goto out; } const struct file_operations tpm_ascii_bios_measurements_ops = { @@ -465,7 +460,7 @@ static int tpm_binary_bios_measurements_open(struct inode *inode, return -ENOMEM; if ((err = read_log(log))) - goto out_free; + return err; /* now register seq file */ err = seq_open(file, &tpm_binary_b_measurments_seqops); @@ -473,15 +468,10 @@ static int tpm_binary_bios_measurements_open(struct inode *inode, seq = file->private_data; seq->private = log; } else { - goto out_free; + kfree(log->bios_event_log); + kfree(log); } - -out: return err; -out_free: - kfree(log->bios_event_log); - kfree(log); - goto out; } const struct file_operations tpm_binary_bios_measurements_ops = { diff --git a/trunk/drivers/char/vme_scc.c b/trunk/drivers/char/vme_scc.c index e122a0e87bb0..bef6d886d4fb 100644 --- a/trunk/drivers/char/vme_scc.c +++ b/trunk/drivers/char/vme_scc.c @@ -1013,10 +1013,18 @@ static struct tty_driver *scc_console_device(struct console *c, int *index) return scc_driver; } + +static int __init scc_console_setup(struct console *co, char *options) +{ + return 0; +} + + static struct console sercons = { .name = "ttyS", .write = scc_console_write, .device = scc_console_device, + .setup = scc_console_setup, .flags = CON_PRINTBUFFER, .index = -1, }; diff --git a/trunk/drivers/char/watchdog/Kconfig b/trunk/drivers/char/watchdog/Kconfig index ad5cc5f6862f..2f48ba329961 100644 --- a/trunk/drivers/char/watchdog/Kconfig +++ b/trunk/drivers/char/watchdog/Kconfig @@ -602,7 +602,7 @@ config ZVM_WATCHDOG config SH_WDT tristate "SuperH Watchdog" - depends on SUPERH && (CPU_SH3 || CPU_SH4) + depends on SUPERH help This driver adds watchdog support for the integrated watchdog in the SuperH processors. If you have one of these processors and wish diff --git a/trunk/drivers/ide/legacy/falconide.c b/trunk/drivers/ide/legacy/falconide.c index f0829b83e970..e1e9d9d6893f 100644 --- a/trunk/drivers/ide/legacy/falconide.c +++ b/trunk/drivers/ide/legacy/falconide.c @@ -8,7 +8,6 @@ * more details. */ -#include #include #include #include @@ -55,7 +54,6 @@ static int falconide_offsets[IDE_NR_PORTS] __initdata = { */ int falconide_intr_lock; -EXPORT_SYMBOL(falconide_intr_lock); /* diff --git a/trunk/drivers/input/input.c b/trunk/drivers/input/input.c index 5fe755586623..75b4d2a83dd9 100644 --- a/trunk/drivers/input/input.c +++ b/trunk/drivers/input/input.c @@ -471,16 +471,37 @@ static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait) return 0; } +static struct list_head *list_get_nth_element(struct list_head *list, loff_t *pos) +{ + struct list_head *node; + loff_t i = 0; + + list_for_each(node, list) + if (i++ == *pos) + return node; + + return NULL; +} + +static struct list_head *list_get_next_element(struct list_head *list, struct list_head *element, loff_t *pos) +{ + if (element->next == list) + return NULL; + + ++(*pos); + return element->next; +} + static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos) { /* acquire lock here ... Yes, we do need locking, I knowi, I know... */ - return seq_list_start(&input_dev_list, *pos); + return list_get_nth_element(&input_dev_list, pos); } static void *input_devices_seq_next(struct seq_file *seq, void *v, loff_t *pos) { - return seq_list_next(v, &input_dev_list, pos); + return list_get_next_element(&input_dev_list, v, pos); } static void input_devices_seq_stop(struct seq_file *seq, void *v) @@ -571,13 +592,13 @@ static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos) { /* acquire lock here ... Yes, we do need locking, I knowi, I know... */ seq->private = (void *)(unsigned long)*pos; - return seq_list_start(&input_handler_list, *pos); + return list_get_nth_element(&input_handler_list, pos); } static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos) { seq->private = (void *)(unsigned long)(*pos + 1); - return seq_list_next(v, &input_handler_list, pos); + return list_get_next_element(&input_handler_list, v, pos); } static void input_handlers_seq_stop(struct seq_file *seq, void *v) diff --git a/trunk/drivers/input/joystick/Kconfig b/trunk/drivers/input/joystick/Kconfig index e2abe18e575d..12db72d83ea0 100644 --- a/trunk/drivers/input/joystick/Kconfig +++ b/trunk/drivers/input/joystick/Kconfig @@ -275,11 +275,4 @@ config JOYSTICK_XPAD_FF ---help--- Say Y here if you want to take advantage of xbox 360 rumble features. -config JOYSTICK_XPAD_LEDS - bool "LED Support for Xbox360 controller 'BigX' LED" - depends on LEDS_CLASS && JOYSTICK_XPAD - ---help--- - This option enables support for the LED which surrounds the Big X on - XBox 360 controller. - endif diff --git a/trunk/drivers/input/joystick/xpad.c b/trunk/drivers/input/joystick/xpad.c index 28080395899c..244089c52650 100644 --- a/trunk/drivers/input/joystick/xpad.c +++ b/trunk/drivers/input/joystick/xpad.c @@ -191,18 +191,13 @@ struct usb_xpad { unsigned char *idata; /* input data */ dma_addr_t idata_dma; -#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) +#ifdef CONFIG_JOYSTICK_XPAD_FF struct urb *irq_out; /* urb for interrupt out report */ unsigned char *odata; /* output data */ dma_addr_t odata_dma; - struct mutex odata_mutex; -#endif - -#if defined(CONFIG_JOYSTICK_XPAD_LEDS) - struct xpad_led *led; #endif - char phys[64]; /* physical device path */ + char phys[65]; /* physical device path */ int dpad_mapping; /* map d-pad to buttons or to axes */ int xtype; /* type of xbox device */ @@ -354,7 +349,7 @@ static void xpad_irq_in(struct urb *urb) __FUNCTION__, retval); } -#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) +#ifdef CONFIG_JOYSTICK_XPAD_FF static void xpad_irq_out(struct urb *urb) { int retval; @@ -381,7 +376,29 @@ static void xpad_irq_out(struct urb *urb) __FUNCTION__, retval); } -static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) +static int xpad_play_effect(struct input_dev *dev, void *data, + struct ff_effect *effect) +{ + struct usb_xpad *xpad = input_get_drvdata(dev); + + if (effect->type == FF_RUMBLE) { + __u16 strong = effect->u.rumble.strong_magnitude; + __u16 weak = effect->u.rumble.weak_magnitude; + xpad->odata[0] = 0x00; + xpad->odata[1] = 0x08; + xpad->odata[2] = 0x00; + xpad->odata[3] = strong / 256; + xpad->odata[4] = weak / 256; + xpad->odata[5] = 0x00; + xpad->odata[6] = 0x00; + xpad->odata[7] = 0x00; + usb_submit_urb(xpad->irq_out, GFP_KERNEL); + } + + return 0; +} + +static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) { struct usb_endpoint_descriptor *ep_irq_out; int error = -ENOMEM; @@ -394,8 +411,6 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) if (!xpad->odata) goto fail1; - mutex_init(&xpad->odata_mutex); - xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_out) goto fail2; @@ -408,19 +423,25 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) xpad->irq_out->transfer_dma = xpad->odata_dma; xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); + + error = input_ff_create_memless(xpad->dev, NULL, xpad_play_effect); + if (error) + goto fail2; + return 0; fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); fail1: return error; } -static void xpad_stop_output(struct usb_xpad *xpad) +static void xpad_stop_ff(struct usb_xpad *xpad) { if (xpad->xtype == XTYPE_XBOX360) usb_kill_urb(xpad->irq_out); } -static void xpad_deinit_output(struct usb_xpad *xpad) +static void xpad_deinit_ff(struct usb_xpad *xpad) { if (xpad->xtype == XTYPE_XBOX360) { usb_free_urb(xpad->irq_out); @@ -428,130 +449,13 @@ static void xpad_deinit_output(struct usb_xpad *xpad) xpad->odata, xpad->odata_dma); } } -#else -static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; } -static void xpad_deinit_output(struct usb_xpad *xpad) {} -static void xpad_stop_output(struct usb_xpad *xpad) {} -#endif - -#ifdef CONFIG_JOYSTICK_XPAD_FF -static int xpad_play_effect(struct input_dev *dev, void *data, - struct ff_effect *effect) -{ - struct usb_xpad *xpad = input_get_drvdata(dev); - if (effect->type == FF_RUMBLE) { - __u16 strong = effect->u.rumble.strong_magnitude; - __u16 weak = effect->u.rumble.weak_magnitude; - xpad->odata[0] = 0x00; - xpad->odata[1] = 0x08; - xpad->odata[2] = 0x00; - xpad->odata[3] = strong / 256; - xpad->odata[4] = weak / 256; - xpad->odata[5] = 0x00; - xpad->odata[6] = 0x00; - xpad->odata[7] = 0x00; - usb_submit_urb(xpad->irq_out, GFP_KERNEL); - } - - return 0; -} - -static int xpad_init_ff(struct usb_xpad *xpad) -{ - input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); - - return input_ff_create_memless(xpad->dev, NULL, xpad_play_effect); -} - -#else -static int xpad_init_ff(struct usb_xpad *xpad) { return 0; } -#endif - -#if defined(CONFIG_JOYSTICK_XPAD_LEDS) -#include - -struct xpad_led { - char name[16]; - struct led_classdev led_cdev; - struct usb_xpad *xpad; -}; - -static void xpad_send_led_command(struct usb_xpad *xpad, int command) -{ - if (command >= 0 && command < 14) { - mutex_lock(&xpad->odata_mutex); - xpad->odata[0] = 0x01; - xpad->odata[1] = 0x03; - xpad->odata[2] = command; - usb_submit_urb(xpad->irq_out, GFP_KERNEL); - mutex_unlock(&xpad->odata_mutex); - } -} - -static void xpad_led_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct xpad_led *xpad_led = container_of(led_cdev, - struct xpad_led, led_cdev); - - xpad_send_led_command(xpad_led->xpad, value); -} - -static int xpad_led_probe(struct usb_xpad *xpad) -{ - static atomic_t led_seq = ATOMIC_INIT(0); - long led_no; - struct xpad_led *led; - struct led_classdev *led_cdev; - int error; - - if (xpad->xtype != XTYPE_XBOX360) - return 0; - - xpad->led = led = kzalloc(sizeof(struct xpad_led), GFP_KERNEL); - if (!led) - return -ENOMEM; - - led_no = (long)atomic_inc_return(&led_seq) - 1; - - snprintf(led->name, sizeof(led->name), "xpad%ld", led_no); - led->xpad = xpad; - - led_cdev = &led->led_cdev; - led_cdev->name = led->name; - led_cdev->brightness_set = xpad_led_set; - - error = led_classdev_register(&xpad->udev->dev, led_cdev); - if (error) { - kfree(led); - xpad->led = NULL; - return error; - } - - /* - * Light up the segment corresponding to controller number - */ - xpad_send_led_command(xpad, (led_no % 4) + 2); - - return 0; -} - -static void xpad_led_disconnect(struct usb_xpad *xpad) -{ - struct xpad_led *xpad_led = xpad->led; - - if (xpad_led) { - led_classdev_unregister(&xpad_led->led_cdev); - kfree(xpad_led->name); - } -} #else -static int xpad_led_probe(struct usb_xpad *xpad) { return 0; } -static void xpad_led_disconnect(struct usb_xpad *xpad) { } +static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; } +static void xpad_stop_ff(struct usb_xpad *xpad) { } +static void xpad_deinit_ff(struct usb_xpad *xpad) { } #endif - static int xpad_open(struct input_dev *dev) { struct usb_xpad *xpad = input_get_drvdata(dev); @@ -568,7 +472,7 @@ static void xpad_close(struct input_dev *dev) struct usb_xpad *xpad = input_get_drvdata(dev); usb_kill_urb(xpad->irq_in); - xpad_stop_output(xpad); + xpad_stop_ff(xpad); } static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) @@ -660,18 +564,10 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id for (i = 0; xpad_abs_pad[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_pad[i]); - error = xpad_init_output(intf, xpad); + error = xpad_init_ff(intf, xpad); if (error) goto fail2; - error = xpad_init_ff(xpad); - if (error) - goto fail3; - - error = xpad_led_probe(xpad); - if (error) - goto fail3; - ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), @@ -682,13 +578,12 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id error = input_register_device(xpad->dev); if (error) - goto fail4; + goto fail3; usb_set_intfdata(intf, xpad); return 0; - fail4: usb_free_urb(xpad->irq_in); - fail3: xpad_deinit_output(xpad); + fail3: usb_free_urb(xpad->irq_in); fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); fail1: input_free_device(input_dev); kfree(xpad); @@ -702,9 +597,8 @@ static void xpad_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (xpad) { - xpad_led_disconnect(xpad); input_unregister_device(xpad->dev); - xpad_deinit_output(xpad); + xpad_deinit_ff(xpad); usb_free_urb(xpad->irq_in); usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); diff --git a/trunk/drivers/input/mouse/appletouch.c b/trunk/drivers/input/mouse/appletouch.c index 2bea1b2c631c..e3215267db11 100644 --- a/trunk/drivers/input/mouse/appletouch.c +++ b/trunk/drivers/input/mouse/appletouch.c @@ -155,8 +155,6 @@ struct atp { int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; int overflowwarn; /* overflow warning printed? */ int datalen; /* size of an USB urb transfer */ - int idlecount; /* number of empty packets */ - struct work_struct work; }; #define dbg_dump(msg, tab) \ @@ -210,55 +208,6 @@ static inline int atp_is_geyser_3(struct atp *dev) (productId == GEYSER4_JIS_PRODUCT_ID); } -/* - * By default Geyser 3 device sends standard USB HID mouse - * packets (Report ID 2). This code changes device mode, so it - * sends raw sensor reports (Report ID 5). - */ -static int atp_geyser3_init(struct usb_device *udev) -{ - char data[8]; - int size; - - size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - ATP_GEYSER3_MODE_READ_REQUEST_ID, - USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - ATP_GEYSER3_MODE_REQUEST_VALUE, - ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); - - if (size != 8) { - err("Could not do mode read request from device" - " (Geyser 3 mode)"); - return -EIO; - } - - /* Apply the mode switch */ - data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE; - - size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - ATP_GEYSER3_MODE_WRITE_REQUEST_ID, - USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - ATP_GEYSER3_MODE_REQUEST_VALUE, - ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); - - if (size != 8) { - err("Could not do mode write request to device" - " (Geyser 3 mode)"); - return -EIO; - } - return 0; -} - -/* Reinitialise the device if it's a geyser 3 */ -static void atp_reinit(struct work_struct *work) -{ - struct atp *dev = container_of(work, struct atp, work); - struct usb_device *udev = dev->udev; - - dev->idlecount = 0; - atp_geyser3_init(udev); -} - static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, int *z, int *fingers) { @@ -490,8 +439,8 @@ static void atp_complete(struct urb* urb) } dev->x_old = x; dev->y_old = y; - - } else if (!x && !y) { + } + else if (!x && !y) { dev->x_old = dev->y_old = -1; input_report_key(dev->input, BTN_TOUCH, 0); @@ -500,21 +449,11 @@ static void atp_complete(struct urb* urb) /* reset the accumulator on release */ memset(dev->xy_acc, 0, sizeof(dev->xy_acc)); - - /* Geyser 3 will continue to send packets continually after - the first touch unless reinitialised. Do so if it's been - idle for a while in order to avoid waking the kernel up - several hundred times a second */ - if (atp_is_geyser_3(dev)) { - dev->idlecount++; - if (dev->idlecount == 10) { - dev->valid = 0; - schedule_work(&dev->work); - } - } } - input_report_key(dev->input, BTN_LEFT, dev->data[dev->datalen - 1] & 1); + input_report_key(dev->input, BTN_LEFT, + !!dev->data[dev->datalen - 1]); + input_sync(dev->input); exit: @@ -541,7 +480,6 @@ static void atp_close(struct input_dev *input) struct atp *dev = input_get_drvdata(input); usb_kill_urb(dev->urb); - cancel_work_sync(&dev->work); dev->open = 0; } @@ -590,10 +528,40 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id dev->datalen = 81; if (atp_is_geyser_3(dev)) { - /* switch to raw sensor mode */ - if (atp_geyser3_init(udev)) + /* + * By default Geyser 3 device sends standard USB HID mouse + * packets (Report ID 2). This code changes device mode, so it + * sends raw sensor reports (Report ID 5). + */ + char data[8]; + int size; + + size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ATP_GEYSER3_MODE_READ_REQUEST_ID, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + ATP_GEYSER3_MODE_REQUEST_VALUE, + ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); + + if (size != 8) { + err("Could not do mode read request from device" + " (Geyser 3 mode)"); goto err_free_devs; + } + + /* Apply the mode switch */ + data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE; + + size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + ATP_GEYSER3_MODE_WRITE_REQUEST_ID, + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + ATP_GEYSER3_MODE_REQUEST_VALUE, + ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); + if (size != 8) { + err("Could not do mode write request to device" + " (Geyser 3 mode)"); + goto err_free_devs; + } printk("appletouch Geyser 3 inited.\n"); } @@ -668,8 +636,6 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id /* save our data pointer in this interface device */ usb_set_intfdata(iface, dev); - INIT_WORK(&dev->work, atp_reinit); - return 0; err_free_buffer: @@ -703,17 +669,14 @@ static void atp_disconnect(struct usb_interface *iface) static int atp_suspend(struct usb_interface *iface, pm_message_t message) { struct atp *dev = usb_get_intfdata(iface); - usb_kill_urb(dev->urb); dev->valid = 0; - return 0; } static int atp_resume(struct usb_interface *iface) { struct atp *dev = usb_get_intfdata(iface); - if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC)) return -EIO; diff --git a/trunk/drivers/input/mouse/lifebook.c b/trunk/drivers/input/mouse/lifebook.c index 91109b49fde1..1740cadd9594 100644 --- a/trunk/drivers/input/mouse/lifebook.c +++ b/trunk/drivers/input/mouse/lifebook.c @@ -109,7 +109,7 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) { struct lifebook_data *priv = psmouse->private; struct input_dev *dev1 = psmouse->dev; - struct input_dev *dev2 = priv ? priv->dev2 : NULL; + struct input_dev *dev2 = priv->dev2; unsigned char *packet = psmouse->packet; int relative_packet = packet[0] & 0x08; diff --git a/trunk/drivers/input/serio/i8042-x86ia64io.h b/trunk/drivers/input/serio/i8042-x86ia64io.h index 702a526cf45b..4fca1e7f2678 100644 --- a/trunk/drivers/input/serio/i8042-x86ia64io.h +++ b/trunk/drivers/input/serio/i8042-x86ia64io.h @@ -366,7 +366,6 @@ static void i8042_pnp_exit(void) static int __init i8042_pnp_init(void) { char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 }; - int pnp_data_busted = 0; int err; if (i8042_nopnp) { @@ -414,48 +413,27 @@ static int __init i8042_pnp_init(void) #endif if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && - i8042_pnp_data_reg != i8042_data_reg) || - !i8042_pnp_data_reg) { - printk(KERN_WARNING - "PNP: PS/2 controller has invalid data port %#x; " - "using default %#x\n", + i8042_pnp_data_reg != i8042_data_reg) || !i8042_pnp_data_reg) { + printk(KERN_WARNING "PNP: PS/2 controller has invalid data port %#x; using default %#x\n", i8042_pnp_data_reg, i8042_data_reg); i8042_pnp_data_reg = i8042_data_reg; - pnp_data_busted = 1; } if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && - i8042_pnp_command_reg != i8042_command_reg) || - !i8042_pnp_command_reg) { - printk(KERN_WARNING - "PNP: PS/2 controller has invalid command port %#x; " - "using default %#x\n", + i8042_pnp_command_reg != i8042_command_reg) || !i8042_pnp_command_reg) { + printk(KERN_WARNING "PNP: PS/2 controller has invalid command port %#x; using default %#x\n", i8042_pnp_command_reg, i8042_command_reg); i8042_pnp_command_reg = i8042_command_reg; - pnp_data_busted = 1; } if (!i8042_nokbd && !i8042_pnp_kbd_irq) { - printk(KERN_WARNING - "PNP: PS/2 controller doesn't have KBD irq; " - "using default %d\n", i8042_kbd_irq); + printk(KERN_WARNING "PNP: PS/2 controller doesn't have KBD irq; using default %d\n", i8042_kbd_irq); i8042_pnp_kbd_irq = i8042_kbd_irq; - pnp_data_busted = 1; } if (!i8042_noaux && !i8042_pnp_aux_irq) { - if (!pnp_data_busted && i8042_pnp_kbd_irq) { - printk(KERN_WARNING - "PNP: PS/2 appears to have AUX port disabled, " - "if this is incorrect please boot with " - "i8042.nopnp\n"); - i8042_noaux = 1; - } else { - printk(KERN_WARNING - "PNP: PS/2 controller doesn't have AUX irq; " - "using default %d\n", i8042_aux_irq); - i8042_pnp_aux_irq = i8042_aux_irq; - } + printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; using default %d\n", i8042_aux_irq); + i8042_pnp_aux_irq = i8042_aux_irq; } i8042_data_reg = i8042_pnp_data_reg; diff --git a/trunk/drivers/input/touchscreen/Kconfig b/trunk/drivers/input/touchscreen/Kconfig index f929fcdbae2e..69371779806a 100644 --- a/trunk/drivers/input/touchscreen/Kconfig +++ b/trunk/drivers/input/touchscreen/Kconfig @@ -54,19 +54,6 @@ config TOUCHSCREEN_CORGI To compile this driver as a module, choose M here: the module will be called corgi_ts. -config TOUCHSCREEN_FUJITSU - tristate "Fujitsu serial touchscreen" - select SERIO - help - Say Y here if you have the Fujitsu touchscreen (such as one - installed in Lifebook P series laptop) connected to your - system. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called fujitsu-ts. - config TOUCHSCREEN_GUNZE tristate "Gunze AHL-51S touchscreen" select SERIO diff --git a/trunk/drivers/input/touchscreen/Makefile b/trunk/drivers/input/touchscreen/Makefile index 5de8933c4993..2f86d6ad06d3 100644 --- a/trunk/drivers/input/touchscreen/Makefile +++ b/trunk/drivers/input/touchscreen/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o -obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o diff --git a/trunk/drivers/input/touchscreen/ads7846.c b/trunk/drivers/input/touchscreen/ads7846.c index 96581d08774f..1c9069cd3bae 100644 --- a/trunk/drivers/input/touchscreen/ads7846.c +++ b/trunk/drivers/input/touchscreen/ads7846.c @@ -95,7 +95,7 @@ struct ads7846 { u16 dummy; /* for the pwrdown read */ struct ts_event tc; - struct spi_transfer xfer[18]; + struct spi_transfer xfer[10]; struct spi_message msg[5]; struct spi_message *last_msg; int msg_idx; @@ -107,8 +107,6 @@ struct ads7846 { u16 debounce_tol; u16 debounce_rep; - u16 penirq_recheck_delay_usecs; - spinlock_t lock; struct hrtimer timer; unsigned pendown:1; /* P: lock */ @@ -555,15 +553,6 @@ static void ads7846_rx(void *ads) return; } - /* Maybe check the pendown state before reporting. This discards - * false readings when the pen is lifted. - */ - if (ts->penirq_recheck_delay_usecs) { - udelay(ts->penirq_recheck_delay_usecs); - if (!ts->get_pendown_state()) - Rt = 0; - } - /* NOTE: We can't rely on the pressure to determine the pen down * state, even this controller has a pressure sensor. The pressure * value can fluctuate for quite a while after lifting the pen and @@ -907,10 +896,6 @@ static int __devinit ads7846_probe(struct spi_device *spi) ts->filter = ads7846_no_filter; ts->get_pendown_state = pdata->get_pendown_state; - if (pdata->penirq_recheck_delay_usecs) - ts->penirq_recheck_delay_usecs = - pdata->penirq_recheck_delay_usecs; - snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); input_dev->name = "ADS784x Touchscreen"; @@ -951,24 +936,6 @@ static int __devinit ads7846_probe(struct spi_device *spi) x->len = 2; spi_message_add_tail(x, m); - /* the first sample after switching drivers can be low quality; - * optionally discard it, using a second one after the signals - * have had enough time to stabilize. - */ - if (pdata->settle_delay_usecs) { - x->delay_usecs = pdata->settle_delay_usecs; - - x++; - x->tx_buf = &ts->read_y; - x->len = 1; - spi_message_add_tail(x, m); - - x++; - x->rx_buf = &ts->tc.y; - x->len = 2; - spi_message_add_tail(x, m); - } - m->complete = ads7846_rx_val; m->context = ts; @@ -987,21 +954,6 @@ static int __devinit ads7846_probe(struct spi_device *spi) x->len = 2; spi_message_add_tail(x, m); - /* ... maybe discard first sample ... */ - if (pdata->settle_delay_usecs) { - x->delay_usecs = pdata->settle_delay_usecs; - - x++; - x->tx_buf = &ts->read_x; - x->len = 1; - spi_message_add_tail(x, m); - - x++; - x->rx_buf = &ts->tc.x; - x->len = 2; - spi_message_add_tail(x, m); - } - m->complete = ads7846_rx_val; m->context = ts; @@ -1021,21 +973,6 @@ static int __devinit ads7846_probe(struct spi_device *spi) x->len = 2; spi_message_add_tail(x, m); - /* ... maybe discard first sample ... */ - if (pdata->settle_delay_usecs) { - x->delay_usecs = pdata->settle_delay_usecs; - - x++; - x->tx_buf = &ts->read_z1; - x->len = 1; - spi_message_add_tail(x, m); - - x++; - x->rx_buf = &ts->tc.z1; - x->len = 2; - spi_message_add_tail(x, m); - } - m->complete = ads7846_rx_val; m->context = ts; @@ -1053,21 +990,6 @@ static int __devinit ads7846_probe(struct spi_device *spi) x->len = 2; spi_message_add_tail(x, m); - /* ... maybe discard first sample ... */ - if (pdata->settle_delay_usecs) { - x->delay_usecs = pdata->settle_delay_usecs; - - x++; - x->tx_buf = &ts->read_z2; - x->len = 1; - spi_message_add_tail(x, m); - - x++; - x->rx_buf = &ts->tc.z2; - x->len = 2; - spi_message_add_tail(x, m); - } - m->complete = ads7846_rx_val; m->context = ts; } diff --git a/trunk/drivers/input/touchscreen/fujitsu_ts.c b/trunk/drivers/input/touchscreen/fujitsu_ts.c deleted file mode 100644 index daf7a4afc935..000000000000 --- a/trunk/drivers/input/touchscreen/fujitsu_ts.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Fujitsu serial touchscreen driver - * - * Copyright (c) Dmitry Torokhov - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_DESC "Fujitsu serial touchscreen driver" - -MODULE_AUTHOR("Dmitry Torokhov "); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -#define FUJITSU_LENGTH 5 - -/* - * Per-touchscreen data. - */ -struct fujitsu { - struct input_dev *dev; - struct serio *serio; - int idx; - unsigned char data[FUJITSU_LENGTH]; - char phys[32]; -}; - -/* - * Decode serial data (5 bytes per packet) - * First byte - * 1 C 0 0 R S S S - * Where C is 1 while in calibration mode (which we don't use) - * R is 1 when no coordinate corection was done. - * S are button state - */ -static irqreturn_t fujitsu_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) -{ - struct fujitsu *fujitsu = serio_get_drvdata(serio); - struct input_dev *dev = fujitsu->dev; - - if (fujitsu->idx == 0) { - /* resync skip until start of frame */ - if ((data & 0xf0) != 0x80) - return IRQ_HANDLED; - } else { - /* resync skip garbage */ - if (data & 0x80) { - fujitsu->idx = 0; - return IRQ_HANDLED; - } - } - - fujitsu->data[fujitsu->idx++] = data; - if (fujitsu->idx == FUJITSU_LENGTH) { - input_report_abs(dev, ABS_X, - (fujitsu->data[2] << 7) | fujitsu->data[1]); - input_report_abs(dev, ABS_Y, - (fujitsu->data[4] << 7) | fujitsu->data[3]); - input_report_key(dev, BTN_TOUCH, - (fujitsu->data[0] & 0x03) != 2); - input_sync(dev); - fujitsu->idx = 0; - } - - return IRQ_HANDLED; -} - -/* - * fujitsu_disconnect() is the opposite of fujitsu_connect() - */ -static void fujitsu_disconnect(struct serio *serio) -{ - struct fujitsu *fujitsu = serio_get_drvdata(serio); - - input_get_device(fujitsu->dev); - input_unregister_device(fujitsu->dev); - serio_close(serio); - serio_set_drvdata(serio, NULL); - input_put_device(fujitsu->dev); - kfree(fujitsu); -} - -/* - * fujitsu_connect() is the routine that is called when someone adds a - * new serio device that supports the Fujitsu protocol and registers it - * as input device. - */ -static int fujitsu_connect(struct serio *serio, struct serio_driver *drv) -{ - struct fujitsu *fujitsu; - struct input_dev *input_dev; - int err; - - fujitsu = kzalloc(sizeof(struct fujitsu), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!fujitsu || !input_dev) { - err = -ENOMEM; - goto fail1; - } - - fujitsu->serio = serio; - fujitsu->dev = input_dev; - snprintf(fujitsu->phys, sizeof(fujitsu->phys), - "%s/input0", serio->phys); - - input_dev->name = "Fujitsu Serial Touchscreen"; - input_dev->phys = fujitsu->phys; - input_dev->id.bustype = BUS_RS232; - input_dev->id.vendor = SERIO_FUJITSU; - input_dev->id.product = 0; - input_dev->id.version = 0x0100; - input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - - input_set_abs_params(input_dev, ABS_X, 0, 4096, 0, 0); - input_set_abs_params(input_dev, ABS_Y, 0, 4096, 0, 0); - serio_set_drvdata(serio, fujitsu); - - err = serio_open(serio, drv); - if (err) - goto fail2; - - err = input_register_device(fujitsu->dev); - if (err) - goto fail3; - - return 0; - - fail3: - serio_close(serio); - fail2: - serio_set_drvdata(serio, NULL); - fail1: - input_free_device(input_dev); - kfree(fujitsu); - return err; -} - -/* - * The serio driver structure. - */ -static struct serio_device_id fujitsu_serio_ids[] = { - { - .type = SERIO_RS232, - .proto = SERIO_FUJITSU, - .id = SERIO_ANY, - .extra = SERIO_ANY, - }, - { 0 } -}; - -MODULE_DEVICE_TABLE(serio, fujitsu_serio_ids); - -static struct serio_driver fujitsu_drv = { - .driver = { - .name = "fujitsu_ts", - }, - .description = DRIVER_DESC, - .id_table = fujitsu_serio_ids, - .interrupt = fujitsu_interrupt, - .connect = fujitsu_connect, - .disconnect = fujitsu_disconnect, -}; - -static int __init fujitsu_init(void) -{ - return serio_register_driver(&fujitsu_drv); -} - -static void __exit fujitsu_exit(void) -{ - serio_unregister_driver(&fujitsu_drv); -} - -module_init(fujitsu_init); -module_exit(fujitsu_exit); diff --git a/trunk/drivers/kvm/kvm.h b/trunk/drivers/kvm/kvm.h index 3ac9cbce3369..a7c5e6bee034 100644 --- a/trunk/drivers/kvm/kvm.h +++ b/trunk/drivers/kvm/kvm.h @@ -121,7 +121,7 @@ struct kvm_pte_chain { * bits 4:7 - page table level for this shadow (1-4) * bits 8:9 - page table quadrant for 2-level guests * bit 16 - "metaphysical" - gfn is not a real page (huge page/real mode) - * bits 17:19 - "access" - the user, writable, and nx bits of a huge page pde + * bits 17:18 - "access" - the user and writable bits of a huge page pde */ union kvm_mmu_page_role { unsigned word; @@ -131,7 +131,7 @@ union kvm_mmu_page_role { unsigned quadrant : 2; unsigned pad_for_nice_hex_output : 6; unsigned metaphysical : 1; - unsigned hugepage_access : 3; + unsigned hugepage_access : 2; }; }; @@ -535,8 +535,8 @@ int kvm_mmu_create(struct kvm_vcpu *vcpu); int kvm_mmu_setup(struct kvm_vcpu *vcpu); int kvm_mmu_reset_context(struct kvm_vcpu *vcpu); -void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot); -void kvm_mmu_zap_all(struct kvm *kvm); +void kvm_mmu_slot_remove_write_access(struct kvm_vcpu *vcpu, int slot); +void kvm_mmu_zap_all(struct kvm_vcpu *vcpu); hpa_t gpa_to_hpa(struct kvm_vcpu *vcpu, gpa_t gpa); #define HPA_MSB ((sizeof(hpa_t) * 8) - 1) @@ -569,8 +569,6 @@ void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr); void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long value, unsigned long *rflags); -int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *data); -int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); struct x86_emulate_ctxt; diff --git a/trunk/drivers/kvm/kvm_main.c b/trunk/drivers/kvm/kvm_main.c index bcbe6835beb4..1b206f197c6b 100644 --- a/trunk/drivers/kvm/kvm_main.c +++ b/trunk/drivers/kvm/kvm_main.c @@ -238,6 +238,23 @@ static void vcpu_load(struct kvm_vcpu *vcpu) kvm_arch_ops->vcpu_load(vcpu); } +/* + * Switches to specified vcpu, until a matching vcpu_put(). Will return NULL + * if the slot is not populated. + */ +static struct kvm_vcpu *vcpu_load_slot(struct kvm *kvm, int slot) +{ + struct kvm_vcpu *vcpu = &kvm->vcpus[slot]; + + mutex_lock(&vcpu->mutex); + if (!vcpu->vmcs) { + mutex_unlock(&vcpu->mutex); + return NULL; + } + kvm_arch_ops->vcpu_load(vcpu); + return vcpu; +} + static void vcpu_put(struct kvm_vcpu *vcpu) { kvm_arch_ops->vcpu_put(vcpu); @@ -646,6 +663,13 @@ void fx_init(struct kvm_vcpu *vcpu) } EXPORT_SYMBOL_GPL(fx_init); +static void do_remove_write_access(struct kvm_vcpu *vcpu, int slot) +{ + spin_lock(&vcpu->kvm->lock); + kvm_mmu_slot_remove_write_access(vcpu, slot); + spin_unlock(&vcpu->kvm->lock); +} + /* * Allocate some memory and give it an address in the guest physical address * space. @@ -768,11 +792,20 @@ static int kvm_vm_ioctl_set_memory_region(struct kvm *kvm, *memslot = new; ++kvm->memory_config_version; - kvm_mmu_slot_remove_write_access(kvm, mem->slot); - kvm_flush_remote_tlbs(kvm); - spin_unlock(&kvm->lock); + for (i = 0; i < KVM_MAX_VCPUS; ++i) { + struct kvm_vcpu *vcpu; + + vcpu = vcpu_load_slot(kvm, i); + if (!vcpu) + continue; + if (new.flags & KVM_MEM_LOG_DIRTY_PAGES) + do_remove_write_access(vcpu, mem->slot); + kvm_mmu_reset_context(vcpu); + vcpu_put(vcpu); + } + kvm_free_physmem_slot(&old, &new); return 0; @@ -793,6 +826,7 @@ static int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot; int r, i; int n; + int cleared; unsigned long any = 0; spin_lock(&kvm->lock); @@ -821,11 +855,23 @@ static int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n)) goto out; - spin_lock(&kvm->lock); - kvm_mmu_slot_remove_write_access(kvm, log->slot); - kvm_flush_remote_tlbs(kvm); - memset(memslot->dirty_bitmap, 0, n); - spin_unlock(&kvm->lock); + if (any) { + cleared = 0; + for (i = 0; i < KVM_MAX_VCPUS; ++i) { + struct kvm_vcpu *vcpu; + + vcpu = vcpu_load_slot(kvm, i); + if (!vcpu) + continue; + if (!cleared) { + do_remove_write_access(vcpu, log->slot); + memset(memslot->dirty_bitmap, 0, n); + cleared = 1; + } + kvm_arch_ops->tlb_flush(vcpu); + vcpu_put(vcpu); + } + } r = 0; @@ -874,9 +920,13 @@ static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm, break; kvm->naliases = n; - kvm_mmu_zap_all(kvm); + spin_unlock(&kvm->lock); + vcpu_load(&kvm->vcpus[0]); + spin_lock(&kvm->lock); + kvm_mmu_zap_all(&kvm->vcpus[0]); spin_unlock(&kvm->lock); + vcpu_put(&kvm->vcpus[0]); return 0; @@ -1517,7 +1567,7 @@ EXPORT_SYMBOL_GPL(kvm_get_msr_common); * Returns 0 on success, non-0 otherwise. * Assumes vcpu_load() was already called. */ -int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) +static int get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) { return kvm_arch_ops->get_msr(vcpu, msr_index, pdata); } @@ -1595,7 +1645,7 @@ EXPORT_SYMBOL_GPL(kvm_set_msr_common); * Returns 0 on success, non-0 otherwise. * Assumes vcpu_load() was already called. */ -int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) +static int set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) { return kvm_arch_ops->set_msr(vcpu, msr_index, data); } @@ -2133,7 +2183,7 @@ static __init void kvm_init_msr_list(void) */ static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data) { - return kvm_set_msr(vcpu, index, *data); + return set_msr(vcpu, index, *data); } /* @@ -2617,7 +2667,7 @@ static long kvm_vcpu_ioctl(struct file *filp, break; } case KVM_GET_MSRS: - r = msr_io(vcpu, argp, kvm_get_msr, 1); + r = msr_io(vcpu, argp, get_msr, 1); break; case KVM_SET_MSRS: r = msr_io(vcpu, argp, do_set_msr, 0); diff --git a/trunk/drivers/kvm/mmu.c b/trunk/drivers/kvm/mmu.c index d99d2fe53dca..1199d3f32ac3 100644 --- a/trunk/drivers/kvm/mmu.c +++ b/trunk/drivers/kvm/mmu.c @@ -154,6 +154,7 @@ struct kvm_rmap_desc { static struct kmem_cache *pte_chain_cache; static struct kmem_cache *rmap_desc_cache; +static struct kmem_cache *mmu_page_cache; static struct kmem_cache *mmu_page_header_cache; static int is_write_protection(struct kvm_vcpu *vcpu) @@ -224,29 +225,6 @@ static void mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc) kfree(mc->objects[--mc->nobjs]); } -static int mmu_topup_memory_cache_page(struct kvm_mmu_memory_cache *cache, - int min, gfp_t gfp_flags) -{ - struct page *page; - - if (cache->nobjs >= min) - return 0; - while (cache->nobjs < ARRAY_SIZE(cache->objects)) { - page = alloc_page(gfp_flags); - if (!page) - return -ENOMEM; - set_page_private(page, 0); - cache->objects[cache->nobjs++] = page_address(page); - } - return 0; -} - -static void mmu_free_memory_cache_page(struct kvm_mmu_memory_cache *mc) -{ - while (mc->nobjs) - __free_page(mc->objects[--mc->nobjs]); -} - static int __mmu_topup_memory_caches(struct kvm_vcpu *vcpu, gfp_t gfp_flags) { int r; @@ -259,7 +237,8 @@ static int __mmu_topup_memory_caches(struct kvm_vcpu *vcpu, gfp_t gfp_flags) rmap_desc_cache, 1, gfp_flags); if (r) goto out; - r = mmu_topup_memory_cache_page(&vcpu->mmu_page_cache, 4, gfp_flags); + r = mmu_topup_memory_cache(&vcpu->mmu_page_cache, + mmu_page_cache, 4, gfp_flags); if (r) goto out; r = mmu_topup_memory_cache(&vcpu->mmu_page_header_cache, @@ -287,7 +266,7 @@ static void mmu_free_memory_caches(struct kvm_vcpu *vcpu) { mmu_free_memory_cache(&vcpu->mmu_pte_chain_cache); mmu_free_memory_cache(&vcpu->mmu_rmap_desc_cache); - mmu_free_memory_cache_page(&vcpu->mmu_page_cache); + mmu_free_memory_cache(&vcpu->mmu_page_cache); mmu_free_memory_cache(&vcpu->mmu_page_header_cache); } @@ -302,15 +281,24 @@ static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc, return p; } +static void mmu_memory_cache_free(struct kvm_mmu_memory_cache *mc, void *obj) +{ + if (mc->nobjs < KVM_NR_MEM_OBJS) + mc->objects[mc->nobjs++] = obj; + else + kfree(obj); +} + static struct kvm_pte_chain *mmu_alloc_pte_chain(struct kvm_vcpu *vcpu) { return mmu_memory_cache_alloc(&vcpu->mmu_pte_chain_cache, sizeof(struct kvm_pte_chain)); } -static void mmu_free_pte_chain(struct kvm_pte_chain *pc) +static void mmu_free_pte_chain(struct kvm_vcpu *vcpu, + struct kvm_pte_chain *pc) { - kfree(pc); + mmu_memory_cache_free(&vcpu->mmu_pte_chain_cache, pc); } static struct kvm_rmap_desc *mmu_alloc_rmap_desc(struct kvm_vcpu *vcpu) @@ -319,9 +307,10 @@ static struct kvm_rmap_desc *mmu_alloc_rmap_desc(struct kvm_vcpu *vcpu) sizeof(struct kvm_rmap_desc)); } -static void mmu_free_rmap_desc(struct kvm_rmap_desc *rd) +static void mmu_free_rmap_desc(struct kvm_vcpu *vcpu, + struct kvm_rmap_desc *rd) { - kfree(rd); + mmu_memory_cache_free(&vcpu->mmu_rmap_desc_cache, rd); } /* @@ -366,7 +355,8 @@ static void rmap_add(struct kvm_vcpu *vcpu, u64 *spte) } } -static void rmap_desc_remove_entry(struct page *page, +static void rmap_desc_remove_entry(struct kvm_vcpu *vcpu, + struct page *page, struct kvm_rmap_desc *desc, int i, struct kvm_rmap_desc *prev_desc) @@ -386,10 +376,10 @@ static void rmap_desc_remove_entry(struct page *page, prev_desc->more = desc->more; else set_page_private(page,(unsigned long)desc->more | 1); - mmu_free_rmap_desc(desc); + mmu_free_rmap_desc(vcpu, desc); } -static void rmap_remove(u64 *spte) +static void rmap_remove(struct kvm_vcpu *vcpu, u64 *spte) { struct page *page; struct kvm_rmap_desc *desc; @@ -417,7 +407,7 @@ static void rmap_remove(u64 *spte) while (desc) { for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i) if (desc->shadow_ptes[i] == spte) { - rmap_desc_remove_entry(page, + rmap_desc_remove_entry(vcpu, page, desc, i, prev_desc); return; @@ -452,7 +442,7 @@ static void rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn) BUG_ON(!(*spte & PT_PRESENT_MASK)); BUG_ON(!(*spte & PT_WRITABLE_MASK)); rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte); - rmap_remove(spte); + rmap_remove(vcpu, spte); set_shadow_pte(spte, *spte & ~PT_WRITABLE_MASK); kvm_flush_remote_tlbs(vcpu->kvm); } @@ -474,14 +464,14 @@ static int is_empty_shadow_page(u64 *spt) } #endif -static void kvm_mmu_free_page(struct kvm *kvm, +static void kvm_mmu_free_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page_head) { ASSERT(is_empty_shadow_page(page_head->spt)); list_del(&page_head->link); - __free_page(virt_to_page(page_head->spt)); - kfree(page_head); - ++kvm->n_free_mmu_pages; + mmu_memory_cache_free(&vcpu->mmu_page_cache, page_head->spt); + mmu_memory_cache_free(&vcpu->mmu_page_header_cache, page_head); + ++vcpu->kvm->n_free_mmu_pages; } static unsigned kvm_page_table_hashfn(gfn_t gfn) @@ -547,7 +537,8 @@ static void mmu_page_add_parent_pte(struct kvm_vcpu *vcpu, pte_chain->parent_ptes[0] = parent_pte; } -static void mmu_page_remove_parent_pte(struct kvm_mmu_page *page, +static void mmu_page_remove_parent_pte(struct kvm_vcpu *vcpu, + struct kvm_mmu_page *page, u64 *parent_pte) { struct kvm_pte_chain *pte_chain; @@ -574,7 +565,7 @@ static void mmu_page_remove_parent_pte(struct kvm_mmu_page *page, pte_chain->parent_ptes[i] = NULL; if (i == 0) { hlist_del(&pte_chain->link); - mmu_free_pte_chain(pte_chain); + mmu_free_pte_chain(vcpu, pte_chain); if (hlist_empty(&page->parent_ptes)) { page->multimapped = 0; page->parent_pte = NULL; @@ -652,7 +643,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, return page; } -static void kvm_mmu_page_unlink_children(struct kvm *kvm, +static void kvm_mmu_page_unlink_children(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page) { unsigned i; @@ -664,10 +655,10 @@ static void kvm_mmu_page_unlink_children(struct kvm *kvm, if (page->role.level == PT_PAGE_TABLE_LEVEL) { for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { if (pt[i] & PT_PRESENT_MASK) - rmap_remove(&pt[i]); + rmap_remove(vcpu, &pt[i]); pt[i] = 0; } - kvm_flush_remote_tlbs(kvm); + kvm_flush_remote_tlbs(vcpu->kvm); return; } @@ -678,18 +669,19 @@ static void kvm_mmu_page_unlink_children(struct kvm *kvm, if (!(ent & PT_PRESENT_MASK)) continue; ent &= PT64_BASE_ADDR_MASK; - mmu_page_remove_parent_pte(page_header(ent), &pt[i]); + mmu_page_remove_parent_pte(vcpu, page_header(ent), &pt[i]); } - kvm_flush_remote_tlbs(kvm); + kvm_flush_remote_tlbs(vcpu->kvm); } -static void kvm_mmu_put_page(struct kvm_mmu_page *page, +static void kvm_mmu_put_page(struct kvm_vcpu *vcpu, + struct kvm_mmu_page *page, u64 *parent_pte) { - mmu_page_remove_parent_pte(page, parent_pte); + mmu_page_remove_parent_pte(vcpu, page, parent_pte); } -static void kvm_mmu_zap_page(struct kvm *kvm, +static void kvm_mmu_zap_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page) { u64 *parent_pte; @@ -705,15 +697,15 @@ static void kvm_mmu_zap_page(struct kvm *kvm, parent_pte = chain->parent_ptes[0]; } BUG_ON(!parent_pte); - kvm_mmu_put_page(page, parent_pte); + kvm_mmu_put_page(vcpu, page, parent_pte); set_shadow_pte(parent_pte, 0); } - kvm_mmu_page_unlink_children(kvm, page); + kvm_mmu_page_unlink_children(vcpu, page); if (!page->root_count) { hlist_del(&page->hash_link); - kvm_mmu_free_page(kvm, page); + kvm_mmu_free_page(vcpu, page); } else - list_move(&page->link, &kvm->active_mmu_pages); + list_move(&page->link, &vcpu->kvm->active_mmu_pages); } static int kvm_mmu_unprotect_page(struct kvm_vcpu *vcpu, gfn_t gfn) @@ -732,7 +724,7 @@ static int kvm_mmu_unprotect_page(struct kvm_vcpu *vcpu, gfn_t gfn) if (page->gfn == gfn && !page->role.metaphysical) { pgprintk("%s: gfn %lx role %x\n", __FUNCTION__, gfn, page->role.word); - kvm_mmu_zap_page(vcpu->kvm, page); + kvm_mmu_zap_page(vcpu, page); r = 1; } return r; @@ -745,7 +737,7 @@ static void mmu_unshadow(struct kvm_vcpu *vcpu, gfn_t gfn) while ((page = kvm_mmu_lookup_page(vcpu, gfn)) != NULL) { pgprintk("%s: zap %lx %x\n", __FUNCTION__, gfn, page->role.word); - kvm_mmu_zap_page(vcpu->kvm, page); + kvm_mmu_zap_page(vcpu, page); } } @@ -1097,10 +1089,10 @@ static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu, pte = *spte; if (is_present_pte(pte)) { if (page->role.level == PT_PAGE_TABLE_LEVEL) - rmap_remove(spte); + rmap_remove(vcpu, spte); else { child = page_header(pte & PT64_BASE_ADDR_MASK); - mmu_page_remove_parent_pte(child, spte); + mmu_page_remove_parent_pte(vcpu, child, spte); } } *spte = 0; @@ -1169,7 +1161,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, */ pgprintk("misaligned: gpa %llx bytes %d role %x\n", gpa, bytes, page->role.word); - kvm_mmu_zap_page(vcpu->kvm, page); + kvm_mmu_zap_page(vcpu, page); continue; } page_offset = offset; @@ -1215,7 +1207,7 @@ void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) page = container_of(vcpu->kvm->active_mmu_pages.prev, struct kvm_mmu_page, link); - kvm_mmu_zap_page(vcpu->kvm, page); + kvm_mmu_zap_page(vcpu, page); } } EXPORT_SYMBOL_GPL(kvm_mmu_free_some_pages); @@ -1227,7 +1219,7 @@ static void free_mmu_pages(struct kvm_vcpu *vcpu) while (!list_empty(&vcpu->kvm->active_mmu_pages)) { page = container_of(vcpu->kvm->active_mmu_pages.next, struct kvm_mmu_page, link); - kvm_mmu_zap_page(vcpu->kvm, page); + kvm_mmu_zap_page(vcpu, page); } free_page((unsigned long)vcpu->mmu.pae_root); } @@ -1285,8 +1277,9 @@ void kvm_mmu_destroy(struct kvm_vcpu *vcpu) mmu_free_memory_caches(vcpu); } -void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot) +void kvm_mmu_slot_remove_write_access(struct kvm_vcpu *vcpu, int slot) { + struct kvm *kvm = vcpu->kvm; struct kvm_mmu_page *page; list_for_each_entry(page, &kvm->active_mmu_pages, link) { @@ -1300,20 +1293,27 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot) for (i = 0; i < PT64_ENT_PER_PAGE; ++i) /* avoid RMW */ if (pt[i] & PT_WRITABLE_MASK) { - rmap_remove(&pt[i]); + rmap_remove(vcpu, &pt[i]); pt[i] &= ~PT_WRITABLE_MASK; } } } -void kvm_mmu_zap_all(struct kvm *kvm) +void kvm_mmu_zap_all(struct kvm_vcpu *vcpu) { - struct kvm_mmu_page *page, *node; + destroy_kvm_mmu(vcpu); + + while (!list_empty(&vcpu->kvm->active_mmu_pages)) { + struct kvm_mmu_page *page; - list_for_each_entry_safe(page, node, &kvm->active_mmu_pages, link) - kvm_mmu_zap_page(kvm, page); + page = container_of(vcpu->kvm->active_mmu_pages.next, + struct kvm_mmu_page, link); + kvm_mmu_zap_page(vcpu, page); + } - kvm_flush_remote_tlbs(kvm); + mmu_free_memory_caches(vcpu); + kvm_flush_remote_tlbs(vcpu->kvm); + init_kvm_mmu(vcpu); } void kvm_mmu_module_exit(void) @@ -1322,6 +1322,8 @@ void kvm_mmu_module_exit(void) kmem_cache_destroy(pte_chain_cache); if (rmap_desc_cache) kmem_cache_destroy(rmap_desc_cache); + if (mmu_page_cache) + kmem_cache_destroy(mmu_page_cache); if (mmu_page_header_cache) kmem_cache_destroy(mmu_page_header_cache); } @@ -1339,6 +1341,12 @@ int kvm_mmu_module_init(void) if (!rmap_desc_cache) goto nomem; + mmu_page_cache = kmem_cache_create("kvm_mmu_page", + PAGE_SIZE, + PAGE_SIZE, 0, NULL); + if (!mmu_page_cache) + goto nomem; + mmu_page_header_cache = kmem_cache_create("kvm_mmu_page_header", sizeof(struct kvm_mmu_page), 0, 0, NULL); diff --git a/trunk/drivers/kvm/paging_tmpl.h b/trunk/drivers/kvm/paging_tmpl.h index 4b5391c717f8..a7c5cb0319ea 100644 --- a/trunk/drivers/kvm/paging_tmpl.h +++ b/trunk/drivers/kvm/paging_tmpl.h @@ -366,8 +366,6 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, metaphysical = 1; hugepage_access = *guest_ent; hugepage_access &= PT_USER_MASK | PT_WRITABLE_MASK; - if (*guest_ent & PT64_NX_MASK) - hugepage_access |= (1 << 2); hugepage_access >>= PT_WRITABLE_SHIFT; table_gfn = (*guest_ent & PT_BASE_ADDR_MASK) >> PAGE_SHIFT; diff --git a/trunk/drivers/kvm/x86_emulate.c b/trunk/drivers/kvm/x86_emulate.c index 1b800fc00342..f60012d62610 100644 --- a/trunk/drivers/kvm/x86_emulate.c +++ b/trunk/drivers/kvm/x86_emulate.c @@ -163,7 +163,7 @@ static u16 twobyte_table[256] = { ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3F */ - ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x47 */ DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, @@ -486,7 +486,6 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) unsigned long modrm_ea; int use_modrm_ea, index_reg = 0, base_reg = 0, scale, rip_relative = 0; int no_wb = 0; - u64 msr_data; /* Shadow copy of register state. Committed on successful emulation. */ unsigned long _regs[NR_VCPU_REGS]; @@ -1345,29 +1344,6 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) goto cannot_emulate; realmode_set_cr(ctxt->vcpu, modrm_reg, modrm_val, &_eflags); break; - case 0x30: - /* wrmsr */ - msr_data = (u32)_regs[VCPU_REGS_RAX] - | ((u64)_regs[VCPU_REGS_RDX] << 32); - rc = kvm_set_msr(ctxt->vcpu, _regs[VCPU_REGS_RCX], msr_data); - if (rc) { - kvm_arch_ops->inject_gp(ctxt->vcpu, 0); - _eip = ctxt->vcpu->rip; - } - rc = X86EMUL_CONTINUE; - break; - case 0x32: - /* rdmsr */ - rc = kvm_get_msr(ctxt->vcpu, _regs[VCPU_REGS_RCX], &msr_data); - if (rc) { - kvm_arch_ops->inject_gp(ctxt->vcpu, 0); - _eip = ctxt->vcpu->rip; - } else { - _regs[VCPU_REGS_RAX] = (u32)msr_data; - _regs[VCPU_REGS_RDX] = msr_data >> 32; - } - rc = X86EMUL_CONTINUE; - break; case 0xc7: /* Grp9 (cmpxchg8b) */ { u64 old, new; diff --git a/trunk/drivers/lguest/interrupts_and_traps.c b/trunk/drivers/lguest/interrupts_and_traps.c index bee029bb2c7b..d9de5bbc613f 100644 --- a/trunk/drivers/lguest/interrupts_and_traps.c +++ b/trunk/drivers/lguest/interrupts_and_traps.c @@ -38,12 +38,12 @@ static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err) ss = lg->regs->ss; } - /* We use IF bit in eflags to indicate whether irqs were enabled - (it's always 1, since irqs are enabled when guest is running). */ + /* We use IF bit in eflags to indicate whether irqs were disabled + (it's always 0, since irqs are enabled when guest is running). */ eflags = lg->regs->eflags; - if (get_user(irq_enable, &lg->lguest_data->irq_enabled) == 0 - && !(irq_enable & X86_EFLAGS_IF)) - eflags &= ~X86_EFLAGS_IF; + if (get_user(irq_enable, &lg->lguest_data->irq_enabled)) + irq_enable = 0; + eflags |= (irq_enable & X86_EFLAGS_IF); push_guest_stack(lg, &gstack, eflags); push_guest_stack(lg, &gstack, lg->regs->cs); diff --git a/trunk/drivers/lguest/io.c b/trunk/drivers/lguest/io.c index c8eb79266991..06bdba2337ef 100644 --- a/trunk/drivers/lguest/io.c +++ b/trunk/drivers/lguest/io.c @@ -187,7 +187,7 @@ static u32 copy_data(struct lguest *srclg, /* FIXME: This is not completely portable, since archs do different things for copy_to_user_page. */ if (copy_from_user(maddr + (dst->addr[di] + dstoff)%PAGE_SIZE, - (void __user *)src->addr[si], len) != 0) { + (void *__user)src->addr[si], len) != 0) { kill_guest(srclg, "bad address in sending DMA"); totlen = 0; break; diff --git a/trunk/drivers/lguest/lguest.c b/trunk/drivers/lguest/lguest.c index 434fea1e82f7..b9a58b78c990 100644 --- a/trunk/drivers/lguest/lguest.c +++ b/trunk/drivers/lguest/lguest.c @@ -39,6 +39,7 @@ #include #include #include +//#include /* Declarations for definitions in lguest_guest.S */ extern char lguest_noirq_start[], lguest_noirq_end[]; @@ -56,7 +57,6 @@ struct lguest_data lguest_data = { .blocked_interrupts = { 1 }, /* Block timer interrupts */ }; struct lguest_device_desc *lguest_devices; -static cycle_t clock_base; static enum paravirt_lazy_mode lazy_mode; static void lguest_lazy_mode(enum paravirt_lazy_mode mode) @@ -363,11 +363,6 @@ static struct clocksource lguest_clock = { .read = lguest_clock_read, }; -static unsigned long long lguest_sched_clock(void) -{ - return cyc2ns(&lguest_clock, lguest_clock_read() - clock_base); -} - /* We also need a "struct clock_event_device": Linux asks us to set it to go * off some time in the future. Actually, James Morris figured all this out, I * just applied the patch. */ @@ -444,7 +439,6 @@ static void lguest_time_init(void) lguest_clock.mult = (((u64)NSEC_PER_SEC<<8)/ACTHZ) << 8; lguest_clock.mask = CLOCKSOURCE_MASK(32); } - clock_base = lguest_clock_read(); clocksource_register(&lguest_clock); /* We can't set cpumask in the initializer: damn C limitations! */ @@ -590,7 +584,6 @@ __init void lguest_init(void *boot) paravirt_ops.time_init = lguest_time_init; paravirt_ops.set_lazy_mode = lguest_lazy_mode; paravirt_ops.wbinvd = lguest_wbinvd; - paravirt_ops.sched_clock = lguest_sched_clock; hcall(LHCALL_LGUEST_INIT, __pa(&lguest_data), 0, 0); diff --git a/trunk/drivers/lguest/lguest_asm.S b/trunk/drivers/lguest/lguest_asm.S index a3dbf22ee365..00046c57b5ba 100644 --- a/trunk/drivers/lguest/lguest_asm.S +++ b/trunk/drivers/lguest/lguest_asm.S @@ -2,7 +2,9 @@ #include #include #include -#include + +/* FIXME: Once asm/processor-flags.h goes in, include that */ +#define X86_EFLAGS_IF 0x00000200 /* * This is where we begin: we have a magic signature which the launcher looks diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index d90ee145effe..c8dfdb302916 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -493,12 +493,12 @@ async_copy_data(int frombio, struct bio *bio, struct page *page, if (frombio) tx = async_memcpy(page, bio_page, page_offset, b_offset, clen, - ASYNC_TX_DEP_ACK, + ASYNC_TX_DEP_ACK | ASYNC_TX_KMAP_SRC, tx, NULL, NULL); else tx = async_memcpy(bio_page, page, b_offset, page_offset, clen, - ASYNC_TX_DEP_ACK, + ASYNC_TX_DEP_ACK | ASYNC_TX_KMAP_DST, tx, NULL, NULL); } if (clen < len) /* hit end of page */ diff --git a/trunk/drivers/media/common/ir-functions.c b/trunk/drivers/media/common/ir-functions.c index a3292e955aaa..fe447a06e24e 100644 --- a/trunk/drivers/media/common/ir-functions.c +++ b/trunk/drivers/media/common/ir-functions.c @@ -345,8 +345,8 @@ void ir_rc5_timer_end(unsigned long data) } /* Set/reset key-up timer */ - timeout = current_jiffies + - msecs_to_jiffies(ir->rc5_key_timeout); + timeout = current_jiffies + (500 + ir->rc5_key_timeout + * HZ) / 1000; mod_timer(&ir->timer_keyup, timeout); /* Save code for repeat test */ diff --git a/trunk/drivers/media/dvb/ttpci/av7110.c b/trunk/drivers/media/dvb/ttpci/av7110.c index 8178832d14a8..2cee9e3bd29f 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110.c +++ b/trunk/drivers/media/dvb/ttpci/av7110.c @@ -2267,7 +2267,7 @@ static int frontend_init(struct av7110 *av7110) FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd); FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst); FE_FUNC_OVERRIDE(av7110->fe->ops.set_tone, av7110->fe_set_tone, av7110_fe_set_tone); - FE_FUNC_OVERRIDE(av7110->fe->ops.set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage); + FE_FUNC_OVERRIDE(av7110->fe->ops.set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;) FE_FUNC_OVERRIDE(av7110->fe->ops.dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command); FE_FUNC_OVERRIDE(av7110->fe->ops.set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend); diff --git a/trunk/drivers/media/radio/radio-aimslab.c b/trunk/drivers/media/radio/radio-aimslab.c index f0a67e93d7fd..ce940b1b787f 100644 --- a/trunk/drivers/media/radio/radio-aimslab.c +++ b/trunk/drivers/media/radio/radio-aimslab.c @@ -63,7 +63,7 @@ struct rt_device static void sleep_delay(long n) { /* Sleep nicely for 'n' uS */ - int d=n/msecs_to_jiffies(1000); + int d=n/(1000000/HZ); if(!d) udelay(n); else diff --git a/trunk/drivers/media/radio/radio-cadet.c b/trunk/drivers/media/radio/radio-cadet.c index 34e317ced5a3..8cf2e9df5c8a 100644 --- a/trunk/drivers/media/radio/radio-cadet.c +++ b/trunk/drivers/media/radio/radio-cadet.c @@ -329,7 +329,7 @@ cadet_handler(unsigned long data) init_timer(&readtimer); readtimer.function=cadet_handler; readtimer.data=(unsigned long)0; - readtimer.expires=jiffies+msecs_to_jiffies(50); + readtimer.expires=jiffies+(HZ/20); add_timer(&readtimer); } @@ -349,7 +349,7 @@ cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos) init_timer(&readtimer); readtimer.function=cadet_handler; readtimer.data=(unsigned long)0; - readtimer.expires=jiffies+msecs_to_jiffies(50); + readtimer.expires=jiffies+(HZ/20); add_timer(&readtimer); } if(rdsin==rdsout) { diff --git a/trunk/drivers/media/radio/radio-gemtek-pci.c b/trunk/drivers/media/radio/radio-gemtek-pci.c index 99a323131333..4db05b2b1b6e 100644 --- a/trunk/drivers/media/radio/radio-gemtek-pci.c +++ b/trunk/drivers/media/radio/radio-gemtek-pci.c @@ -94,6 +94,7 @@ struct gemtek_pci_card { u32 iobase; u32 length; + u16 model; u32 current_frequency; u8 mute; @@ -412,6 +413,8 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci goto err_pci; } + pci_read_config_word( pci_dev, PCI_SUBSYSTEM_ID, &card->model ); + pci_set_drvdata( pci_dev, card ); if ( (devradio = kmalloc( sizeof( struct video_device ), GFP_KERNEL )) == NULL ) { diff --git a/trunk/drivers/media/video/bt866.c b/trunk/drivers/media/video/bt866.c index b767b098d14b..2e4cf1efdd21 100644 --- a/trunk/drivers/media/video/bt866.c +++ b/trunk/drivers/media/video/bt866.c @@ -257,7 +257,7 @@ static int bt866_write(struct bt866 *encoder, printk(KERN_WARNING "%s: I/O error #%d " "(write 0x%02x/0x%02x)\n", encoder->i2c->name, err, encoder->addr, subaddr); - schedule_timeout_interruptible(msecs_to_jiffies(100)); + schedule_timeout_interruptible(HZ/10); } if (err == 3) { printk(KERN_WARNING "%s: giving up\n", diff --git a/trunk/drivers/media/video/bt8xx/bttv-cards.c b/trunk/drivers/media/video/bt8xx/bttv-cards.c index 387cb2122d4f..2aea09c72093 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-cards.c +++ b/trunk/drivers/media/video/bt8xx/bttv-cards.c @@ -4209,7 +4209,7 @@ static int tea5757_read(struct bttv *btv) bus_low(btv,btv->mbox_clk); udelay(10); - timeout= jiffies + msecs_to_jiffies(1000); + timeout= jiffies + HZ; /* wait for DATA line to go low; error if it doesn't */ while (bus_in(btv,btv->mbox_data) && time_before(jiffies, timeout)) diff --git a/trunk/drivers/media/video/bt8xx/bttv-input.c b/trunk/drivers/media/video/bt8xx/bttv-input.c index 4201552bc3c0..94a13d0ee614 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-input.c +++ b/trunk/drivers/media/video/bt8xx/bttv-input.c @@ -153,7 +153,7 @@ static void bttv_ir_start(struct bttv *btv, struct card_ir *ir) { if (ir->polling) { setup_timer(&ir->timer, bttv_input_timer, (unsigned long)btv); - ir->timer.expires = jiffies + msecs_to_jiffies(1000); + ir->timer.expires = jiffies + HZ; add_timer(&ir->timer); } else if (ir->rc5_gpio) { /* set timer_end for code completion */ diff --git a/trunk/drivers/media/video/bt8xx/bttvp.h b/trunk/drivers/media/video/bt8xx/bttvp.h index 5b25faca1504..bd85f6d0fbe3 100644 --- a/trunk/drivers/media/video/bt8xx/bttvp.h +++ b/trunk/drivers/media/video/bt8xx/bttvp.h @@ -284,8 +284,8 @@ extern int fini_bttv_i2c(struct bttv *btv); #define d2printk if (bttv_debug >= 2) printk #define BTTV_MAX_FBUF 0x208000 -#define BTTV_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ -#define BTTV_FREE_IDLE msecs_to_jiffies(1000) /* one second */ +#define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */ +#define BTTV_FREE_IDLE (HZ) /* one second */ struct bttv_pll_info { diff --git a/trunk/drivers/media/video/c-qcam.c b/trunk/drivers/media/video/c-qcam.c index f76c6a6c3766..925ff17efbbc 100644 --- a/trunk/drivers/media/video/c-qcam.c +++ b/trunk/drivers/media/video/c-qcam.c @@ -95,7 +95,7 @@ static unsigned int qcam_await_ready1(struct qcam_device *qcam, unsigned long oldjiffies = jiffies; unsigned int i; - for (oldjiffies = jiffies; (jiffies - oldjiffies) < msecs_to_jiffies(40); ) + for (oldjiffies = jiffies; (jiffies - oldjiffies) < (HZ/25); ) if (qcam_ready1(qcam) == value) return 0; @@ -120,7 +120,7 @@ static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value) unsigned long oldjiffies = jiffies; unsigned int i; - for (oldjiffies = jiffies; (jiffies - oldjiffies) < msecs_to_jiffies(40); ) + for (oldjiffies = jiffies; (jiffies - oldjiffies) < (HZ/25); ) if (qcam_ready2(qcam) == value) return 0; diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c index 06b233a7b20b..98fa35421bdd 100644 --- a/trunk/drivers/media/video/cx88/cx88-video.c +++ b/trunk/drivers/media/video/cx88/cx88-video.c @@ -1881,14 +1881,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, mutex_unlock(&core->lock); /* start tvaudio thread */ - if (core->tuner_type != TUNER_ABSENT) { + if (core->tuner_type != TUNER_ABSENT) core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio"); - if (IS_ERR(core->kthread)) { - err = PTR_ERR(core->kthread); - printk(KERN_ERR "Failed to create cx88 audio thread, err=%d\n", - err); - } - } return 0; fail_unreg: diff --git a/trunk/drivers/media/video/cx88/cx88.h b/trunk/drivers/media/video/cx88/cx88.h index 809126866a3e..c4f656ec46b0 100644 --- a/trunk/drivers/media/video/cx88/cx88.h +++ b/trunk/drivers/media/video/cx88/cx88.h @@ -259,7 +259,7 @@ struct cx88_subid { #define RESOURCE_VIDEO 2 #define RESOURCE_VBI 4 -#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ +#define BUFFER_TIMEOUT (HZ/2) /* 0.5 seconds */ /* buffer for one video frame */ struct cx88_buffer { diff --git a/trunk/drivers/media/video/ivtv/Kconfig b/trunk/drivers/media/video/ivtv/Kconfig index e43beb2c9cbf..1aaeaa02f158 100644 --- a/trunk/drivers/media/video/ivtv/Kconfig +++ b/trunk/drivers/media/video/ivtv/Kconfig @@ -1,7 +1,6 @@ config VIDEO_IVTV tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL - select I2C_ALGOBIT select FW_LOADER select VIDEO_TUNER select VIDEO_TVEEPROM @@ -17,11 +16,11 @@ config VIDEO_IVTV select VIDEO_UPD64031A select VIDEO_UPD64083 ---help--- - This is a video4linux driver for Conexant cx23416 or cx23415 based + This is a video4linux driver for Conexant cx23416 or cx23416 based PCI personal video recorder devices. This is used in devices such as the Hauppauge PVR-150/250/350/500 - cards. There is a driver homepage at . + cards. To compile this driver as a module, choose M here: the module will be called ivtv. diff --git a/trunk/drivers/media/video/ivtv/ivtv-driver.c b/trunk/drivers/media/video/ivtv/ivtv-driver.c index d73d433a4ff6..4c93466a89e5 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-driver.c +++ b/trunk/drivers/media/video/ivtv/ivtv-driver.c @@ -56,6 +56,7 @@ #include "ivtv-gpio.h" #include "ivtv-yuv.h" +#include #include #include @@ -275,10 +276,9 @@ int ivtv_waitq(wait_queue_head_t *waitq) } /* Generic utility functions */ -int ivtv_msleep_timeout(unsigned int msecs, int intr) +int ivtv_sleep_timeout(int timeout, int intr) { int ret; - int timeout = msecs_to_jiffies(msecs); do { set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); @@ -427,7 +427,7 @@ static void ivtv_process_eeprom(struct ivtv *itv) if (itv->options.newi2c == -1 && tv.has_ir != -1 && tv.has_ir != 2) { itv->options.newi2c = (tv.has_ir & 2) ? 1 : 0; if (itv->options.newi2c) { - IVTV_INFO("Reopen i2c bus for IR-blaster support\n"); + IVTV_INFO("reopen i2c bus for IR-blaster support\n"); exit_ivtv_i2c(itv); init_ivtv_i2c(itv); } @@ -951,7 +951,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev, /* Make sure we've got a place for this card */ if (ivtv_cards_active == IVTV_MAX_CARDS) { - printk(KERN_ERR "ivtv: Maximum number of cards detected (%d)\n", + printk(KERN_ERR "ivtv: Maximum number of cards detected (%d).\n", ivtv_cards_active); spin_unlock(&ivtv_cards_lock); return -ENOMEM; @@ -966,7 +966,9 @@ static int __devinit ivtv_probe(struct pci_dev *dev, itv->dev = dev; itv->num = ivtv_cards_active++; snprintf(itv->name, sizeof(itv->name) - 1, "ivtv%d", itv->num); - IVTV_INFO("Initializing card #%d\n", itv->num); + if (itv->num) { + printk(KERN_INFO "ivtv: ====================== NEXT CARD ======================\n"); + } spin_unlock(&ivtv_cards_lock); @@ -1213,7 +1215,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev, if (itv->has_cx23415) ivtv_set_osd_alpha(itv); - IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name); + IVTV_INFO("Initialized %s, card #%d\n", itv->card_name, itv->num); return 0; @@ -1246,15 +1248,15 @@ static void ivtv_remove(struct pci_dev *pci_dev) { struct ivtv *itv = pci_get_drvdata(pci_dev); - IVTV_DEBUG_INFO("Removing Card #%d\n", itv->num); + IVTV_DEBUG_INFO("Removing Card #%d.\n", itv->num); /* Stop all captures */ - IVTV_DEBUG_INFO("Stopping all streams\n"); + IVTV_DEBUG_INFO(" Stopping all streams.\n"); if (atomic_read(&itv->capturing) > 0) ivtv_stop_all_captures(itv); /* Stop all decoding */ - IVTV_DEBUG_INFO("Stopping decoding\n"); + IVTV_DEBUG_INFO(" Stopping decoding.\n"); if (atomic_read(&itv->decoding) > 0) { int type; @@ -1267,30 +1269,30 @@ static void ivtv_remove(struct pci_dev *pci_dev) } /* Interrupts */ - IVTV_DEBUG_INFO("Disabling interrupts\n"); + IVTV_DEBUG_INFO(" Disabling interrupts.\n"); ivtv_set_irq_mask(itv, 0xffffffff); del_timer_sync(&itv->dma_timer); /* Stop all Work Queues */ - IVTV_DEBUG_INFO("Stop Work Queues\n"); + IVTV_DEBUG_INFO(" Stop Work Queues.\n"); flush_workqueue(itv->irq_work_queues); destroy_workqueue(itv->irq_work_queues); - IVTV_DEBUG_INFO("Stopping Firmware\n"); + IVTV_DEBUG_INFO(" Stopping Firmware.\n"); ivtv_halt_firmware(itv); - IVTV_DEBUG_INFO("Unregistering v4l devices\n"); + IVTV_DEBUG_INFO(" Unregistering v4l devices.\n"); ivtv_streams_cleanup(itv); - IVTV_DEBUG_INFO("Freeing dma resources\n"); + IVTV_DEBUG_INFO(" Freeing dma resources.\n"); ivtv_udma_free(itv); exit_ivtv_i2c(itv); - IVTV_DEBUG_INFO(" Releasing irq\n"); + IVTV_DEBUG_INFO(" Releasing irq.\n"); free_irq(itv->dev->irq, (void *)itv); ivtv_iounmap(itv); - IVTV_DEBUG_INFO(" Releasing mem\n"); + IVTV_DEBUG_INFO(" Releasing mem.\n"); release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); if (itv->has_cx23415) @@ -1311,27 +1313,28 @@ static struct pci_driver ivtv_pci_driver = { static int module_start(void) { - printk(KERN_INFO "ivtv: Start initialization, version %s\n", IVTV_VERSION); + printk(KERN_INFO "ivtv: ==================== START INIT IVTV ====================\n"); + printk(KERN_INFO "ivtv: version %s (" VERMAGIC_STRING ") loading\n", IVTV_VERSION); memset(ivtv_cards, 0, sizeof(ivtv_cards)); /* Validate parameters */ if (ivtv_first_minor < 0 || ivtv_first_minor >= IVTV_MAX_CARDS) { - printk(KERN_ERR "ivtv: Exiting, ivtv_first_minor must be between 0 and %d\n", + printk(KERN_ERR "ivtv: ivtv_first_minor must be between 0 and %d. Exiting...\n", IVTV_MAX_CARDS - 1); return -1; } if (ivtv_debug < 0 || ivtv_debug > 1023) { ivtv_debug = 0; - printk(KERN_INFO "ivtv: Debug value must be >= 0 and <= 1023\n"); + printk(KERN_INFO "ivtv: debug value must be >= 0 and <= 1023!\n"); } if (pci_register_driver(&ivtv_pci_driver)) { printk(KERN_ERR "ivtv: Error detecting PCI card\n"); return -ENODEV; } - printk(KERN_INFO "ivtv: End initialization\n"); + printk(KERN_INFO "ivtv: ==================== END INIT IVTV ====================\n"); return 0; } diff --git a/trunk/drivers/media/video/ivtv/ivtv-driver.h b/trunk/drivers/media/video/ivtv/ivtv-driver.h index 91b588d261ae..6c1a85f1ee1b 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-driver.h +++ b/trunk/drivers/media/video/ivtv/ivtv-driver.h @@ -848,7 +848,7 @@ int ivtv_set_output_mode(struct ivtv *itv, int mode); struct ivtv_stream *ivtv_get_output_stream(struct ivtv *itv); /* Return non-zero if a signal is pending */ -int ivtv_msleep_timeout(unsigned int msecs, int intr); +int ivtv_sleep_timeout(int timeout, int intr); /* Wait on queue, returns -EINTR if interrupted */ int ivtv_waitq(wait_queue_head_t *waitq); diff --git a/trunk/drivers/media/video/ivtv/ivtv-fileops.c b/trunk/drivers/media/video/ivtv/ivtv-fileops.c index 8e97a938398f..ee7e884e9c4f 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-fileops.c +++ b/trunk/drivers/media/video/ivtv/ivtv-fileops.c @@ -218,7 +218,7 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, /* Process pending program info updates and pending VBI data */ ivtv_update_pgm_info(itv); - if (jiffies - itv->dualwatch_jiffies > msecs_to_jiffies(1000)) { + if (jiffies - itv->dualwatch_jiffies > HZ) { itv->dualwatch_jiffies = jiffies; ivtv_dualwatch(itv); } @@ -832,7 +832,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp) if (itv == NULL) { /* Couldn't find a device registered on that minor, shouldn't happen! */ - printk(KERN_WARNING "ivtv: No ivtv device found on minor %d\n", minor); + printk(KERN_WARNING "ivtv: no ivtv device found on minor %d\n", minor); return -ENXIO; } @@ -924,7 +924,7 @@ void ivtv_unmute(struct ivtv *itv) if (atomic_read(&itv->capturing) == 0) ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0); - ivtv_msleep_timeout(100, 0); + ivtv_sleep_timeout(HZ / 10, 0); if (atomic_read(&itv->capturing)) { ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12); diff --git a/trunk/drivers/media/video/ivtv/ivtv-firmware.c b/trunk/drivers/media/video/ivtv/ivtv-firmware.c index d0feabf93080..2b6208a6a108 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-firmware.c +++ b/trunk/drivers/media/video/ivtv/ivtv-firmware.c @@ -36,7 +36,7 @@ #define IVTV_CMD_SPU_STOP 0x00000001 #define IVTV_CMD_SDRAM_PRECHARGE_INIT 0x0000001A #define IVTV_CMD_SDRAM_REFRESH_INIT 0x80000640 -#define IVTV_SDRAM_SLEEPTIME 600 +#define IVTV_SDRAM_SLEEPTIME (60 * HZ / 100) /* 600 ms */ #define IVTV_DECODE_INIT_MPEG_FILENAME "v4l-cx2341x-init.mpg" #define IVTV_DECODE_INIT_MPEG_SIZE (152*1024) @@ -61,7 +61,7 @@ static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv the wrong file was sometimes loaded. So we check filesizes to see if at least the right-sized file was loaded. If not, then we retry. */ - IVTV_INFO("Retry: file loaded was not %s (expected size %ld, got %zd)\n", fn, size, fw->size); + IVTV_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n", fn, size, fw->size); release_firmware(fw); retries--; goto retry; @@ -73,11 +73,11 @@ static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv src++; } release_firmware(fw); - IVTV_INFO("Loaded %s firmware (%zd bytes)\n", fn, fw->size); + IVTV_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size); return size; } - IVTV_ERR("Unable to open firmware %s (must be %ld bytes)\n", fn, size); - IVTV_ERR("Did you put the firmware in the hotplug firmware directory?\n"); + IVTV_ERR("unable to open firmware %s (must be %ld bytes)\n", fn, size); + IVTV_ERR("did you put the firmware in the hotplug firmware directory?\n"); return -ENOMEM; } @@ -89,7 +89,7 @@ void ivtv_halt_firmware(struct ivtv *itv) if (itv->enc_mbox.mbox) ivtv_vapi(itv, CX2341X_ENC_HALT_FW, 0); - ivtv_msleep_timeout(10, 0); + ivtv_sleep_timeout(HZ / 100, 0); itv->enc_mbox.mbox = itv->dec_mbox.mbox = NULL; IVTV_DEBUG_INFO("Stopping VDM\n"); @@ -113,7 +113,7 @@ void ivtv_halt_firmware(struct ivtv *itv) IVTV_DEBUG_INFO("Stopping SPU\n"); write_reg(IVTV_CMD_SPU_STOP, IVTV_REG_SPU); - ivtv_msleep_timeout(10, 0); + ivtv_sleep_timeout(HZ / 100, 0); IVTV_DEBUG_INFO("init Encoder SDRAM pre-charge\n"); write_reg(IVTV_CMD_SDRAM_PRECHARGE_INIT, IVTV_REG_ENC_SDRAM_PRECHARGE); @@ -129,8 +129,9 @@ void ivtv_halt_firmware(struct ivtv *itv) write_reg(IVTV_CMD_SDRAM_REFRESH_INIT, IVTV_REG_DEC_SDRAM_REFRESH); } - IVTV_DEBUG_INFO("Sleeping for %dms\n", IVTV_SDRAM_SLEEPTIME); - ivtv_msleep_timeout(IVTV_SDRAM_SLEEPTIME, 0); + IVTV_DEBUG_INFO("Sleeping for %dms (600 recommended)\n", + (int)(IVTV_SDRAM_SLEEPTIME * 1000 / HZ)); + ivtv_sleep_timeout(IVTV_SDRAM_SLEEPTIME, 0); } void ivtv_firmware_versions(struct ivtv *itv) @@ -203,12 +204,12 @@ int ivtv_firmware_init(struct ivtv *itv) /* start firmware */ write_reg(read_reg(IVTV_REG_SPU) & IVTV_MASK_SPU_ENABLE, IVTV_REG_SPU); - ivtv_msleep_timeout(100, 0); + ivtv_sleep_timeout(HZ / 10, 0); if (itv->has_cx23415) write_reg(read_reg(IVTV_REG_VPU) & IVTV_MASK_VPU_ENABLE15, IVTV_REG_VPU); else write_reg(read_reg(IVTV_REG_VPU) & IVTV_MASK_VPU_ENABLE16, IVTV_REG_VPU); - ivtv_msleep_timeout(100, 0); + ivtv_sleep_timeout(HZ / 10, 0); /* find mailboxes and ping firmware */ itv->enc_mbox.mbox = ivtv_search_mailbox(itv->enc_mem, IVTV_ENCODER_SIZE); @@ -263,7 +264,7 @@ void ivtv_init_mpeg_decoder(struct ivtv *itv) IVTV_DECODE_INIT_MPEG_FILENAME); } else { ivtv_vapi(itv, CX2341X_DEC_SCHED_DMA_FROM_HOST, 3, 0, readbytes, 0); - ivtv_msleep_timeout(100, 0); + ivtv_sleep_timeout(HZ / 10, 0); } ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 4, 0, 0, 0, 1); } diff --git a/trunk/drivers/media/video/ivtv/ivtv-gpio.c b/trunk/drivers/media/video/ivtv/ivtv-gpio.c index 6a5a7aa66976..676418cbaaad 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-gpio.c +++ b/trunk/drivers/media/video/ivtv/ivtv-gpio.c @@ -130,7 +130,7 @@ int ivtv_reset_tuner_gpio(enum v4l2_tuner_type mode, void *priv, int ptr) if (itv->card->type != IVTV_CARD_PG600V2 || itv->options.tuner != TUNER_XCEIVE_XC3028) return -EINVAL; - IVTV_INFO("Resetting tuner\n"); + IVTV_INFO("Resetting tuner.\n"); curout = read_reg(IVTV_REG_GPIO_OUT); curdir = read_reg(IVTV_REG_GPIO_DIR); curdir |= (1 << 12); /* GPIO bit 12 */ diff --git a/trunk/drivers/media/video/ivtv/ivtv-i2c.c b/trunk/drivers/media/video/ivtv/ivtv-i2c.c index b3557435456d..50624c6a62a5 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-i2c.c +++ b/trunk/drivers/media/video/ivtv/ivtv-i2c.c @@ -144,7 +144,7 @@ static int attach_inform(struct i2c_client *client) } } if (i == I2C_CLIENTS_MAX) { - IVTV_ERR("Insufficient room for new I2C client\n"); + IVTV_ERR("insufficient room for new I2C client!\n"); } return 0; } @@ -236,7 +236,7 @@ static int ivtv_ack(struct ivtv *itv) int ret = 0; if (ivtv_getscl(itv) == 1) { - IVTV_DEBUG_HI_I2C("SCL was high starting an ack\n"); + IVTV_DEBUG_I2C("SCL was high starting an ack\n"); ivtv_setscl(itv, 0); if (!ivtv_waitscl(itv, 0)) { IVTV_DEBUG_I2C("Could not set SCL low starting an ack\n"); @@ -263,7 +263,7 @@ static int ivtv_sendbyte(struct ivtv *itv, unsigned char byte) { int i, bit; - IVTV_DEBUG_HI_I2C("write %x\n",byte); + IVTV_DEBUG_I2C("write %x\n",byte); for (i = 0; i < 8; ++i, byte<<=1) { ivtv_setscl(itv, 0); if (!ivtv_waitscl(itv, 0)) { @@ -318,7 +318,7 @@ static int ivtv_readbyte(struct ivtv *itv, unsigned char *byte, int nack) ivtv_scldelay(itv); ivtv_setscl(itv, 0); ivtv_scldelay(itv); - IVTV_DEBUG_HI_I2C("read %x\n",*byte); + IVTV_DEBUG_I2C("read %x\n",*byte); return 0; } @@ -330,7 +330,7 @@ static int ivtv_start(struct ivtv *itv) sda = ivtv_getsda(itv); if (sda != 1) { - IVTV_DEBUG_HI_I2C("SDA was low at start\n"); + IVTV_DEBUG_I2C("SDA was low at start\n"); ivtv_setsda(itv, 1); if (!ivtv_waitsda(itv, 1)) { IVTV_DEBUG_I2C("SDA stuck low\n"); @@ -355,7 +355,7 @@ static int ivtv_stop(struct ivtv *itv) int i; if (ivtv_getscl(itv) != 0) { - IVTV_DEBUG_HI_I2C("SCL not low when stopping\n"); + IVTV_DEBUG_I2C("SCL not low when stopping\n"); ivtv_setscl(itv, 0); if (!ivtv_waitscl(itv, 0)) { IVTV_DEBUG_I2C("SCL could not be set low\n"); @@ -569,7 +569,7 @@ int ivtv_call_i2c_client(struct ivtv *itv, int addr, unsigned int cmd, void *arg } } if (cmd != VIDIOC_G_CHIP_IDENT) - IVTV_ERR("i2c addr 0x%02x not found for command 0x%x\n", addr, cmd); + IVTV_ERR("i2c addr 0x%02x not found for command 0x%x!\n", addr, cmd); return -ENODEV; } @@ -640,7 +640,7 @@ int ivtv_i2c_hw(struct ivtv *itv, u32 hw, unsigned int cmd, void *arg) addr = ivtv_i2c_hw_addr(itv, hw); if (addr < 0) { - IVTV_ERR("i2c hardware 0x%08x (%s) not found for command 0x%x\n", + IVTV_ERR("i2c hardware 0x%08x (%s) not found for command 0x%x!\n", hw, ivtv_i2c_hw_name(hw), cmd); return addr; } @@ -655,7 +655,7 @@ int ivtv_i2c_id(struct ivtv *itv, u32 id, unsigned int cmd, void *arg) addr = ivtv_i2c_id_addr(itv, id); if (addr < 0) { if (cmd != VIDIOC_G_CHIP_IDENT) - IVTV_ERR("i2c ID 0x%08x (%s) not found for command 0x%x\n", + IVTV_ERR("i2c ID 0x%08x (%s) not found for command 0x%x!\n", id, ivtv_i2c_id_name(id), cmd); return addr; } @@ -696,7 +696,7 @@ int ivtv_upd64083(struct ivtv *itv, unsigned int cmd, void *arg) void ivtv_call_i2c_clients(struct ivtv *itv, unsigned int cmd, void *arg) { if (itv->i2c_adap.algo == NULL) { - IVTV_ERR("Adapter is not set"); + IVTV_ERR("adapter is not set"); return; } i2c_clients_command(&itv->i2c_adap, cmd, arg); diff --git a/trunk/drivers/media/video/ivtv/ivtv-irq.c b/trunk/drivers/media/video/ivtv/ivtv-irq.c index fcd6e7f5f121..1a3ee464a826 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-irq.c +++ b/trunk/drivers/media/video/ivtv/ivtv-irq.c @@ -403,11 +403,6 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) /* Mark last buffer size for Interrupt flag */ s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000); - if (s->type == IVTV_ENC_STREAM_TYPE_VBI) - set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); - else - clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); - if (ivtv_use_pio(s)) { for (i = 0; i < s->SG_length; i++) { s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src); @@ -425,7 +420,7 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER); set_bit(IVTV_F_I_DMA, &itv->i_flags); itv->cur_dma_stream = s->type; - itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); + itv->dma_timer.expires = jiffies + HZ / 10; add_timer(&itv->dma_timer); } } @@ -442,7 +437,7 @@ static void ivtv_dma_dec_start(struct ivtv_stream *s) write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); set_bit(IVTV_F_I_DMA, &itv->i_flags); itv->cur_dma_stream = s->type; - itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); + itv->dma_timer.expires = jiffies + HZ / 10; add_timer(&itv->dma_timer); } @@ -602,6 +597,7 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv) data[0], data[1], data[2]); return; } + clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); s = &itv->streams[ivtv_stream_map[data[0]]]; if (!stream_enc_dma_append(s, data)) { set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags); @@ -638,6 +634,7 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv) then start a DMA request for just the VBI data. */ if (!stream_enc_dma_append(s, data) && !test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) { + set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags); } } diff --git a/trunk/drivers/media/video/ivtv/ivtv-mailbox.c b/trunk/drivers/media/video/ivtv/ivtv-mailbox.c index 814a673712b3..6ae42a3b03cc 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-mailbox.c +++ b/trunk/drivers/media/video/ivtv/ivtv-mailbox.c @@ -37,7 +37,6 @@ #define API_RESULT (1 << 1) /* Allow 1 second for this cmd to end */ #define API_FAST_RESULT (3 << 1) /* Allow 0.1 second for this cmd to end */ #define API_DMA (1 << 3) /* DMA mailbox, has special handling */ -#define API_HIGH_VOL (1 << 5) /* High volume command (i.e. called during encoding or decoding) */ #define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */ #define API_NO_WAIT_RES (1 << 5) /* Command may not wait for the result */ @@ -78,11 +77,11 @@ static const struct ivtv_api_info api_info[256] = { API_ENTRY(CX2341X_ENC_SET_DMA_BLOCK_SIZE, API_CACHE), API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_10, API_FAST_RESULT), API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_9, API_FAST_RESULT), - API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST, API_DMA | API_HIGH_VOL), + API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST, API_DMA), API_ENTRY(CX2341X_ENC_INITIALIZE_INPUT, API_RESULT), API_ENTRY(CX2341X_ENC_SET_FRAME_DROP_RATE, API_CACHE), API_ENTRY(CX2341X_ENC_PAUSE_ENCODER, API_RESULT), - API_ENTRY(CX2341X_ENC_REFRESH_INPUT, API_NO_WAIT_MB | API_HIGH_VOL), + API_ENTRY(CX2341X_ENC_REFRESH_INPUT, API_NO_WAIT_MB), API_ENTRY(CX2341X_ENC_SET_COPYRIGHT, API_CACHE), API_ENTRY(CX2341X_ENC_SET_EVENT_NOTIFICATION, API_RESULT), API_ENTRY(CX2341X_ENC_SET_NUM_VSYNC_LINES, API_CACHE), @@ -103,7 +102,7 @@ static const struct ivtv_api_info api_info[256] = { API_ENTRY(CX2341X_DEC_SET_DMA_BLOCK_SIZE, API_CACHE), API_ENTRY(CX2341X_DEC_GET_XFER_INFO, API_FAST_RESULT), API_ENTRY(CX2341X_DEC_GET_DMA_STATUS, API_FAST_RESULT), - API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST, API_DMA | API_HIGH_VOL), + API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST, API_DMA), API_ENTRY(CX2341X_DEC_PAUSE_PLAYBACK, API_RESULT), API_ENTRY(CX2341X_DEC_HALT_FW, API_FAST_RESULT), API_ENTRY(CX2341X_DEC_SET_STANDARD, API_CACHE), @@ -176,9 +175,9 @@ static int get_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int f /* Sleep before a retry, if not atomic */ if (!(flags & API_NO_WAIT_MB)) { - if (jiffies - then > msecs_to_jiffies(10*retries)) + if (jiffies - then > retries * HZ / 100) break; - ivtv_msleep_timeout(10, 0); + ivtv_sleep_timeout(HZ / 100, 0); } } return -ENODEV; @@ -213,7 +212,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) { struct ivtv_mailbox_data *mbdata = (cmd >= 128) ? &itv->enc_mbox : &itv->dec_mbox; volatile struct ivtv_mailbox __iomem *mbox; - int api_timeout = msecs_to_jiffies(1000); + int api_timeout = HZ; int flags, mb, i; unsigned long then; @@ -228,12 +227,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) return -EINVAL; } - if (api_info[cmd].flags & API_HIGH_VOL) { - IVTV_DEBUG_HI_API("API Call: %s\n", api_info[cmd].name); - } - else { - IVTV_DEBUG_API("API Call: %s\n", api_info[cmd].name); - } + IVTV_DEBUG_API("API Call: %s\n", api_info[cmd].name); /* clear possibly uninitialized part of data array */ for (i = args; i < CX2341X_MBOX_MAX_DATA; i++) @@ -243,7 +237,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) data, then just return 0 as there is no need to issue this command again. Just an optimization to prevent unnecessary use of mailboxes. */ if (itv->api_cache[cmd].last_jiffies && - jiffies - itv->api_cache[cmd].last_jiffies < msecs_to_jiffies(1800000) && + jiffies - itv->api_cache[cmd].last_jiffies < HZ * 1800 && !memcmp(data, itv->api_cache[cmd].data, sizeof(itv->api_cache[cmd].data))) { itv->api_cache[cmd].last_jiffies = jiffies; return 0; @@ -268,7 +262,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) } if ((flags & API_FAST_RESULT) == API_FAST_RESULT) - api_timeout = msecs_to_jiffies(100); + api_timeout = HZ / 10; mb = get_mailbox(itv, mbdata, flags); if (mb < 0) { @@ -301,12 +295,11 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) if (flags & API_NO_WAIT_RES) mdelay(1); else - ivtv_msleep_timeout(10, 0); + ivtv_sleep_timeout(HZ / 100, 0); } - if (jiffies - then > msecs_to_jiffies(100)) - IVTV_DEBUG_WARN("%s took %u jiffies\n", - api_info[cmd].name, - jiffies_to_msecs(jiffies - then)); + if (jiffies - then > HZ / 10) + IVTV_DEBUG_WARN("%s took %lu jiffies (%d per HZ)\n", + api_info[cmd].name, jiffies - then, HZ); for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++) data[i] = readl(&mbox->data[i]); diff --git a/trunk/drivers/media/video/ivtv/ivtv-streams.c b/trunk/drivers/media/video/ivtv/ivtv-streams.c index 322b347b67c2..287117187499 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-streams.c +++ b/trunk/drivers/media/video/ivtv/ivtv-streams.c @@ -565,7 +565,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) /* Initialize Digitizer for Capture */ ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0); - ivtv_msleep_timeout(100, 0); + ivtv_sleep_timeout(HZ / 10, 0); } /* begin_capture */ @@ -781,9 +781,8 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) set_current_state(TASK_INTERRUPTIBLE); /* wait 2s for EOS interrupt */ - while (!test_bit(IVTV_F_I_EOS, &itv->i_flags) && - jiffies < then + msecs_to_jiffies (2000)) { - schedule_timeout(msecs_to_jiffies(10)); + while (!test_bit(IVTV_F_I_EOS, &itv->i_flags) && jiffies < then + 2 * HZ) { + schedule_timeout(HZ / 100); } /* To convert jiffies to ms, we must multiply by 1000 @@ -822,8 +821,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) } else if (read_reg(IVTV_REG_DMASTATUS) & 0x02) { break; } - } while (!ivtv_msleep_timeout(10, 1) && - then + msecs_to_jiffies(2000) > jiffies); + } while (!ivtv_sleep_timeout(HZ / 100, 1) && then + HZ * 2 > jiffies); set_current_state(TASK_RUNNING); remove_wait_queue(&s->waitq, &wait); @@ -894,7 +892,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) break; tmp = data[3]; } - if (ivtv_msleep_timeout(100, 1)) + if (ivtv_sleep_timeout(HZ/10, 1)) break; } } diff --git a/trunk/drivers/media/video/saa5249.c b/trunk/drivers/media/video/saa5249.c index 17f1e2e9a66b..f2a2f34cd626 100644 --- a/trunk/drivers/media/video/saa5249.c +++ b/trunk/drivers/media/video/saa5249.c @@ -86,9 +86,9 @@ static const int disp_modes[8][3] = -#define PAGE_WAIT msecs_to_jiffies(300) /* Time between requesting page and */ +#define PAGE_WAIT (300*HZ/1000) /* Time between requesting page and */ /* checking status bits */ -#define PGBUF_EXPIRE msecs_to_jiffies(15000) /* Time to wait before retransmitting */ +#define PGBUF_EXPIRE (15*HZ) /* Time to wait before retransmitting */ /* page regardless of infobits */ typedef struct { u8 pgbuf[VTX_VIRTUALSIZE]; /* Page-buffer */ @@ -115,8 +115,8 @@ struct saa5249_device #define CCTWR 34 /* I²C write/read-address of vtx-chip */ #define CCTRD 35 #define NOACK_REPEAT 10 /* Retry access this many times on failure */ -#define CLEAR_DELAY msecs_to_jiffies(50) /* Time required to clear a page */ -#define READY_TIMEOUT msecs_to_jiffies(30) /* Time to wait for ready signal of I2C-bus interface */ +#define CLEAR_DELAY (HZ/20) /* Time required to clear a page */ +#define READY_TIMEOUT (30*HZ/1000) /* Time to wait for ready signal of I²C-bus interface */ #define INIT_DELAY 500 /* Time in usec to wait at initialization of CEA interface */ #define START_DELAY 10 /* Time in usec to wait before starting write-cycle (CEA) */ diff --git a/trunk/drivers/media/video/saa7110.c b/trunk/drivers/media/video/saa7110.c index 061134a7ba9f..676b9970eb2e 100644 --- a/trunk/drivers/media/video/saa7110.c +++ b/trunk/drivers/media/video/saa7110.c @@ -208,7 +208,7 @@ determine_norm (struct i2c_client *client) saa7110_write_block(client, initseq, sizeof(initseq)); saa7110_selmux(client, decoder->input); prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(250)); + schedule_timeout(HZ/4); finish_wait(&decoder->wq, &wait); status = saa7110_read(client); if (status & 0x40) { @@ -249,7 +249,7 @@ determine_norm (struct i2c_client *client) //saa7110_write(client,0x2E,0x9A); prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(250)); + schedule_timeout(HZ/4); finish_wait(&decoder->wq, &wait); status = saa7110_read(client); diff --git a/trunk/drivers/media/video/saa7134/saa7134.h b/trunk/drivers/media/video/saa7134/saa7134.h index 346255468dad..d32a856192d7 100644 --- a/trunk/drivers/media/video/saa7134/saa7134.h +++ b/trunk/drivers/media/video/saa7134/saa7134.h @@ -314,7 +314,7 @@ struct saa7134_board { #define INTERLACE_ON 1 #define INTERLACE_OFF 2 -#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ +#define BUFFER_TIMEOUT (HZ/2) /* 0.5 seconds */ struct saa7134_dev; struct saa7134_dma; diff --git a/trunk/drivers/media/video/tvaudio.c b/trunk/drivers/media/video/tvaudio.c index cffb011590e3..9da338dc4f3b 100644 --- a/trunk/drivers/media/video/tvaudio.c +++ b/trunk/drivers/media/video/tvaudio.c @@ -290,7 +290,7 @@ static int chip_thread(void *data) desc->checkmode(chip); /* schedule next check */ - mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000)); + mod_timer(&chip->wt, jiffies+2*HZ); } v4l_dbg(1, debug, &chip->c, "%s: thread exiting\n", chip->c.name); @@ -1770,7 +1770,7 @@ static int chip_command(struct i2c_client *client, desc->setmode(chip,VIDEO_SOUND_MONO); if (chip->prevmode != VIDEO_SOUND_MONO) chip->prevmode = -1; /* reset previous mode */ - mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000)); + mod_timer(&chip->wt, jiffies+2*HZ); /* the thread will call checkmode() later */ } break; diff --git a/trunk/drivers/media/video/v4l2-common.c b/trunk/drivers/media/video/v4l2-common.c index d2915d3530ea..13ee550d3215 100644 --- a/trunk/drivers/media/video/v4l2-common.c +++ b/trunk/drivers/media/video/v4l2-common.c @@ -939,25 +939,16 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc When no more controls are available 0 is returned. */ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) { - u32 ctrl_class = V4L2_CTRL_ID2CLASS(id); + u32 ctrl_class; const u32 *pctrl; + /* if no query is desired, then just return the control ID */ + if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0) + return id; if (ctrl_classes == NULL) return 0; - - /* if no query is desired, then check if the ID is part of ctrl_classes */ - if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0) { - /* find class */ - while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) != ctrl_class) - ctrl_classes++; - if (*ctrl_classes == NULL) - return 0; - pctrl = *ctrl_classes; - /* find control ID */ - while (*pctrl && *pctrl != id) pctrl++; - return *pctrl ? id : 0; - } id &= V4L2_CTRL_ID_MASK; + ctrl_class = V4L2_CTRL_ID2CLASS(id); id++; /* select next control */ /* find first class that matches (or is greater than) the class of the ID */ diff --git a/trunk/drivers/media/video/vino.c b/trunk/drivers/media/video/vino.c index a0c1647a2ba4..e94a9a6036f5 100644 --- a/trunk/drivers/media/video/vino.c +++ b/trunk/drivers/media/video/vino.c @@ -2080,7 +2080,7 @@ static int vino_wait_for_frame(struct vino_channel_settings *vcs) /* to ensure that schedule_timeout will return immediately * if VINO interrupt was triggered meanwhile */ - schedule_timeout_interruptible(msecs_to_jiffies(100)); + schedule_timeout_interruptible(HZ / 10); if (signal_pending(current)) err = -EINTR; diff --git a/trunk/drivers/media/video/wm8739.c b/trunk/drivers/media/video/wm8739.c index 1bf4cbec6a87..8f6741a28a47 100644 --- a/trunk/drivers/media/video/wm8739.c +++ b/trunk/drivers/media/video/wm8739.c @@ -321,14 +321,12 @@ static int wm8739_probe(struct i2c_adapter *adapter) static int wm8739_detach(struct i2c_client *client) { - struct wm8739_state *state = i2c_get_clientdata(client); int err; err = i2c_detach_client(client); if (err) return err; - kfree(state); kfree(client); return 0; } diff --git a/trunk/drivers/media/video/wm8775.c b/trunk/drivers/media/video/wm8775.c index 9f7e894ef962..4df5d30d4d09 100644 --- a/trunk/drivers/media/video/wm8775.c +++ b/trunk/drivers/media/video/wm8775.c @@ -222,14 +222,12 @@ static int wm8775_probe(struct i2c_adapter *adapter) static int wm8775_detach(struct i2c_client *client) { - struct wm8775_state *state = i2c_get_clientdata(client); int err; err = i2c_detach_client(client); if (err) { return err; } - kfree(state); kfree(client); return 0; diff --git a/trunk/drivers/net/mac89x0.c b/trunk/drivers/net/mac89x0.c index 62c1c6262feb..26a3b45a4a34 100644 --- a/trunk/drivers/net/mac89x0.c +++ b/trunk/drivers/net/mac89x0.c @@ -608,7 +608,7 @@ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "CS89[02]0 debug level (0-5)"); MODULE_LICENSE("GPL"); -int __init +int init_module(void) { net_debug = debug; diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index 13f08a390e1f..a2f32151559e 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -692,7 +692,6 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) { struct sky2_port *sky2 = netdev_priv(hw->dev[port]); u16 reg; - u32 rx_reg; int i; const u8 *addr = hw->dev[port]->dev_addr; @@ -769,11 +768,11 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) /* Configure Rx MAC FIFO */ sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); - rx_reg = GMF_OPER_ON | GMF_RX_F_FL_ON; + reg = GMF_OPER_ON | GMF_RX_F_FL_ON; if (hw->chip_id == CHIP_ID_YUKON_EX) - rx_reg |= GMF_RX_OVER_ON; + reg |= GMF_RX_OVER_ON; - sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg); + sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), reg); /* Flush Rx MAC FIFO on any flow control or error */ sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); diff --git a/trunk/drivers/net/sunvnet.c b/trunk/drivers/net/sunvnet.c index 61f98251feab..b801e3b3a11a 100644 --- a/trunk/drivers/net/sunvnet.c +++ b/trunk/drivers/net/sunvnet.c @@ -459,22 +459,6 @@ static int vnet_nack(struct vnet_port *port, void *msgbuf) return 0; } -static int handle_mcast(struct vnet_port *port, void *msgbuf) -{ - struct vio_net_mcast_info *pkt = msgbuf; - - if (pkt->tag.stype != VIO_SUBTYPE_ACK) - printk(KERN_ERR PFX "%s: Got unexpected MCAST reply " - "[%02x:%02x:%04x:%08x]\n", - port->vp->dev->name, - pkt->tag.type, - pkt->tag.stype, - pkt->tag.stype_env, - pkt->tag.sid); - - return 0; -} - static void maybe_tx_wakeup(struct vnet *vp) { struct net_device *dev = vp->dev; @@ -560,10 +544,7 @@ static void vnet_event(void *arg, int event) err = vnet_nack(port, &msgbuf); } } else if (msgbuf.tag.type == VIO_TYPE_CTRL) { - if (msgbuf.tag.stype_env == VNET_MCAST_INFO) - err = handle_mcast(port, &msgbuf); - else - err = vio_control_pkt_engine(vio, &msgbuf); + err = vio_control_pkt_engine(vio, &msgbuf); if (err) break; } else { @@ -750,122 +731,9 @@ static int vnet_close(struct net_device *dev) return 0; } -static struct vnet_mcast_entry *__vnet_mc_find(struct vnet *vp, u8 *addr) -{ - struct vnet_mcast_entry *m; - - for (m = vp->mcast_list; m; m = m->next) { - if (!memcmp(m->addr, addr, ETH_ALEN)) - return m; - } - return NULL; -} - -static void __update_mc_list(struct vnet *vp, struct net_device *dev) -{ - struct dev_addr_list *p; - - for (p = dev->mc_list; p; p = p->next) { - struct vnet_mcast_entry *m; - - m = __vnet_mc_find(vp, p->dmi_addr); - if (m) { - m->hit = 1; - continue; - } - - if (!m) { - m = kzalloc(sizeof(*m), GFP_ATOMIC); - if (!m) - continue; - memcpy(m->addr, p->dmi_addr, ETH_ALEN); - m->hit = 1; - - m->next = vp->mcast_list; - vp->mcast_list = m; - } - } -} - -static void __send_mc_list(struct vnet *vp, struct vnet_port *port) -{ - struct vio_net_mcast_info info; - struct vnet_mcast_entry *m, **pp; - int n_addrs; - - memset(&info, 0, sizeof(info)); - - info.tag.type = VIO_TYPE_CTRL; - info.tag.stype = VIO_SUBTYPE_INFO; - info.tag.stype_env = VNET_MCAST_INFO; - info.tag.sid = vio_send_sid(&port->vio); - info.set = 1; - - n_addrs = 0; - for (m = vp->mcast_list; m; m = m->next) { - if (m->sent) - continue; - m->sent = 1; - memcpy(&info.mcast_addr[n_addrs * ETH_ALEN], - m->addr, ETH_ALEN); - if (++n_addrs == VNET_NUM_MCAST) { - info.count = n_addrs; - - (void) vio_ldc_send(&port->vio, &info, - sizeof(info)); - n_addrs = 0; - } - } - if (n_addrs) { - info.count = n_addrs; - (void) vio_ldc_send(&port->vio, &info, sizeof(info)); - } - - info.set = 0; - - n_addrs = 0; - pp = &vp->mcast_list; - while ((m = *pp) != NULL) { - if (m->hit) { - m->hit = 0; - pp = &m->next; - continue; - } - - memcpy(&info.mcast_addr[n_addrs * ETH_ALEN], - m->addr, ETH_ALEN); - if (++n_addrs == VNET_NUM_MCAST) { - info.count = n_addrs; - (void) vio_ldc_send(&port->vio, &info, - sizeof(info)); - n_addrs = 0; - } - - *pp = m->next; - kfree(m); - } - if (n_addrs) { - info.count = n_addrs; - (void) vio_ldc_send(&port->vio, &info, sizeof(info)); - } -} - static void vnet_set_rx_mode(struct net_device *dev) { - struct vnet *vp = netdev_priv(dev); - struct vnet_port *port; - unsigned long flags; - - spin_lock_irqsave(&vp->lock, flags); - if (!list_empty(&vp->port_list)) { - port = list_entry(vp->port_list.next, struct vnet_port, list); - - if (port->switch_port) { - __update_mc_list(vp, dev); - __send_mc_list(vp, port); - } - } - spin_unlock_irqrestore(&vp->lock, flags); + /* XXX Implement multicast support XXX */ } static int vnet_change_mtu(struct net_device *dev, int new_mtu) @@ -1202,7 +1070,6 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev, switch_port = 0; if (mdesc_get_property(hp, vdev->mp, "switch-port", NULL) != NULL) switch_port = 1; - port->switch_port = switch_port; spin_lock_irqsave(&vp->lock, flags); if (switch_port) @@ -1269,7 +1136,7 @@ static struct vio_device_id vnet_port_match[] = { }, {}, }; -MODULE_DEVICE_TABLE(vio, vnet_port_match); +MODULE_DEVICE_TABLE(vio, vnet_match); static struct vio_driver vnet_port_driver = { .id_table = vnet_port_match, diff --git a/trunk/drivers/net/sunvnet.h b/trunk/drivers/net/sunvnet.h index d347a5bf24b0..7d3a0cac727b 100644 --- a/trunk/drivers/net/sunvnet.h +++ b/trunk/drivers/net/sunvnet.h @@ -30,8 +30,6 @@ struct vnet_port { struct hlist_node hash; u8 raddr[ETH_ALEN]; - u8 switch_port; - u8 __pad; struct vnet *vp; @@ -55,13 +53,6 @@ static inline unsigned int vnet_hashfn(u8 *mac) return val & (VNET_PORT_HASH_MASK); } -struct vnet_mcast_entry { - u8 addr[ETH_ALEN]; - u8 sent; - u8 hit; - struct vnet_mcast_entry *next; -}; - struct vnet { /* Protects port_list and port_hash. */ spinlock_t lock; @@ -74,8 +65,6 @@ struct vnet { struct hlist_head port_hash[VNET_PORT_HASH_SIZE]; - struct vnet_mcast_entry *mcast_list; - struct list_head list; u64 local_mac; }; diff --git a/trunk/drivers/of/Kconfig b/trunk/drivers/of/Kconfig deleted file mode 100644 index c03072b12f42..000000000000 --- a/trunk/drivers/of/Kconfig +++ /dev/null @@ -1,3 +0,0 @@ -config OF_DEVICE - def_bool y - depends on OF && (SPARC || PPC_OF) diff --git a/trunk/drivers/of/Makefile b/trunk/drivers/of/Makefile deleted file mode 100644 index ab9be5d5255b..000000000000 --- a/trunk/drivers/of/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-y = base.o -obj-$(CONFIG_OF_DEVICE) += device.o platform.o diff --git a/trunk/drivers/of/base.c b/trunk/drivers/of/base.c deleted file mode 100644 index 9377f3bc410a..000000000000 --- a/trunk/drivers/of/base.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Procedures for creating, accessing and interpreting the device tree. - * - * Paul Mackerras August 1996. - * Copyright (C) 1996-2005 Paul Mackerras. - * - * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. - * {engebret|bergner}@us.ibm.com - * - * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net - * - * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include -#include -#include - -struct device_node *allnodes; - -/* use when traversing tree through the allnext, child, sibling, - * or parent members of struct device_node. - */ -DEFINE_RWLOCK(devtree_lock); - -int of_n_addr_cells(struct device_node *np) -{ - const int *ip; - - do { - if (np->parent) - np = np->parent; - ip = of_get_property(np, "#address-cells", NULL); - if (ip) - return *ip; - } while (np->parent); - /* No #address-cells property for the root node */ - return OF_ROOT_NODE_ADDR_CELLS_DEFAULT; -} -EXPORT_SYMBOL(of_n_addr_cells); - -int of_n_size_cells(struct device_node *np) -{ - const int *ip; - - do { - if (np->parent) - np = np->parent; - ip = of_get_property(np, "#size-cells", NULL); - if (ip) - return *ip; - } while (np->parent); - /* No #size-cells property for the root node */ - return OF_ROOT_NODE_SIZE_CELLS_DEFAULT; -} -EXPORT_SYMBOL(of_n_size_cells); - -struct property *of_find_property(const struct device_node *np, - const char *name, - int *lenp) -{ - struct property *pp; - - read_lock(&devtree_lock); - for (pp = np->properties; pp != 0; pp = pp->next) { - if (of_prop_cmp(pp->name, name) == 0) { - if (lenp != 0) - *lenp = pp->length; - break; - } - } - read_unlock(&devtree_lock); - - return pp; -} -EXPORT_SYMBOL(of_find_property); - -/* - * Find a property with a given name for a given node - * and return the value. - */ -const void *of_get_property(const struct device_node *np, const char *name, - int *lenp) -{ - struct property *pp = of_find_property(np, name, lenp); - - return pp ? pp->value : NULL; -} -EXPORT_SYMBOL(of_get_property); - -/** Checks if the given "compat" string matches one of the strings in - * the device's "compatible" property - */ -int of_device_is_compatible(const struct device_node *device, - const char *compat) -{ - const char* cp; - int cplen, l; - - cp = of_get_property(device, "compatible", &cplen); - if (cp == NULL) - return 0; - while (cplen > 0) { - if (of_compat_cmp(cp, compat, strlen(compat)) == 0) - return 1; - l = strlen(cp) + 1; - cp += l; - cplen -= l; - } - - return 0; -} -EXPORT_SYMBOL(of_device_is_compatible); - -/** - * of_get_parent - Get a node's parent if any - * @node: Node to get parent - * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. - */ -struct device_node *of_get_parent(const struct device_node *node) -{ - struct device_node *np; - - if (!node) - return NULL; - - read_lock(&devtree_lock); - np = of_node_get(node->parent); - read_unlock(&devtree_lock); - return np; -} -EXPORT_SYMBOL(of_get_parent); - -/** - * of_get_next_child - Iterate a node childs - * @node: parent node - * @prev: previous child of the parent node, or NULL to get first - * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. - */ -struct device_node *of_get_next_child(const struct device_node *node, - struct device_node *prev) -{ - struct device_node *next; - - read_lock(&devtree_lock); - next = prev ? prev->sibling : node->child; - for (; next; next = next->sibling) - if (of_node_get(next)) - break; - of_node_put(prev); - read_unlock(&devtree_lock); - return next; -} -EXPORT_SYMBOL(of_get_next_child); - -/** - * of_find_node_by_path - Find a node matching a full OF path - * @path: The full path to match - * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. - */ -struct device_node *of_find_node_by_path(const char *path) -{ - struct device_node *np = allnodes; - - read_lock(&devtree_lock); - for (; np; np = np->allnext) { - if (np->full_name && (of_node_cmp(np->full_name, path) == 0) - && of_node_get(np)) - break; - } - read_unlock(&devtree_lock); - return np; -} -EXPORT_SYMBOL(of_find_node_by_path); - -/** - * of_find_node_by_name - Find a node by its "name" property - * @from: The node to start searching from or NULL, the node - * you pass will not be searched, only the next one - * will; typically, you pass what the previous call - * returned. of_node_put() will be called on it - * @name: The name string to match against - * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. - */ -struct device_node *of_find_node_by_name(struct device_node *from, - const char *name) -{ - struct device_node *np; - - read_lock(&devtree_lock); - np = from ? from->allnext : allnodes; - for (; np; np = np->allnext) - if (np->name && (of_node_cmp(np->name, name) == 0) - && of_node_get(np)) - break; - of_node_put(from); - read_unlock(&devtree_lock); - return np; -} -EXPORT_SYMBOL(of_find_node_by_name); - -/** - * of_find_node_by_type - Find a node by its "device_type" property - * @from: The node to start searching from, or NULL to start searching - * the entire device tree. The node you pass will not be - * searched, only the next one will; typically, you pass - * what the previous call returned. of_node_put() will be - * called on from for you. - * @type: The type string to match against - * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. - */ -struct device_node *of_find_node_by_type(struct device_node *from, - const char *type) -{ - struct device_node *np; - - read_lock(&devtree_lock); - np = from ? from->allnext : allnodes; - for (; np; np = np->allnext) - if (np->type && (of_node_cmp(np->type, type) == 0) - && of_node_get(np)) - break; - of_node_put(from); - read_unlock(&devtree_lock); - return np; -} -EXPORT_SYMBOL(of_find_node_by_type); - -/** - * of_find_compatible_node - Find a node based on type and one of the - * tokens in its "compatible" property - * @from: The node to start searching from or NULL, the node - * you pass will not be searched, only the next one - * will; typically, you pass what the previous call - * returned. of_node_put() will be called on it - * @type: The type string to match "device_type" or NULL to ignore - * @compatible: The string to match to one of the tokens in the device - * "compatible" list. - * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. - */ -struct device_node *of_find_compatible_node(struct device_node *from, - const char *type, const char *compatible) -{ - struct device_node *np; - - read_lock(&devtree_lock); - np = from ? from->allnext : allnodes; - for (; np; np = np->allnext) { - if (type - && !(np->type && (of_node_cmp(np->type, type) == 0))) - continue; - if (of_device_is_compatible(np, compatible) && of_node_get(np)) - break; - } - of_node_put(from); - read_unlock(&devtree_lock); - return np; -} -EXPORT_SYMBOL(of_find_compatible_node); diff --git a/trunk/drivers/of/device.c b/trunk/drivers/of/device.c deleted file mode 100644 index 6245f060fb77..000000000000 --- a/trunk/drivers/of/device.c +++ /dev/null @@ -1,131 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/** - * of_match_node - Tell if an device_node has a matching of_match structure - * @ids: array of of device match structures to search in - * @node: the of device structure to match against - * - * Low level utility function used by device matching. - */ -const struct of_device_id *of_match_node(const struct of_device_id *matches, - const struct device_node *node) -{ - while (matches->name[0] || matches->type[0] || matches->compatible[0]) { - int match = 1; - if (matches->name[0]) - match &= node->name - && !strcmp(matches->name, node->name); - if (matches->type[0]) - match &= node->type - && !strcmp(matches->type, node->type); - if (matches->compatible[0]) - match &= of_device_is_compatible(node, - matches->compatible); - if (match) - return matches; - matches++; - } - return NULL; -} -EXPORT_SYMBOL(of_match_node); - -/** - * of_match_device - Tell if an of_device structure has a matching - * of_match structure - * @ids: array of of device match structures to search in - * @dev: the of device structure to match against - * - * Used by a driver to check whether an of_device present in the - * system is in its list of supported devices. - */ -const struct of_device_id *of_match_device(const struct of_device_id *matches, - const struct of_device *dev) -{ - if (!dev->node) - return NULL; - return of_match_node(matches, dev->node); -} -EXPORT_SYMBOL(of_match_device); - -struct of_device *of_dev_get(struct of_device *dev) -{ - struct device *tmp; - - if (!dev) - return NULL; - tmp = get_device(&dev->dev); - if (tmp) - return to_of_device(tmp); - else - return NULL; -} -EXPORT_SYMBOL(of_dev_get); - -void of_dev_put(struct of_device *dev) -{ - if (dev) - put_device(&dev->dev); -} -EXPORT_SYMBOL(of_dev_put); - -static ssize_t dev_show_devspec(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct of_device *ofdev; - - ofdev = to_of_device(dev); - return sprintf(buf, "%s", ofdev->node->full_name); -} - -static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); - -/** - * of_release_dev - free an of device structure when all users of it are finished. - * @dev: device that's been disconnected - * - * Will be called only by the device core when all users of this of device are - * done. - */ -void of_release_dev(struct device *dev) -{ - struct of_device *ofdev; - - ofdev = to_of_device(dev); - of_node_put(ofdev->node); - kfree(ofdev); -} -EXPORT_SYMBOL(of_release_dev); - -int of_device_register(struct of_device *ofdev) -{ - int rc; - - BUG_ON(ofdev->node == NULL); - - rc = device_register(&ofdev->dev); - if (rc) - return rc; - - rc = device_create_file(&ofdev->dev, &dev_attr_devspec); - if (rc) - device_unregister(&ofdev->dev); - - return rc; -} -EXPORT_SYMBOL(of_device_register); - -void of_device_unregister(struct of_device *ofdev) -{ - device_remove_file(&ofdev->dev, &dev_attr_devspec); - device_unregister(&ofdev->dev); -} -EXPORT_SYMBOL(of_device_unregister); diff --git a/trunk/drivers/of/platform.c b/trunk/drivers/of/platform.c deleted file mode 100644 index 864f09fd9f86..000000000000 --- a/trunk/drivers/of/platform.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. - * - * and Arnd Bergmann, IBM Corp. - * Merged from powerpc/kernel/of_platform.c and - * sparc{,64}/kernel/of_device.c by Stephen Rothwell - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ -#include -#include -#include -#include - -static int of_platform_bus_match(struct device *dev, struct device_driver *drv) -{ - struct of_device *of_dev = to_of_device(dev); - struct of_platform_driver *of_drv = to_of_platform_driver(drv); - const struct of_device_id *matches = of_drv->match_table; - - if (!matches) - return 0; - - return of_match_device(matches, of_dev) != NULL; -} - -static int of_platform_device_probe(struct device *dev) -{ - int error = -ENODEV; - struct of_platform_driver *drv; - struct of_device *of_dev; - const struct of_device_id *match; - - drv = to_of_platform_driver(dev->driver); - of_dev = to_of_device(dev); - - if (!drv->probe) - return error; - - of_dev_get(of_dev); - - match = of_match_device(drv->match_table, of_dev); - if (match) - error = drv->probe(of_dev, match); - if (error) - of_dev_put(of_dev); - - return error; -} - -static int of_platform_device_remove(struct device *dev) -{ - struct of_device *of_dev = to_of_device(dev); - struct of_platform_driver *drv = to_of_platform_driver(dev->driver); - - if (dev->driver && drv->remove) - drv->remove(of_dev); - return 0; -} - -static int of_platform_device_suspend(struct device *dev, pm_message_t state) -{ - struct of_device *of_dev = to_of_device(dev); - struct of_platform_driver *drv = to_of_platform_driver(dev->driver); - int error = 0; - - if (dev->driver && drv->suspend) - error = drv->suspend(of_dev, state); - return error; -} - -static int of_platform_device_resume(struct device * dev) -{ - struct of_device *of_dev = to_of_device(dev); - struct of_platform_driver *drv = to_of_platform_driver(dev->driver); - int error = 0; - - if (dev->driver && drv->resume) - error = drv->resume(of_dev); - return error; -} - -int of_bus_type_init(struct bus_type *bus, const char *name) -{ - bus->name = name; - bus->match = of_platform_bus_match; - bus->probe = of_platform_device_probe; - bus->remove = of_platform_device_remove; - bus->suspend = of_platform_device_suspend; - bus->resume = of_platform_device_resume; - return bus_register(bus); -} diff --git a/trunk/drivers/oprofile/buffer_sync.c b/trunk/drivers/oprofile/buffer_sync.c index 8134c7e198a5..edd6de995726 100644 --- a/trunk/drivers/oprofile/buffer_sync.c +++ b/trunk/drivers/oprofile/buffer_sync.c @@ -26,9 +26,8 @@ #include #include #include -#include #include - + #include "oprofile_stats.h" #include "event_buffer.h" #include "cpu_buffer.h" diff --git a/trunk/drivers/oprofile/event_buffer.h b/trunk/drivers/oprofile/event_buffer.h index 5076ed1ebd8f..9b6a4ebd03e3 100644 --- a/trunk/drivers/oprofile/event_buffer.h +++ b/trunk/drivers/oprofile/event_buffer.h @@ -19,10 +19,28 @@ void free_event_buffer(void); /* wake up the process sleeping on the event file */ void wake_up_buffer_waiter(void); - + +/* Each escaped entry is prefixed by ESCAPE_CODE + * then one of the following codes, then the + * relevant data. + */ +#define ESCAPE_CODE ~0UL +#define CTX_SWITCH_CODE 1 +#define CPU_SWITCH_CODE 2 +#define COOKIE_SWITCH_CODE 3 +#define KERNEL_ENTER_SWITCH_CODE 4 +#define KERNEL_EXIT_SWITCH_CODE 5 +#define MODULE_LOADED_CODE 6 +#define CTX_TGID_CODE 7 +#define TRACE_BEGIN_CODE 8 +#define TRACE_END_CODE 9 + #define INVALID_COOKIE ~0UL #define NO_COOKIE 0UL +/* add data to the event buffer */ +void add_event_entry(unsigned long data); + extern const struct file_operations event_buffer_fops; /* mutex between sync_cpu_buffers() and the diff --git a/trunk/drivers/oprofile/oprof.c b/trunk/drivers/oprofile/oprof.c index 2c645170f06e..e5162a64018b 100644 --- a/trunk/drivers/oprofile/oprof.c +++ b/trunk/drivers/oprofile/oprof.c @@ -53,24 +53,9 @@ int oprofile_setup(void) * us missing task deaths and eventually oopsing * when trying to process the event buffer. */ - if (oprofile_ops.sync_start) { - int sync_ret = oprofile_ops.sync_start(); - switch (sync_ret) { - case 0: - goto post_sync; - case 1: - goto do_generic; - case -1: - goto out3; - default: - goto out3; - } - } -do_generic: if ((err = sync_start())) goto out3; -post_sync: is_setup = 1; mutex_unlock(&start_mutex); return 0; @@ -133,20 +118,7 @@ void oprofile_stop(void) void oprofile_shutdown(void) { mutex_lock(&start_mutex); - if (oprofile_ops.sync_stop) { - int sync_ret = oprofile_ops.sync_stop(); - switch (sync_ret) { - case 0: - goto post_sync; - case 1: - goto do_generic; - default: - goto post_sync; - } - } -do_generic: sync_stop(); -post_sync: if (oprofile_ops.shutdown) oprofile_ops.shutdown(); is_setup = 0; diff --git a/trunk/drivers/parport/Kconfig b/trunk/drivers/parport/Kconfig index d449b150930e..09c93ff932b1 100644 --- a/trunk/drivers/parport/Kconfig +++ b/trunk/drivers/parport/Kconfig @@ -35,7 +35,7 @@ if PARPORT config PARPORT_PC tristate "PC-style hardware" - depends on (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV && (!M68K || ISA) + depends on (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV ---help--- You should say Y here if you have a PC-style parallel port. All IBM PC compatible computers and some Alphas have PC-style diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index 35f34665e3c4..cea401feb0f3 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -394,7 +394,7 @@ config RTC_DRV_SA1100 config RTC_DRV_SH tristate "SuperH On-Chip RTC" - depends on RTC_CLASS && SUPERH && (CPU_SH3 || CPU_SH4) + depends on RTC_CLASS && SUPERH help Say Y here to enable support for the on-chip RTC found in most SuperH processors. diff --git a/trunk/drivers/sbus/sbus.c b/trunk/drivers/sbus/sbus.c index 2553629ec15d..002643392d42 100644 --- a/trunk/drivers/sbus/sbus.c +++ b/trunk/drivers/sbus/sbus.c @@ -33,7 +33,6 @@ struct sbus_bus *sbus_root; static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev) { - struct dev_archdata *sd; unsigned long base; const void *pval; int len, err; @@ -68,10 +67,6 @@ static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sde sbus_fill_device_irq(sdev); - sd = &sdev->ofdev.dev.archdata; - sd->prom_node = dp; - sd->op = &sdev->ofdev; - sdev->ofdev.node = dp; if (sdev->parent) sdev->ofdev.dev.parent = &sdev->parent->ofdev.dev; diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index a947257b8964..372723161c97 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -483,7 +483,7 @@ source "drivers/scsi/aic94xx/Kconfig" # All the I2O code and drivers do not seem to be 64bit safe. config SCSI_DPT_I2O tristate "Adaptec I2O RAID support " - depends on !64BIT && SCSI && PCI && VIRT_TO_BUS + depends on !64BIT && SCSI && PCI help This driver supports all of Adaptec's I2O based RAID controllers as well as the DPT SmartRaid V cards. This is an Adaptec maintained diff --git a/trunk/drivers/scsi/NCR53C9x.c b/trunk/drivers/scsi/NCR53C9x.c index 79b4df158140..773d11dd9953 100644 --- a/trunk/drivers/scsi/NCR53C9x.c +++ b/trunk/drivers/scsi/NCR53C9x.c @@ -95,8 +95,6 @@ enum { /* The master ring of all esp hosts we are managing in this driver. */ static struct NCR_ESP *espchain; int nesps = 0, esps_in_use = 0, esps_running = 0; -EXPORT_SYMBOL(nesps); -EXPORT_SYMBOL(esps_running); irqreturn_t esp_intr(int irq, void *dev_id); @@ -526,7 +524,6 @@ void esp_bootup_reset(struct NCR_ESP *esp, struct ESP_regs *eregs) /* Eat any bitrot in the chip and we are done... */ trash = esp_read(eregs->esp_intrpt); } -EXPORT_SYMBOL(esp_bootup_reset); /* Allocate structure and insert basic data such as SCSI chip frequency * data and a pointer to the device @@ -775,7 +772,6 @@ const char *esp_info(struct Scsi_Host *host) panic("Bogon ESP revision"); }; } -EXPORT_SYMBOL(esp_info); /* From Wolfgang Stanglmeier's NCR scsi driver. */ struct info_str @@ -906,7 +902,6 @@ int esp_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t off *start = buffer; return esp_host_info(esp, buffer, offset, length); } -EXPORT_SYMBOL(esp_proc_info); static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp) { @@ -3540,7 +3535,6 @@ void esp_handle(struct NCR_ESP *esp) if(esp->dma_irq_exit) esp->dma_irq_exit(esp); } -EXPORT_SYMBOL(esp_handle); #ifndef CONFIG_SMP irqreturn_t esp_intr(int irq, void *dev_id) @@ -3637,7 +3631,6 @@ void esp_release(void) esps_in_use--; esps_running = esps_in_use; } -EXPORT_SYMBOL(esp_release); #endif EXPORT_SYMBOL(esp_abort); diff --git a/trunk/drivers/scsi/iscsi_tcp.c b/trunk/drivers/scsi/iscsi_tcp.c index 7829ab1e2fb4..aebcd5fcdc55 100644 --- a/trunk/drivers/scsi/iscsi_tcp.c +++ b/trunk/drivers/scsi/iscsi_tcp.c @@ -1885,7 +1885,7 @@ static int iscsi_tcp_get_addr(struct iscsi_conn *conn, struct socket *sock, struct sockaddr_in *sin; int rc = 0, len; - addr = kmalloc(sizeof(*addr), GFP_KERNEL); + addr = kmalloc(GFP_KERNEL, sizeof(*addr)); if (!addr) return -ENOMEM; diff --git a/trunk/drivers/serial/suncore.c b/trunk/drivers/serial/suncore.c index 70a09a3d5af0..b45ba5392dd3 100644 --- a/trunk/drivers/serial/suncore.c +++ b/trunk/drivers/serial/suncore.c @@ -16,10 +16,9 @@ #include #include #include -#include #include -#include +#include #include "suncore.h" @@ -27,60 +26,92 @@ int sunserial_current_minor = 64; EXPORT_SYMBOL(sunserial_current_minor); -int sunserial_console_match(struct console *con, struct device_node *dp, - struct uart_driver *drv, int line) +void +sunserial_console_termios(struct console *con) { - int off; + char mode[16], buf[16], *s; + char mode_prop[] = "ttyX-mode"; + char cd_prop[] = "ttyX-ignore-cd"; + char dtr_prop[] = "ttyX-rts-dtr-off"; + char *ssp_console_modes_prop = "ssp-console-modes"; + int baud, bits, stop, cflag; + char parity; + int carrier = 0; + int rtsdtr = 1; + int topnd, nd; + + if (!serial_console) + return; + + switch (serial_console) { + case PROMDEV_OTTYA: + mode_prop[3] = 'a'; + cd_prop[3] = 'a'; + dtr_prop[3] = 'a'; + break; + + case PROMDEV_OTTYB: + mode_prop[3] = 'b'; + cd_prop[3] = 'b'; + dtr_prop[3] = 'b'; + break; + + case PROMDEV_ORSC: + + nd = prom_pathtoinode("rsc"); + if (!nd) { + strcpy(mode, "115200,8,n,1,-"); + goto no_options; + } - if (!con || of_console_device != dp) - return 0; + if (!prom_node_has_property(nd, ssp_console_modes_prop)) { + strcpy(mode, "115200,8,n,1,-"); + goto no_options; + } - off = 0; - if (of_console_options && - *of_console_options == 'b') - off = 1; + memset(mode, 0, sizeof(mode)); + prom_getstring(nd, ssp_console_modes_prop, mode, sizeof(mode)); + goto no_options; - if ((line & 1) != off) - return 0; + default: + strcpy(mode, "9600,8,n,1,-"); + goto no_options; + } - con->index = line; - drv->cons = con; - add_preferred_console(con->name, line, NULL); + topnd = prom_getchild(prom_root_node); + nd = prom_searchsiblings(topnd, "options"); + if (!nd) { + strcpy(mode, "9600,8,n,1,-"); + goto no_options; + } - return 1; -} -EXPORT_SYMBOL(sunserial_console_match); + if (!prom_node_has_property(nd, mode_prop)) { + strcpy(mode, "9600,8,n,1,-"); + goto no_options; + } -void -sunserial_console_termios(struct console *con) -{ - struct device_node *dp; - const char *od, *mode, *s; - char mode_prop[] = "ttyX-mode"; - int baud, bits, stop, cflag; - char parity; + memset(mode, 0, sizeof(mode)); + prom_getstring(nd, mode_prop, mode, sizeof(mode)); + + if (prom_node_has_property(nd, cd_prop)) { + memset(buf, 0, sizeof(buf)); + prom_getstring(nd, cd_prop, buf, sizeof(buf)); + if (!strcmp(buf, "false")) + carrier = 1; + + /* XXX: this is unused below. */ + } + + if (prom_node_has_property(nd, dtr_prop)) { + memset(buf, 0, sizeof(buf)); + prom_getstring(nd, dtr_prop, buf, sizeof(buf)); + if (!strcmp(buf, "false")) + rtsdtr = 0; - dp = of_find_node_by_path("/options"); - od = of_get_property(dp, "output-device", NULL); - if (!strcmp(od, "rsc")) { - mode = of_get_property(of_console_device, - "ssp-console-modes", NULL); - if (!mode) - mode = "115200,8,n,1,-"; - } else { - char c; - - c = 'a'; - if (of_console_options) - c = *of_console_options; - - mode_prop[3] = c; - - mode = of_get_property(dp, mode_prop, NULL); - if (!mode) - mode = "9600,8,n,1,-"; + /* XXX: this is unused below. */ } +no_options: cflag = CREAD | HUPCL | CLOCAL; s = mode; diff --git a/trunk/drivers/serial/suncore.h b/trunk/drivers/serial/suncore.h index 829d7d65d6db..513916a8ce37 100644 --- a/trunk/drivers/serial/suncore.h +++ b/trunk/drivers/serial/suncore.h @@ -24,8 +24,6 @@ extern int suncore_mouse_baud_detection(unsigned char, int); extern int sunserial_current_minor; -extern int sunserial_console_match(struct console *, struct device_node *, - struct uart_driver *, int); extern void sunserial_console_termios(struct console *); #endif /* !(_SERIAL_SUN_H) */ diff --git a/trunk/drivers/serial/sunhv.c b/trunk/drivers/serial/sunhv.c index 8ff900b09811..d82be42ff29a 100644 --- a/trunk/drivers/serial/sunhv.c +++ b/trunk/drivers/serial/sunhv.c @@ -520,6 +520,16 @@ static struct console sunhv_console = { .data = &sunhv_reg, }; +static inline struct console *SUNHV_CONSOLE(void) +{ + if (con_is_present()) + return NULL; + + sunhv_console.index = 0; + + return &sunhv_console; +} + static int __devinit hv_probe(struct of_device *op, const struct of_device_id *match) { struct uart_port *port; @@ -572,8 +582,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m sunhv_reg.tty_driver->name_base = sunhv_reg.minor - 64; sunserial_current_minor += 1; - sunserial_console_match(&sunhv_console, op->node, - &sunhv_reg, port->line); + sunhv_reg.cons = SUNHV_CONSOLE(); err = uart_add_one_port(&sunhv_reg, port); if (err) diff --git a/trunk/drivers/serial/sunsab.c b/trunk/drivers/serial/sunsab.c index bca57bb94939..8a0f9e4408d4 100644 --- a/trunk/drivers/serial/sunsab.c +++ b/trunk/drivers/serial/sunsab.c @@ -968,6 +968,22 @@ static struct console sunsab_console = { static inline struct console *SUNSAB_CONSOLE(void) { + int i; + + if (con_is_present()) + return NULL; + + for (i = 0; i < num_channels; i++) { + int this_minor = sunsab_reg.minor + i; + + if ((this_minor - 64) == (serial_console - 1)) + break; + } + if (i == num_channels) + return NULL; + + sunsab_console.index = i; + return &sunsab_console; } #else @@ -1064,12 +1080,7 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * return err; } - sunserial_console_match(SUNSAB_CONSOLE(), op->node, - &sunsab_reg, up[0].port.line); uart_add_one_port(&sunsab_reg, &up[0].port); - - sunserial_console_match(SUNSAB_CONSOLE(), op->node, - &sunsab_reg, up[1].port.line); uart_add_one_port(&sunsab_reg, &up[1].port); dev_set_drvdata(&op->dev, &up[0]); @@ -1153,6 +1164,7 @@ static int __init sunsab_init(void) } sunsab_reg.tty_driver->name_base = sunsab_reg.minor - 64; + sunsab_reg.cons = SUNSAB_CONSOLE(); sunserial_current_minor += num_channels; } diff --git a/trunk/drivers/serial/sunsu.c b/trunk/drivers/serial/sunsu.c index 79b13685bdfa..26d720baf88c 100644 --- a/trunk/drivers/serial/sunsu.c +++ b/trunk/drivers/serial/sunsu.c @@ -1371,12 +1371,28 @@ static struct console sunsu_console = { * Register console. */ -static inline struct console *SUNSU_CONSOLE(void) +static inline struct console *SUNSU_CONSOLE(int num_uart) { + int i; + + if (con_is_present()) + return NULL; + + for (i = 0; i < num_uart; i++) { + int this_minor = sunsu_reg.minor + i; + + if ((this_minor - 64) == (serial_console - 1)) + break; + } + if (i == num_uart) + return NULL; + + sunsu_console.index = i; + return &sunsu_console; } #else -#define SUNSU_CONSOLE() (NULL) +#define SUNSU_CONSOLE(num_uart) (NULL) #define sunsu_serial_console_init() do { } while (0) #endif @@ -1466,8 +1482,6 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m up->port.ops = &sunsu_pops; - sunserial_console_match(SUNSU_CONSOLE(), dp, - &sunsu_reg, up->port.line); err = uart_add_one_port(&sunsu_reg, &up->port); if (err) goto out_unmap; @@ -1558,6 +1572,7 @@ static int __init sunsu_init(void) return err; sunsu_reg.tty_driver->name_base = sunsu_reg.minor - 64; sunserial_current_minor += num_uart; + sunsu_reg.cons = SUNSU_CONSOLE(num_uart); } err = of_register_driver(&su_driver, &of_bus_type); diff --git a/trunk/drivers/serial/sunzilog.c b/trunk/drivers/serial/sunzilog.c index 1d262c0c613f..0a3e10a4a35d 100644 --- a/trunk/drivers/serial/sunzilog.c +++ b/trunk/drivers/serial/sunzilog.c @@ -1226,6 +1226,23 @@ static struct console sunzilog_console_ops = { static inline struct console *SUNZILOG_CONSOLE(void) { + int i; + + if (con_is_present()) + return NULL; + + for (i = 0; i < NUM_CHANNELS; i++) { + int this_minor = sunzilog_reg.minor + i; + + if ((this_minor - 64) == (serial_console - 1)) + break; + } + if (i == NUM_CHANNELS) + return NULL; + + sunzilog_console_ops.index = i; + sunzilog_port_table[i].flags |= SUNZILOG_FLAG_IS_CONS; + return &sunzilog_console_ops; } @@ -1411,18 +1428,12 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m sunzilog_init_hw(&up[1]); if (!keyboard_mouse) { - if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, - &sunzilog_reg, up[0].port.line)) - up->flags |= SUNZILOG_FLAG_IS_CONS; err = uart_add_one_port(&sunzilog_reg, &up[0].port); if (err) { of_iounmap(&op->resource[0], rp, sizeof(struct zilog_layout)); return err; } - if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, - &sunzilog_reg, up[1].port.line)) - up->flags |= SUNZILOG_FLAG_IS_CONS; err = uart_add_one_port(&sunzilog_reg, &up[1].port); if (err) { uart_remove_one_port(&sunzilog_reg, &up[0].port); @@ -1520,6 +1531,7 @@ static int __init sunzilog_init(void) goto out_free_tables; sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64; + sunzilog_reg.cons = SUNZILOG_CONSOLE(); sunserial_current_minor += uart_count; } diff --git a/trunk/drivers/usb/atm/cxacru.c b/trunk/drivers/usb/atm/cxacru.c index 02c52f8d5dbf..1bc884051e0f 100644 --- a/trunk/drivers/usb/atm/cxacru.c +++ b/trunk/drivers/usb/atm/cxacru.c @@ -456,7 +456,7 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, int* actual_length) { struct timer_list timer; - int status = urb->status; + int status; init_timer(&timer); timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT); @@ -464,6 +464,7 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, timer.function = cxacru_timeout_kill; add_timer(&timer); wait_for_completion(done); + status = urb->status; del_timer_sync(&timer); if (actual_length) diff --git a/trunk/drivers/usb/atm/speedtch.c b/trunk/drivers/usb/atm/speedtch.c index eb0615abff68..638b8009b3bc 100644 --- a/trunk/drivers/usb/atm/speedtch.c +++ b/trunk/drivers/usb/atm/speedtch.c @@ -612,8 +612,7 @@ static void speedtch_handle_int(struct urb *int_urb) struct speedtch_instance_data *instance = int_urb->context; struct usbatm_data *usbatm = instance->usbatm; unsigned int count = int_urb->actual_length; - int status = int_urb->status; - int ret; + int ret = int_urb->status; /* The magic interrupt for "up state" */ static const unsigned char up_int[6] = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 }; @@ -622,8 +621,8 @@ static void speedtch_handle_int(struct urb *int_urb) atm_dbg(usbatm, "%s entered\n", __func__); - if (status < 0) { - atm_dbg(usbatm, "%s: nonzero urb status %d!\n", __func__, status); + if (ret < 0) { + atm_dbg(usbatm, "%s: nonzero urb status %d!\n", __func__, ret); goto fail; } diff --git a/trunk/drivers/usb/atm/ueagle-atm.c b/trunk/drivers/usb/atm/ueagle-atm.c index a1a1c9d467e0..8f046659b4e9 100644 --- a/trunk/drivers/usb/atm/ueagle-atm.c +++ b/trunk/drivers/usb/atm/ueagle-atm.c @@ -1308,13 +1308,11 @@ static void uea_intr(struct urb *urb) { struct uea_softc *sc = urb->context; struct intr_pkt *intr = urb->transfer_buffer; - int status = urb->status; - uea_enters(INS_TO_USBDEV(sc)); - if (unlikely(status < 0)) { + if (unlikely(urb->status < 0)) { uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n", - status); + urb->status); return; } diff --git a/trunk/drivers/usb/atm/usbatm.c b/trunk/drivers/usb/atm/usbatm.c index e717f5b1caee..11e9b15ca45a 100644 --- a/trunk/drivers/usb/atm/usbatm.c +++ b/trunk/drivers/usb/atm/usbatm.c @@ -257,10 +257,9 @@ static void usbatm_complete(struct urb *urb) { struct usbatm_channel *channel = urb->context; unsigned long flags; - int status = urb->status; vdbg("%s: urb 0x%p, status %d, actual_length %d", - __func__, urb, status, urb->actual_length); + __func__, urb, urb->status, urb->actual_length); /* usually in_interrupt(), but not always */ spin_lock_irqsave(&channel->lock, flags); @@ -270,16 +269,16 @@ static void usbatm_complete(struct urb *urb) spin_unlock_irqrestore(&channel->lock, flags); - if (unlikely(status) && + if (unlikely(urb->status) && (!(channel->usbatm->flags & UDSL_IGNORE_EILSEQ) || - status != -EILSEQ )) + urb->status != -EILSEQ )) { - if (status == -ESHUTDOWN) + if (urb->status == -ESHUTDOWN) return; if (printk_ratelimit()) atm_warn(channel->usbatm, "%s: urb 0x%p failed (%d)!\n", - __func__, urb, status); + __func__, urb, urb->status); /* throttle processing in case of an error */ mod_timer(&channel->delay, jiffies + msecs_to_jiffies(THROTTLE_MSECS)); } else diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index fe940e0536e0..cd51520c7e72 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -257,10 +257,9 @@ static void acm_ctrl_irq(struct urb *urb) struct usb_cdc_notification *dr = urb->transfer_buffer; unsigned char *data; int newctrl; - int retval; - int status = urb->status; + int status; - switch (status) { + switch (urb->status) { case 0: /* success */ break; @@ -268,10 +267,10 @@ static void acm_ctrl_irq(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, status); + dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); return; default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, status); + dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); goto exit; } @@ -312,10 +311,10 @@ static void acm_ctrl_irq(struct urb *urb) break; } exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) + status = usb_submit_urb (urb, GFP_ATOMIC); + if (status) err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); + __FUNCTION__, status); } /* data interface returns incoming bytes, or we got unthrottled */ @@ -325,8 +324,7 @@ static void acm_read_bulk(struct urb *urb) struct acm_ru *rcv = urb->context; struct acm *acm = rcv->instance; int status = urb->status; - - dbg("Entering acm_read_bulk with status %d", status); + dbg("Entering acm_read_bulk with status %d", urb->status); if (!ACM_READY(acm)) return; diff --git a/trunk/drivers/usb/class/usblp.c b/trunk/drivers/usb/class/usblp.c index 5192cd9356de..9a1478972bf5 100644 --- a/trunk/drivers/usb/class/usblp.c +++ b/trunk/drivers/usb/class/usblp.c @@ -289,17 +289,16 @@ static int proto_bias = -1; static void usblp_bulk_read(struct urb *urb) { struct usblp *usblp = urb->context; - int status = urb->status; if (usblp->present && usblp->used) { - if (status) + if (urb->status) printk(KERN_WARNING "usblp%d: " "nonzero read bulk status received: %d\n", - usblp->minor, status); + usblp->minor, urb->status); } spin_lock(&usblp->lock); - if (status < 0) - usblp->rstatus = status; + if (urb->status < 0) + usblp->rstatus = urb->status; else usblp->rstatus = urb->actual_length; usblp->rcomplete = 1; @@ -312,17 +311,16 @@ static void usblp_bulk_read(struct urb *urb) static void usblp_bulk_write(struct urb *urb) { struct usblp *usblp = urb->context; - int status = urb->status; if (usblp->present && usblp->used) { - if (status) + if (urb->status) printk(KERN_WARNING "usblp%d: " "nonzero write bulk status received: %d\n", - usblp->minor, status); + usblp->minor, urb->status); } spin_lock(&usblp->lock); - if (status < 0) - usblp->wstatus = status; + if (urb->status < 0) + usblp->wstatus = urb->status; else usblp->wstatus = urb->actual_length; usblp->wcomplete = 1; @@ -743,11 +741,10 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t */ rv = usblp_wwait(usblp, !!(file->f_flags&O_NONBLOCK)); if (rv < 0) { - if (rv == -EAGAIN) { - /* Presume that it's going to complete well. */ - writecount += transfer_length; - } - /* Leave URB dangling, to be cleaned on close. */ + /* + * If interrupted, we simply leave the URB to dangle, + * so the ->release will call usb_kill_urb(). + */ goto collect_error; } diff --git a/trunk/drivers/usb/core/hcd.c b/trunk/drivers/usb/core/hcd.c index 42ef1d5f6c8a..963520fbef90 100644 --- a/trunk/drivers/usb/core/hcd.c +++ b/trunk/drivers/usb/core/hcd.c @@ -99,17 +99,12 @@ EXPORT_SYMBOL_GPL (usb_bus_list_lock); /* used for controlling access to virtual root hubs */ static DEFINE_SPINLOCK(hcd_root_hub_lock); -/* used when updating an endpoint's URB list */ -static DEFINE_SPINLOCK(hcd_urb_list_lock); +/* used when updating hcd data */ +static DEFINE_SPINLOCK(hcd_data_lock); /* wait queue for synchronous unlinks */ DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue); -static inline int is_root_hub(struct usb_device *udev) -{ - return (udev->parent == NULL); -} - /*-------------------------------------------------------------------------*/ /* @@ -911,13 +906,14 @@ EXPORT_SYMBOL (usb_calc_bus_time); static void urb_unlink(struct usb_hcd *hcd, struct urb *urb) { unsigned long flags; + int at_root_hub = (urb->dev == hcd->self.root_hub); /* clear all state linking urb to this dev (and hcd) */ - spin_lock_irqsave(&hcd_urb_list_lock, flags); + spin_lock_irqsave (&hcd_data_lock, flags); list_del_init (&urb->urb_list); - spin_unlock_irqrestore(&hcd_urb_list_lock, flags); + spin_unlock_irqrestore (&hcd_data_lock, flags); - if (hcd->self.uses_dma && !is_root_hub(urb->dev)) { + if (hcd->self.uses_dma && !at_root_hub) { if (usb_pipecontrol (urb->pipe) && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) dma_unmap_single (hcd->self.controller, urb->setup_dma, @@ -959,7 +955,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) // FIXME: verify that quiescing hc works right (RH cleans up) - spin_lock_irqsave(&hcd_urb_list_lock, flags); + spin_lock_irqsave (&hcd_data_lock, flags); ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out) [usb_pipeendpoint(urb->pipe)]; if (unlikely (!ep)) @@ -976,7 +972,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) status = -ESHUTDOWN; break; } - spin_unlock_irqrestore(&hcd_urb_list_lock, flags); + spin_unlock_irqrestore (&hcd_data_lock, flags); if (status) { INIT_LIST_HEAD (&urb->urb_list); usbmon_urb_submit_error(&hcd->self, urb, status); @@ -990,7 +986,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) urb = usb_get_urb (urb); atomic_inc (&urb->use_count); - if (is_root_hub(urb->dev)) { + if (urb->dev == hcd->self.root_hub) { /* NOTE: requirement on hub callers (usbfs and the hub * driver, for now) that URBs' urb->transfer_buffer be * valid and usb_buffer_{sync,unmap}() not be needed, since @@ -1037,6 +1033,18 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) /*-------------------------------------------------------------------------*/ +/* called in any context */ +int usb_hcd_get_frame_number (struct usb_device *udev) +{ + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + + if (!HC_IS_RUNNING (hcd->state)) + return -ESHUTDOWN; + return hcd->driver->get_frame_number (hcd); +} + +/*-------------------------------------------------------------------------*/ + /* this makes the hcd giveback() the urb more quickly, by kicking it * off hardware queues (which may take a while) and returning it as * soon as practical. we've already set up the urb's return status, @@ -1047,7 +1055,7 @@ unlink1 (struct usb_hcd *hcd, struct urb *urb) { int value; - if (is_root_hub(urb->dev)) + if (urb->dev == hcd->self.root_hub) value = usb_rh_urb_dequeue (hcd, urb); else { @@ -1095,11 +1103,11 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) * that it was submitted. But as a rule it can't know whether or * not it's already been unlinked ... so we respect the reversed * lock sequence needed for the usb_hcd_giveback_urb() code paths - * (urb lock, then hcd_urb_list_lock) in case some other CPU is now + * (urb lock, then hcd_data_lock) in case some other CPU is now * unlinking it. */ spin_lock_irqsave (&urb->lock, flags); - spin_lock(&hcd_urb_list_lock); + spin_lock (&hcd_data_lock); sys = &urb->dev->dev; hcd = bus_to_hcd(urb->dev->bus); @@ -1131,16 +1139,17 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) * finish unlinking the initial failed usb_set_address() * or device descriptor fetch. */ - if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags) && - !is_root_hub(urb->dev)) { + if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags) + && hcd->self.root_hub != urb->dev) { dev_warn (hcd->self.controller, "Unlink after no-IRQ? " - "Controller is probably using the wrong IRQ.\n"); + "Controller is probably using the wrong IRQ." + "\n"); set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); } urb->status = status; - spin_unlock(&hcd_urb_list_lock); + spin_unlock (&hcd_data_lock); spin_unlock_irqrestore (&urb->lock, flags); retval = unlink1 (hcd, urb); @@ -1149,7 +1158,7 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) return retval; done: - spin_unlock(&hcd_urb_list_lock); + spin_unlock (&hcd_data_lock); spin_unlock_irqrestore (&urb->lock, flags); if (retval != -EIDRM && sys && sys->driver) dev_dbg (sys, "hcd_unlink_urb %p fail %d\n", urb, retval); @@ -1158,35 +1167,6 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) /*-------------------------------------------------------------------------*/ -/** - * usb_hcd_giveback_urb - return URB from HCD to device driver - * @hcd: host controller returning the URB - * @urb: urb being returned to the USB device driver. - * Context: in_interrupt() - * - * This hands the URB from HCD to its USB device driver, using its - * completion function. The HCD has freed all per-urb resources - * (and is done using urb->hcpriv). It also released all HCD locks; - * the device driver won't cause problems if it frees, modifies, - * or resubmits this URB. - */ -void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) -{ - urb_unlink(hcd, urb); - usbmon_urb_complete (&hcd->self, urb); - usb_unanchor_urb(urb); - - /* pass ownership to the completion handler */ - urb->complete (urb); - atomic_dec (&urb->use_count); - if (unlikely (urb->reject)) - wake_up (&usb_kill_urb_queue); - usb_put_urb (urb); -} -EXPORT_SYMBOL (usb_hcd_giveback_urb); - -/*-------------------------------------------------------------------------*/ - /* disables the endpoint: cancels any pending urbs, then synchronizes with * the hcd to make sure all endpoint state is gone from hardware, and then * waits until the endpoint's queue is completely drained. use for @@ -1206,7 +1186,7 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, /* ep is already gone from udev->ep_{in,out}[]; no more submits */ rescan: - spin_lock(&hcd_urb_list_lock); + spin_lock (&hcd_data_lock); list_for_each_entry (urb, &ep->urb_list, urb_list) { int tmp; @@ -1214,7 +1194,7 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, if (urb->status != -EINPROGRESS) continue; usb_get_urb (urb); - spin_unlock(&hcd_urb_list_lock); + spin_unlock (&hcd_data_lock); spin_lock (&urb->lock); tmp = urb->status; @@ -1243,7 +1223,7 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, /* list contents may have changed */ goto rescan; } - spin_unlock(&hcd_urb_list_lock); + spin_unlock (&hcd_data_lock); local_irq_enable (); /* synchronize with the hardware, so old configuration state @@ -1260,7 +1240,7 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, * endpoint_disable methods. */ while (!list_empty (&ep->urb_list)) { - spin_lock_irq(&hcd_urb_list_lock); + spin_lock_irq (&hcd_data_lock); /* The list may have changed while we acquired the spinlock */ urb = NULL; @@ -1269,7 +1249,7 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, urb_list); usb_get_urb (urb); } - spin_unlock_irq(&hcd_urb_list_lock); + spin_unlock_irq (&hcd_data_lock); if (urb) { usb_kill_urb (urb); @@ -1280,18 +1260,6 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, /*-------------------------------------------------------------------------*/ -/* called in any context */ -int usb_hcd_get_frame_number (struct usb_device *udev) -{ - struct usb_hcd *hcd = bus_to_hcd(udev->bus); - - if (!HC_IS_RUNNING (hcd->state)) - return -ESHUTDOWN; - return hcd->driver->get_frame_number (hcd); -} - -/*-------------------------------------------------------------------------*/ - #ifdef CONFIG_PM int hcd_bus_suspend(struct usb_device *rhdev) @@ -1426,6 +1394,35 @@ EXPORT_SYMBOL (usb_bus_start_enum); /*-------------------------------------------------------------------------*/ +/** + * usb_hcd_giveback_urb - return URB from HCD to device driver + * @hcd: host controller returning the URB + * @urb: urb being returned to the USB device driver. + * Context: in_interrupt() + * + * This hands the URB from HCD to its USB device driver, using its + * completion function. The HCD has freed all per-urb resources + * (and is done using urb->hcpriv). It also released all HCD locks; + * the device driver won't cause problems if it frees, modifies, + * or resubmits this URB. + */ +void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) +{ + urb_unlink(hcd, urb); + usbmon_urb_complete (&hcd->self, urb); + usb_unanchor_urb(urb); + + /* pass ownership to the completion handler */ + urb->complete (urb); + atomic_dec (&urb->use_count); + if (unlikely (urb->reject)) + wake_up (&usb_kill_urb_queue); + usb_put_urb (urb); +} +EXPORT_SYMBOL (usb_hcd_giveback_urb); + +/*-------------------------------------------------------------------------*/ + /** * usb_hcd_irq - hook IRQs to HCD framework (bus glue) * @irq: the IRQ being raised diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index e341a1da517f..fd74c50b1804 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -1335,10 +1335,6 @@ int usb_new_device(struct usb_device *udev) udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); - /* Increment the parent's count of unsuspended children */ - if (udev->parent) - usb_autoresume_device(udev->parent); - /* Register the device. The device driver is responsible * for adding the device files to sysfs and for configuring * the device. @@ -1346,11 +1342,13 @@ int usb_new_device(struct usb_device *udev) err = device_add(&udev->dev); if (err) { dev_err(&udev->dev, "can't device_add, error %d\n", err); - if (udev->parent) - usb_autosuspend_device(udev->parent); goto fail; } + /* Increment the parent's count of unsuspended children */ + if (udev->parent) + usb_autoresume_device(udev->parent); + exit: return err; diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index 25f63f1096b4..530e854961ce 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -34,14 +34,13 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) { struct completion done; unsigned long expire; - int retval; - int status = urb->status; + int status; init_completion(&done); urb->context = &done; urb->actual_length = 0; - retval = usb_submit_urb(urb, GFP_NOIO); - if (unlikely(retval)) + status = usb_submit_urb(urb, GFP_NOIO); + if (unlikely(status)) goto out; expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; @@ -56,15 +55,15 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) urb->transfer_buffer_length); usb_kill_urb(urb); - retval = status == -ENOENT ? -ETIMEDOUT : status; + status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status; } else - retval = status; + status = urb->status; out: if (actual_length) *actual_length = urb->actual_length; usb_free_urb(urb); - return retval; + return status; } /*-------------------------------------------------------------------*/ @@ -251,7 +250,6 @@ static void sg_clean (struct usb_sg_request *io) static void sg_complete (struct urb *urb) { struct usb_sg_request *io = urb->context; - int status = urb->status; spin_lock (&io->lock); @@ -267,21 +265,21 @@ static void sg_complete (struct urb *urb) */ if (io->status && (io->status != -ECONNRESET - || status != -ECONNRESET) + || urb->status != -ECONNRESET) && urb->actual_length) { dev_err (io->dev->bus->controller, "dev %s ep%d%s scatterlist error %d/%d\n", io->dev->devpath, usb_pipeendpoint (urb->pipe), usb_pipein (urb->pipe) ? "in" : "out", - status, io->status); + urb->status, io->status); // BUG (); } - if (io->status == 0 && status && status != -ECONNRESET) { - int i, found, retval; + if (io->status == 0 && urb->status && urb->status != -ECONNRESET) { + int i, found, status; - io->status = status; + io->status = urb->status; /* the previous urbs, and this one, completed already. * unlink pending urbs so they won't rx/tx bad data. @@ -292,13 +290,13 @@ static void sg_complete (struct urb *urb) if (!io->urbs [i] || !io->urbs [i]->dev) continue; if (found) { - retval = usb_unlink_urb (io->urbs [i]); - if (retval != -EINPROGRESS && - retval != -ENODEV && - retval != -EBUSY) + status = usb_unlink_urb (io->urbs [i]); + if (status != -EINPROGRESS + && status != -ENODEV + && status != -EBUSY) dev_err (&io->dev->dev, "%s, unlink --> %d\n", - __FUNCTION__, retval); + __FUNCTION__, status); } else if (urb == io->urbs [i]) found = 1; } diff --git a/trunk/drivers/usb/core/sysfs.c b/trunk/drivers/usb/core/sysfs.c index 2ab222be8fd1..d47ae89154a7 100644 --- a/trunk/drivers/usb/core/sysfs.c +++ b/trunk/drivers/usb/core/sysfs.c @@ -441,54 +441,6 @@ static struct attribute_group dev_attr_grp = { .attrs = dev_attrs, }; -/* Binary descriptors */ - -static ssize_t -read_descriptors(struct kobject *kobj, struct bin_attribute *attr, - char *buf, loff_t off, size_t count) -{ - struct usb_device *udev = to_usb_device( - container_of(kobj, struct device, kobj)); - size_t nleft = count; - size_t srclen, n; - - usb_lock_device(udev); - - /* The binary attribute begins with the device descriptor */ - srclen = sizeof(struct usb_device_descriptor); - if (off < srclen) { - n = min_t(size_t, nleft, srclen - off); - memcpy(buf, off + (char *) &udev->descriptor, n); - nleft -= n; - buf += n; - off = 0; - } else { - off -= srclen; - } - - /* Then follows the raw descriptor entry for the current - * configuration (config plus subsidiary descriptors). - */ - if (udev->actconfig) { - int cfgno = udev->actconfig - udev->config; - - srclen = __le16_to_cpu(udev->actconfig->desc.wTotalLength); - if (off < srclen) { - n = min_t(size_t, nleft, srclen - off); - memcpy(buf, off + udev->rawdescriptors[cfgno], n); - nleft -= n; - } - } - usb_unlock_device(udev); - return count - nleft; -} - -static struct bin_attribute dev_bin_attr_descriptors = { - .attr = {.name = "descriptors", .mode = 0444}, - .read = read_descriptors, - .size = 18 + 65535, /* dev descr + max-size raw descriptor */ -}; - int usb_create_sysfs_dev_files(struct usb_device *udev) { struct device *dev = &udev->dev; @@ -498,10 +450,6 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) if (retval) return retval; - retval = device_create_bin_file(dev, &dev_bin_attr_descriptors); - if (retval) - goto error; - retval = add_persist_attributes(dev); if (retval) goto error; @@ -544,7 +492,6 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev) device_remove_file(dev, &dev_attr_serial); remove_power_attributes(dev); remove_persist_attributes(dev); - device_remove_bin_file(dev, &dev_bin_attr_descriptors); sysfs_remove_group(&dev->kobj, &dev_attr_grp); } diff --git a/trunk/drivers/usb/core/urb.c b/trunk/drivers/usb/core/urb.c index be630228461c..52ec44b828f3 100644 --- a/trunk/drivers/usb/core/urb.c +++ b/trunk/drivers/usb/core/urb.c @@ -440,57 +440,55 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) * @urb: pointer to urb describing a previously submitted request, * may be NULL * - * This routine cancels an in-progress request. URBs complete only once - * per submission, and may be canceled only once per submission. - * Successful cancellation means termination of @urb will be expedited - * and the completion handler will be called with a status code - * indicating that the request has been canceled (rather than any other - * code). - * - * This request is always asynchronous. Success is indicated by - * returning -EINPROGRESS, at which time the URB will probably not yet - * have been given back to the device driver. When it is eventually - * called, the completion function will see @urb->status == -ECONNRESET. - * Failure is indicated by usb_unlink_urb() returning any other value. - * Unlinking will fail when @urb is not currently "linked" (i.e., it was - * never submitted, or it was unlinked before, or the hardware is already - * finished with it), even if the completion handler has not yet run. + * This routine cancels an in-progress request. URBs complete only + * once per submission, and may be canceled only once per submission. + * Successful cancellation means the requests's completion handler will + * be called with a status code indicating that the request has been + * canceled (rather than any other code) and will quickly be removed + * from host controller data structures. + * + * This request is always asynchronous. + * Success is indicated by returning -EINPROGRESS, + * at which time the URB will normally have been unlinked but not yet + * given back to the device driver. When it is called, the completion + * function will see urb->status == -ECONNRESET. Failure is indicated + * by any other return value. Unlinking will fail when the URB is not + * currently "linked" (i.e., it was never submitted, or it was unlinked + * before, or the hardware is already finished with it), even if the + * completion handler has not yet run. * * Unlinking and Endpoint Queues: * - * [The behaviors and guarantees described below do not apply to virtual - * root hubs but only to endpoint queues for physical USB devices.] - * * Host Controller Drivers (HCDs) place all the URBs for a particular * endpoint in a queue. Normally the queue advances as the controller * hardware processes each request. But when an URB terminates with an - * error its queue generally stops (see below), at least until that URB's - * completion routine returns. It is guaranteed that a stopped queue - * will not restart until all its unlinked URBs have been fully retired, - * with their completion routines run, even if that's not until some time - * after the original completion handler returns. The same behavior and - * guarantee apply when an URB terminates because it was unlinked. - * - * Bulk and interrupt endpoint queues are guaranteed to stop whenever an - * URB terminates with any sort of error, including -ECONNRESET, -ENOENT, - * and -EREMOTEIO. Control endpoint queues behave the same way except - * that they are not guaranteed to stop for -EREMOTEIO errors. Queues - * for isochronous endpoints are treated differently, because they must - * advance at fixed rates. Such queues do not stop when an URB - * encounters an error or is unlinked. An unlinked isochronous URB may - * leave a gap in the stream of packets; it is undefined whether such - * gaps can be filled in. - * - * Note that early termination of an URB because a short packet was - * received will generate a -EREMOTEIO error if and only if the - * URB_SHORT_NOT_OK flag is set. By setting this flag, USB device - * drivers can build deep queues for large or complex bulk transfers - * and clean them up reliably after any sort of aborted transfer by - * unlinking all pending URBs at the first fault. - * - * When a control URB terminates with an error other than -EREMOTEIO, it - * is quite likely that the status stage of the transfer will not take - * place. + * error its queue stops, at least until that URB's completion routine + * returns. It is guaranteed that the queue will not restart until all + * its unlinked URBs have been fully retired, with their completion + * routines run, even if that's not until some time after the original + * completion handler returns. Normally the same behavior and guarantees + * apply when an URB terminates because it was unlinked; however if an + * URB is unlinked before the hardware has started to execute it, then + * its queue is not guaranteed to stop until all the preceding URBs have + * completed. + * + * This means that USB device drivers can safely build deep queues for + * large or complex transfers, and clean them up reliably after any sort + * of aborted transfer by unlinking all pending URBs at the first fault. + * + * Note that an URB terminating early because a short packet was received + * will count as an error if and only if the URB_SHORT_NOT_OK flag is set. + * Also, that all unlinks performed in any URB completion handler must + * be asynchronous. + * + * Queues for isochronous endpoints are treated differently, because they + * advance at fixed rates. Such queues do not stop when an URB is unlinked. + * An unlinked URB may leave a gap in the stream of packets. It is undefined + * whether such gaps can be filled in. + * + * When a control URB terminates with an error, it is likely that the + * status stage of the transfer will not take place, even if it is merely + * a soft error resulting from a short-packet with URB_SHORT_NOT_OK set. */ int usb_unlink_urb(struct urb *urb) { diff --git a/trunk/drivers/usb/gadget/Kconfig b/trunk/drivers/usb/gadget/Kconfig index 767aed5b4bea..45e01e289455 100644 --- a/trunk/drivers/usb/gadget/Kconfig +++ b/trunk/drivers/usb/gadget/Kconfig @@ -82,27 +82,6 @@ choice Many controller drivers are platform-specific; these often need board-specific hooks. -config USB_GADGET_AMD5536UDC - boolean "AMD5536 UDC" - depends on PCI - select USB_GADGET_DUALSPEED - help - The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. - It is a USB Highspeed DMA capable USB device controller. Beside ep0 - it provides 4 IN and 4 OUT endpoints (bulk or interrupt type). - The UDC port supports OTG operation, and may be used as a host port - if it's not being used to implement peripheral or OTG roles. - - Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "amd5536udc" and force all - gadget drivers to also be dynamically linked. - -config USB_AMD5536UDC - tristate - depends on USB_GADGET_AMD5536UDC - default USB_GADGET - select USB_GADGET_SELECTED - config USB_GADGET_FSL_USB2 boolean "Freescale Highspeed USB DR Peripheral Controller" depends on MPC834x || PPC_MPC831x @@ -177,24 +156,6 @@ config USB_PXA2XX_SMALL default y if USB_ETH default y if USB_G_SERIAL -config USB_GADGET_M66592 - boolean "Renesas M66592 USB Peripheral Controller" - select USB_GADGET_DUALSPEED - help - M66592 is a discrete USB peripheral controller chip that - supports both full and high speed USB 2.0 data transfers. - It has seven configurable endpoints, and endpoint zero. - - Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "m66592_udc" and force all - gadget drivers to also be dynamically linked. - -config USB_M66592 - tristate - depends on USB_GADGET_M66592 - default USB_GADGET - select USB_GADGET_SELECTED - config USB_GADGET_GOKU boolean "Toshiba TC86C001 'Goku-S'" depends on PCI @@ -300,6 +261,24 @@ config USB_AT91 depends on USB_GADGET_AT91 default USB_GADGET +config USB_GADGET_M66592 + boolean "M66592 driver" + select USB_GADGET_DUALSPEED + help + M66592 is a USB 2.0 peripheral controller. + + It has seven configurable endpoints, and endpoint zero. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "m66592_udc" and force all + gadget drivers to also be dynamically linked. + +config USB_M66592 + tristate + depends on USB_GADGET_M66592 + default USB_GADGET + select USB_GADGET_SELECTED + config USB_GADGET_DUMMY_HCD boolean "Dummy HCD (DEVELOPMENT)" depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL diff --git a/trunk/drivers/usb/gadget/Makefile b/trunk/drivers/usb/gadget/Makefile index 1bc0f03550ce..8ae76f738635 100644 --- a/trunk/drivers/usb/gadget/Makefile +++ b/trunk/drivers/usb/gadget/Makefile @@ -7,7 +7,6 @@ endif obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o obj-$(CONFIG_USB_NET2280) += net2280.o -obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o obj-$(CONFIG_USB_GOKU) += goku_udc.o obj-$(CONFIG_USB_OMAP) += omap_udc.o diff --git a/trunk/drivers/usb/gadget/amd5536udc.c b/trunk/drivers/usb/gadget/amd5536udc.c deleted file mode 100644 index 714156ca8fe4..000000000000 --- a/trunk/drivers/usb/gadget/amd5536udc.c +++ /dev/null @@ -1,3454 +0,0 @@ -/* - * amd5536.c -- AMD 5536 UDC high/full speed USB device controller - * - * Copyright (C) 2005-2007 AMD (http://www.amd.com) - * Author: Thomas Dahlmann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * The AMD5536 UDC is part of the x86 southbridge AMD Geode CS5536. - * It is a USB Highspeed DMA capable USB device controller. Beside ep0 it - * provides 4 IN and 4 OUT endpoints (bulk or interrupt type). - * - * Make sure that UDC is assigned to port 4 by BIOS settings (port can also - * be used as host port) and UOC bits PAD_EN and APU are set (should be done - * by BIOS init). - * - * UDC DMA requires 32-bit aligned buffers so DMA with gadget ether does not - * work without updating NET_IP_ALIGN. Or PIO mode (module param "use_dma=0") - * can be used with gadget ether. - */ - -/* debug control */ -/* #define UDC_VERBOSE */ - -/* Driver strings */ -#define UDC_MOD_DESCRIPTION "AMD 5536 UDC - USB Device Controller" -#define UDC_DRIVER_VERSION_STRING "01.00.0206 - $Revision: #3 $" - -/* system */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* gadget stack */ -#include -#include - -/* udc specific */ -#include "amd5536udc.h" - - -static void udc_tasklet_disconnect(unsigned long); -static void empty_req_queue(struct udc_ep *); -static int udc_probe(struct udc *dev); -static void udc_basic_init(struct udc *dev); -static void udc_setup_endpoints(struct udc *dev); -static void udc_soft_reset(struct udc *dev); -static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep); -static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq); -static int udc_free_dma_chain(struct udc *dev, struct udc_request *req); -static int udc_create_dma_chain(struct udc_ep *ep, struct udc_request *req, - unsigned long buf_len, gfp_t gfp_flags); -static int udc_remote_wakeup(struct udc *dev); -static int udc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); -static void udc_pci_remove(struct pci_dev *pdev); - -/* description */ -static const char mod_desc[] = UDC_MOD_DESCRIPTION; -static const char name[] = "amd5536udc"; - -/* structure to hold endpoint function pointers */ -static const struct usb_ep_ops udc_ep_ops; - -/* received setup data */ -static union udc_setup_data setup_data; - -/* pointer to device object */ -static struct udc *udc; - -/* irq spin lock for soft reset */ -static DEFINE_SPINLOCK(udc_irq_spinlock); -/* stall spin lock */ -static DEFINE_SPINLOCK(udc_stall_spinlock); - -/* -* slave mode: pending bytes in rx fifo after nyet, -* used if EPIN irq came but no req was available -*/ -static unsigned int udc_rxfifo_pending; - -/* count soft resets after suspend to avoid loop */ -static int soft_reset_occured; -static int soft_reset_after_usbreset_occured; - -/* timer */ -static struct timer_list udc_timer; -static int stop_timer; - -/* set_rde -- Is used to control enabling of RX DMA. Problem is - * that UDC has only one bit (RDE) to enable/disable RX DMA for - * all OUT endpoints. So we have to handle race conditions like - * when OUT data reaches the fifo but no request was queued yet. - * This cannot be solved by letting the RX DMA disabled until a - * request gets queued because there may be other OUT packets - * in the FIFO (important for not blocking control traffic). - * The value of set_rde controls the correspondig timer. - * - * set_rde -1 == not used, means it is alloed to be set to 0 or 1 - * set_rde 0 == do not touch RDE, do no start the RDE timer - * set_rde 1 == timer function will look whether FIFO has data - * set_rde 2 == set by timer function to enable RX DMA on next call - */ -static int set_rde = -1; - -static DECLARE_COMPLETION(on_exit); -static struct timer_list udc_pollstall_timer; -static int stop_pollstall_timer; -static DECLARE_COMPLETION(on_pollstall_exit); - -/* tasklet for usb disconnect */ -static DECLARE_TASKLET(disconnect_tasklet, udc_tasklet_disconnect, - (unsigned long) &udc); - - -/* endpoint names used for print */ -static const char ep0_string[] = "ep0in"; -static const char *ep_string[] = { - ep0_string, - "ep1in-int", "ep2in-bulk", "ep3in-bulk", "ep4in-bulk", "ep5in-bulk", - "ep6in-bulk", "ep7in-bulk", "ep8in-bulk", "ep9in-bulk", "ep10in-bulk", - "ep11in-bulk", "ep12in-bulk", "ep13in-bulk", "ep14in-bulk", - "ep15in-bulk", "ep0out", "ep1out-bulk", "ep2out-bulk", "ep3out-bulk", - "ep4out-bulk", "ep5out-bulk", "ep6out-bulk", "ep7out-bulk", - "ep8out-bulk", "ep9out-bulk", "ep10out-bulk", "ep11out-bulk", - "ep12out-bulk", "ep13out-bulk", "ep14out-bulk", "ep15out-bulk" -}; - -/* DMA usage flag */ -static int use_dma = 1; -/* packet per buffer dma */ -static int use_dma_ppb = 1; -/* with per descr. update */ -static int use_dma_ppb_du; -/* buffer fill mode */ -static int use_dma_bufferfill_mode; -/* full speed only mode */ -static int use_fullspeed; -/* tx buffer size for high speed */ -static unsigned long hs_tx_buf = UDC_EPIN_BUFF_SIZE; - -/* module parameters */ -module_param(use_dma, bool, S_IRUGO); -MODULE_PARM_DESC(use_dma, "true for DMA"); -module_param(use_dma_ppb, bool, S_IRUGO); -MODULE_PARM_DESC(use_dma_ppb, "true for DMA in packet per buffer mode"); -module_param(use_dma_ppb_du, bool, S_IRUGO); -MODULE_PARM_DESC(use_dma_ppb_du, - "true for DMA in packet per buffer mode with descriptor update"); -module_param(use_fullspeed, bool, S_IRUGO); -MODULE_PARM_DESC(use_fullspeed, "true for fullspeed only"); - -/*---------------------------------------------------------------------------*/ -/* Prints UDC device registers and endpoint irq registers */ -static void print_regs(struct udc *dev) -{ - DBG(dev, "------- Device registers -------\n"); - DBG(dev, "dev config = %08x\n", readl(&dev->regs->cfg)); - DBG(dev, "dev control = %08x\n", readl(&dev->regs->ctl)); - DBG(dev, "dev status = %08x\n", readl(&dev->regs->sts)); - DBG(dev, "\n"); - DBG(dev, "dev int's = %08x\n", readl(&dev->regs->irqsts)); - DBG(dev, "dev intmask = %08x\n", readl(&dev->regs->irqmsk)); - DBG(dev, "\n"); - DBG(dev, "dev ep int's = %08x\n", readl(&dev->regs->ep_irqsts)); - DBG(dev, "dev ep intmask = %08x\n", readl(&dev->regs->ep_irqmsk)); - DBG(dev, "\n"); - DBG(dev, "USE DMA = %d\n", use_dma); - if (use_dma && use_dma_ppb && !use_dma_ppb_du) { - DBG(dev, "DMA mode = PPBNDU (packet per buffer " - "WITHOUT desc. update)\n"); - dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBNDU"); - } else if (use_dma && use_dma_ppb_du && use_dma_ppb_du) { - DBG(dev, "DMA mode = PPBDU (packet per buffer " - "WITH desc. update)\n"); - dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBDU"); - } - if (use_dma && use_dma_bufferfill_mode) { - DBG(dev, "DMA mode = BF (buffer fill mode)\n"); - dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "BF"); - } - if (!use_dma) { - dev_info(&dev->pdev->dev, "FIFO mode\n"); - } - DBG(dev, "-------------------------------------------------------\n"); -} - -/* Masks unused interrupts */ -static int udc_mask_unused_interrupts(struct udc *dev) -{ - u32 tmp; - - /* mask all dev interrupts */ - tmp = AMD_BIT(UDC_DEVINT_SVC) | - AMD_BIT(UDC_DEVINT_ENUM) | - AMD_BIT(UDC_DEVINT_US) | - AMD_BIT(UDC_DEVINT_UR) | - AMD_BIT(UDC_DEVINT_ES) | - AMD_BIT(UDC_DEVINT_SI) | - AMD_BIT(UDC_DEVINT_SOF)| - AMD_BIT(UDC_DEVINT_SC); - writel(tmp, &dev->regs->irqmsk); - - /* mask all ep interrupts */ - writel(UDC_EPINT_MSK_DISABLE_ALL, &dev->regs->ep_irqmsk); - - return 0; -} - -/* Enables endpoint 0 interrupts */ -static int udc_enable_ep0_interrupts(struct udc *dev) -{ - u32 tmp; - - DBG(dev, "udc_enable_ep0_interrupts()\n"); - - /* read irq mask */ - tmp = readl(&dev->regs->ep_irqmsk); - /* enable ep0 irq's */ - tmp &= AMD_UNMASK_BIT(UDC_EPINT_IN_EP0) - & AMD_UNMASK_BIT(UDC_EPINT_OUT_EP0); - writel(tmp, &dev->regs->ep_irqmsk); - - return 0; -} - -/* Enables device interrupts for SET_INTF and SET_CONFIG */ -static int udc_enable_dev_setup_interrupts(struct udc *dev) -{ - u32 tmp; - - DBG(dev, "enable device interrupts for setup data\n"); - - /* read irq mask */ - tmp = readl(&dev->regs->irqmsk); - - /* enable SET_INTERFACE, SET_CONFIG and other needed irq's */ - tmp &= AMD_UNMASK_BIT(UDC_DEVINT_SI) - & AMD_UNMASK_BIT(UDC_DEVINT_SC) - & AMD_UNMASK_BIT(UDC_DEVINT_UR) - & AMD_UNMASK_BIT(UDC_DEVINT_SVC) - & AMD_UNMASK_BIT(UDC_DEVINT_ENUM); - writel(tmp, &dev->regs->irqmsk); - - return 0; -} - -/* Calculates fifo start of endpoint based on preceeding endpoints */ -static int udc_set_txfifo_addr(struct udc_ep *ep) -{ - struct udc *dev; - u32 tmp; - int i; - - if (!ep || !(ep->in)) - return -EINVAL; - - dev = ep->dev; - ep->txfifo = dev->txfifo; - - /* traverse ep's */ - for (i = 0; i < ep->num; i++) { - if (dev->ep[i].regs) { - /* read fifo size */ - tmp = readl(&dev->ep[i].regs->bufin_framenum); - tmp = AMD_GETBITS(tmp, UDC_EPIN_BUFF_SIZE); - ep->txfifo += tmp; - } - } - return 0; -} - -/* CNAK pending field: bit0 = ep0in, bit16 = ep0out */ -static u32 cnak_pending; - -static void UDC_QUEUE_CNAK(struct udc_ep *ep, unsigned num) -{ - if (readl(&ep->regs->ctl) & AMD_BIT(UDC_EPCTL_NAK)) { - DBG(ep->dev, "NAK could not be cleared for ep%d\n", num); - cnak_pending |= 1 << (num); - ep->naking = 1; - } else - cnak_pending = cnak_pending & (~(1 << (num))); -} - - -/* Enables endpoint, is called by gadget driver */ -static int -udc_ep_enable(struct usb_ep *usbep, const struct usb_endpoint_descriptor *desc) -{ - struct udc_ep *ep; - struct udc *dev; - u32 tmp; - unsigned long iflags; - u8 udc_csr_epix; - - if (!usbep - || usbep->name == ep0_string - || !desc - || desc->bDescriptorType != USB_DT_ENDPOINT) - return -EINVAL; - - ep = container_of(usbep, struct udc_ep, ep); - dev = ep->dev; - - DBG(dev, "udc_ep_enable() ep %d\n", ep->num); - - if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) - return -ESHUTDOWN; - - spin_lock_irqsave(&dev->lock, iflags); - ep->desc = desc; - - ep->halted = 0; - - /* set traffic type */ - tmp = readl(&dev->ep[ep->num].regs->ctl); - tmp = AMD_ADDBITS(tmp, desc->bmAttributes, UDC_EPCTL_ET); - writel(tmp, &dev->ep[ep->num].regs->ctl); - - /* set max packet size */ - tmp = readl(&dev->ep[ep->num].regs->bufout_maxpkt); - tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, UDC_EP_MAX_PKT_SIZE); - ep->ep.maxpacket = desc->wMaxPacketSize; - writel(tmp, &dev->ep[ep->num].regs->bufout_maxpkt); - - /* IN ep */ - if (ep->in) { - - /* ep ix in UDC CSR register space */ - udc_csr_epix = ep->num; - - /* set buffer size (tx fifo entries) */ - tmp = readl(&dev->ep[ep->num].regs->bufin_framenum); - /* double buffering: fifo size = 2 x max packet size */ - tmp = AMD_ADDBITS( - tmp, - desc->wMaxPacketSize * UDC_EPIN_BUFF_SIZE_MULT - / UDC_DWORD_BYTES, - UDC_EPIN_BUFF_SIZE); - writel(tmp, &dev->ep[ep->num].regs->bufin_framenum); - - /* calc. tx fifo base addr */ - udc_set_txfifo_addr(ep); - - /* flush fifo */ - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_F); - writel(tmp, &ep->regs->ctl); - - /* OUT ep */ - } else { - /* ep ix in UDC CSR register space */ - udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS; - - /* set max packet size UDC CSR */ - tmp = readl(&dev->csr->ne[ep->num - UDC_CSR_EP_OUT_IX_OFS]); - tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, - UDC_CSR_NE_MAX_PKT); - writel(tmp, &dev->csr->ne[ep->num - UDC_CSR_EP_OUT_IX_OFS]); - - if (use_dma && !ep->in) { - /* alloc and init BNA dummy request */ - ep->bna_dummy_req = udc_alloc_bna_dummy(ep); - ep->bna_occurred = 0; - } - - if (ep->num != UDC_EP0OUT_IX) - dev->data_ep_enabled = 1; - } - - /* set ep values */ - tmp = readl(&dev->csr->ne[udc_csr_epix]); - /* max packet */ - tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, UDC_CSR_NE_MAX_PKT); - /* ep number */ - tmp = AMD_ADDBITS(tmp, desc->bEndpointAddress, UDC_CSR_NE_NUM); - /* ep direction */ - tmp = AMD_ADDBITS(tmp, ep->in, UDC_CSR_NE_DIR); - /* ep type */ - tmp = AMD_ADDBITS(tmp, desc->bmAttributes, UDC_CSR_NE_TYPE); - /* ep config */ - tmp = AMD_ADDBITS(tmp, ep->dev->cur_config, UDC_CSR_NE_CFG); - /* ep interface */ - tmp = AMD_ADDBITS(tmp, ep->dev->cur_intf, UDC_CSR_NE_INTF); - /* ep alt */ - tmp = AMD_ADDBITS(tmp, ep->dev->cur_alt, UDC_CSR_NE_ALT); - /* write reg */ - writel(tmp, &dev->csr->ne[udc_csr_epix]); - - /* enable ep irq */ - tmp = readl(&dev->regs->ep_irqmsk); - tmp &= AMD_UNMASK_BIT(ep->num); - writel(tmp, &dev->regs->ep_irqmsk); - - /* - * clear NAK by writing CNAK - * avoid BNA for OUT DMA, don't clear NAK until DMA desc. written - */ - if (!use_dma || ep->in) { - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &ep->regs->ctl); - ep->naking = 0; - UDC_QUEUE_CNAK(ep, ep->num); - } - tmp = desc->bEndpointAddress; - DBG(dev, "%s enabled\n", usbep->name); - - spin_unlock_irqrestore(&dev->lock, iflags); - return 0; -} - -/* Resets endpoint */ -static void ep_init(struct udc_regs __iomem *regs, struct udc_ep *ep) -{ - u32 tmp; - - VDBG(ep->dev, "ep-%d reset\n", ep->num); - ep->desc = NULL; - ep->ep.ops = &udc_ep_ops; - INIT_LIST_HEAD(&ep->queue); - - ep->ep.maxpacket = (u16) ~0; - /* set NAK */ - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_SNAK); - writel(tmp, &ep->regs->ctl); - ep->naking = 1; - - /* disable interrupt */ - tmp = readl(®s->ep_irqmsk); - tmp |= AMD_BIT(ep->num); - writel(tmp, ®s->ep_irqmsk); - - if (ep->in) { - /* unset P and IN bit of potential former DMA */ - tmp = readl(&ep->regs->ctl); - tmp &= AMD_UNMASK_BIT(UDC_EPCTL_P); - writel(tmp, &ep->regs->ctl); - - tmp = readl(&ep->regs->sts); - tmp |= AMD_BIT(UDC_EPSTS_IN); - writel(tmp, &ep->regs->sts); - - /* flush the fifo */ - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_F); - writel(tmp, &ep->regs->ctl); - - } - /* reset desc pointer */ - writel(0, &ep->regs->desptr); -} - -/* Disables endpoint, is called by gadget driver */ -static int udc_ep_disable(struct usb_ep *usbep) -{ - struct udc_ep *ep = NULL; - unsigned long iflags; - - if (!usbep) - return -EINVAL; - - ep = container_of(usbep, struct udc_ep, ep); - if (usbep->name == ep0_string || !ep->desc) - return -EINVAL; - - DBG(ep->dev, "Disable ep-%d\n", ep->num); - - spin_lock_irqsave(&ep->dev->lock, iflags); - udc_free_request(&ep->ep, &ep->bna_dummy_req->req); - empty_req_queue(ep); - ep_init(ep->dev->regs, ep); - spin_unlock_irqrestore(&ep->dev->lock, iflags); - - return 0; -} - -/* Allocates request packet, called by gadget driver */ -static struct usb_request * -udc_alloc_request(struct usb_ep *usbep, gfp_t gfp) -{ - struct udc_request *req; - struct udc_data_dma *dma_desc; - struct udc_ep *ep; - - if (!usbep) - return NULL; - - ep = container_of(usbep, struct udc_ep, ep); - - VDBG(ep->dev, "udc_alloc_req(): ep%d\n", ep->num); - req = kzalloc(sizeof(struct udc_request), gfp); - if (!req) - return NULL; - - req->req.dma = DMA_DONT_USE; - INIT_LIST_HEAD(&req->queue); - - if (ep->dma) { - /* ep0 in requests are allocated from data pool here */ - dma_desc = pci_pool_alloc(ep->dev->data_requests, gfp, - &req->td_phys); - if (!dma_desc) { - kfree(req); - return NULL; - } - - VDBG(ep->dev, "udc_alloc_req: req = %p dma_desc = %p, " - "td_phys = %lx\n", - req, dma_desc, - (unsigned long)req->td_phys); - /* prevent from using desc. - set HOST BUSY */ - dma_desc->status = AMD_ADDBITS(dma_desc->status, - UDC_DMA_STP_STS_BS_HOST_BUSY, - UDC_DMA_STP_STS_BS); - dma_desc->bufptr = __constant_cpu_to_le32(DMA_DONT_USE); - req->td_data = dma_desc; - req->td_data_last = NULL; - req->chain_len = 1; - } - - return &req->req; -} - -/* Frees request packet, called by gadget driver */ -static void -udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq) -{ - struct udc_ep *ep; - struct udc_request *req; - - if (!usbep || !usbreq) - return; - - ep = container_of(usbep, struct udc_ep, ep); - req = container_of(usbreq, struct udc_request, req); - VDBG(ep->dev, "free_req req=%p\n", req); - BUG_ON(!list_empty(&req->queue)); - if (req->td_data) { - VDBG(ep->dev, "req->td_data=%p\n", req->td_data); - - /* free dma chain if created */ - if (req->chain_len > 1) { - udc_free_dma_chain(ep->dev, req); - } - - pci_pool_free(ep->dev->data_requests, req->td_data, - req->td_phys); - } - kfree(req); -} - -/* Init BNA dummy descriptor for HOST BUSY and pointing to itself */ -static void udc_init_bna_dummy(struct udc_request *req) -{ - if (req) { - /* set last bit */ - req->td_data->status |= AMD_BIT(UDC_DMA_IN_STS_L); - /* set next pointer to itself */ - req->td_data->next = req->td_phys; - /* set HOST BUSY */ - req->td_data->status - = AMD_ADDBITS(req->td_data->status, - UDC_DMA_STP_STS_BS_DMA_DONE, - UDC_DMA_STP_STS_BS); -#ifdef UDC_VERBOSE - pr_debug("bna desc = %p, sts = %08x\n", - req->td_data, req->td_data->status); -#endif - } -} - -/* Allocate BNA dummy descriptor */ -static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep) -{ - struct udc_request *req = NULL; - struct usb_request *_req = NULL; - - /* alloc the dummy request */ - _req = udc_alloc_request(&ep->ep, GFP_ATOMIC); - if (_req) { - req = container_of(_req, struct udc_request, req); - ep->bna_dummy_req = req; - udc_init_bna_dummy(req); - } - return req; -} - -/* Write data to TX fifo for IN packets */ -static void -udc_txfifo_write(struct udc_ep *ep, struct usb_request *req) -{ - u8 *req_buf; - u32 *buf; - int i, j; - unsigned bytes = 0; - unsigned remaining = 0; - - if (!req || !ep) - return; - - req_buf = req->buf + req->actual; - prefetch(req_buf); - remaining = req->length - req->actual; - - buf = (u32 *) req_buf; - - bytes = ep->ep.maxpacket; - if (bytes > remaining) - bytes = remaining; - - /* dwords first */ - for (i = 0; i < bytes / UDC_DWORD_BYTES; i++) { - writel(*(buf + i), ep->txfifo); - } - - /* remaining bytes must be written by byte access */ - for (j = 0; j < bytes % UDC_DWORD_BYTES; j++) { - writeb((u8)(*(buf + i) >> (j << UDC_BITS_PER_BYTE_SHIFT)), - ep->txfifo); - } - - /* dummy write confirm */ - writel(0, &ep->regs->confirm); -} - -/* Read dwords from RX fifo for OUT transfers */ -static int udc_rxfifo_read_dwords(struct udc *dev, u32 *buf, int dwords) -{ - int i; - - VDBG(dev, "udc_read_dwords(): %d dwords\n", dwords); - - for (i = 0; i < dwords; i++) { - *(buf + i) = readl(dev->rxfifo); - } - return 0; -} - -/* Read bytes from RX fifo for OUT transfers */ -static int udc_rxfifo_read_bytes(struct udc *dev, u8 *buf, int bytes) -{ - int i, j; - u32 tmp; - - VDBG(dev, "udc_read_bytes(): %d bytes\n", bytes); - - /* dwords first */ - for (i = 0; i < bytes / UDC_DWORD_BYTES; i++) { - *((u32 *)(buf + (i<<2))) = readl(dev->rxfifo); - } - - /* remaining bytes must be read by byte access */ - if (bytes % UDC_DWORD_BYTES) { - tmp = readl(dev->rxfifo); - for (j = 0; j < bytes % UDC_DWORD_BYTES; j++) { - *(buf + (i<<2) + j) = (u8)(tmp & UDC_BYTE_MASK); - tmp = tmp >> UDC_BITS_PER_BYTE; - } - } - - return 0; -} - -/* Read data from RX fifo for OUT transfers */ -static int -udc_rxfifo_read(struct udc_ep *ep, struct udc_request *req) -{ - u8 *buf; - unsigned buf_space; - unsigned bytes = 0; - unsigned finished = 0; - - /* received number bytes */ - bytes = readl(&ep->regs->sts); - bytes = AMD_GETBITS(bytes, UDC_EPSTS_RX_PKT_SIZE); - - buf_space = req->req.length - req->req.actual; - buf = req->req.buf + req->req.actual; - if (bytes > buf_space) { - if ((buf_space % ep->ep.maxpacket) != 0) { - DBG(ep->dev, - "%s: rx %d bytes, rx-buf space = %d bytesn\n", - ep->ep.name, bytes, buf_space); - req->req.status = -EOVERFLOW; - } - bytes = buf_space; - } - req->req.actual += bytes; - - /* last packet ? */ - if (((bytes % ep->ep.maxpacket) != 0) || (!bytes) - || ((req->req.actual == req->req.length) && !req->req.zero)) - finished = 1; - - /* read rx fifo bytes */ - VDBG(ep->dev, "ep %s: rxfifo read %d bytes\n", ep->ep.name, bytes); - udc_rxfifo_read_bytes(ep->dev, buf, bytes); - - return finished; -} - -/* create/re-init a DMA descriptor or a DMA descriptor chain */ -static int prep_dma(struct udc_ep *ep, struct udc_request *req, gfp_t gfp) -{ - int retval = 0; - u32 tmp; - - VDBG(ep->dev, "prep_dma\n"); - VDBG(ep->dev, "prep_dma ep%d req->td_data=%p\n", - ep->num, req->td_data); - - /* set buffer pointer */ - req->td_data->bufptr = req->req.dma; - - /* set last bit */ - req->td_data->status |= AMD_BIT(UDC_DMA_IN_STS_L); - - /* build/re-init dma chain if maxpkt scatter mode, not for EP0 */ - if (use_dma_ppb) { - - retval = udc_create_dma_chain(ep, req, ep->ep.maxpacket, gfp); - if (retval != 0) { - if (retval == -ENOMEM) - DBG(ep->dev, "Out of DMA memory\n"); - return retval; - } - if (ep->in) { - if (req->req.length == ep->ep.maxpacket) { - /* write tx bytes */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - ep->ep.maxpacket, - UDC_DMA_IN_STS_TXBYTES); - - } - } - - } - - if (ep->in) { - VDBG(ep->dev, "IN: use_dma_ppb=%d req->req.len=%d " - "maxpacket=%d ep%d\n", - use_dma_ppb, req->req.length, - ep->ep.maxpacket, ep->num); - /* - * if bytes < max packet then tx bytes must - * be written in packet per buffer mode - */ - if (!use_dma_ppb || req->req.length < ep->ep.maxpacket - || ep->num == UDC_EP0OUT_IX - || ep->num == UDC_EP0IN_IX) { - /* write tx bytes */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - req->req.length, - UDC_DMA_IN_STS_TXBYTES); - /* reset frame num */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - 0, - UDC_DMA_IN_STS_FRAMENUM); - } - /* set HOST BUSY */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - UDC_DMA_STP_STS_BS_HOST_BUSY, - UDC_DMA_STP_STS_BS); - } else { - VDBG(ep->dev, "OUT set host ready\n"); - /* set HOST READY */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - UDC_DMA_STP_STS_BS_HOST_READY, - UDC_DMA_STP_STS_BS); - - - /* clear NAK by writing CNAK */ - if (ep->naking) { - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &ep->regs->ctl); - ep->naking = 0; - UDC_QUEUE_CNAK(ep, ep->num); - } - - } - - return retval; -} - -/* Completes request packet ... caller MUST hold lock */ -static void -complete_req(struct udc_ep *ep, struct udc_request *req, int sts) -__releases(ep->dev->lock) -__acquires(ep->dev->lock) -{ - struct udc *dev; - unsigned halted; - - VDBG(ep->dev, "complete_req(): ep%d\n", ep->num); - - dev = ep->dev; - /* unmap DMA */ - if (req->dma_mapping) { - if (ep->in) - pci_unmap_single(dev->pdev, - req->req.dma, - req->req.length, - PCI_DMA_TODEVICE); - else - pci_unmap_single(dev->pdev, - req->req.dma, - req->req.length, - PCI_DMA_FROMDEVICE); - req->dma_mapping = 0; - req->req.dma = DMA_DONT_USE; - } - - halted = ep->halted; - ep->halted = 1; - - /* set new status if pending */ - if (req->req.status == -EINPROGRESS) - req->req.status = sts; - - /* remove from ep queue */ - list_del_init(&req->queue); - - VDBG(ep->dev, "req %p => complete %d bytes at %s with sts %d\n", - &req->req, req->req.length, ep->ep.name, sts); - - spin_unlock(&dev->lock); - req->req.complete(&ep->ep, &req->req); - spin_lock(&dev->lock); - ep->halted = halted; -} - -/* frees pci pool descriptors of a DMA chain */ -static int udc_free_dma_chain(struct udc *dev, struct udc_request *req) -{ - - int ret_val = 0; - struct udc_data_dma *td; - struct udc_data_dma *td_last = NULL; - unsigned int i; - - DBG(dev, "free chain req = %p\n", req); - - /* do not free first desc., will be done by free for request */ - td_last = req->td_data; - td = phys_to_virt(td_last->next); - - for (i = 1; i < req->chain_len; i++) { - - pci_pool_free(dev->data_requests, td, - (dma_addr_t) td_last->next); - td_last = td; - td = phys_to_virt(td_last->next); - } - - return ret_val; -} - -/* Iterates to the end of a DMA chain and returns last descriptor */ -static struct udc_data_dma *udc_get_last_dma_desc(struct udc_request *req) -{ - struct udc_data_dma *td; - - td = req->td_data; - while (td && !(td->status & AMD_BIT(UDC_DMA_IN_STS_L))) { - td = phys_to_virt(td->next); - } - - return td; - -} - -/* Iterates to the end of a DMA chain and counts bytes received */ -static u32 udc_get_ppbdu_rxbytes(struct udc_request *req) -{ - struct udc_data_dma *td; - u32 count; - - td = req->td_data; - /* received number bytes */ - count = AMD_GETBITS(td->status, UDC_DMA_OUT_STS_RXBYTES); - - while (td && !(td->status & AMD_BIT(UDC_DMA_IN_STS_L))) { - td = phys_to_virt(td->next); - /* received number bytes */ - if (td) { - count += AMD_GETBITS(td->status, - UDC_DMA_OUT_STS_RXBYTES); - } - } - - return count; - -} - -/* Creates or re-inits a DMA chain */ -static int udc_create_dma_chain( - struct udc_ep *ep, - struct udc_request *req, - unsigned long buf_len, gfp_t gfp_flags -) -{ - unsigned long bytes = req->req.length; - unsigned int i; - dma_addr_t dma_addr; - struct udc_data_dma *td = NULL; - struct udc_data_dma *last = NULL; - unsigned long txbytes; - unsigned create_new_chain = 0; - unsigned len; - - VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n", - bytes, buf_len); - dma_addr = DMA_DONT_USE; - - /* unset L bit in first desc for OUT */ - if (!ep->in) { - req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L); - } - - /* alloc only new desc's if not already available */ - len = req->req.length / ep->ep.maxpacket; - if (req->req.length % ep->ep.maxpacket) { - len++; - } - - if (len > req->chain_len) { - /* shorter chain already allocated before */ - if (req->chain_len > 1) { - udc_free_dma_chain(ep->dev, req); - } - req->chain_len = len; - create_new_chain = 1; - } - - td = req->td_data; - /* gen. required number of descriptors and buffers */ - for (i = buf_len; i < bytes; i += buf_len) { - /* create or determine next desc. */ - if (create_new_chain) { - - td = pci_pool_alloc(ep->dev->data_requests, - gfp_flags, &dma_addr); - if (!td) - return -ENOMEM; - - td->status = 0; - } else if (i == buf_len) { - /* first td */ - td = (struct udc_data_dma *) phys_to_virt( - req->td_data->next); - td->status = 0; - } else { - td = (struct udc_data_dma *) phys_to_virt(last->next); - td->status = 0; - } - - - if (td) - td->bufptr = req->req.dma + i; /* assign buffer */ - else - break; - - /* short packet ? */ - if ((bytes - i) >= buf_len) { - txbytes = buf_len; - } else { - /* short packet */ - txbytes = bytes - i; - } - - /* link td and assign tx bytes */ - if (i == buf_len) { - if (create_new_chain) { - req->td_data->next = dma_addr; - } else { - /* req->td_data->next = virt_to_phys(td); */ - } - /* write tx bytes */ - if (ep->in) { - /* first desc */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - ep->ep.maxpacket, - UDC_DMA_IN_STS_TXBYTES); - /* second desc */ - td->status = AMD_ADDBITS(td->status, - txbytes, - UDC_DMA_IN_STS_TXBYTES); - } - } else { - if (create_new_chain) { - last->next = dma_addr; - } else { - /* last->next = virt_to_phys(td); */ - } - if (ep->in) { - /* write tx bytes */ - td->status = AMD_ADDBITS(td->status, - txbytes, - UDC_DMA_IN_STS_TXBYTES); - } - } - last = td; - } - /* set last bit */ - if (td) { - td->status |= AMD_BIT(UDC_DMA_IN_STS_L); - /* last desc. points to itself */ - req->td_data_last = td; - } - - return 0; -} - -/* Enabling RX DMA */ -static void udc_set_rde(struct udc *dev) -{ - u32 tmp; - - VDBG(dev, "udc_set_rde()\n"); - /* stop RDE timer */ - if (timer_pending(&udc_timer)) { - set_rde = 0; - mod_timer(&udc_timer, jiffies - 1); - } - /* set RDE */ - tmp = readl(&dev->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_RDE); - writel(tmp, &dev->regs->ctl); -} - -/* Queues a request packet, called by gadget driver */ -static int -udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp) -{ - int retval = 0; - u8 open_rxfifo = 0; - unsigned long iflags; - struct udc_ep *ep; - struct udc_request *req; - struct udc *dev; - u32 tmp; - - /* check the inputs */ - req = container_of(usbreq, struct udc_request, req); - - if (!usbep || !usbreq || !usbreq->complete || !usbreq->buf - || !list_empty(&req->queue)) - return -EINVAL; - - ep = container_of(usbep, struct udc_ep, ep); - if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX)) - return -EINVAL; - - VDBG(ep->dev, "udc_queue(): ep%d-in=%d\n", ep->num, ep->in); - dev = ep->dev; - - if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) - return -ESHUTDOWN; - - /* map dma (usually done before) */ - if (ep->dma && usbreq->length != 0 - && (usbreq->dma == DMA_DONT_USE || usbreq->dma == 0)) { - VDBG(dev, "DMA map req %p\n", req); - if (ep->in) - usbreq->dma = pci_map_single(dev->pdev, - usbreq->buf, - usbreq->length, - PCI_DMA_TODEVICE); - else - usbreq->dma = pci_map_single(dev->pdev, - usbreq->buf, - usbreq->length, - PCI_DMA_FROMDEVICE); - req->dma_mapping = 1; - } - - VDBG(dev, "%s queue req %p, len %d req->td_data=%p buf %p\n", - usbep->name, usbreq, usbreq->length, - req->td_data, usbreq->buf); - - spin_lock_irqsave(&dev->lock, iflags); - usbreq->actual = 0; - usbreq->status = -EINPROGRESS; - req->dma_done = 0; - - /* on empty queue just do first transfer */ - if (list_empty(&ep->queue)) { - /* zlp */ - if (usbreq->length == 0) { - /* IN zlp's are handled by hardware */ - complete_req(ep, req, 0); - VDBG(dev, "%s: zlp\n", ep->ep.name); - /* - * if set_config or set_intf is waiting for ack by zlp - * then set CSR_DONE - */ - if (dev->set_cfg_not_acked) { - tmp = readl(&dev->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_CSR_DONE); - writel(tmp, &dev->regs->ctl); - dev->set_cfg_not_acked = 0; - } - /* setup command is ACK'ed now by zlp */ - if (dev->waiting_zlp_ack_ep0in) { - /* clear NAK by writing CNAK in EP0_IN */ - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); - dev->ep[UDC_EP0IN_IX].naking = 0; - UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX], - UDC_EP0IN_IX); - dev->waiting_zlp_ack_ep0in = 0; - } - goto finished; - } - if (ep->dma) { - retval = prep_dma(ep, req, gfp); - if (retval != 0) - goto finished; - /* write desc pointer to enable DMA */ - if (ep->in) { - /* set HOST READY */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - UDC_DMA_IN_STS_BS_HOST_READY, - UDC_DMA_IN_STS_BS); - } - - /* disabled rx dma while descriptor update */ - if (!ep->in) { - /* stop RDE timer */ - if (timer_pending(&udc_timer)) { - set_rde = 0; - mod_timer(&udc_timer, jiffies - 1); - } - /* clear RDE */ - tmp = readl(&dev->regs->ctl); - tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_RDE); - writel(tmp, &dev->regs->ctl); - open_rxfifo = 1; - - /* - * if BNA occurred then let BNA dummy desc. - * point to current desc. - */ - if (ep->bna_occurred) { - VDBG(dev, "copy to BNA dummy desc.\n"); - memcpy(ep->bna_dummy_req->td_data, - req->td_data, - sizeof(struct udc_data_dma)); - } - } - /* write desc pointer */ - writel(req->td_phys, &ep->regs->desptr); - - /* clear NAK by writing CNAK */ - if (ep->naking) { - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &ep->regs->ctl); - ep->naking = 0; - UDC_QUEUE_CNAK(ep, ep->num); - } - - if (ep->in) { - /* enable ep irq */ - tmp = readl(&dev->regs->ep_irqmsk); - tmp &= AMD_UNMASK_BIT(ep->num); - writel(tmp, &dev->regs->ep_irqmsk); - } - } - - } else if (ep->dma) { - - /* - * prep_dma not used for OUT ep's, this is not possible - * for PPB modes, because of chain creation reasons - */ - if (ep->in) { - retval = prep_dma(ep, req, gfp); - if (retval != 0) - goto finished; - } - } - VDBG(dev, "list_add\n"); - /* add request to ep queue */ - if (req) { - - list_add_tail(&req->queue, &ep->queue); - - /* open rxfifo if out data queued */ - if (open_rxfifo) { - /* enable DMA */ - req->dma_going = 1; - udc_set_rde(dev); - if (ep->num != UDC_EP0OUT_IX) - dev->data_ep_queued = 1; - } - /* stop OUT naking */ - if (!ep->in) { - if (!use_dma && udc_rxfifo_pending) { - DBG(dev, "udc_queue(): pending bytes in" - "rxfifo after nyet\n"); - /* - * read pending bytes afer nyet: - * referring to isr - */ - if (udc_rxfifo_read(ep, req)) { - /* finish */ - complete_req(ep, req, 0); - } - udc_rxfifo_pending = 0; - - } - } - } - -finished: - spin_unlock_irqrestore(&dev->lock, iflags); - return retval; -} - -/* Empty request queue of an endpoint; caller holds spinlock */ -static void empty_req_queue(struct udc_ep *ep) -{ - struct udc_request *req; - - ep->halted = 1; - while (!list_empty(&ep->queue)) { - req = list_entry(ep->queue.next, - struct udc_request, - queue); - complete_req(ep, req, -ESHUTDOWN); - } -} - -/* Dequeues a request packet, called by gadget driver */ -static int udc_dequeue(struct usb_ep *usbep, struct usb_request *usbreq) -{ - struct udc_ep *ep; - struct udc_request *req; - unsigned halted; - unsigned long iflags; - - ep = container_of(usbep, struct udc_ep, ep); - if (!usbep || !usbreq || (!ep->desc && (ep->num != 0 - && ep->num != UDC_EP0OUT_IX))) - return -EINVAL; - - req = container_of(usbreq, struct udc_request, req); - - spin_lock_irqsave(&ep->dev->lock, iflags); - halted = ep->halted; - ep->halted = 1; - /* request in processing or next one */ - if (ep->queue.next == &req->queue) { - if (ep->dma && req->dma_going) { - if (ep->in) - ep->cancel_transfer = 1; - else { - u32 tmp; - u32 dma_sts; - /* stop potential receive DMA */ - tmp = readl(&udc->regs->ctl); - writel(tmp & AMD_UNMASK_BIT(UDC_DEVCTL_RDE), - &udc->regs->ctl); - /* - * Cancel transfer later in ISR - * if descriptor was touched. - */ - dma_sts = AMD_GETBITS(req->td_data->status, - UDC_DMA_OUT_STS_BS); - if (dma_sts != UDC_DMA_OUT_STS_BS_HOST_READY) - ep->cancel_transfer = 1; - else { - udc_init_bna_dummy(ep->req); - writel(ep->bna_dummy_req->td_phys, - &ep->regs->desptr); - } - writel(tmp, &udc->regs->ctl); - } - } - } - complete_req(ep, req, -ECONNRESET); - ep->halted = halted; - - spin_unlock_irqrestore(&ep->dev->lock, iflags); - return 0; -} - -/* Halt or clear halt of endpoint */ -static int -udc_set_halt(struct usb_ep *usbep, int halt) -{ - struct udc_ep *ep; - u32 tmp; - unsigned long iflags; - int retval = 0; - - if (!usbep) - return -EINVAL; - - pr_debug("set_halt %s: halt=%d\n", usbep->name, halt); - - ep = container_of(usbep, struct udc_ep, ep); - if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX)) - return -EINVAL; - if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) - return -ESHUTDOWN; - - spin_lock_irqsave(&udc_stall_spinlock, iflags); - /* halt or clear halt */ - if (halt) { - if (ep->num == 0) - ep->dev->stall_ep0in = 1; - else { - /* - * set STALL - * rxfifo empty not taken into acount - */ - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_S); - writel(tmp, &ep->regs->ctl); - ep->halted = 1; - - /* setup poll timer */ - if (!timer_pending(&udc_pollstall_timer)) { - udc_pollstall_timer.expires = jiffies + - HZ * UDC_POLLSTALL_TIMER_USECONDS - / (1000 * 1000); - if (!stop_pollstall_timer) { - DBG(ep->dev, "start polltimer\n"); - add_timer(&udc_pollstall_timer); - } - } - } - } else { - /* ep is halted by set_halt() before */ - if (ep->halted) { - tmp = readl(&ep->regs->ctl); - /* clear stall bit */ - tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S); - /* clear NAK by writing CNAK */ - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &ep->regs->ctl); - ep->halted = 0; - UDC_QUEUE_CNAK(ep, ep->num); - } - } - spin_unlock_irqrestore(&udc_stall_spinlock, iflags); - return retval; -} - -/* gadget interface */ -static const struct usb_ep_ops udc_ep_ops = { - .enable = udc_ep_enable, - .disable = udc_ep_disable, - - .alloc_request = udc_alloc_request, - .free_request = udc_free_request, - - .queue = udc_queue, - .dequeue = udc_dequeue, - - .set_halt = udc_set_halt, - /* fifo ops not implemented */ -}; - -/*-------------------------------------------------------------------------*/ - -/* Get frame counter (not implemented) */ -static int udc_get_frame(struct usb_gadget *gadget) -{ - return -EOPNOTSUPP; -} - -/* Remote wakeup gadget interface */ -static int udc_wakeup(struct usb_gadget *gadget) -{ - struct udc *dev; - - if (!gadget) - return -EINVAL; - dev = container_of(gadget, struct udc, gadget); - udc_remote_wakeup(dev); - - return 0; -} - -/* gadget operations */ -static const struct usb_gadget_ops udc_ops = { - .wakeup = udc_wakeup, - .get_frame = udc_get_frame, -}; - -/* Setups endpoint parameters, adds endpoints to linked list */ -static void make_ep_lists(struct udc *dev) -{ - /* make gadget ep lists */ - INIT_LIST_HEAD(&dev->gadget.ep_list); - list_add_tail(&dev->ep[UDC_EPIN_STATUS_IX].ep.ep_list, - &dev->gadget.ep_list); - list_add_tail(&dev->ep[UDC_EPIN_IX].ep.ep_list, - &dev->gadget.ep_list); - list_add_tail(&dev->ep[UDC_EPOUT_IX].ep.ep_list, - &dev->gadget.ep_list); - - /* fifo config */ - dev->ep[UDC_EPIN_STATUS_IX].fifo_depth = UDC_EPIN_SMALLINT_BUFF_SIZE; - if (dev->gadget.speed == USB_SPEED_FULL) - dev->ep[UDC_EPIN_IX].fifo_depth = UDC_FS_EPIN_BUFF_SIZE; - else if (dev->gadget.speed == USB_SPEED_HIGH) - dev->ep[UDC_EPIN_IX].fifo_depth = hs_tx_buf; - dev->ep[UDC_EPOUT_IX].fifo_depth = UDC_RXFIFO_SIZE; -} - -/* init registers at driver load time */ -static int startup_registers(struct udc *dev) -{ - u32 tmp; - - /* init controller by soft reset */ - udc_soft_reset(dev); - - /* mask not needed interrupts */ - udc_mask_unused_interrupts(dev); - - /* put into initial config */ - udc_basic_init(dev); - /* link up all endpoints */ - udc_setup_endpoints(dev); - - /* program speed */ - tmp = readl(&dev->regs->cfg); - if (use_fullspeed) { - tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); - } else { - tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD); - } - writel(tmp, &dev->regs->cfg); - - return 0; -} - -/* Inits UDC context */ -static void udc_basic_init(struct udc *dev) -{ - u32 tmp; - - DBG(dev, "udc_basic_init()\n"); - - dev->gadget.speed = USB_SPEED_UNKNOWN; - - /* stop RDE timer */ - if (timer_pending(&udc_timer)) { - set_rde = 0; - mod_timer(&udc_timer, jiffies - 1); - } - /* stop poll stall timer */ - if (timer_pending(&udc_pollstall_timer)) { - mod_timer(&udc_pollstall_timer, jiffies - 1); - } - /* disable DMA */ - tmp = readl(&dev->regs->ctl); - tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_RDE); - tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_TDE); - writel(tmp, &dev->regs->ctl); - - /* enable dynamic CSR programming */ - tmp = readl(&dev->regs->cfg); - tmp |= AMD_BIT(UDC_DEVCFG_CSR_PRG); - /* set self powered */ - tmp |= AMD_BIT(UDC_DEVCFG_SP); - /* set remote wakeupable */ - tmp |= AMD_BIT(UDC_DEVCFG_RWKP); - writel(tmp, &dev->regs->cfg); - - make_ep_lists(dev); - - dev->data_ep_enabled = 0; - dev->data_ep_queued = 0; -} - -/* Sets initial endpoint parameters */ -static void udc_setup_endpoints(struct udc *dev) -{ - struct udc_ep *ep; - u32 tmp; - u32 reg; - - DBG(dev, "udc_setup_endpoints()\n"); - - /* read enum speed */ - tmp = readl(&dev->regs->sts); - tmp = AMD_GETBITS(tmp, UDC_DEVSTS_ENUM_SPEED); - if (tmp == UDC_DEVSTS_ENUM_SPEED_HIGH) { - dev->gadget.speed = USB_SPEED_HIGH; - } else if (tmp == UDC_DEVSTS_ENUM_SPEED_FULL) { - dev->gadget.speed = USB_SPEED_FULL; - } - - /* set basic ep parameters */ - for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { - ep = &dev->ep[tmp]; - ep->dev = dev; - ep->ep.name = ep_string[tmp]; - ep->num = tmp; - /* txfifo size is calculated at enable time */ - ep->txfifo = dev->txfifo; - - /* fifo size */ - if (tmp < UDC_EPIN_NUM) { - ep->fifo_depth = UDC_TXFIFO_SIZE; - ep->in = 1; - } else { - ep->fifo_depth = UDC_RXFIFO_SIZE; - ep->in = 0; - - } - ep->regs = &dev->ep_regs[tmp]; - /* - * ep will be reset only if ep was not enabled before to avoid - * disabling ep interrupts when ENUM interrupt occurs but ep is - * not enabled by gadget driver - */ - if (!ep->desc) { - ep_init(dev->regs, ep); - } - - if (use_dma) { - /* - * ep->dma is not really used, just to indicate that - * DMA is active: remove this - * dma regs = dev control regs - */ - ep->dma = &dev->regs->ctl; - - /* nak OUT endpoints until enable - not for ep0 */ - if (tmp != UDC_EP0IN_IX && tmp != UDC_EP0OUT_IX - && tmp > UDC_EPIN_NUM) { - /* set NAK */ - reg = readl(&dev->ep[tmp].regs->ctl); - reg |= AMD_BIT(UDC_EPCTL_SNAK); - writel(reg, &dev->ep[tmp].regs->ctl); - dev->ep[tmp].naking = 1; - - } - } - } - /* EP0 max packet */ - if (dev->gadget.speed == USB_SPEED_FULL) { - dev->ep[UDC_EP0IN_IX].ep.maxpacket = UDC_FS_EP0IN_MAX_PKT_SIZE; - dev->ep[UDC_EP0OUT_IX].ep.maxpacket = - UDC_FS_EP0OUT_MAX_PKT_SIZE; - } else if (dev->gadget.speed == USB_SPEED_HIGH) { - dev->ep[UDC_EP0IN_IX].ep.maxpacket = UDC_EP0IN_MAX_PKT_SIZE; - dev->ep[UDC_EP0OUT_IX].ep.maxpacket = UDC_EP0OUT_MAX_PKT_SIZE; - } - - /* - * with suspend bug workaround, ep0 params for gadget driver - * are set at gadget driver bind() call - */ - dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IX].ep; - dev->ep[UDC_EP0IN_IX].halted = 0; - INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); - - /* init cfg/alt/int */ - dev->cur_config = 0; - dev->cur_intf = 0; - dev->cur_alt = 0; -} - -/* Bringup after Connect event, initial bringup to be ready for ep0 events */ -static void usb_connect(struct udc *dev) -{ - - dev_info(&dev->pdev->dev, "USB Connect\n"); - - dev->connected = 1; - - /* put into initial config */ - udc_basic_init(dev); - - /* enable device setup interrupts */ - udc_enable_dev_setup_interrupts(dev); -} - -/* - * Calls gadget with disconnect event and resets the UDC and makes - * initial bringup to be ready for ep0 events - */ -static void usb_disconnect(struct udc *dev) -{ - - dev_info(&dev->pdev->dev, "USB Disconnect\n"); - - dev->connected = 0; - - /* mask interrupts */ - udc_mask_unused_interrupts(dev); - - /* REVISIT there doesn't seem to be a point to having this - * talk to a tasklet ... do it directly, we already hold - * the spinlock needed to process the disconnect. - */ - - tasklet_schedule(&disconnect_tasklet); -} - -/* Tasklet for disconnect to be outside of interrupt context */ -static void udc_tasklet_disconnect(unsigned long par) -{ - struct udc *dev = (struct udc *)(*((struct udc **) par)); - u32 tmp; - - DBG(dev, "Tasklet disconnect\n"); - spin_lock_irq(&dev->lock); - - if (dev->driver) { - spin_unlock(&dev->lock); - dev->driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - - /* empty queues */ - for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { - empty_req_queue(&dev->ep[tmp]); - } - - } - - /* disable ep0 */ - ep_init(dev->regs, - &dev->ep[UDC_EP0IN_IX]); - - - if (!soft_reset_occured) { - /* init controller by soft reset */ - udc_soft_reset(dev); - soft_reset_occured++; - } - - /* re-enable dev interrupts */ - udc_enable_dev_setup_interrupts(dev); - /* back to full speed ? */ - if (use_fullspeed) { - tmp = readl(&dev->regs->cfg); - tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); - writel(tmp, &dev->regs->cfg); - } - - spin_unlock_irq(&dev->lock); -} - -/* Reset the UDC core */ -static void udc_soft_reset(struct udc *dev) -{ - unsigned long flags; - - DBG(dev, "Soft reset\n"); - /* - * reset possible waiting interrupts, because int. - * status is lost after soft reset, - * ep int. status reset - */ - writel(UDC_EPINT_MSK_DISABLE_ALL, &dev->regs->ep_irqsts); - /* device int. status reset */ - writel(UDC_DEV_MSK_DISABLE, &dev->regs->irqsts); - - spin_lock_irqsave(&udc_irq_spinlock, flags); - writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg); - readl(&dev->regs->cfg); - spin_unlock_irqrestore(&udc_irq_spinlock, flags); - -} - -/* RDE timer callback to set RDE bit */ -static void udc_timer_function(unsigned long v) -{ - u32 tmp; - - spin_lock_irq(&udc_irq_spinlock); - - if (set_rde > 0) { - /* - * open the fifo if fifo was filled on last timer call - * conditionally - */ - if (set_rde > 1) { - /* set RDE to receive setup data */ - tmp = readl(&udc->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_RDE); - writel(tmp, &udc->regs->ctl); - set_rde = -1; - } else if (readl(&udc->regs->sts) - & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) { - /* - * if fifo empty setup polling, do not just - * open the fifo - */ - udc_timer.expires = jiffies + HZ/UDC_RDE_TIMER_DIV; - if (!stop_timer) { - add_timer(&udc_timer); - } - } else { - /* - * fifo contains data now, setup timer for opening - * the fifo when timer expires to be able to receive - * setup packets, when data packets gets queued by - * gadget layer then timer will forced to expire with - * set_rde=0 (RDE is set in udc_queue()) - */ - set_rde++; - /* debug: lhadmot_timer_start = 221070 */ - udc_timer.expires = jiffies + HZ*UDC_RDE_TIMER_SECONDS; - if (!stop_timer) { - add_timer(&udc_timer); - } - } - - } else - set_rde = -1; /* RDE was set by udc_queue() */ - spin_unlock_irq(&udc_irq_spinlock); - if (stop_timer) - complete(&on_exit); - -} - -/* Handle halt state, used in stall poll timer */ -static void udc_handle_halt_state(struct udc_ep *ep) -{ - u32 tmp; - /* set stall as long not halted */ - if (ep->halted == 1) { - tmp = readl(&ep->regs->ctl); - /* STALL cleared ? */ - if (!(tmp & AMD_BIT(UDC_EPCTL_S))) { - /* - * FIXME: MSC spec requires that stall remains - * even on receivng of CLEAR_FEATURE HALT. So - * we would set STALL again here to be compliant. - * But with current mass storage drivers this does - * not work (would produce endless host retries). - * So we clear halt on CLEAR_FEATURE. - * - DBG(ep->dev, "ep %d: set STALL again\n", ep->num); - tmp |= AMD_BIT(UDC_EPCTL_S); - writel(tmp, &ep->regs->ctl);*/ - - /* clear NAK by writing CNAK */ - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &ep->regs->ctl); - ep->halted = 0; - UDC_QUEUE_CNAK(ep, ep->num); - } - } -} - -/* Stall timer callback to poll S bit and set it again after */ -static void udc_pollstall_timer_function(unsigned long v) -{ - struct udc_ep *ep; - int halted = 0; - - spin_lock_irq(&udc_stall_spinlock); - /* - * only one IN and OUT endpoints are handled - * IN poll stall - */ - ep = &udc->ep[UDC_EPIN_IX]; - udc_handle_halt_state(ep); - if (ep->halted) - halted = 1; - /* OUT poll stall */ - ep = &udc->ep[UDC_EPOUT_IX]; - udc_handle_halt_state(ep); - if (ep->halted) - halted = 1; - - /* setup timer again when still halted */ - if (!stop_pollstall_timer && halted) { - udc_pollstall_timer.expires = jiffies + - HZ * UDC_POLLSTALL_TIMER_USECONDS - / (1000 * 1000); - add_timer(&udc_pollstall_timer); - } - spin_unlock_irq(&udc_stall_spinlock); - - if (stop_pollstall_timer) - complete(&on_pollstall_exit); -} - -/* Inits endpoint 0 so that SETUP packets are processed */ -static void activate_control_endpoints(struct udc *dev) -{ - u32 tmp; - - DBG(dev, "activate_control_endpoints\n"); - - /* flush fifo */ - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_F); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); - - /* set ep0 directions */ - dev->ep[UDC_EP0IN_IX].in = 1; - dev->ep[UDC_EP0OUT_IX].in = 0; - - /* set buffer size (tx fifo entries) of EP0_IN */ - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->bufin_framenum); - if (dev->gadget.speed == USB_SPEED_FULL) - tmp = AMD_ADDBITS(tmp, UDC_FS_EPIN0_BUFF_SIZE, - UDC_EPIN_BUFF_SIZE); - else if (dev->gadget.speed == USB_SPEED_HIGH) - tmp = AMD_ADDBITS(tmp, UDC_EPIN0_BUFF_SIZE, - UDC_EPIN_BUFF_SIZE); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->bufin_framenum); - - /* set max packet size of EP0_IN */ - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->bufout_maxpkt); - if (dev->gadget.speed == USB_SPEED_FULL) - tmp = AMD_ADDBITS(tmp, UDC_FS_EP0IN_MAX_PKT_SIZE, - UDC_EP_MAX_PKT_SIZE); - else if (dev->gadget.speed == USB_SPEED_HIGH) - tmp = AMD_ADDBITS(tmp, UDC_EP0IN_MAX_PKT_SIZE, - UDC_EP_MAX_PKT_SIZE); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->bufout_maxpkt); - - /* set max packet size of EP0_OUT */ - tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->bufout_maxpkt); - if (dev->gadget.speed == USB_SPEED_FULL) - tmp = AMD_ADDBITS(tmp, UDC_FS_EP0OUT_MAX_PKT_SIZE, - UDC_EP_MAX_PKT_SIZE); - else if (dev->gadget.speed == USB_SPEED_HIGH) - tmp = AMD_ADDBITS(tmp, UDC_EP0OUT_MAX_PKT_SIZE, - UDC_EP_MAX_PKT_SIZE); - writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->bufout_maxpkt); - - /* set max packet size of EP0 in UDC CSR */ - tmp = readl(&dev->csr->ne[0]); - if (dev->gadget.speed == USB_SPEED_FULL) - tmp = AMD_ADDBITS(tmp, UDC_FS_EP0OUT_MAX_PKT_SIZE, - UDC_CSR_NE_MAX_PKT); - else if (dev->gadget.speed == USB_SPEED_HIGH) - tmp = AMD_ADDBITS(tmp, UDC_EP0OUT_MAX_PKT_SIZE, - UDC_CSR_NE_MAX_PKT); - writel(tmp, &dev->csr->ne[0]); - - if (use_dma) { - dev->ep[UDC_EP0OUT_IX].td->status |= - AMD_BIT(UDC_DMA_OUT_STS_L); - /* write dma desc address */ - writel(dev->ep[UDC_EP0OUT_IX].td_stp_dma, - &dev->ep[UDC_EP0OUT_IX].regs->subptr); - writel(dev->ep[UDC_EP0OUT_IX].td_phys, - &dev->ep[UDC_EP0OUT_IX].regs->desptr); - /* stop RDE timer */ - if (timer_pending(&udc_timer)) { - set_rde = 0; - mod_timer(&udc_timer, jiffies - 1); - } - /* stop pollstall timer */ - if (timer_pending(&udc_pollstall_timer)) { - mod_timer(&udc_pollstall_timer, jiffies - 1); - } - /* enable DMA */ - tmp = readl(&dev->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_MODE) - | AMD_BIT(UDC_DEVCTL_RDE) - | AMD_BIT(UDC_DEVCTL_TDE); - if (use_dma_bufferfill_mode) { - tmp |= AMD_BIT(UDC_DEVCTL_BF); - } else if (use_dma_ppb_du) { - tmp |= AMD_BIT(UDC_DEVCTL_DU); - } - writel(tmp, &dev->regs->ctl); - } - - /* clear NAK by writing CNAK for EP0IN */ - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); - dev->ep[UDC_EP0IN_IX].naking = 0; - UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX], UDC_EP0IN_IX); - - /* clear NAK by writing CNAK for EP0OUT */ - tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->ctl); - dev->ep[UDC_EP0OUT_IX].naking = 0; - UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX], UDC_EP0OUT_IX); -} - -/* Make endpoint 0 ready for control traffic */ -static int setup_ep0(struct udc *dev) -{ - activate_control_endpoints(dev); - /* enable ep0 interrupts */ - udc_enable_ep0_interrupts(dev); - /* enable device setup interrupts */ - udc_enable_dev_setup_interrupts(dev); - - return 0; -} - -/* Called by gadget driver to register itself */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) -{ - struct udc *dev = udc; - int retval; - u32 tmp; - - if (!driver || !driver->bind || !driver->setup - || driver->speed != USB_SPEED_HIGH) - return -EINVAL; - if (!dev) - return -ENODEV; - if (dev->driver) - return -EBUSY; - - driver->driver.bus = NULL; - dev->driver = driver; - dev->gadget.dev.driver = &driver->driver; - - retval = driver->bind(&dev->gadget); - - /* Some gadget drivers use both ep0 directions. - * NOTE: to gadget driver, ep0 is just one endpoint... - */ - dev->ep[UDC_EP0OUT_IX].ep.driver_data = - dev->ep[UDC_EP0IN_IX].ep.driver_data; - - if (retval) { - DBG(dev, "binding to %s returning %d\n", - driver->driver.name, retval); - dev->driver = NULL; - dev->gadget.dev.driver = NULL; - return retval; - } - - /* get ready for ep0 traffic */ - setup_ep0(dev); - - /* clear SD */ - tmp = readl(&dev->regs->ctl); - tmp = tmp & AMD_CLEAR_BIT(UDC_DEVCTL_SD); - writel(tmp, &dev->regs->ctl); - - usb_connect(dev); - - return 0; -} -EXPORT_SYMBOL(usb_gadget_register_driver); - -/* shutdown requests and disconnect from gadget */ -static void -shutdown(struct udc *dev, struct usb_gadget_driver *driver) -__releases(dev->lock) -__acquires(dev->lock) -{ - int tmp; - - /* empty queues and init hardware */ - udc_basic_init(dev); - for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { - empty_req_queue(&dev->ep[tmp]); - } - - if (dev->gadget.speed != USB_SPEED_UNKNOWN) { - spin_unlock(&dev->lock); - driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - } - /* init */ - udc_setup_endpoints(dev); -} - -/* Called by gadget driver to unregister itself */ -int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) -{ - struct udc *dev = udc; - unsigned long flags; - u32 tmp; - - if (!dev) - return -ENODEV; - if (!driver || driver != dev->driver || !driver->unbind) - return -EINVAL; - - spin_lock_irqsave(&dev->lock, flags); - udc_mask_unused_interrupts(dev); - shutdown(dev, driver); - spin_unlock_irqrestore(&dev->lock, flags); - - driver->unbind(&dev->gadget); - dev->driver = NULL; - - /* set SD */ - tmp = readl(&dev->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_SD); - writel(tmp, &dev->regs->ctl); - - - DBG(dev, "%s: unregistered\n", driver->driver.name); - - return 0; -} -EXPORT_SYMBOL(usb_gadget_unregister_driver); - - -/* Clear pending NAK bits */ -static void udc_process_cnak_queue(struct udc *dev) -{ - u32 tmp; - u32 reg; - - /* check epin's */ - DBG(dev, "CNAK pending queue processing\n"); - for (tmp = 0; tmp < UDC_EPIN_NUM_USED; tmp++) { - if (cnak_pending & (1 << tmp)) { - DBG(dev, "CNAK pending for ep%d\n", tmp); - /* clear NAK by writing CNAK */ - reg = readl(&dev->ep[tmp].regs->ctl); - reg |= AMD_BIT(UDC_EPCTL_CNAK); - writel(reg, &dev->ep[tmp].regs->ctl); - dev->ep[tmp].naking = 0; - UDC_QUEUE_CNAK(&dev->ep[tmp], dev->ep[tmp].num); - } - } - /* ... and ep0out */ - if (cnak_pending & (1 << UDC_EP0OUT_IX)) { - DBG(dev, "CNAK pending for ep%d\n", UDC_EP0OUT_IX); - /* clear NAK by writing CNAK */ - reg = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl); - reg |= AMD_BIT(UDC_EPCTL_CNAK); - writel(reg, &dev->ep[UDC_EP0OUT_IX].regs->ctl); - dev->ep[UDC_EP0OUT_IX].naking = 0; - UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX], - dev->ep[UDC_EP0OUT_IX].num); - } -} - -/* Enabling RX DMA after setup packet */ -static void udc_ep0_set_rde(struct udc *dev) -{ - if (use_dma) { - /* - * only enable RXDMA when no data endpoint enabled - * or data is queued - */ - if (!dev->data_ep_enabled || dev->data_ep_queued) { - udc_set_rde(dev); - } else { - /* - * setup timer for enabling RDE (to not enable - * RXFIFO DMA for data endpoints to early) - */ - if (set_rde != 0 && !timer_pending(&udc_timer)) { - udc_timer.expires = - jiffies + HZ/UDC_RDE_TIMER_DIV; - set_rde = 1; - if (!stop_timer) { - add_timer(&udc_timer); - } - } - } - } -} - - -/* Interrupt handler for data OUT traffic */ -static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix) -{ - irqreturn_t ret_val = IRQ_NONE; - u32 tmp; - struct udc_ep *ep; - struct udc_request *req; - unsigned int count; - struct udc_data_dma *td = NULL; - unsigned dma_done; - - VDBG(dev, "ep%d irq\n", ep_ix); - ep = &dev->ep[ep_ix]; - - tmp = readl(&ep->regs->sts); - if (use_dma) { - /* BNA event ? */ - if (tmp & AMD_BIT(UDC_EPSTS_BNA)) { - DBG(dev, "BNA ep%dout occured - DESPTR = %x \n", - ep->num, readl(&ep->regs->desptr)); - /* clear BNA */ - writel(tmp | AMD_BIT(UDC_EPSTS_BNA), &ep->regs->sts); - if (!ep->cancel_transfer) - ep->bna_occurred = 1; - else - ep->cancel_transfer = 0; - ret_val = IRQ_HANDLED; - goto finished; - } - } - /* HE event ? */ - if (tmp & AMD_BIT(UDC_EPSTS_HE)) { - dev_err(&dev->pdev->dev, "HE ep%dout occured\n", ep->num); - - /* clear HE */ - writel(tmp | AMD_BIT(UDC_EPSTS_HE), &ep->regs->sts); - ret_val = IRQ_HANDLED; - goto finished; - } - - if (!list_empty(&ep->queue)) { - - /* next request */ - req = list_entry(ep->queue.next, - struct udc_request, queue); - } else { - req = NULL; - udc_rxfifo_pending = 1; - } - VDBG(dev, "req = %p\n", req); - /* fifo mode */ - if (!use_dma) { - - /* read fifo */ - if (req && udc_rxfifo_read(ep, req)) { - ret_val = IRQ_HANDLED; - - /* finish */ - complete_req(ep, req, 0); - /* next request */ - if (!list_empty(&ep->queue) && !ep->halted) { - req = list_entry(ep->queue.next, - struct udc_request, queue); - } else - req = NULL; - } - - /* DMA */ - } else if (!ep->cancel_transfer && req != NULL) { - ret_val = IRQ_HANDLED; - - /* check for DMA done */ - if (!use_dma_ppb) { - dma_done = AMD_GETBITS(req->td_data->status, - UDC_DMA_OUT_STS_BS); - /* packet per buffer mode - rx bytes */ - } else { - /* - * if BNA occurred then recover desc. from - * BNA dummy desc. - */ - if (ep->bna_occurred) { - VDBG(dev, "Recover desc. from BNA dummy\n"); - memcpy(req->td_data, ep->bna_dummy_req->td_data, - sizeof(struct udc_data_dma)); - ep->bna_occurred = 0; - udc_init_bna_dummy(ep->req); - } - td = udc_get_last_dma_desc(req); - dma_done = AMD_GETBITS(td->status, UDC_DMA_OUT_STS_BS); - } - if (dma_done == UDC_DMA_OUT_STS_BS_DMA_DONE) { - /* buffer fill mode - rx bytes */ - if (!use_dma_ppb) { - /* received number bytes */ - count = AMD_GETBITS(req->td_data->status, - UDC_DMA_OUT_STS_RXBYTES); - VDBG(dev, "rx bytes=%u\n", count); - /* packet per buffer mode - rx bytes */ - } else { - VDBG(dev, "req->td_data=%p\n", req->td_data); - VDBG(dev, "last desc = %p\n", td); - /* received number bytes */ - if (use_dma_ppb_du) { - /* every desc. counts bytes */ - count = udc_get_ppbdu_rxbytes(req); - } else { - /* last desc. counts bytes */ - count = AMD_GETBITS(td->status, - UDC_DMA_OUT_STS_RXBYTES); - if (!count && req->req.length - == UDC_DMA_MAXPACKET) { - /* - * on 64k packets the RXBYTES - * field is zero - */ - count = UDC_DMA_MAXPACKET; - } - } - VDBG(dev, "last desc rx bytes=%u\n", count); - } - - tmp = req->req.length - req->req.actual; - if (count > tmp) { - if ((tmp % ep->ep.maxpacket) != 0) { - DBG(dev, "%s: rx %db, space=%db\n", - ep->ep.name, count, tmp); - req->req.status = -EOVERFLOW; - } - count = tmp; - } - req->req.actual += count; - req->dma_going = 0; - /* complete request */ - complete_req(ep, req, 0); - - /* next request */ - if (!list_empty(&ep->queue) && !ep->halted) { - req = list_entry(ep->queue.next, - struct udc_request, - queue); - /* - * DMA may be already started by udc_queue() - * called by gadget drivers completion - * routine. This happens when queue - * holds one request only. - */ - if (req->dma_going == 0) { - /* next dma */ - if (prep_dma(ep, req, GFP_ATOMIC) != 0) - goto finished; - /* write desc pointer */ - writel(req->td_phys, - &ep->regs->desptr); - req->dma_going = 1; - /* enable DMA */ - udc_set_rde(dev); - } - } else { - /* - * implant BNA dummy descriptor to allow - * RXFIFO opening by RDE - */ - if (ep->bna_dummy_req) { - /* write desc pointer */ - writel(ep->bna_dummy_req->td_phys, - &ep->regs->desptr); - ep->bna_occurred = 0; - } - - /* - * schedule timer for setting RDE if queue - * remains empty to allow ep0 packets pass - * through - */ - if (set_rde != 0 - && !timer_pending(&udc_timer)) { - udc_timer.expires = - jiffies - + HZ*UDC_RDE_TIMER_SECONDS; - set_rde = 1; - if (!stop_timer) { - add_timer(&udc_timer); - } - } - if (ep->num != UDC_EP0OUT_IX) - dev->data_ep_queued = 0; - } - - } else { - /* - * RX DMA must be reenabled for each desc in PPBDU mode - * and must be enabled for PPBNDU mode in case of BNA - */ - udc_set_rde(dev); - } - - } else if (ep->cancel_transfer) { - ret_val = IRQ_HANDLED; - ep->cancel_transfer = 0; - } - - /* check pending CNAKS */ - if (cnak_pending) { - /* CNAk processing when rxfifo empty only */ - if (readl(&dev->regs->sts) & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) { - udc_process_cnak_queue(dev); - } - } - - /* clear OUT bits in ep status */ - writel(UDC_EPSTS_OUT_CLEAR, &ep->regs->sts); -finished: - return ret_val; -} - -/* Interrupt handler for data IN traffic */ -static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix) -{ - irqreturn_t ret_val = IRQ_NONE; - u32 tmp; - u32 epsts; - struct udc_ep *ep; - struct udc_request *req; - struct udc_data_dma *td; - unsigned dma_done; - unsigned len; - - ep = &dev->ep[ep_ix]; - - epsts = readl(&ep->regs->sts); - if (use_dma) { - /* BNA ? */ - if (epsts & AMD_BIT(UDC_EPSTS_BNA)) { - dev_err(&dev->pdev->dev, - "BNA ep%din occured - DESPTR = %08lx \n", - ep->num, - (unsigned long) readl(&ep->regs->desptr)); - - /* clear BNA */ - writel(epsts, &ep->regs->sts); - ret_val = IRQ_HANDLED; - goto finished; - } - } - /* HE event ? */ - if (epsts & AMD_BIT(UDC_EPSTS_HE)) { - dev_err(&dev->pdev->dev, - "HE ep%dn occured - DESPTR = %08lx \n", - ep->num, (unsigned long) readl(&ep->regs->desptr)); - - /* clear HE */ - writel(epsts | AMD_BIT(UDC_EPSTS_HE), &ep->regs->sts); - ret_val = IRQ_HANDLED; - goto finished; - } - - /* DMA completion */ - if (epsts & AMD_BIT(UDC_EPSTS_TDC)) { - VDBG(dev, "TDC set- completion\n"); - ret_val = IRQ_HANDLED; - if (!ep->cancel_transfer && !list_empty(&ep->queue)) { - req = list_entry(ep->queue.next, - struct udc_request, queue); - if (req) { - /* - * length bytes transfered - * check dma done of last desc. in PPBDU mode - */ - if (use_dma_ppb_du) { - td = udc_get_last_dma_desc(req); - if (td) { - dma_done = - AMD_GETBITS(td->status, - UDC_DMA_IN_STS_BS); - /* don't care DMA done */ - req->req.actual = - req->req.length; - } - } else { - /* assume all bytes transferred */ - req->req.actual = req->req.length; - } - - if (req->req.actual == req->req.length) { - /* complete req */ - complete_req(ep, req, 0); - req->dma_going = 0; - /* further request available ? */ - if (list_empty(&ep->queue)) { - /* disable interrupt */ - tmp = readl( - &dev->regs->ep_irqmsk); - tmp |= AMD_BIT(ep->num); - writel(tmp, - &dev->regs->ep_irqmsk); - } - - } - } - } - ep->cancel_transfer = 0; - - } - /* - * status reg has IN bit set and TDC not set (if TDC was handled, - * IN must not be handled (UDC defect) ? - */ - if ((epsts & AMD_BIT(UDC_EPSTS_IN)) - && !(epsts & AMD_BIT(UDC_EPSTS_TDC))) { - ret_val = IRQ_HANDLED; - if (!list_empty(&ep->queue)) { - /* next request */ - req = list_entry(ep->queue.next, - struct udc_request, queue); - /* FIFO mode */ - if (!use_dma) { - /* write fifo */ - udc_txfifo_write(ep, &req->req); - len = req->req.length - req->req.actual; - if (len > ep->ep.maxpacket) - len = ep->ep.maxpacket; - req->req.actual += len; - if (req->req.actual == req->req.length - || (len != ep->ep.maxpacket)) { - /* complete req */ - complete_req(ep, req, 0); - } - /* DMA */ - } else if (req && !req->dma_going) { - VDBG(dev, "IN DMA : req=%p req->td_data=%p\n", - req, req->td_data); - if (req->td_data) { - - req->dma_going = 1; - - /* - * unset L bit of first desc. - * for chain - */ - if (use_dma_ppb && req->req.length > - ep->ep.maxpacket) { - req->td_data->status &= - AMD_CLEAR_BIT( - UDC_DMA_IN_STS_L); - } - - /* write desc pointer */ - writel(req->td_phys, &ep->regs->desptr); - - /* set HOST READY */ - req->td_data->status = - AMD_ADDBITS( - req->td_data->status, - UDC_DMA_IN_STS_BS_HOST_READY, - UDC_DMA_IN_STS_BS); - - /* set poll demand bit */ - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_P); - writel(tmp, &ep->regs->ctl); - } - } - - } - } - /* clear status bits */ - writel(epsts, &ep->regs->sts); - -finished: - return ret_val; - -} - -/* Interrupt handler for Control OUT traffic */ -static irqreturn_t udc_control_out_isr(struct udc *dev) -__releases(dev->lock) -__acquires(dev->lock) -{ - irqreturn_t ret_val = IRQ_NONE; - u32 tmp; - int setup_supported; - u32 count; - int set = 0; - struct udc_ep *ep; - struct udc_ep *ep_tmp; - - ep = &dev->ep[UDC_EP0OUT_IX]; - - /* clear irq */ - writel(AMD_BIT(UDC_EPINT_OUT_EP0), &dev->regs->ep_irqsts); - - tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->sts); - /* check BNA and clear if set */ - if (tmp & AMD_BIT(UDC_EPSTS_BNA)) { - VDBG(dev, "ep0: BNA set\n"); - writel(AMD_BIT(UDC_EPSTS_BNA), - &dev->ep[UDC_EP0OUT_IX].regs->sts); - ep->bna_occurred = 1; - ret_val = IRQ_HANDLED; - goto finished; - } - - /* type of data: SETUP or DATA 0 bytes */ - tmp = AMD_GETBITS(tmp, UDC_EPSTS_OUT); - VDBG(dev, "data_typ = %x\n", tmp); - - /* setup data */ - if (tmp == UDC_EPSTS_OUT_SETUP) { - ret_val = IRQ_HANDLED; - - ep->dev->stall_ep0in = 0; - dev->waiting_zlp_ack_ep0in = 0; - - /* set NAK for EP0_IN */ - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_SNAK); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); - dev->ep[UDC_EP0IN_IX].naking = 1; - /* get setup data */ - if (use_dma) { - - /* clear OUT bits in ep status */ - writel(UDC_EPSTS_OUT_CLEAR, - &dev->ep[UDC_EP0OUT_IX].regs->sts); - - setup_data.data[0] = - dev->ep[UDC_EP0OUT_IX].td_stp->data12; - setup_data.data[1] = - dev->ep[UDC_EP0OUT_IX].td_stp->data34; - /* set HOST READY */ - dev->ep[UDC_EP0OUT_IX].td_stp->status = - UDC_DMA_STP_STS_BS_HOST_READY; - } else { - /* read fifo */ - udc_rxfifo_read_dwords(dev, setup_data.data, 2); - } - - /* determine direction of control data */ - if ((setup_data.request.bRequestType & USB_DIR_IN) != 0) { - dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IX].ep; - /* enable RDE */ - udc_ep0_set_rde(dev); - set = 0; - } else { - dev->gadget.ep0 = &dev->ep[UDC_EP0OUT_IX].ep; - /* - * implant BNA dummy descriptor to allow RXFIFO opening - * by RDE - */ - if (ep->bna_dummy_req) { - /* write desc pointer */ - writel(ep->bna_dummy_req->td_phys, - &dev->ep[UDC_EP0OUT_IX].regs->desptr); - ep->bna_occurred = 0; - } - - set = 1; - dev->ep[UDC_EP0OUT_IX].naking = 1; - /* - * setup timer for enabling RDE (to not enable - * RXFIFO DMA for data to early) - */ - set_rde = 1; - if (!timer_pending(&udc_timer)) { - udc_timer.expires = jiffies + - HZ/UDC_RDE_TIMER_DIV; - if (!stop_timer) { - add_timer(&udc_timer); - } - } - } - - /* - * mass storage reset must be processed here because - * next packet may be a CLEAR_FEATURE HALT which would not - * clear the stall bit when no STALL handshake was received - * before (autostall can cause this) - */ - if (setup_data.data[0] == UDC_MSCRES_DWORD0 - && setup_data.data[1] == UDC_MSCRES_DWORD1) { - DBG(dev, "MSC Reset\n"); - /* - * clear stall bits - * only one IN and OUT endpoints are handled - */ - ep_tmp = &udc->ep[UDC_EPIN_IX]; - udc_set_halt(&ep_tmp->ep, 0); - ep_tmp = &udc->ep[UDC_EPOUT_IX]; - udc_set_halt(&ep_tmp->ep, 0); - } - - /* call gadget with setup data received */ - spin_unlock(&dev->lock); - setup_supported = dev->driver->setup(&dev->gadget, - &setup_data.request); - spin_lock(&dev->lock); - - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); - /* ep0 in returns data (not zlp) on IN phase */ - if (setup_supported >= 0 && setup_supported < - UDC_EP0IN_MAXPACKET) { - /* clear NAK by writing CNAK in EP0_IN */ - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); - dev->ep[UDC_EP0IN_IX].naking = 0; - UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX], UDC_EP0IN_IX); - - /* if unsupported request then stall */ - } else if (setup_supported < 0) { - tmp |= AMD_BIT(UDC_EPCTL_S); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); - } else - dev->waiting_zlp_ack_ep0in = 1; - - - /* clear NAK by writing CNAK in EP0_OUT */ - if (!set) { - tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->ctl); - dev->ep[UDC_EP0OUT_IX].naking = 0; - UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX], UDC_EP0OUT_IX); - } - - if (!use_dma) { - /* clear OUT bits in ep status */ - writel(UDC_EPSTS_OUT_CLEAR, - &dev->ep[UDC_EP0OUT_IX].regs->sts); - } - - /* data packet 0 bytes */ - } else if (tmp == UDC_EPSTS_OUT_DATA) { - /* clear OUT bits in ep status */ - writel(UDC_EPSTS_OUT_CLEAR, &dev->ep[UDC_EP0OUT_IX].regs->sts); - - /* get setup data: only 0 packet */ - if (use_dma) { - /* no req if 0 packet, just reactivate */ - if (list_empty(&dev->ep[UDC_EP0OUT_IX].queue)) { - VDBG(dev, "ZLP\n"); - - /* set HOST READY */ - dev->ep[UDC_EP0OUT_IX].td->status = - AMD_ADDBITS( - dev->ep[UDC_EP0OUT_IX].td->status, - UDC_DMA_OUT_STS_BS_HOST_READY, - UDC_DMA_OUT_STS_BS); - /* enable RDE */ - udc_ep0_set_rde(dev); - ret_val = IRQ_HANDLED; - - } else { - /* control write */ - ret_val |= udc_data_out_isr(dev, UDC_EP0OUT_IX); - /* re-program desc. pointer for possible ZLPs */ - writel(dev->ep[UDC_EP0OUT_IX].td_phys, - &dev->ep[UDC_EP0OUT_IX].regs->desptr); - /* enable RDE */ - udc_ep0_set_rde(dev); - } - } else { - - /* received number bytes */ - count = readl(&dev->ep[UDC_EP0OUT_IX].regs->sts); - count = AMD_GETBITS(count, UDC_EPSTS_RX_PKT_SIZE); - /* out data for fifo mode not working */ - count = 0; - - /* 0 packet or real data ? */ - if (count != 0) { - ret_val |= udc_data_out_isr(dev, UDC_EP0OUT_IX); - } else { - /* dummy read confirm */ - readl(&dev->ep[UDC_EP0OUT_IX].regs->confirm); - ret_val = IRQ_HANDLED; - } - } - } - - /* check pending CNAKS */ - if (cnak_pending) { - /* CNAk processing when rxfifo empty only */ - if (readl(&dev->regs->sts) & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) { - udc_process_cnak_queue(dev); - } - } - -finished: - return ret_val; -} - -/* Interrupt handler for Control IN traffic */ -static irqreturn_t udc_control_in_isr(struct udc *dev) -{ - irqreturn_t ret_val = IRQ_NONE; - u32 tmp; - struct udc_ep *ep; - struct udc_request *req; - unsigned len; - - ep = &dev->ep[UDC_EP0IN_IX]; - - /* clear irq */ - writel(AMD_BIT(UDC_EPINT_IN_EP0), &dev->regs->ep_irqsts); - - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->sts); - /* DMA completion */ - if (tmp & AMD_BIT(UDC_EPSTS_TDC)) { - VDBG(dev, "isr: TDC clear \n"); - ret_val = IRQ_HANDLED; - - /* clear TDC bit */ - writel(AMD_BIT(UDC_EPSTS_TDC), - &dev->ep[UDC_EP0IN_IX].regs->sts); - - /* status reg has IN bit set ? */ - } else if (tmp & AMD_BIT(UDC_EPSTS_IN)) { - ret_val = IRQ_HANDLED; - - if (ep->dma) { - /* clear IN bit */ - writel(AMD_BIT(UDC_EPSTS_IN), - &dev->ep[UDC_EP0IN_IX].regs->sts); - } - if (dev->stall_ep0in) { - DBG(dev, "stall ep0in\n"); - /* halt ep0in */ - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_S); - writel(tmp, &ep->regs->ctl); - } else { - if (!list_empty(&ep->queue)) { - /* next request */ - req = list_entry(ep->queue.next, - struct udc_request, queue); - - if (ep->dma) { - /* write desc pointer */ - writel(req->td_phys, &ep->regs->desptr); - /* set HOST READY */ - req->td_data->status = - AMD_ADDBITS( - req->td_data->status, - UDC_DMA_STP_STS_BS_HOST_READY, - UDC_DMA_STP_STS_BS); - - /* set poll demand bit */ - tmp = - readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_P); - writel(tmp, - &dev->ep[UDC_EP0IN_IX].regs->ctl); - - /* all bytes will be transferred */ - req->req.actual = req->req.length; - - /* complete req */ - complete_req(ep, req, 0); - - } else { - /* write fifo */ - udc_txfifo_write(ep, &req->req); - - /* lengh bytes transfered */ - len = req->req.length - req->req.actual; - if (len > ep->ep.maxpacket) - len = ep->ep.maxpacket; - - req->req.actual += len; - if (req->req.actual == req->req.length - || (len != ep->ep.maxpacket)) { - /* complete req */ - complete_req(ep, req, 0); - } - } - - } - } - ep->halted = 0; - dev->stall_ep0in = 0; - if (!ep->dma) { - /* clear IN bit */ - writel(AMD_BIT(UDC_EPSTS_IN), - &dev->ep[UDC_EP0IN_IX].regs->sts); - } - } - - return ret_val; -} - - -/* Interrupt handler for global device events */ -static irqreturn_t udc_dev_isr(struct udc *dev, u32 dev_irq) -__releases(dev->lock) -__acquires(dev->lock) -{ - irqreturn_t ret_val = IRQ_NONE; - u32 tmp; - u32 cfg; - struct udc_ep *ep; - u16 i; - u8 udc_csr_epix; - - /* SET_CONFIG irq ? */ - if (dev_irq & AMD_BIT(UDC_DEVINT_SC)) { - ret_val = IRQ_HANDLED; - - /* read config value */ - tmp = readl(&dev->regs->sts); - cfg = AMD_GETBITS(tmp, UDC_DEVSTS_CFG); - DBG(dev, "SET_CONFIG interrupt: config=%d\n", cfg); - dev->cur_config = cfg; - dev->set_cfg_not_acked = 1; - - /* make usb request for gadget driver */ - memset(&setup_data, 0 , sizeof(union udc_setup_data)); - setup_data.request.bRequest = USB_REQ_SET_CONFIGURATION; - setup_data.request.wValue = dev->cur_config; - - /* programm the NE registers */ - for (i = 0; i < UDC_EP_NUM; i++) { - ep = &dev->ep[i]; - if (ep->in) { - - /* ep ix in UDC CSR register space */ - udc_csr_epix = ep->num; - - - /* OUT ep */ - } else { - /* ep ix in UDC CSR register space */ - udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS; - } - - tmp = readl(&dev->csr->ne[udc_csr_epix]); - /* ep cfg */ - tmp = AMD_ADDBITS(tmp, ep->dev->cur_config, - UDC_CSR_NE_CFG); - /* write reg */ - writel(tmp, &dev->csr->ne[udc_csr_epix]); - - /* clear stall bits */ - ep->halted = 0; - tmp = readl(&ep->regs->ctl); - tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S); - writel(tmp, &ep->regs->ctl); - } - /* call gadget zero with setup data received */ - spin_unlock(&dev->lock); - tmp = dev->driver->setup(&dev->gadget, &setup_data.request); - spin_lock(&dev->lock); - - } /* SET_INTERFACE ? */ - if (dev_irq & AMD_BIT(UDC_DEVINT_SI)) { - ret_val = IRQ_HANDLED; - - dev->set_cfg_not_acked = 1; - /* read interface and alt setting values */ - tmp = readl(&dev->regs->sts); - dev->cur_alt = AMD_GETBITS(tmp, UDC_DEVSTS_ALT); - dev->cur_intf = AMD_GETBITS(tmp, UDC_DEVSTS_INTF); - - /* make usb request for gadget driver */ - memset(&setup_data, 0 , sizeof(union udc_setup_data)); - setup_data.request.bRequest = USB_REQ_SET_INTERFACE; - setup_data.request.bRequestType = USB_RECIP_INTERFACE; - setup_data.request.wValue = dev->cur_alt; - setup_data.request.wIndex = dev->cur_intf; - - DBG(dev, "SET_INTERFACE interrupt: alt=%d intf=%d\n", - dev->cur_alt, dev->cur_intf); - - /* programm the NE registers */ - for (i = 0; i < UDC_EP_NUM; i++) { - ep = &dev->ep[i]; - if (ep->in) { - - /* ep ix in UDC CSR register space */ - udc_csr_epix = ep->num; - - - /* OUT ep */ - } else { - /* ep ix in UDC CSR register space */ - udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS; - } - - /* UDC CSR reg */ - /* set ep values */ - tmp = readl(&dev->csr->ne[udc_csr_epix]); - /* ep interface */ - tmp = AMD_ADDBITS(tmp, ep->dev->cur_intf, - UDC_CSR_NE_INTF); - /* tmp = AMD_ADDBITS(tmp, 2, UDC_CSR_NE_INTF); */ - /* ep alt */ - tmp = AMD_ADDBITS(tmp, ep->dev->cur_alt, - UDC_CSR_NE_ALT); - /* write reg */ - writel(tmp, &dev->csr->ne[udc_csr_epix]); - - /* clear stall bits */ - ep->halted = 0; - tmp = readl(&ep->regs->ctl); - tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S); - writel(tmp, &ep->regs->ctl); - } - - /* call gadget zero with setup data received */ - spin_unlock(&dev->lock); - tmp = dev->driver->setup(&dev->gadget, &setup_data.request); - spin_lock(&dev->lock); - - } /* USB reset */ - if (dev_irq & AMD_BIT(UDC_DEVINT_UR)) { - DBG(dev, "USB Reset interrupt\n"); - ret_val = IRQ_HANDLED; - - /* allow soft reset when suspend occurs */ - soft_reset_occured = 0; - - dev->waiting_zlp_ack_ep0in = 0; - dev->set_cfg_not_acked = 0; - - /* mask not needed interrupts */ - udc_mask_unused_interrupts(dev); - - /* call gadget to resume and reset configs etc. */ - spin_unlock(&dev->lock); - if (dev->sys_suspended && dev->driver->resume) { - dev->driver->resume(&dev->gadget); - dev->sys_suspended = 0; - } - dev->driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - - /* disable ep0 to empty req queue */ - empty_req_queue(&dev->ep[UDC_EP0IN_IX]); - ep_init(dev->regs, &dev->ep[UDC_EP0IN_IX]); - - /* soft reset when rxfifo not empty */ - tmp = readl(&dev->regs->sts); - if (!(tmp & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) - && !soft_reset_after_usbreset_occured) { - udc_soft_reset(dev); - soft_reset_after_usbreset_occured++; - } - - /* - * DMA reset to kill potential old DMA hw hang, - * POLL bit is already reset by ep_init() through - * disconnect() - */ - DBG(dev, "DMA machine reset\n"); - tmp = readl(&dev->regs->cfg); - writel(tmp | AMD_BIT(UDC_DEVCFG_DMARST), &dev->regs->cfg); - writel(tmp, &dev->regs->cfg); - - /* put into initial config */ - udc_basic_init(dev); - - /* enable device setup interrupts */ - udc_enable_dev_setup_interrupts(dev); - - /* enable suspend interrupt */ - tmp = readl(&dev->regs->irqmsk); - tmp &= AMD_UNMASK_BIT(UDC_DEVINT_US); - writel(tmp, &dev->regs->irqmsk); - - } /* USB suspend */ - if (dev_irq & AMD_BIT(UDC_DEVINT_US)) { - DBG(dev, "USB Suspend interrupt\n"); - ret_val = IRQ_HANDLED; - if (dev->driver->suspend) { - spin_unlock(&dev->lock); - dev->sys_suspended = 1; - dev->driver->suspend(&dev->gadget); - spin_lock(&dev->lock); - } - } /* new speed ? */ - if (dev_irq & AMD_BIT(UDC_DEVINT_ENUM)) { - DBG(dev, "ENUM interrupt\n"); - ret_val = IRQ_HANDLED; - soft_reset_after_usbreset_occured = 0; - - /* disable ep0 to empty req queue */ - empty_req_queue(&dev->ep[UDC_EP0IN_IX]); - ep_init(dev->regs, &dev->ep[UDC_EP0IN_IX]); - - /* link up all endpoints */ - udc_setup_endpoints(dev); - if (dev->gadget.speed == USB_SPEED_HIGH) { - dev_info(&dev->pdev->dev, "Connect: speed = %s\n", - "high"); - } else if (dev->gadget.speed == USB_SPEED_FULL) { - dev_info(&dev->pdev->dev, "Connect: speed = %s\n", - "full"); - } - - /* init ep 0 */ - activate_control_endpoints(dev); - - /* enable ep0 interrupts */ - udc_enable_ep0_interrupts(dev); - } - /* session valid change interrupt */ - if (dev_irq & AMD_BIT(UDC_DEVINT_SVC)) { - DBG(dev, "USB SVC interrupt\n"); - ret_val = IRQ_HANDLED; - - /* check that session is not valid to detect disconnect */ - tmp = readl(&dev->regs->sts); - if (!(tmp & AMD_BIT(UDC_DEVSTS_SESSVLD))) { - /* disable suspend interrupt */ - tmp = readl(&dev->regs->irqmsk); - tmp |= AMD_BIT(UDC_DEVINT_US); - writel(tmp, &dev->regs->irqmsk); - DBG(dev, "USB Disconnect (session valid low)\n"); - /* cleanup on disconnect */ - usb_disconnect(udc); - } - - } - - return ret_val; -} - -/* Interrupt Service Routine, see Linux Kernel Doc for parameters */ -static irqreturn_t udc_irq(int irq, void *pdev) -{ - struct udc *dev = pdev; - u32 reg; - u16 i; - u32 ep_irq; - irqreturn_t ret_val = IRQ_NONE; - - spin_lock(&dev->lock); - - /* check for ep irq */ - reg = readl(&dev->regs->ep_irqsts); - if (reg) { - if (reg & AMD_BIT(UDC_EPINT_OUT_EP0)) - ret_val |= udc_control_out_isr(dev); - if (reg & AMD_BIT(UDC_EPINT_IN_EP0)) - ret_val |= udc_control_in_isr(dev); - - /* - * data endpoint - * iterate ep's - */ - for (i = 1; i < UDC_EP_NUM; i++) { - ep_irq = 1 << i; - if (!(reg & ep_irq) || i == UDC_EPINT_OUT_EP0) - continue; - - /* clear irq status */ - writel(ep_irq, &dev->regs->ep_irqsts); - - /* irq for out ep ? */ - if (i > UDC_EPIN_NUM) - ret_val |= udc_data_out_isr(dev, i); - else - ret_val |= udc_data_in_isr(dev, i); - } - - } - - - /* check for dev irq */ - reg = readl(&dev->regs->irqsts); - if (reg) { - /* clear irq */ - writel(reg, &dev->regs->irqsts); - ret_val |= udc_dev_isr(dev, reg); - } - - - spin_unlock(&dev->lock); - return ret_val; -} - -/* Tears down device */ -static void gadget_release(struct device *pdev) -{ - struct amd5536udc *dev = dev_get_drvdata(pdev); - kfree(dev); -} - -/* Cleanup on device remove */ -static void udc_remove(struct udc *dev) -{ - /* remove timer */ - stop_timer++; - if (timer_pending(&udc_timer)) - wait_for_completion(&on_exit); - if (udc_timer.data) - del_timer_sync(&udc_timer); - /* remove pollstall timer */ - stop_pollstall_timer++; - if (timer_pending(&udc_pollstall_timer)) - wait_for_completion(&on_pollstall_exit); - if (udc_pollstall_timer.data) - del_timer_sync(&udc_pollstall_timer); - udc = NULL; -} - -/* Reset all pci context */ -static void udc_pci_remove(struct pci_dev *pdev) -{ - struct udc *dev; - - dev = pci_get_drvdata(pdev); - - /* gadget driver must not be registered */ - BUG_ON(dev->driver != NULL); - - /* dma pool cleanup */ - if (dev->data_requests) - pci_pool_destroy(dev->data_requests); - - if (dev->stp_requests) { - /* cleanup DMA desc's for ep0in */ - pci_pool_free(dev->stp_requests, - dev->ep[UDC_EP0OUT_IX].td_stp, - dev->ep[UDC_EP0OUT_IX].td_stp_dma); - pci_pool_free(dev->stp_requests, - dev->ep[UDC_EP0OUT_IX].td, - dev->ep[UDC_EP0OUT_IX].td_phys); - - pci_pool_destroy(dev->stp_requests); - } - - /* reset controller */ - writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg); - if (dev->irq_registered) - free_irq(pdev->irq, dev); - if (dev->regs) - iounmap(dev->regs); - if (dev->mem_region) - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - if (dev->active) - pci_disable_device(pdev); - - device_unregister(&dev->gadget.dev); - pci_set_drvdata(pdev, NULL); - - udc_remove(dev); -} - -/* create dma pools on init */ -static int init_dma_pools(struct udc *dev) -{ - struct udc_stp_dma *td_stp; - struct udc_data_dma *td_data; - int retval; - - /* consistent DMA mode setting ? */ - if (use_dma_ppb) { - use_dma_bufferfill_mode = 0; - } else { - use_dma_ppb_du = 0; - use_dma_bufferfill_mode = 1; - } - - /* DMA setup */ - dev->data_requests = dma_pool_create("data_requests", NULL, - sizeof(struct udc_data_dma), 0, 0); - if (!dev->data_requests) { - DBG(dev, "can't get request data pool\n"); - retval = -ENOMEM; - goto finished; - } - - /* EP0 in dma regs = dev control regs */ - dev->ep[UDC_EP0IN_IX].dma = &dev->regs->ctl; - - /* dma desc for setup data */ - dev->stp_requests = dma_pool_create("setup requests", NULL, - sizeof(struct udc_stp_dma), 0, 0); - if (!dev->stp_requests) { - DBG(dev, "can't get stp request pool\n"); - retval = -ENOMEM; - goto finished; - } - /* setup */ - td_stp = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, - &dev->ep[UDC_EP0OUT_IX].td_stp_dma); - if (td_stp == NULL) { - retval = -ENOMEM; - goto finished; - } - dev->ep[UDC_EP0OUT_IX].td_stp = td_stp; - - /* data: 0 packets !? */ - td_data = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, - &dev->ep[UDC_EP0OUT_IX].td_phys); - if (td_data == NULL) { - retval = -ENOMEM; - goto finished; - } - dev->ep[UDC_EP0OUT_IX].td = td_data; - return 0; - -finished: - return retval; -} - -/* Called by pci bus driver to init pci context */ -static int udc_pci_probe( - struct pci_dev *pdev, - const struct pci_device_id *id -) -{ - struct udc *dev; - unsigned long resource; - unsigned long len; - int retval = 0; - - /* one udc only */ - if (udc) { - dev_dbg(&pdev->dev, "already probed\n"); - return -EBUSY; - } - - /* init */ - dev = kzalloc(sizeof(struct udc), GFP_KERNEL); - if (!dev) { - retval = -ENOMEM; - goto finished; - } - memset(dev, 0, sizeof(struct udc)); - - /* pci setup */ - if (pci_enable_device(pdev) < 0) { - retval = -ENODEV; - goto finished; - } - dev->active = 1; - - /* PCI resource allocation */ - resource = pci_resource_start(pdev, 0); - len = pci_resource_len(pdev, 0); - - if (!request_mem_region(resource, len, name)) { - dev_dbg(&pdev->dev, "pci device used already\n"); - retval = -EBUSY; - goto finished; - } - dev->mem_region = 1; - - dev->virt_addr = ioremap_nocache(resource, len); - if (dev->virt_addr == NULL) { - dev_dbg(&pdev->dev, "start address cannot be mapped\n"); - retval = -EFAULT; - goto finished; - } - - if (!pdev->irq) { - dev_err(&dev->pdev->dev, "irq not set\n"); - retval = -ENODEV; - goto finished; - } - - if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) { - dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq); - retval = -EBUSY; - goto finished; - } - dev->irq_registered = 1; - - pci_set_drvdata(pdev, dev); - - /* chip revision */ - dev->chiprev = 0; - - pci_set_master(pdev); - pci_set_mwi(pdev); - - /* chip rev for Hs AMD5536 */ - pci_read_config_byte(pdev, PCI_REVISION_ID, (u8 *) &dev->chiprev); - /* init dma pools */ - if (use_dma) { - retval = init_dma_pools(dev); - if (retval != 0) - goto finished; - } - - dev->phys_addr = resource; - dev->irq = pdev->irq; - dev->pdev = pdev; - dev->gadget.dev.parent = &pdev->dev; - dev->gadget.dev.dma_mask = pdev->dev.dma_mask; - - /* general probing */ - if (udc_probe(dev) == 0) - return 0; - -finished: - if (dev) - udc_pci_remove(pdev); - return retval; -} - -/* general probe */ -static int udc_probe(struct udc *dev) -{ - char tmp[128]; - u32 reg; - int retval; - - /* mark timer as not initialized */ - udc_timer.data = 0; - udc_pollstall_timer.data = 0; - - /* device struct setup */ - spin_lock_init(&dev->lock); - dev->gadget.ops = &udc_ops; - - strcpy(dev->gadget.dev.bus_id, "gadget"); - dev->gadget.dev.release = gadget_release; - dev->gadget.name = name; - dev->gadget.name = name; - dev->gadget.is_dualspeed = 1; - - /* udc csr registers base */ - dev->csr = dev->virt_addr + UDC_CSR_ADDR; - /* dev registers base */ - dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR; - /* ep registers base */ - dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR; - /* fifo's base */ - dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR); - dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR); - - /* init registers, interrupts, ... */ - startup_registers(dev); - - dev_info(&dev->pdev->dev, "%s\n", mod_desc); - - snprintf(tmp, sizeof tmp, "%d", dev->irq); - dev_info(&dev->pdev->dev, - "irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n", - tmp, dev->phys_addr, dev->chiprev, - (dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1"); - strcpy(tmp, UDC_DRIVER_VERSION_STRING); - if (dev->chiprev == UDC_HSA0_REV) { - dev_err(&dev->pdev->dev, "chip revision is A0; too old\n"); - retval = -ENODEV; - goto finished; - } - dev_info(&dev->pdev->dev, - "driver version: %s(for Geode5536 B1)\n", tmp); - udc = dev; - - retval = device_register(&dev->gadget.dev); - if (retval) - goto finished; - - /* timer init */ - init_timer(&udc_timer); - udc_timer.function = udc_timer_function; - udc_timer.data = 1; - /* timer pollstall init */ - init_timer(&udc_pollstall_timer); - udc_pollstall_timer.function = udc_pollstall_timer_function; - udc_pollstall_timer.data = 1; - - /* set SD */ - reg = readl(&dev->regs->ctl); - reg |= AMD_BIT(UDC_DEVCTL_SD); - writel(reg, &dev->regs->ctl); - - /* print dev register info */ - print_regs(dev); - - return 0; - -finished: - return retval; -} - -/* Initiates a remote wakeup */ -static int udc_remote_wakeup(struct udc *dev) -{ - unsigned long flags; - u32 tmp; - - DBG(dev, "UDC initiates remote wakeup\n"); - - spin_lock_irqsave(&dev->lock, flags); - - tmp = readl(&dev->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_RES); - writel(tmp, &dev->regs->ctl); - tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES); - writel(tmp, &dev->regs->ctl); - - spin_unlock_irqrestore(&dev->lock, flags); - return 0; -} - -/* PCI device parameters */ -static const struct pci_device_id pci_id[] = { - { - PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x2096), - .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, - .class_mask = 0xffffffff, - }, - {}, -}; -MODULE_DEVICE_TABLE(pci, pci_id); - -/* PCI functions */ -static struct pci_driver udc_pci_driver = { - .name = (char *) name, - .id_table = pci_id, - .probe = udc_pci_probe, - .remove = udc_pci_remove, -}; - -/* Inits driver */ -static int __init init(void) -{ - return pci_register_driver(&udc_pci_driver); -} -module_init(init); - -/* Cleans driver */ -static void __exit cleanup(void) -{ - pci_unregister_driver(&udc_pci_driver); -} -module_exit(cleanup); - -MODULE_DESCRIPTION(UDC_MOD_DESCRIPTION); -MODULE_AUTHOR("Thomas Dahlmann"); -MODULE_LICENSE("GPL"); - diff --git a/trunk/drivers/usb/gadget/amd5536udc.h b/trunk/drivers/usb/gadget/amd5536udc.h deleted file mode 100644 index 4bbabbbfc93f..000000000000 --- a/trunk/drivers/usb/gadget/amd5536udc.h +++ /dev/null @@ -1,626 +0,0 @@ -/* - * amd5536.h -- header for AMD 5536 UDC high/full speed USB device controller - * - * Copyright (C) 2007 AMD (http://www.amd.com) - * Author: Thomas Dahlmann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef AMD5536UDC_H -#define AMD5536UDC_H - -/* various constants */ -#define UDC_RDE_TIMER_SECONDS 1 -#define UDC_RDE_TIMER_DIV 10 -#define UDC_POLLSTALL_TIMER_USECONDS 500 - -/* Hs AMD5536 chip rev. */ -#define UDC_HSA0_REV 1 -#define UDC_HSB1_REV 2 - -/* - * SETUP usb commands - * needed, because some SETUP's are handled in hw, but must be passed to - * gadget driver above - * SET_CONFIG - */ -#define UDC_SETCONFIG_DWORD0 0x00000900 -#define UDC_SETCONFIG_DWORD0_VALUE_MASK 0xffff0000 -#define UDC_SETCONFIG_DWORD0_VALUE_OFS 16 - -#define UDC_SETCONFIG_DWORD1 0x00000000 - -/* SET_INTERFACE */ -#define UDC_SETINTF_DWORD0 0x00000b00 -#define UDC_SETINTF_DWORD0_ALT_MASK 0xffff0000 -#define UDC_SETINTF_DWORD0_ALT_OFS 16 - -#define UDC_SETINTF_DWORD1 0x00000000 -#define UDC_SETINTF_DWORD1_INTF_MASK 0x0000ffff -#define UDC_SETINTF_DWORD1_INTF_OFS 0 - -/* Mass storage reset */ -#define UDC_MSCRES_DWORD0 0x0000ff21 -#define UDC_MSCRES_DWORD1 0x00000000 - -/* Global CSR's -------------------------------------------------------------*/ -#define UDC_CSR_ADDR 0x500 - -/* EP NE bits */ -/* EP number */ -#define UDC_CSR_NE_NUM_MASK 0x0000000f -#define UDC_CSR_NE_NUM_OFS 0 -/* EP direction */ -#define UDC_CSR_NE_DIR_MASK 0x00000010 -#define UDC_CSR_NE_DIR_OFS 4 -/* EP type */ -#define UDC_CSR_NE_TYPE_MASK 0x00000060 -#define UDC_CSR_NE_TYPE_OFS 5 -/* EP config number */ -#define UDC_CSR_NE_CFG_MASK 0x00000780 -#define UDC_CSR_NE_CFG_OFS 7 -/* EP interface number */ -#define UDC_CSR_NE_INTF_MASK 0x00007800 -#define UDC_CSR_NE_INTF_OFS 11 -/* EP alt setting */ -#define UDC_CSR_NE_ALT_MASK 0x00078000 -#define UDC_CSR_NE_ALT_OFS 15 - -/* max pkt */ -#define UDC_CSR_NE_MAX_PKT_MASK 0x3ff80000 -#define UDC_CSR_NE_MAX_PKT_OFS 19 - -/* Device Config Register ---------------------------------------------------*/ -#define UDC_DEVCFG_ADDR 0x400 - -#define UDC_DEVCFG_SOFTRESET 31 -#define UDC_DEVCFG_HNPSFEN 30 -#define UDC_DEVCFG_DMARST 29 -#define UDC_DEVCFG_SET_DESC 18 -#define UDC_DEVCFG_CSR_PRG 17 -#define UDC_DEVCFG_STATUS 7 -#define UDC_DEVCFG_DIR 6 -#define UDC_DEVCFG_PI 5 -#define UDC_DEVCFG_SS 4 -#define UDC_DEVCFG_SP 3 -#define UDC_DEVCFG_RWKP 2 - -#define UDC_DEVCFG_SPD_MASK 0x3 -#define UDC_DEVCFG_SPD_OFS 0 -#define UDC_DEVCFG_SPD_HS 0x0 -#define UDC_DEVCFG_SPD_FS 0x1 -#define UDC_DEVCFG_SPD_LS 0x2 -/*#define UDC_DEVCFG_SPD_FS 0x3*/ - - -/* Device Control Register --------------------------------------------------*/ -#define UDC_DEVCTL_ADDR 0x404 - -#define UDC_DEVCTL_THLEN_MASK 0xff000000 -#define UDC_DEVCTL_THLEN_OFS 24 - -#define UDC_DEVCTL_BRLEN_MASK 0x00ff0000 -#define UDC_DEVCTL_BRLEN_OFS 16 - -#define UDC_DEVCTL_CSR_DONE 13 -#define UDC_DEVCTL_DEVNAK 12 -#define UDC_DEVCTL_SD 10 -#define UDC_DEVCTL_MODE 9 -#define UDC_DEVCTL_BREN 8 -#define UDC_DEVCTL_THE 7 -#define UDC_DEVCTL_BF 6 -#define UDC_DEVCTL_BE 5 -#define UDC_DEVCTL_DU 4 -#define UDC_DEVCTL_TDE 3 -#define UDC_DEVCTL_RDE 2 -#define UDC_DEVCTL_RES 0 - - -/* Device Status Register ---------------------------------------------------*/ -#define UDC_DEVSTS_ADDR 0x408 - -#define UDC_DEVSTS_TS_MASK 0xfffc0000 -#define UDC_DEVSTS_TS_OFS 18 - -#define UDC_DEVSTS_SESSVLD 17 -#define UDC_DEVSTS_PHY_ERROR 16 -#define UDC_DEVSTS_RXFIFO_EMPTY 15 - -#define UDC_DEVSTS_ENUM_SPEED_MASK 0x00006000 -#define UDC_DEVSTS_ENUM_SPEED_OFS 13 -#define UDC_DEVSTS_ENUM_SPEED_FULL 1 -#define UDC_DEVSTS_ENUM_SPEED_HIGH 0 - -#define UDC_DEVSTS_SUSP 12 - -#define UDC_DEVSTS_ALT_MASK 0x00000f00 -#define UDC_DEVSTS_ALT_OFS 8 - -#define UDC_DEVSTS_INTF_MASK 0x000000f0 -#define UDC_DEVSTS_INTF_OFS 4 - -#define UDC_DEVSTS_CFG_MASK 0x0000000f -#define UDC_DEVSTS_CFG_OFS 0 - - -/* Device Interrupt Register ------------------------------------------------*/ -#define UDC_DEVINT_ADDR 0x40c - -#define UDC_DEVINT_SVC 7 -#define UDC_DEVINT_ENUM 6 -#define UDC_DEVINT_SOF 5 -#define UDC_DEVINT_US 4 -#define UDC_DEVINT_UR 3 -#define UDC_DEVINT_ES 2 -#define UDC_DEVINT_SI 1 -#define UDC_DEVINT_SC 0 - -/* Device Interrupt Mask Register -------------------------------------------*/ -#define UDC_DEVINT_MSK_ADDR 0x410 - -#define UDC_DEVINT_MSK 0x7f - -/* Endpoint Interrupt Register ----------------------------------------------*/ -#define UDC_EPINT_ADDR 0x414 - -#define UDC_EPINT_OUT_MASK 0xffff0000 -#define UDC_EPINT_OUT_OFS 16 -#define UDC_EPINT_IN_MASK 0x0000ffff -#define UDC_EPINT_IN_OFS 0 - -#define UDC_EPINT_IN_EP0 0 -#define UDC_EPINT_IN_EP1 1 -#define UDC_EPINT_IN_EP2 2 -#define UDC_EPINT_IN_EP3 3 -#define UDC_EPINT_OUT_EP0 16 -#define UDC_EPINT_OUT_EP1 17 -#define UDC_EPINT_OUT_EP2 18 -#define UDC_EPINT_OUT_EP3 19 - -#define UDC_EPINT_EP0_ENABLE_MSK 0x001e001e - -/* Endpoint Interrupt Mask Register -----------------------------------------*/ -#define UDC_EPINT_MSK_ADDR 0x418 - -#define UDC_EPINT_OUT_MSK_MASK 0xffff0000 -#define UDC_EPINT_OUT_MSK_OFS 16 -#define UDC_EPINT_IN_MSK_MASK 0x0000ffff -#define UDC_EPINT_IN_MSK_OFS 0 - -#define UDC_EPINT_MSK_DISABLE_ALL 0xffffffff -/* mask non-EP0 endpoints */ -#define UDC_EPDATAINT_MSK_DISABLE 0xfffefffe -/* mask all dev interrupts */ -#define UDC_DEV_MSK_DISABLE 0x7f - -/* Endpoint-specific CSR's --------------------------------------------------*/ -#define UDC_EPREGS_ADDR 0x0 -#define UDC_EPIN_REGS_ADDR 0x0 -#define UDC_EPOUT_REGS_ADDR 0x200 - -#define UDC_EPCTL_ADDR 0x0 - -#define UDC_EPCTL_RRDY 9 -#define UDC_EPCTL_CNAK 8 -#define UDC_EPCTL_SNAK 7 -#define UDC_EPCTL_NAK 6 - -#define UDC_EPCTL_ET_MASK 0x00000030 -#define UDC_EPCTL_ET_OFS 4 -#define UDC_EPCTL_ET_CONTROL 0 -#define UDC_EPCTL_ET_ISO 1 -#define UDC_EPCTL_ET_BULK 2 -#define UDC_EPCTL_ET_INTERRUPT 3 - -#define UDC_EPCTL_P 3 -#define UDC_EPCTL_SN 2 -#define UDC_EPCTL_F 1 -#define UDC_EPCTL_S 0 - -/* Endpoint Status Registers ------------------------------------------------*/ -#define UDC_EPSTS_ADDR 0x4 - -#define UDC_EPSTS_RX_PKT_SIZE_MASK 0x007ff800 -#define UDC_EPSTS_RX_PKT_SIZE_OFS 11 - -#define UDC_EPSTS_TDC 10 -#define UDC_EPSTS_HE 9 -#define UDC_EPSTS_BNA 7 -#define UDC_EPSTS_IN 6 - -#define UDC_EPSTS_OUT_MASK 0x00000030 -#define UDC_EPSTS_OUT_OFS 4 -#define UDC_EPSTS_OUT_DATA 1 -#define UDC_EPSTS_OUT_DATA_CLEAR 0x10 -#define UDC_EPSTS_OUT_SETUP 2 -#define UDC_EPSTS_OUT_SETUP_CLEAR 0x20 -#define UDC_EPSTS_OUT_CLEAR 0x30 - -/* Endpoint Buffer Size IN/ Receive Packet Frame Number OUT Registers ------*/ -#define UDC_EPIN_BUFF_SIZE_ADDR 0x8 -#define UDC_EPOUT_FRAME_NUMBER_ADDR 0x8 - -#define UDC_EPIN_BUFF_SIZE_MASK 0x0000ffff -#define UDC_EPIN_BUFF_SIZE_OFS 0 -/* EP0in txfifo = 128 bytes*/ -#define UDC_EPIN0_BUFF_SIZE 32 -/* EP0in fullspeed txfifo = 128 bytes*/ -#define UDC_FS_EPIN0_BUFF_SIZE 32 - -/* fifo size mult = fifo size / max packet */ -#define UDC_EPIN_BUFF_SIZE_MULT 2 - -/* EPin data fifo size = 1024 bytes DOUBLE BUFFERING */ -#define UDC_EPIN_BUFF_SIZE 256 -/* EPin small INT data fifo size = 128 bytes */ -#define UDC_EPIN_SMALLINT_BUFF_SIZE 32 - -/* EPin fullspeed data fifo size = 128 bytes DOUBLE BUFFERING */ -#define UDC_FS_EPIN_BUFF_SIZE 32 - -#define UDC_EPOUT_FRAME_NUMBER_MASK 0x0000ffff -#define UDC_EPOUT_FRAME_NUMBER_OFS 0 - -/* Endpoint Buffer Size OUT/Max Packet Size Registers -----------------------*/ -#define UDC_EPOUT_BUFF_SIZE_ADDR 0x0c -#define UDC_EP_MAX_PKT_SIZE_ADDR 0x0c - -#define UDC_EPOUT_BUFF_SIZE_MASK 0xffff0000 -#define UDC_EPOUT_BUFF_SIZE_OFS 16 -#define UDC_EP_MAX_PKT_SIZE_MASK 0x0000ffff -#define UDC_EP_MAX_PKT_SIZE_OFS 0 -/* EP0in max packet size = 64 bytes */ -#define UDC_EP0IN_MAX_PKT_SIZE 64 -/* EP0out max packet size = 64 bytes */ -#define UDC_EP0OUT_MAX_PKT_SIZE 64 -/* EP0in fullspeed max packet size = 64 bytes */ -#define UDC_FS_EP0IN_MAX_PKT_SIZE 64 -/* EP0out fullspeed max packet size = 64 bytes */ -#define UDC_FS_EP0OUT_MAX_PKT_SIZE 64 - -/* - * Endpoint dma descriptors ------------------------------------------------ - * - * Setup data, Status dword - */ -#define UDC_DMA_STP_STS_CFG_MASK 0x0fff0000 -#define UDC_DMA_STP_STS_CFG_OFS 16 -#define UDC_DMA_STP_STS_CFG_ALT_MASK 0x000f0000 -#define UDC_DMA_STP_STS_CFG_ALT_OFS 16 -#define UDC_DMA_STP_STS_CFG_INTF_MASK 0x00f00000 -#define UDC_DMA_STP_STS_CFG_INTF_OFS 20 -#define UDC_DMA_STP_STS_CFG_NUM_MASK 0x0f000000 -#define UDC_DMA_STP_STS_CFG_NUM_OFS 24 -#define UDC_DMA_STP_STS_RX_MASK 0x30000000 -#define UDC_DMA_STP_STS_RX_OFS 28 -#define UDC_DMA_STP_STS_BS_MASK 0xc0000000 -#define UDC_DMA_STP_STS_BS_OFS 30 -#define UDC_DMA_STP_STS_BS_HOST_READY 0 -#define UDC_DMA_STP_STS_BS_DMA_BUSY 1 -#define UDC_DMA_STP_STS_BS_DMA_DONE 2 -#define UDC_DMA_STP_STS_BS_HOST_BUSY 3 -/* IN data, Status dword */ -#define UDC_DMA_IN_STS_TXBYTES_MASK 0x0000ffff -#define UDC_DMA_IN_STS_TXBYTES_OFS 0 -#define UDC_DMA_IN_STS_FRAMENUM_MASK 0x07ff0000 -#define UDC_DMA_IN_STS_FRAMENUM_OFS 0 -#define UDC_DMA_IN_STS_L 27 -#define UDC_DMA_IN_STS_TX_MASK 0x30000000 -#define UDC_DMA_IN_STS_TX_OFS 28 -#define UDC_DMA_IN_STS_BS_MASK 0xc0000000 -#define UDC_DMA_IN_STS_BS_OFS 30 -#define UDC_DMA_IN_STS_BS_HOST_READY 0 -#define UDC_DMA_IN_STS_BS_DMA_BUSY 1 -#define UDC_DMA_IN_STS_BS_DMA_DONE 2 -#define UDC_DMA_IN_STS_BS_HOST_BUSY 3 -/* OUT data, Status dword */ -#define UDC_DMA_OUT_STS_RXBYTES_MASK 0x0000ffff -#define UDC_DMA_OUT_STS_RXBYTES_OFS 0 -#define UDC_DMA_OUT_STS_FRAMENUM_MASK 0x07ff0000 -#define UDC_DMA_OUT_STS_FRAMENUM_OFS 0 -#define UDC_DMA_OUT_STS_L 27 -#define UDC_DMA_OUT_STS_RX_MASK 0x30000000 -#define UDC_DMA_OUT_STS_RX_OFS 28 -#define UDC_DMA_OUT_STS_BS_MASK 0xc0000000 -#define UDC_DMA_OUT_STS_BS_OFS 30 -#define UDC_DMA_OUT_STS_BS_HOST_READY 0 -#define UDC_DMA_OUT_STS_BS_DMA_BUSY 1 -#define UDC_DMA_OUT_STS_BS_DMA_DONE 2 -#define UDC_DMA_OUT_STS_BS_HOST_BUSY 3 -/* max ep0in packet */ -#define UDC_EP0IN_MAXPACKET 1000 -/* max dma packet */ -#define UDC_DMA_MAXPACKET 65536 - -/* un-usable DMA address */ -#define DMA_DONT_USE (~(dma_addr_t) 0 ) - -/* other Endpoint register addresses and values-----------------------------*/ -#define UDC_EP_SUBPTR_ADDR 0x10 -#define UDC_EP_DESPTR_ADDR 0x14 -#define UDC_EP_WRITE_CONFIRM_ADDR 0x1c - -/* EP number as layouted in AHB space */ -#define UDC_EP_NUM 32 -#define UDC_EPIN_NUM 16 -#define UDC_EPIN_NUM_USED 5 -#define UDC_EPOUT_NUM 16 -/* EP number of EP's really used = EP0 + 8 data EP's */ -#define UDC_USED_EP_NUM 9 -/* UDC CSR regs are aligned but AHB regs not - offset for OUT EP's */ -#define UDC_CSR_EP_OUT_IX_OFS 12 - -#define UDC_EP0OUT_IX 16 -#define UDC_EP0IN_IX 0 - -/* Rx fifo address and size = 1k -------------------------------------------*/ -#define UDC_RXFIFO_ADDR 0x800 -#define UDC_RXFIFO_SIZE 0x400 - -/* Tx fifo address and size = 1.5k -----------------------------------------*/ -#define UDC_TXFIFO_ADDR 0xc00 -#define UDC_TXFIFO_SIZE 0x600 - -/* default data endpoints --------------------------------------------------*/ -#define UDC_EPIN_STATUS_IX 1 -#define UDC_EPIN_IX 2 -#define UDC_EPOUT_IX 18 - -/* general constants -------------------------------------------------------*/ -#define UDC_DWORD_BYTES 4 -#define UDC_BITS_PER_BYTE_SHIFT 3 -#define UDC_BYTE_MASK 0xff -#define UDC_BITS_PER_BYTE 8 - -/*---------------------------------------------------------------------------*/ -/* UDC CSR's */ -struct udc_csrs { - - /* sca - setup command address */ - u32 sca; - - /* ep ne's */ - u32 ne[UDC_USED_EP_NUM]; -} __attribute__ ((packed)); - -/* AHB subsystem CSR registers */ -struct udc_regs { - - /* device configuration */ - u32 cfg; - - /* device control */ - u32 ctl; - - /* device status */ - u32 sts; - - /* device interrupt */ - u32 irqsts; - - /* device interrupt mask */ - u32 irqmsk; - - /* endpoint interrupt */ - u32 ep_irqsts; - - /* endpoint interrupt mask */ - u32 ep_irqmsk; -} __attribute__ ((packed)); - -/* endpoint specific registers */ -struct udc_ep_regs { - - /* endpoint control */ - u32 ctl; - - /* endpoint status */ - u32 sts; - - /* endpoint buffer size in/ receive packet frame number out */ - u32 bufin_framenum; - - /* endpoint buffer size out/max packet size */ - u32 bufout_maxpkt; - - /* endpoint setup buffer pointer */ - u32 subptr; - - /* endpoint data descriptor pointer */ - u32 desptr; - - /* reserverd */ - u32 reserved; - - /* write/read confirmation */ - u32 confirm; - -} __attribute__ ((packed)); - -/* control data DMA desc */ -struct udc_stp_dma { - /* status quadlet */ - u32 status; - /* reserved */ - u32 _reserved; - /* first setup word */ - u32 data12; - /* second setup word */ - u32 data34; -} __attribute__ ((aligned (16))); - -/* normal data DMA desc */ -struct udc_data_dma { - /* status quadlet */ - u32 status; - /* reserved */ - u32 _reserved; - /* buffer pointer */ - u32 bufptr; - /* next descriptor pointer */ - u32 next; -} __attribute__ ((aligned (16))); - -/* request packet */ -struct udc_request { - /* embedded gadget ep */ - struct usb_request req; - - /* flags */ - unsigned dma_going : 1, - dma_mapping : 1, - dma_done : 1; - /* phys. address */ - dma_addr_t td_phys; - /* first dma desc. of chain */ - struct udc_data_dma *td_data; - /* last dma desc. of chain */ - struct udc_data_dma *td_data_last; - struct list_head queue; - - /* chain length */ - unsigned chain_len; - -}; - -/* UDC specific endpoint parameters */ -struct udc_ep { - struct usb_ep ep; - struct udc_ep_regs __iomem *regs; - u32 __iomem *txfifo; - u32 __iomem *dma; - dma_addr_t td_phys; - dma_addr_t td_stp_dma; - struct udc_stp_dma *td_stp; - struct udc_data_dma *td; - /* temp request */ - struct udc_request *req; - unsigned req_used; - unsigned req_completed; - /* dummy DMA desc for BNA dummy */ - struct udc_request *bna_dummy_req; - unsigned bna_occurred; - - /* NAK state */ - unsigned naking; - - struct udc *dev; - - /* queue for requests */ - struct list_head queue; - const struct usb_endpoint_descriptor *desc; - unsigned halted; - unsigned cancel_transfer; - unsigned num : 5, - fifo_depth : 14, - in : 1; -}; - -/* device struct */ -struct udc { - struct usb_gadget gadget; - spinlock_t lock; /* protects all state */ - /* all endpoints */ - struct udc_ep ep[UDC_EP_NUM]; - struct usb_gadget_driver *driver; - /* operational flags */ - unsigned active : 1, - stall_ep0in : 1, - waiting_zlp_ack_ep0in : 1, - set_cfg_not_acked : 1, - irq_registered : 1, - data_ep_enabled : 1, - data_ep_queued : 1, - mem_region : 1, - sys_suspended : 1, - connected; - - u16 chiprev; - - /* registers */ - struct pci_dev *pdev; - struct udc_csrs __iomem *csr; - struct udc_regs __iomem *regs; - struct udc_ep_regs __iomem *ep_regs; - u32 __iomem *rxfifo; - u32 __iomem *txfifo; - - /* DMA desc pools */ - struct pci_pool *data_requests; - struct pci_pool *stp_requests; - - /* device data */ - unsigned long phys_addr; - void __iomem *virt_addr; - unsigned irq; - - /* states */ - u16 cur_config; - u16 cur_intf; - u16 cur_alt; -}; - -/* setup request data */ -union udc_setup_data { - u32 data[2]; - struct usb_ctrlrequest request; -}; - -/* - *--------------------------------------------------------------------------- - * SET and GET bitfields in u32 values - * via constants for mask/offset: - * is the text between - * UDC_ and _MASK|_OFS of appropiate - * constant - * - * set bitfield value in u32 u32Val - */ -#define AMD_ADDBITS(u32Val, bitfield_val, bitfield_stub_name) \ - (((u32Val) & (((u32) ~((u32) bitfield_stub_name##_MASK)))) \ - | (((bitfield_val) << ((u32) bitfield_stub_name##_OFS)) \ - & ((u32) bitfield_stub_name##_MASK))) - -/* - * set bitfield value in zero-initialized u32 u32Val - * => bitfield bits in u32Val are all zero - */ -#define AMD_INIT_SETBITS(u32Val, bitfield_val, bitfield_stub_name) \ - ((u32Val) \ - | (((bitfield_val) << ((u32) bitfield_stub_name##_OFS)) \ - & ((u32) bitfield_stub_name##_MASK))) - -/* get bitfield value from u32 u32Val */ -#define AMD_GETBITS(u32Val, bitfield_stub_name) \ - ((u32Val & ((u32) bitfield_stub_name##_MASK)) \ - >> ((u32) bitfield_stub_name##_OFS)) - -/* SET and GET bits in u32 values ------------------------------------------*/ -#define AMD_BIT(bit_stub_name) (1 << bit_stub_name) -#define AMD_UNMASK_BIT(bit_stub_name) (~AMD_BIT(bit_stub_name)) -#define AMD_CLEAR_BIT(bit_stub_name) (~AMD_BIT(bit_stub_name)) - -/* debug macros ------------------------------------------------------------*/ - -#define DBG(udc , args...) dev_dbg(&(udc)->pdev->dev, args) - -#ifdef UDC_VERBOSE -#define VDBG DBG -#else -#define VDBG(udc , args...) do {} while (0) -#endif - -#endif /* #ifdef AMD5536UDC_H */ diff --git a/trunk/drivers/usb/gadget/ether.c b/trunk/drivers/usb/gadget/ether.c index a3376739a81b..dbaf867436df 100644 --- a/trunk/drivers/usb/gadget/ether.c +++ b/trunk/drivers/usb/gadget/ether.c @@ -305,10 +305,6 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); #define DEV_CONFIG_CDC #endif -#ifdef CONFIG_USB_GADGET_AMD5536UDC -#define DEV_CONFIG_CDC -#endif - /*-------------------------------------------------------------------------*/ diff --git a/trunk/drivers/usb/gadget/gadget_chips.h b/trunk/drivers/usb/gadget/gadget_chips.h index f7f159c1002b..53e9139ba388 100644 --- a/trunk/drivers/usb/gadget/gadget_chips.h +++ b/trunk/drivers/usb/gadget/gadget_chips.h @@ -17,12 +17,6 @@ #define gadget_is_net2280(g) 0 #endif -#ifdef CONFIG_USB_GADGET_AMD5536UDC -#define gadget_is_amd5536udc(g) !strcmp("amd5536udc", (g)->name) -#else -#define gadget_is_amd5536udc(g) 0 -#endif - #ifdef CONFIG_USB_GADGET_DUMMY_HCD #define gadget_is_dummy(g) !strcmp("dummy_udc", (g)->name) #else @@ -208,9 +202,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) return 0x18; else if (gadget_is_fsl_usb2(gadget)) return 0x19; - else if (gadget_is_amd5536udc(gadget)) - return 0x20; else if (gadget_is_m66592(gadget)) - return 0x21; + return 0x20; return -ENOENT; } diff --git a/trunk/drivers/usb/gadget/m66592-udc.c b/trunk/drivers/usb/gadget/m66592-udc.c index 700dda8a9157..0174a322e007 100644 --- a/trunk/drivers/usb/gadget/m66592-udc.c +++ b/trunk/drivers/usb/gadget/m66592-udc.c @@ -21,18 +21,26 @@ */ #include -#include +#include +#include +#include +#include +#include +#include #include -#include +#include +#include #include - #include #include -#include "m66592-udc.h" +#include +#include +#include +#include "m66592-udc.h" -MODULE_DESCRIPTION("M66592 USB gadget driver"); +MODULE_DESCRIPTION("M66592 USB gadget driiver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Yoshihiro Shimoda"); @@ -41,21 +49,16 @@ MODULE_AUTHOR("Yoshihiro Shimoda"); /* module parameters */ static unsigned short clock = M66592_XTAL24; module_param(clock, ushort, 0644); -MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " - "(default=16384)"); - +MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0(default=16384)"); static unsigned short vif = M66592_LDRV; module_param(vif, ushort, 0644); -MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0 (default=32768)"); - -static unsigned short endian; +MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0(default=32768)"); +static unsigned short endian = 0; module_param(endian, ushort, 0644); -MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)"); - +MODULE_PARM_DESC(endian, "data endian: big=256, little=0(default=0)"); static unsigned short irq_sense = M66592_INTL; module_param(irq_sense, ushort, 0644); -MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 " - "(default=2)"); +MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0(default=2)"); static const char udc_name[] = "m66592_udc"; static const char *m66592_ep_name[] = { @@ -69,8 +72,8 @@ static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags); static void transfer_complete(struct m66592_ep *ep, - struct m66592_request *req, int status); - + struct m66592_request *req, + int status); /*-------------------------------------------------------------------------*/ static inline u16 get_usb_speed(struct m66592 *m66592) { @@ -78,25 +81,25 @@ static inline u16 get_usb_speed(struct m66592 *m66592) } static void enable_pipe_irq(struct m66592 *m66592, u16 pipenum, - unsigned long reg) + unsigned long reg) { u16 tmp; tmp = m66592_read(m66592, M66592_INTENB0); m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, - M66592_INTENB0); + M66592_INTENB0); m66592_bset(m66592, (1 << pipenum), reg); m66592_write(m66592, tmp, M66592_INTENB0); } static void disable_pipe_irq(struct m66592 *m66592, u16 pipenum, - unsigned long reg) + unsigned long reg) { u16 tmp; tmp = m66592_read(m66592, M66592_INTENB0); m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, - M66592_INTENB0); + M66592_INTENB0); m66592_bclr(m66592, (1 << pipenum), reg); m66592_write(m66592, tmp, M66592_INTENB0); } @@ -105,19 +108,17 @@ static void m66592_usb_connect(struct m66592 *m66592) { m66592_bset(m66592, M66592_CTRE, M66592_INTENB0); m66592_bset(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, - M66592_INTENB0); + M66592_INTENB0); m66592_bset(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); m66592_bset(m66592, M66592_DPRPU, M66592_SYSCFG); } static void m66592_usb_disconnect(struct m66592 *m66592) -__releases(m66592->lock) -__acquires(m66592->lock) { m66592_bclr(m66592, M66592_CTRE, M66592_INTENB0); m66592_bclr(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, - M66592_INTENB0); + M66592_INTENB0); m66592_bclr(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); @@ -147,7 +148,7 @@ static inline u16 control_reg_get_pid(struct m66592 *m66592, u16 pipenum) } static inline void control_reg_set_pid(struct m66592 *m66592, u16 pipenum, - u16 pid) + u16 pid) { unsigned long offset; @@ -249,7 +250,7 @@ static inline void pipe_change(struct m66592 *m66592, u16 pipenum) } static int pipe_buffer_setting(struct m66592 *m66592, - struct m66592_pipe_info *info) + struct m66592_pipe_info *info) { u16 bufnum = 0, buf_bsize = 0; u16 pipecfg = 0; @@ -286,7 +287,7 @@ static int pipe_buffer_setting(struct m66592 *m66592, } if (m66592->bi_bufnum > M66592_MAX_BUFNUM) { printk(KERN_ERR "m66592 pipe memory is insufficient(%d)\n", - m66592->bi_bufnum); + m66592->bi_bufnum); return -ENOMEM; } @@ -327,7 +328,7 @@ static void pipe_buffer_release(struct m66592 *m66592, m66592->bulk--; } else printk(KERN_ERR "ep_release: unexpect pipenum (%d)\n", - info->pipe); + info->pipe); } static void pipe_initialize(struct m66592_ep *ep) @@ -349,8 +350,8 @@ static void pipe_initialize(struct m66592_ep *ep) } static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, - const struct usb_endpoint_descriptor *desc, - u16 pipenum, int dma) + const struct usb_endpoint_descriptor *desc, + u16 pipenum, int dma) { if ((pipenum != 0) && dma) { if (m66592->num_dma == 0) { @@ -384,7 +385,7 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, ep->pipectr = get_pipectr_addr(pipenum); ep->pipenum = pipenum; - ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); + ep->ep.maxpacket = desc->wMaxPacketSize; m66592->pipenum2ep[pipenum] = ep; m66592->epaddr2ep[desc->bEndpointAddress&USB_ENDPOINT_NUMBER_MASK] = ep; INIT_LIST_HEAD(&ep->queue); @@ -406,7 +407,7 @@ static void m66592_ep_release(struct m66592_ep *ep) } static int alloc_pipe_config(struct m66592_ep *ep, - const struct usb_endpoint_descriptor *desc) + const struct usb_endpoint_descriptor *desc) { struct m66592 *m66592 = ep->m66592; struct m66592_pipe_info info; @@ -418,15 +419,15 @@ static int alloc_pipe_config(struct m66592_ep *ep, BUG_ON(ep->pipenum); - switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + switch(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { case USB_ENDPOINT_XFER_BULK: if (m66592->bulk >= M66592_MAX_NUM_BULK) { if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { printk(KERN_ERR "bulk pipe is insufficient\n"); return -ENODEV; } else { - info.pipe = M66592_BASE_PIPENUM_ISOC - + m66592->isochronous; + info.pipe = M66592_BASE_PIPENUM_ISOC + + m66592->isochronous; counter = &m66592->isochronous; } } else { @@ -461,7 +462,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, ep->type = info.type; info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - info.maxpacket = le16_to_cpu(desc->wMaxPacketSize); + info.maxpacket = desc->wMaxPacketSize; info.interval = desc->bInterval; if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) info.dir_in = 1; @@ -524,8 +525,8 @@ static void start_ep0_write(struct m66592_ep *ep, struct m66592_request *req) pipe_change(m66592, ep->pipenum); m66592_mdfy(m66592, M66592_ISEL | M66592_PIPE0, - (M66592_ISEL | M66592_CURPIPE), - M66592_CFIFOSEL); + (M66592_ISEL | M66592_CURPIPE), + M66592_CFIFOSEL); m66592_write(m66592, M66592_BCLR, ep->fifoctr); if (req->req.length == 0) { m66592_bset(m66592, M66592_BVAL, ep->fifoctr); @@ -560,8 +561,8 @@ static void start_packet_read(struct m66592_ep *ep, struct m66592_request *req) if (ep->pipenum == 0) { m66592_mdfy(m66592, M66592_PIPE0, - (M66592_ISEL | M66592_CURPIPE), - M66592_CFIFOSEL); + (M66592_ISEL | M66592_CURPIPE), + M66592_CFIFOSEL); m66592_write(m66592, M66592_BCLR, ep->fifoctr); pipe_start(m66592, pipenum); pipe_irq_enable(m66592, pipenum); @@ -571,9 +572,8 @@ static void start_packet_read(struct m66592_ep *ep, struct m66592_request *req) pipe_change(m66592, pipenum); m66592_bset(m66592, M66592_TRENB, ep->fifosel); m66592_write(m66592, - (req->req.length + ep->ep.maxpacket - 1) - / ep->ep.maxpacket, - ep->fifotrn); + (req->req.length + ep->ep.maxpacket - 1) / + ep->ep.maxpacket, ep->fifotrn); } pipe_start(m66592, pipenum); /* trigger once */ pipe_irq_enable(m66592, pipenum); @@ -614,7 +614,7 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req) static void init_controller(struct m66592 *m66592) { m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND), - M66592_PINCFG); + M66592_PINCFG); m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG); @@ -634,7 +634,7 @@ static void init_controller(struct m66592 *m66592) m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1); m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, - M66592_DMA0CFG); + M66592_DMA0CFG); } static void disable_controller(struct m66592 *m66592) @@ -659,9 +659,8 @@ static void m66592_start_xclock(struct m66592 *m66592) /*-------------------------------------------------------------------------*/ static void transfer_complete(struct m66592_ep *ep, - struct m66592_request *req, int status) -__releases(m66592->lock) -__acquires(m66592->lock) + struct m66592_request *req, + int status) { int restart = 0; @@ -681,9 +680,8 @@ __acquires(m66592->lock) if (!list_empty(&ep->queue)) restart = 1; - spin_unlock(&ep->m66592->lock); - req->req.complete(&ep->ep, &req->req); - spin_lock(&ep->m66592->lock); + if (likely(req->req.complete)) + req->req.complete(&ep->ep, &req->req); if (restart) { req = list_entry(ep->queue.next, struct m66592_request, queue); @@ -695,7 +693,7 @@ __acquires(m66592->lock) static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) { int i; - u16 tmp; + volatile u16 tmp; unsigned bufsize; size_t size; void *buf; @@ -733,9 +731,8 @@ static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) req->req.actual += size; /* check transfer finish */ - if ((!req->req.zero && (req->req.actual == req->req.length)) - || (size % ep->ep.maxpacket) - || (size == 0)) { + if ((!req->req.zero && (req->req.actual == req->req.length)) || + (size % ep->ep.maxpacket) || (size == 0)) { disable_irq_ready(m66592, pipenum); disable_irq_empty(m66592, pipenum); } else { @@ -771,19 +768,16 @@ static void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req) /* write fifo */ if (req->req.buf) { m66592_write_fifo(m66592, ep->fifoaddr, buf, size); - if ((size == 0) - || ((size % ep->ep.maxpacket) != 0) - || ((bufsize != ep->ep.maxpacket) - && (bufsize > size))) + if ((size == 0) || ((size % ep->ep.maxpacket) != 0) || + ((bufsize != ep->ep.maxpacket) && (bufsize > size))) m66592_bset(m66592, M66592_BVAL, ep->fifoctr); } /* update parameters */ req->req.actual += size; /* check transfer finish */ - if ((!req->req.zero && (req->req.actual == req->req.length)) - || (size % ep->ep.maxpacket) - || (size == 0)) { + if ((!req->req.zero && (req->req.actual == req->req.length)) || + (size % ep->ep.maxpacket) || (size == 0)) { disable_irq_ready(m66592, pipenum); enable_irq_empty(m66592, pipenum); } else { @@ -827,9 +821,8 @@ static void irq_packet_read(struct m66592_ep *ep, struct m66592_request *req) req->req.actual += size; /* check transfer finish */ - if ((!req->req.zero && (req->req.actual == req->req.length)) - || (size % ep->ep.maxpacket) - || (size == 0)) { + if ((!req->req.zero && (req->req.actual == req->req.length)) || + (size % ep->ep.maxpacket) || (size == 0)) { pipe_stop(m66592, pipenum); pipe_irq_disable(m66592, pipenum); finish = 1; @@ -857,7 +850,7 @@ static void irq_pipe_ready(struct m66592 *m66592, u16 status, u16 enb) if ((status & M66592_BRDY0) && (enb & M66592_BRDY0)) { m66592_write(m66592, ~M66592_BRDY0, M66592_BRDYSTS); m66592_mdfy(m66592, M66592_PIPE0, M66592_CURPIPE, - M66592_CFIFOSEL); + M66592_CFIFOSEL); ep = &m66592->ep[0]; req = list_entry(ep->queue.next, struct m66592_request, queue); @@ -916,26 +909,23 @@ static void irq_pipe_empty(struct m66592 *m66592, u16 status, u16 enb) } static void get_status(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) -__releases(m66592->lock) -__acquires(m66592->lock) { struct m66592_ep *ep; u16 pid; u16 status = 0; - u16 w_index = le16_to_cpu(ctrl->wIndex); switch (ctrl->bRequestType & USB_RECIP_MASK) { case USB_RECIP_DEVICE: - status = 1 << USB_DEVICE_SELF_POWERED; + status = 1; /* selfpower */ break; case USB_RECIP_INTERFACE: status = 0; break; case USB_RECIP_ENDPOINT: - ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; + ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; pid = control_reg_get_pid(m66592, ep->pipenum); if (pid == M66592_PID_STALL) - status = 1 << USB_ENDPOINT_HALT; + status = 1; else status = 0; break; @@ -944,13 +934,11 @@ __acquires(m66592->lock) return; /* exit */ } - m66592->ep0_data = cpu_to_le16(status); - m66592->ep0_req->buf = &m66592->ep0_data; + *m66592->ep0_buf = status; + m66592->ep0_req->buf = m66592->ep0_buf; m66592->ep0_req->length = 2; /* AV: what happens if we get called again before that gets through? */ - spin_unlock(&m66592->lock); m66592_queue(m66592->gadget.ep0, m66592->ep0_req, GFP_KERNEL); - spin_lock(&m66592->lock); } static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) @@ -965,9 +953,8 @@ static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) case USB_RECIP_ENDPOINT: { struct m66592_ep *ep; struct m66592_request *req; - u16 w_index = le16_to_cpu(ctrl->wIndex); - ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; + ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; pipe_stop(m66592, ep->pipenum); control_reg_sqclr(m66592, ep->pipenum); @@ -1002,9 +989,8 @@ static void set_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) break; case USB_RECIP_ENDPOINT: { struct m66592_ep *ep; - u16 w_index = le16_to_cpu(ctrl->wIndex); - ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; + ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; pipe_stall(m66592, ep->pipenum); control_end(m66592, 1); @@ -1080,16 +1066,14 @@ static void irq_device_state(struct m66592 *m66592) } if (m66592->old_dvsq == M66592_DS_CNFG && dvsq != M66592_DS_CNFG) m66592_update_usb_speed(m66592); - if ((dvsq == M66592_DS_CNFG || dvsq == M66592_DS_ADDS) - && m66592->gadget.speed == USB_SPEED_UNKNOWN) + if ((dvsq == M66592_DS_CNFG || dvsq == M66592_DS_ADDS) && + m66592->gadget.speed == USB_SPEED_UNKNOWN) m66592_update_usb_speed(m66592); m66592->old_dvsq = dvsq; } static void irq_control_stage(struct m66592 *m66592) -__releases(m66592->lock) -__acquires(m66592->lock) { struct usb_ctrlrequest ctrl; u16 ctsq; @@ -1111,10 +1095,8 @@ __acquires(m66592->lock) case M66592_CS_WRDS: case M66592_CS_WRND: if (setup_packet(m66592, &ctrl)) { - spin_unlock(&m66592->lock); if (m66592->driver->setup(&m66592->gadget, &ctrl) < 0) pipe_stall(m66592, 0); - spin_lock(&m66592->lock); } break; case M66592_CS_RDSS: @@ -1137,8 +1119,6 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) u16 savepipe; u16 mask0; - spin_lock(&m66592->lock); - intsts0 = m66592_read(m66592, M66592_INTSTS0); intenb0 = m66592_read(m66592, M66592_INTENB0); @@ -1154,27 +1134,27 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) bempenb = m66592_read(m66592, M66592_BEMPENB); if (mask0 & M66592_VBINT) { - m66592_write(m66592, 0xffff & ~M66592_VBINT, - M66592_INTSTS0); + m66592_write(m66592, (u16)~M66592_VBINT, + M66592_INTSTS0); m66592_start_xclock(m66592); /* start vbus sampling */ m66592->old_vbus = m66592_read(m66592, M66592_INTSTS0) - & M66592_VBSTS; + & M66592_VBSTS; m66592->scount = M66592_MAX_SAMPLING; mod_timer(&m66592->timer, - jiffies + msecs_to_jiffies(50)); + jiffies + msecs_to_jiffies(50)); } if (intsts0 & M66592_DVSQ) irq_device_state(m66592); - if ((intsts0 & M66592_BRDY) && (intenb0 & M66592_BRDYE) - && (brdysts & brdyenb)) { + if ((intsts0 & M66592_BRDY) && (intenb0 & M66592_BRDYE) && + (brdysts & brdyenb)) { irq_pipe_ready(m66592, brdysts, brdyenb); } - if ((intsts0 & M66592_BEMP) && (intenb0 & M66592_BEMPE) - && (bempsts & bempenb)) { + if ((intsts0 & M66592_BEMP) && (intenb0 & M66592_BEMPE) && + (bempsts & bempenb)) { irq_pipe_empty(m66592, bempsts, bempenb); } @@ -1184,7 +1164,6 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) m66592_write(m66592, savepipe, M66592_CFIFOSEL); - spin_unlock(&m66592->lock); return IRQ_HANDLED; } @@ -1212,13 +1191,13 @@ static void m66592_timer(unsigned long _m66592) m66592_usb_disconnect(m66592); } else { mod_timer(&m66592->timer, - jiffies + msecs_to_jiffies(50)); + jiffies + msecs_to_jiffies(50)); } } else { m66592->scount = M66592_MAX_SAMPLING; m66592->old_vbus = tmp; mod_timer(&m66592->timer, - jiffies + msecs_to_jiffies(50)); + jiffies + msecs_to_jiffies(50)); } } spin_unlock_irqrestore(&m66592->lock, flags); @@ -1356,6 +1335,11 @@ static int m66592_set_halt(struct usb_ep *_ep, int value) return ret; } +static int m66592_fifo_status(struct usb_ep *_ep) +{ + return -EOPNOTSUPP; +} + static void m66592_fifo_flush(struct usb_ep *_ep) { struct m66592_ep *ep; @@ -1381,6 +1365,7 @@ static struct usb_ep_ops m66592_ep_ops = { .dequeue = m66592_dequeue, .set_halt = m66592_set_halt, + .fifo_status = m66592_fifo_status, .fifo_flush = m66592_fifo_flush, }; @@ -1392,10 +1377,11 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) struct m66592 *m66592 = the_controller; int retval; - if (!driver - || driver->speed != USB_SPEED_HIGH - || !driver->bind - || !driver->setup) + if (!driver || + driver->speed != USB_SPEED_HIGH || + !driver->bind || + !driver->unbind || + !driver->setup) return -EINVAL; if (!m66592) return -ENODEV; @@ -1427,7 +1413,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) m66592->old_vbus = m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS; m66592->scount = M66592_MAX_SAMPLING; - mod_timer(&m66592->timer, jiffies + msecs_to_jiffies(50)); + mod_timer(&m66592->timer, + jiffies + msecs_to_jiffies(50)); } return 0; @@ -1445,9 +1432,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) struct m66592 *m66592 = the_controller; unsigned long flags; - if (driver != m66592->driver || !driver->unbind) - return -EINVAL; - spin_lock_irqsave(&m66592->lock, flags); if (m66592->gadget.speed != USB_SPEED_UNKNOWN) m66592_usb_disconnect(m66592); @@ -1477,35 +1461,46 @@ static struct usb_gadget_ops m66592_gadget_ops = { .get_frame = m66592_get_frame, }; -static int __exit m66592_remove(struct platform_device *pdev) +#if defined(CONFIG_PM) +static int m66592_suspend(struct platform_device *pdev, pm_message_t state) +{ + pdev->dev.power.power_state = state; + return 0; +} + +static int m66592_resume(struct platform_device *pdev) +{ + pdev->dev.power.power_state = PMSG_ON; + return 0; +} +#else /* if defined(CONFIG_PM) */ +#define m66592_suspend NULL +#define m66592_resume NULL +#endif + +static int __init_or_module m66592_remove(struct platform_device *pdev) { struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); del_timer_sync(&m66592->timer); iounmap(m66592->reg); free_irq(platform_get_irq(pdev, 0), m66592); - m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); kfree(m66592); return 0; } -static void nop_completion(struct usb_ep *ep, struct usb_request *r) -{ -} - #define resource_len(r) (((r)->end - (r)->start) + 1) - static int __init m66592_probe(struct platform_device *pdev) { - struct resource *res; - int irq; + struct resource *res = NULL; + int irq = -1; void __iomem *reg = NULL; struct m66592 *m66592 = NULL; int ret = 0; int i; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - (char *)udc_name); + (char *)udc_name); if (!res) { ret = -ENODEV; printk(KERN_ERR "platform_get_resource_byname error.\n"); @@ -1553,7 +1548,7 @@ static int __init m66592_probe(struct platform_device *pdev) m66592->bi_bufnum = M66592_BASE_BUFNUM; ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED, - udc_name, m66592); + udc_name, m66592); if (ret < 0) { printk(KERN_ERR "request_irq error (%d)\n", ret); goto clean_up; @@ -1568,7 +1563,7 @@ static int __init m66592_probe(struct platform_device *pdev) if (i != 0) { INIT_LIST_HEAD(&m66592->ep[i].ep.ep_list); list_add_tail(&m66592->ep[i].ep.ep_list, - &m66592->gadget.ep_list); + &m66592->gadget.ep_list); } ep->m66592 = m66592; INIT_LIST_HEAD(&ep->queue); @@ -1588,18 +1583,20 @@ static int __init m66592_probe(struct platform_device *pdev) the_controller = m66592; + /* AV: leaks */ m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); if (m66592->ep0_req == NULL) - goto clean_up2; - m66592->ep0_req->complete = nop_completion; + goto clean_up; + /* AV: leaks, and do we really need it separately allocated? */ + m66592->ep0_buf = kzalloc(2, GFP_KERNEL); + if (m66592->ep0_buf == NULL) + goto clean_up; init_controller(m66592); - dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); + printk("driver %s, %s\n", udc_name, DRIVER_VERSION); return 0; -clean_up2: - free_irq(irq, m66592); clean_up: if (m66592) { if (m66592->ep0_req) @@ -1614,7 +1611,10 @@ static int __init m66592_probe(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ static struct platform_driver m66592_driver = { - .remove = __exit_p(m66592_remove), + .probe = m66592_probe, + .remove = m66592_remove, + .suspend = m66592_suspend, + .resume = m66592_resume, .driver = { .name = (char *) udc_name, }, @@ -1622,7 +1622,7 @@ static struct platform_driver m66592_driver = { static int __init m66592_udc_init(void) { - return platform_driver_probe(&m66592_driver, m66592_probe); + return platform_driver_register(&m66592_driver); } module_init(m66592_udc_init); @@ -1631,3 +1631,4 @@ static void __exit m66592_udc_cleanup(void) platform_driver_unregister(&m66592_driver); } module_exit(m66592_udc_cleanup); + diff --git a/trunk/drivers/usb/gadget/m66592-udc.h b/trunk/drivers/usb/gadget/m66592-udc.h index bfa0c645f229..26b54f8b8945 100644 --- a/trunk/drivers/usb/gadget/m66592-udc.h +++ b/trunk/drivers/usb/gadget/m66592-udc.h @@ -24,73 +24,73 @@ #define __M66592_UDC_H__ #define M66592_SYSCFG 0x00 -#define M66592_XTAL 0xC000 /* b15-14: Crystal selection */ -#define M66592_XTAL48 0x8000 /* 48MHz */ -#define M66592_XTAL24 0x4000 /* 24MHz */ -#define M66592_XTAL12 0x0000 /* 12MHz */ -#define M66592_XCKE 0x2000 /* b13: External clock enable */ -#define M66592_RCKE 0x1000 /* b12: Register clock enable */ -#define M66592_PLLC 0x0800 /* b11: PLL control */ -#define M66592_SCKE 0x0400 /* b10: USB clock enable */ -#define M66592_ATCKM 0x0100 /* b8: Automatic clock supply */ -#define M66592_HSE 0x0080 /* b7: Hi-speed enable */ -#define M66592_DCFM 0x0040 /* b6: Controller function select */ -#define M66592_DMRPD 0x0020 /* b5: D- pull down control */ -#define M66592_DPRPU 0x0010 /* b4: D+ pull up control */ -#define M66592_FSRPC 0x0004 /* b2: Full-speed receiver enable */ -#define M66592_PCUT 0x0002 /* b1: Low power sleep enable */ -#define M66592_USBE 0x0001 /* b0: USB module operation enable */ +#define M66592_XTAL 0xC000 /* b15-14: Crystal selection */ +#define M66592_XTAL48 0x8000 /* 48MHz */ +#define M66592_XTAL24 0x4000 /* 24MHz */ +#define M66592_XTAL12 0x0000 /* 12MHz */ +#define M66592_XCKE 0x2000 /* b13: External clock enable */ +#define M66592_RCKE 0x1000 /* b12: Register clock enable */ +#define M66592_PLLC 0x0800 /* b11: PLL control */ +#define M66592_SCKE 0x0400 /* b10: USB clock enable */ +#define M66592_ATCKM 0x0100 /* b8: Automatic supply functional enable */ +#define M66592_HSE 0x0080 /* b7: Hi-speed enable */ +#define M66592_DCFM 0x0040 /* b6: Controller function select */ +#define M66592_DMRPD 0x0020 /* b5: D- pull down control */ +#define M66592_DPRPU 0x0010 /* b4: D+ pull up control */ +#define M66592_FSRPC 0x0004 /* b2: Full-speed receiver enable */ +#define M66592_PCUT 0x0002 /* b1: Low power sleep enable */ +#define M66592_USBE 0x0001 /* b0: USB module operation enable */ #define M66592_SYSSTS 0x02 -#define M66592_LNST 0x0003 /* b1-0: D+, D- line status */ -#define M66592_SE1 0x0003 /* SE1 */ -#define M66592_KSTS 0x0002 /* K State */ -#define M66592_JSTS 0x0001 /* J State */ -#define M66592_SE0 0x0000 /* SE0 */ +#define M66592_LNST 0x0003 /* b1-0: D+, D- line status */ +#define M66592_SE1 0x0003 /* SE1 */ +#define M66592_KSTS 0x0002 /* K State */ +#define M66592_JSTS 0x0001 /* J State */ +#define M66592_SE0 0x0000 /* SE0 */ #define M66592_DVSTCTR 0x04 -#define M66592_WKUP 0x0100 /* b8: Remote wakeup */ -#define M66592_RWUPE 0x0080 /* b7: Remote wakeup sense */ -#define M66592_USBRST 0x0040 /* b6: USB reset enable */ -#define M66592_RESUME 0x0020 /* b5: Resume enable */ -#define M66592_UACT 0x0010 /* b4: USB bus enable */ -#define M66592_RHST 0x0003 /* b1-0: Reset handshake status */ -#define M66592_HSMODE 0x0003 /* Hi-Speed mode */ -#define M66592_FSMODE 0x0002 /* Full-Speed mode */ -#define M66592_HSPROC 0x0001 /* HS handshake is processing */ +#define M66592_WKUP 0x0100 /* b8: Remote wakeup */ +#define M66592_RWUPE 0x0080 /* b7: Remote wakeup sense */ +#define M66592_USBRST 0x0040 /* b6: USB reset enable */ +#define M66592_RESUME 0x0020 /* b5: Resume enable */ +#define M66592_UACT 0x0010 /* b4: USB bus enable */ +#define M66592_RHST 0x0003 /* b1-0: Reset handshake status */ +#define M66592_HSMODE 0x0003 /* Hi-Speed mode */ +#define M66592_FSMODE 0x0002 /* Full-Speed mode */ +#define M66592_HSPROC 0x0001 /* HS handshake is processing */ #define M66592_TESTMODE 0x06 -#define M66592_UTST 0x000F /* b4-0: Test select */ -#define M66592_H_TST_PACKET 0x000C /* HOST TEST Packet */ -#define M66592_H_TST_SE0_NAK 0x000B /* HOST TEST SE0 NAK */ -#define M66592_H_TST_K 0x000A /* HOST TEST K */ -#define M66592_H_TST_J 0x0009 /* HOST TEST J */ -#define M66592_H_TST_NORMAL 0x0000 /* HOST Normal Mode */ -#define M66592_P_TST_PACKET 0x0004 /* PERI TEST Packet */ -#define M66592_P_TST_SE0_NAK 0x0003 /* PERI TEST SE0 NAK */ -#define M66592_P_TST_K 0x0002 /* PERI TEST K */ -#define M66592_P_TST_J 0x0001 /* PERI TEST J */ -#define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */ +#define M66592_UTST 0x000F /* b4-0: Test select */ +#define M66592_H_TST_PACKET 0x000C /* HOST TEST Packet */ +#define M66592_H_TST_SE0_NAK 0x000B /* HOST TEST SE0 NAK */ +#define M66592_H_TST_K 0x000A /* HOST TEST K */ +#define M66592_H_TST_J 0x0009 /* HOST TEST J */ +#define M66592_H_TST_NORMAL 0x0000 /* HOST Normal Mode */ +#define M66592_P_TST_PACKET 0x0004 /* PERI TEST Packet */ +#define M66592_P_TST_SE0_NAK 0x0003 /* PERI TEST SE0 NAK */ +#define M66592_P_TST_K 0x0002 /* PERI TEST K */ +#define M66592_P_TST_J 0x0001 /* PERI TEST J */ +#define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */ #define M66592_PINCFG 0x0A -#define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */ -#define M66592_BIGEND 0x0100 /* b8: Big endian mode */ +#define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */ +#define M66592_BIGEND 0x0100 /* b8: Big endian mode */ #define M66592_DMA0CFG 0x0C #define M66592_DMA1CFG 0x0E -#define M66592_DREQA 0x4000 /* b14: Dreq active select */ -#define M66592_BURST 0x2000 /* b13: Burst mode */ -#define M66592_DACKA 0x0400 /* b10: Dack active select */ -#define M66592_DFORM 0x0380 /* b9-7: DMA mode select */ -#define M66592_CPU_ADR_RD_WR 0x0000 /* Address + RD/WR mode (CPU bus) */ -#define M66592_CPU_DACK_RD_WR 0x0100 /* DACK + RD/WR mode (CPU bus) */ -#define M66592_CPU_DACK_ONLY 0x0180 /* DACK only mode (CPU bus) */ -#define M66592_SPLIT_DACK_ONLY 0x0200 /* DACK only mode (SPLIT bus) */ -#define M66592_SPLIT_DACK_DSTB 0x0300 /* DACK + DSTB0 mode (SPLIT bus) */ -#define M66592_DENDA 0x0040 /* b6: Dend active select */ -#define M66592_PKTM 0x0020 /* b5: Packet mode */ -#define M66592_DENDE 0x0010 /* b4: Dend enable */ -#define M66592_OBUS 0x0004 /* b2: OUTbus mode */ +#define M66592_DREQA 0x4000 /* b14: Dreq active select */ +#define M66592_BURST 0x2000 /* b13: Burst mode */ +#define M66592_DACKA 0x0400 /* b10: Dack active select */ +#define M66592_DFORM 0x0380 /* b9-7: DMA mode select */ +#define M66592_CPU_ADR_RD_WR 0x0000 /* Address + RD/WR mode (CPU bus) */ +#define M66592_CPU_DACK_RD_WR 0x0100 /* DACK + RD/WR mode (CPU bus) */ +#define M66592_CPU_DACK_ONLY 0x0180 /* DACK only mode (CPU bus) */ +#define M66592_SPLIT_DACK_ONLY 0x0200 /* DACK only mode (SPLIT bus) */ +#define M66592_SPLIT_DACK_DSTB 0x0300 /* DACK + DSTB0 mode (SPLIT bus) */ +#define M66592_DENDA 0x0040 /* b6: Dend active select */ +#define M66592_PKTM 0x0020 /* b5: Packet mode */ +#define M66592_DENDE 0x0010 /* b4: Dend enable */ +#define M66592_OBUS 0x0004 /* b2: OUTbus mode */ #define M66592_CFIFO 0x10 #define M66592_D0FIFO 0x14 @@ -99,300 +99,300 @@ #define M66592_CFIFOSEL 0x1E #define M66592_D0FIFOSEL 0x24 #define M66592_D1FIFOSEL 0x2A -#define M66592_RCNT 0x8000 /* b15: Read count mode */ -#define M66592_REW 0x4000 /* b14: Buffer rewind */ -#define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */ -#define M66592_DREQE 0x1000 /* b12: DREQ output enable */ -#define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO */ -#define M66592_MBW_8 0x0000 /* 8bit */ -#define M66592_MBW_16 0x0400 /* 16bit */ -#define M66592_TRENB 0x0200 /* b9: Transaction counter enable */ -#define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */ -#define M66592_DEZPM 0x0080 /* b7: Zero-length packet mode */ -#define M66592_ISEL 0x0020 /* b5: DCP FIFO port direction select */ -#define M66592_CURPIPE 0x0007 /* b2-0: PIPE select */ +#define M66592_RCNT 0x8000 /* b15: Read count mode */ +#define M66592_REW 0x4000 /* b14: Buffer rewind */ +#define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */ +#define M66592_DREQE 0x1000 /* b12: DREQ output enable */ +#define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO access */ +#define M66592_MBW_8 0x0000 /* 8bit */ +#define M66592_MBW_16 0x0400 /* 16bit */ +#define M66592_TRENB 0x0200 /* b9: Transaction counter enable */ +#define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */ +#define M66592_DEZPM 0x0080 /* b7: Zero-length packet additional mode */ +#define M66592_ISEL 0x0020 /* b5: DCP FIFO port direction select */ +#define M66592_CURPIPE 0x0007 /* b2-0: PIPE select */ #define M66592_CFIFOCTR 0x20 #define M66592_D0FIFOCTR 0x26 #define M66592_D1FIFOCTR 0x2c -#define M66592_BVAL 0x8000 /* b15: Buffer valid flag */ -#define M66592_BCLR 0x4000 /* b14: Buffer clear */ -#define M66592_FRDY 0x2000 /* b13: FIFO ready */ -#define M66592_DTLN 0x0FFF /* b11-0: FIFO received data length */ +#define M66592_BVAL 0x8000 /* b15: Buffer valid flag */ +#define M66592_BCLR 0x4000 /* b14: Buffer clear */ +#define M66592_FRDY 0x2000 /* b13: FIFO ready */ +#define M66592_DTLN 0x0FFF /* b11-0: FIFO received data length */ #define M66592_CFIFOSIE 0x22 -#define M66592_TGL 0x8000 /* b15: Buffer toggle */ -#define M66592_SCLR 0x4000 /* b14: Buffer clear */ -#define M66592_SBUSY 0x2000 /* b13: SIE_FIFO busy */ +#define M66592_TGL 0x8000 /* b15: Buffer toggle */ +#define M66592_SCLR 0x4000 /* b14: Buffer clear */ +#define M66592_SBUSY 0x2000 /* b13: SIE_FIFO busy */ #define M66592_D0FIFOTRN 0x28 #define M66592_D1FIFOTRN 0x2E -#define M66592_TRNCNT 0xFFFF /* b15-0: Transaction counter */ +#define M66592_TRNCNT 0xFFFF /* b15-0: Transaction counter */ #define M66592_INTENB0 0x30 -#define M66592_VBSE 0x8000 /* b15: VBUS interrupt */ -#define M66592_RSME 0x4000 /* b14: Resume interrupt */ -#define M66592_SOFE 0x2000 /* b13: Frame update interrupt */ -#define M66592_DVSE 0x1000 /* b12: Device state transition interrupt */ -#define M66592_CTRE 0x0800 /* b11: Control transfer stage transition irq */ -#define M66592_BEMPE 0x0400 /* b10: Buffer empty interrupt */ -#define M66592_NRDYE 0x0200 /* b9: Buffer not ready interrupt */ -#define M66592_BRDYE 0x0100 /* b8: Buffer ready interrupt */ -#define M66592_URST 0x0080 /* b7: USB reset detected interrupt */ -#define M66592_SADR 0x0040 /* b6: Set address executed interrupt */ -#define M66592_SCFG 0x0020 /* b5: Set configuration executed interrupt */ -#define M66592_SUSP 0x0010 /* b4: Suspend detected interrupt */ -#define M66592_WDST 0x0008 /* b3: Control write data stage completed irq */ -#define M66592_RDST 0x0004 /* b2: Control read data stage completed irq */ -#define M66592_CMPL 0x0002 /* b1: Control transfer complete interrupt */ -#define M66592_SERR 0x0001 /* b0: Sequence error interrupt */ +#define M66592_VBSE 0x8000 /* b15: VBUS interrupt */ +#define M66592_RSME 0x4000 /* b14: Resume interrupt */ +#define M66592_SOFE 0x2000 /* b13: Frame update interrupt */ +#define M66592_DVSE 0x1000 /* b12: Device state transition interrupt */ +#define M66592_CTRE 0x0800 /* b11: Control transfer stage transition interrupt */ +#define M66592_BEMPE 0x0400 /* b10: Buffer empty interrupt */ +#define M66592_NRDYE 0x0200 /* b9: Buffer not ready interrupt */ +#define M66592_BRDYE 0x0100 /* b8: Buffer ready interrupt */ +#define M66592_URST 0x0080 /* b7: USB reset detected interrupt */ +#define M66592_SADR 0x0040 /* b6: Set address executed interrupt */ +#define M66592_SCFG 0x0020 /* b5: Set configuration executed interrupt */ +#define M66592_SUSP 0x0010 /* b4: Suspend detected interrupt */ +#define M66592_WDST 0x0008 /* b3: Control write data stage completed interrupt */ +#define M66592_RDST 0x0004 /* b2: Control read data stage completed interrupt */ +#define M66592_CMPL 0x0002 /* b1: Control transfer complete interrupt */ +#define M66592_SERR 0x0001 /* b0: Sequence error interrupt */ #define M66592_INTENB1 0x32 -#define M66592_BCHGE 0x4000 /* b14: USB us chenge interrupt */ -#define M66592_DTCHE 0x1000 /* b12: Detach sense interrupt */ -#define M66592_SIGNE 0x0020 /* b5: SETUP IGNORE interrupt */ -#define M66592_SACKE 0x0010 /* b4: SETUP ACK interrupt */ -#define M66592_BRDYM 0x0004 /* b2: BRDY clear timing */ -#define M66592_INTL 0x0002 /* b1: Interrupt sense select */ -#define M66592_PCSE 0x0001 /* b0: PCUT enable by CS assert */ +#define M66592_BCHGE 0x4000 /* b14: USB us chenge interrupt */ +#define M66592_DTCHE 0x1000 /* b12: Detach sense interrupt */ +#define M66592_SIGNE 0x0020 /* b5: SETUP IGNORE interrupt */ +#define M66592_SACKE 0x0010 /* b4: SETUP ACK interrupt */ +#define M66592_BRDYM 0x0004 /* b2: BRDY clear timing */ +#define M66592_INTL 0x0002 /* b1: Interrupt sense select */ +#define M66592_PCSE 0x0001 /* b0: PCUT enable by CS assert */ #define M66592_BRDYENB 0x36 #define M66592_BRDYSTS 0x46 -#define M66592_BRDY7 0x0080 /* b7: PIPE7 */ -#define M66592_BRDY6 0x0040 /* b6: PIPE6 */ -#define M66592_BRDY5 0x0020 /* b5: PIPE5 */ -#define M66592_BRDY4 0x0010 /* b4: PIPE4 */ -#define M66592_BRDY3 0x0008 /* b3: PIPE3 */ -#define M66592_BRDY2 0x0004 /* b2: PIPE2 */ -#define M66592_BRDY1 0x0002 /* b1: PIPE1 */ -#define M66592_BRDY0 0x0001 /* b1: PIPE0 */ +#define M66592_BRDY7 0x0080 /* b7: PIPE7 */ +#define M66592_BRDY6 0x0040 /* b6: PIPE6 */ +#define M66592_BRDY5 0x0020 /* b5: PIPE5 */ +#define M66592_BRDY4 0x0010 /* b4: PIPE4 */ +#define M66592_BRDY3 0x0008 /* b3: PIPE3 */ +#define M66592_BRDY2 0x0004 /* b2: PIPE2 */ +#define M66592_BRDY1 0x0002 /* b1: PIPE1 */ +#define M66592_BRDY0 0x0001 /* b1: PIPE0 */ #define M66592_NRDYENB 0x38 #define M66592_NRDYSTS 0x48 -#define M66592_NRDY7 0x0080 /* b7: PIPE7 */ -#define M66592_NRDY6 0x0040 /* b6: PIPE6 */ -#define M66592_NRDY5 0x0020 /* b5: PIPE5 */ -#define M66592_NRDY4 0x0010 /* b4: PIPE4 */ -#define M66592_NRDY3 0x0008 /* b3: PIPE3 */ -#define M66592_NRDY2 0x0004 /* b2: PIPE2 */ -#define M66592_NRDY1 0x0002 /* b1: PIPE1 */ -#define M66592_NRDY0 0x0001 /* b1: PIPE0 */ +#define M66592_NRDY7 0x0080 /* b7: PIPE7 */ +#define M66592_NRDY6 0x0040 /* b6: PIPE6 */ +#define M66592_NRDY5 0x0020 /* b5: PIPE5 */ +#define M66592_NRDY4 0x0010 /* b4: PIPE4 */ +#define M66592_NRDY3 0x0008 /* b3: PIPE3 */ +#define M66592_NRDY2 0x0004 /* b2: PIPE2 */ +#define M66592_NRDY1 0x0002 /* b1: PIPE1 */ +#define M66592_NRDY0 0x0001 /* b1: PIPE0 */ #define M66592_BEMPENB 0x3A #define M66592_BEMPSTS 0x4A -#define M66592_BEMP7 0x0080 /* b7: PIPE7 */ -#define M66592_BEMP6 0x0040 /* b6: PIPE6 */ -#define M66592_BEMP5 0x0020 /* b5: PIPE5 */ -#define M66592_BEMP4 0x0010 /* b4: PIPE4 */ -#define M66592_BEMP3 0x0008 /* b3: PIPE3 */ -#define M66592_BEMP2 0x0004 /* b2: PIPE2 */ -#define M66592_BEMP1 0x0002 /* b1: PIPE1 */ -#define M66592_BEMP0 0x0001 /* b0: PIPE0 */ +#define M66592_BEMP7 0x0080 /* b7: PIPE7 */ +#define M66592_BEMP6 0x0040 /* b6: PIPE6 */ +#define M66592_BEMP5 0x0020 /* b5: PIPE5 */ +#define M66592_BEMP4 0x0010 /* b4: PIPE4 */ +#define M66592_BEMP3 0x0008 /* b3: PIPE3 */ +#define M66592_BEMP2 0x0004 /* b2: PIPE2 */ +#define M66592_BEMP1 0x0002 /* b1: PIPE1 */ +#define M66592_BEMP0 0x0001 /* b0: PIPE0 */ #define M66592_SOFCFG 0x3C -#define M66592_SOFM 0x000C /* b3-2: SOF palse mode */ -#define M66592_SOF_125US 0x0008 /* SOF OUT 125us uFrame Signal */ -#define M66592_SOF_1MS 0x0004 /* SOF OUT 1ms Frame Signal */ -#define M66592_SOF_DISABLE 0x0000 /* SOF OUT Disable */ +#define M66592_SOFM 0x000C /* b3-2: SOF palse mode */ +#define M66592_SOF_125US 0x0008 /* SOF OUT 125us uFrame Signal */ +#define M66592_SOF_1MS 0x0004 /* SOF OUT 1ms Frame Signal */ +#define M66592_SOF_DISABLE 0x0000 /* SOF OUT Disable */ #define M66592_INTSTS0 0x40 -#define M66592_VBINT 0x8000 /* b15: VBUS interrupt */ -#define M66592_RESM 0x4000 /* b14: Resume interrupt */ -#define M66592_SOFR 0x2000 /* b13: SOF frame update interrupt */ -#define M66592_DVST 0x1000 /* b12: Device state transition */ -#define M66592_CTRT 0x0800 /* b11: Control stage transition */ -#define M66592_BEMP 0x0400 /* b10: Buffer empty interrupt */ -#define M66592_NRDY 0x0200 /* b9: Buffer not ready interrupt */ -#define M66592_BRDY 0x0100 /* b8: Buffer ready interrupt */ -#define M66592_VBSTS 0x0080 /* b7: VBUS input port */ -#define M66592_DVSQ 0x0070 /* b6-4: Device state */ -#define M66592_DS_SPD_CNFG 0x0070 /* Suspend Configured */ -#define M66592_DS_SPD_ADDR 0x0060 /* Suspend Address */ -#define M66592_DS_SPD_DFLT 0x0050 /* Suspend Default */ -#define M66592_DS_SPD_POWR 0x0040 /* Suspend Powered */ -#define M66592_DS_SUSP 0x0040 /* Suspend */ -#define M66592_DS_CNFG 0x0030 /* Configured */ -#define M66592_DS_ADDS 0x0020 /* Address */ -#define M66592_DS_DFLT 0x0010 /* Default */ -#define M66592_DS_POWR 0x0000 /* Powered */ -#define M66592_DVSQS 0x0030 /* b5-4: Device state */ -#define M66592_VALID 0x0008 /* b3: Setup packet detected flag */ -#define M66592_CTSQ 0x0007 /* b2-0: Control transfer stage */ -#define M66592_CS_SQER 0x0006 /* Sequence error */ -#define M66592_CS_WRND 0x0005 /* Control write nodata status */ -#define M66592_CS_WRSS 0x0004 /* Control write status stage */ -#define M66592_CS_WRDS 0x0003 /* Control write data stage */ -#define M66592_CS_RDSS 0x0002 /* Control read status stage */ -#define M66592_CS_RDDS 0x0001 /* Control read data stage */ -#define M66592_CS_IDST 0x0000 /* Idle or setup stage */ +#define M66592_VBINT 0x8000 /* b15: VBUS interrupt */ +#define M66592_RESM 0x4000 /* b14: Resume interrupt */ +#define M66592_SOFR 0x2000 /* b13: SOF frame update interrupt */ +#define M66592_DVST 0x1000 /* b12: Device state transition interrupt */ +#define M66592_CTRT 0x0800 /* b11: Control transfer stage transition interrupt */ +#define M66592_BEMP 0x0400 /* b10: Buffer empty interrupt */ +#define M66592_NRDY 0x0200 /* b9: Buffer not ready interrupt */ +#define M66592_BRDY 0x0100 /* b8: Buffer ready interrupt */ +#define M66592_VBSTS 0x0080 /* b7: VBUS input port */ +#define M66592_DVSQ 0x0070 /* b6-4: Device state */ +#define M66592_DS_SPD_CNFG 0x0070 /* Suspend Configured */ +#define M66592_DS_SPD_ADDR 0x0060 /* Suspend Address */ +#define M66592_DS_SPD_DFLT 0x0050 /* Suspend Default */ +#define M66592_DS_SPD_POWR 0x0040 /* Suspend Powered */ +#define M66592_DS_SUSP 0x0040 /* Suspend */ +#define M66592_DS_CNFG 0x0030 /* Configured */ +#define M66592_DS_ADDS 0x0020 /* Address */ +#define M66592_DS_DFLT 0x0010 /* Default */ +#define M66592_DS_POWR 0x0000 /* Powered */ +#define M66592_DVSQS 0x0030 /* b5-4: Device state */ +#define M66592_VALID 0x0008 /* b3: Setup packet detected flag */ +#define M66592_CTSQ 0x0007 /* b2-0: Control transfer stage */ +#define M66592_CS_SQER 0x0006 /* Sequence error */ +#define M66592_CS_WRND 0x0005 /* Control write nodata status stage */ +#define M66592_CS_WRSS 0x0004 /* Control write status stage */ +#define M66592_CS_WRDS 0x0003 /* Control write data stage */ +#define M66592_CS_RDSS 0x0002 /* Control read status stage */ +#define M66592_CS_RDDS 0x0001 /* Control read data stage */ +#define M66592_CS_IDST 0x0000 /* Idle or setup stage */ #define M66592_INTSTS1 0x42 -#define M66592_BCHG 0x4000 /* b14: USB bus chenge interrupt */ -#define M66592_DTCH 0x1000 /* b12: Detach sense interrupt */ -#define M66592_SIGN 0x0020 /* b5: SETUP IGNORE interrupt */ -#define M66592_SACK 0x0010 /* b4: SETUP ACK interrupt */ +#define M66592_BCHG 0x4000 /* b14: USB bus chenge interrupt */ +#define M66592_DTCH 0x1000 /* b12: Detach sense interrupt */ +#define M66592_SIGN 0x0020 /* b5: SETUP IGNORE interrupt */ +#define M66592_SACK 0x0010 /* b4: SETUP ACK interrupt */ #define M66592_FRMNUM 0x4C -#define M66592_OVRN 0x8000 /* b15: Overrun error */ -#define M66592_CRCE 0x4000 /* b14: Received data error */ -#define M66592_SOFRM 0x0800 /* b11: SOF output mode */ -#define M66592_FRNM 0x07FF /* b10-0: Frame number */ +#define M66592_OVRN 0x8000 /* b15: Overrun error */ +#define M66592_CRCE 0x4000 /* b14: Received data error */ +#define M66592_SOFRM 0x0800 /* b11: SOF output mode */ +#define M66592_FRNM 0x07FF /* b10-0: Frame number */ #define M66592_UFRMNUM 0x4E -#define M66592_UFRNM 0x0007 /* b2-0: Micro frame number */ +#define M66592_UFRNM 0x0007 /* b2-0: Micro frame number */ #define M66592_RECOVER 0x50 -#define M66592_STSRECOV 0x0700 /* Status recovery */ -#define M66592_STSR_HI 0x0400 /* FULL(0) or HI(1) Speed */ -#define M66592_STSR_DEFAULT 0x0100 /* Default state */ -#define M66592_STSR_ADDRESS 0x0200 /* Address state */ -#define M66592_STSR_CONFIG 0x0300 /* Configured state */ -#define M66592_USBADDR 0x007F /* b6-0: USB address */ +#define M66592_STSRECOV 0x0700 /* Status recovery */ +#define M66592_STSR_HI 0x0400 /* FULL(0) or HI(1) Speed */ +#define M66592_STSR_DEFAULT 0x0100 /* Default state */ +#define M66592_STSR_ADDRESS 0x0200 /* Address state */ +#define M66592_STSR_CONFIG 0x0300 /* Configured state */ +#define M66592_USBADDR 0x007F /* b6-0: USB address */ #define M66592_USBREQ 0x54 -#define M66592_bRequest 0xFF00 /* b15-8: bRequest */ -#define M66592_GET_STATUS 0x0000 -#define M66592_CLEAR_FEATURE 0x0100 -#define M66592_ReqRESERVED 0x0200 -#define M66592_SET_FEATURE 0x0300 -#define M66592_ReqRESERVED1 0x0400 -#define M66592_SET_ADDRESS 0x0500 -#define M66592_GET_DESCRIPTOR 0x0600 -#define M66592_SET_DESCRIPTOR 0x0700 -#define M66592_GET_CONFIGURATION 0x0800 -#define M66592_SET_CONFIGURATION 0x0900 -#define M66592_GET_INTERFACE 0x0A00 -#define M66592_SET_INTERFACE 0x0B00 -#define M66592_SYNCH_FRAME 0x0C00 -#define M66592_bmRequestType 0x00FF /* b7-0: bmRequestType */ -#define M66592_bmRequestTypeDir 0x0080 /* b7 : Data direction */ -#define M66592_HOST_TO_DEVICE 0x0000 -#define M66592_DEVICE_TO_HOST 0x0080 -#define M66592_bmRequestTypeType 0x0060 /* b6-5: Type */ -#define M66592_STANDARD 0x0000 -#define M66592_CLASS 0x0020 -#define M66592_VENDOR 0x0040 -#define M66592_bmRequestTypeRecip 0x001F /* b4-0: Recipient */ -#define M66592_DEVICE 0x0000 -#define M66592_INTERFACE 0x0001 -#define M66592_ENDPOINT 0x0002 +#define M66592_bRequest 0xFF00 /* b15-8: bRequest */ +#define M66592_GET_STATUS 0x0000 +#define M66592_CLEAR_FEATURE 0x0100 +#define M66592_ReqRESERVED 0x0200 +#define M66592_SET_FEATURE 0x0300 +#define M66592_ReqRESERVED1 0x0400 +#define M66592_SET_ADDRESS 0x0500 +#define M66592_GET_DESCRIPTOR 0x0600 +#define M66592_SET_DESCRIPTOR 0x0700 +#define M66592_GET_CONFIGURATION 0x0800 +#define M66592_SET_CONFIGURATION 0x0900 +#define M66592_GET_INTERFACE 0x0A00 +#define M66592_SET_INTERFACE 0x0B00 +#define M66592_SYNCH_FRAME 0x0C00 +#define M66592_bmRequestType 0x00FF /* b7-0: bmRequestType */ +#define M66592_bmRequestTypeDir 0x0080 /* b7 : Data transfer direction */ +#define M66592_HOST_TO_DEVICE 0x0000 +#define M66592_DEVICE_TO_HOST 0x0080 +#define M66592_bmRequestTypeType 0x0060 /* b6-5: Type */ +#define M66592_STANDARD 0x0000 +#define M66592_CLASS 0x0020 +#define M66592_VENDOR 0x0040 +#define M66592_bmRequestTypeRecip 0x001F /* b4-0: Recipient */ +#define M66592_DEVICE 0x0000 +#define M66592_INTERFACE 0x0001 +#define M66592_ENDPOINT 0x0002 #define M66592_USBVAL 0x56 -#define M66592_wValue 0xFFFF /* b15-0: wValue */ +#define M66592_wValue 0xFFFF /* b15-0: wValue */ /* Standard Feature Selector */ -#define M66592_ENDPOINT_HALT 0x0000 -#define M66592_DEVICE_REMOTE_WAKEUP 0x0001 -#define M66592_TEST_MODE 0x0002 +#define M66592_ENDPOINT_HALT 0x0000 +#define M66592_DEVICE_REMOTE_WAKEUP 0x0001 +#define M66592_TEST_MODE 0x0002 /* Descriptor Types */ -#define M66592_DT_TYPE 0xFF00 -#define M66592_GET_DT_TYPE(v) (((v) & DT_TYPE) >> 8) -#define M66592_DT_DEVICE 0x01 -#define M66592_DT_CONFIGURATION 0x02 -#define M66592_DT_STRING 0x03 -#define M66592_DT_INTERFACE 0x04 -#define M66592_DT_ENDPOINT 0x05 -#define M66592_DT_DEVICE_QUALIFIER 0x06 -#define M66592_DT_OTHER_SPEED_CONFIGURATION 0x07 -#define M66592_DT_INTERFACE_POWER 0x08 -#define M66592_DT_INDEX 0x00FF -#define M66592_CONF_NUM 0x00FF -#define M66592_ALT_SET 0x00FF +#define M66592_DT_TYPE 0xFF00 +#define M66592_GET_DT_TYPE(v) (((v) & DT_TYPE) >> 8) +#define M66592_DT_DEVICE 0x01 +#define M66592_DT_CONFIGURATION 0x02 +#define M66592_DT_STRING 0x03 +#define M66592_DT_INTERFACE 0x04 +#define M66592_DT_ENDPOINT 0x05 +#define M66592_DT_DEVICE_QUALIFIER 0x06 +#define M66592_DT_OTHER_SPEED_CONFIGURATION 0x07 +#define M66592_DT_INTERFACE_POWER 0x08 +#define M66592_DT_INDEX 0x00FF +#define M66592_CONF_NUM 0x00FF +#define M66592_ALT_SET 0x00FF #define M66592_USBINDEX 0x58 -#define M66592_wIndex 0xFFFF /* b15-0: wIndex */ -#define M66592_TEST_SELECT 0xFF00 /* b15-b8: Test Mode */ -#define M66592_TEST_J 0x0100 /* Test_J */ -#define M66592_TEST_K 0x0200 /* Test_K */ -#define M66592_TEST_SE0_NAK 0x0300 /* Test_SE0_NAK */ -#define M66592_TEST_PACKET 0x0400 /* Test_Packet */ -#define M66592_TEST_FORCE_ENABLE 0x0500 /* Test_Force_Enable */ -#define M66592_TEST_STSelectors 0x0600 /* Standard test selectors */ -#define M66592_TEST_Reserved 0x4000 /* Reserved */ -#define M66592_TEST_VSTModes 0xC000 /* Vendor-specific tests */ -#define M66592_EP_DIR 0x0080 /* b7: Endpoint Direction */ -#define M66592_EP_DIR_IN 0x0080 -#define M66592_EP_DIR_OUT 0x0000 +#define M66592_wIndex 0xFFFF /* b15-0: wIndex */ +#define M66592_TEST_SELECT 0xFF00 /* b15-b8: Test Mode Selectors */ +#define M66592_TEST_J 0x0100 /* Test_J */ +#define M66592_TEST_K 0x0200 /* Test_K */ +#define M66592_TEST_SE0_NAK 0x0300 /* Test_SE0_NAK */ +#define M66592_TEST_PACKET 0x0400 /* Test_Packet */ +#define M66592_TEST_FORCE_ENABLE 0x0500 /* Test_Force_Enable */ +#define M66592_TEST_STSelectors 0x0600 /* Standard test selectors */ +#define M66592_TEST_Reserved 0x4000 /* Reserved */ +#define M66592_TEST_VSTModes 0xC000 /* Vendor-specific test modes */ +#define M66592_EP_DIR 0x0080 /* b7: Endpoint Direction */ +#define M66592_EP_DIR_IN 0x0080 +#define M66592_EP_DIR_OUT 0x0000 #define M66592_USBLENG 0x5A -#define M66592_wLength 0xFFFF /* b15-0: wLength */ +#define M66592_wLength 0xFFFF /* b15-0: wLength */ #define M66592_DCPCFG 0x5C -#define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode */ -#define M66592_DIR 0x0010 /* b4: Control transfer DIR select */ +#define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode select */ +#define M66592_DIR 0x0010 /* b4: Control transfer DIR select */ #define M66592_DCPMAXP 0x5E -#define M66592_DEVSEL 0xC000 /* b15-14: Device address select */ -#define M66592_DEVICE_0 0x0000 /* Device address 0 */ -#define M66592_DEVICE_1 0x4000 /* Device address 1 */ -#define M66592_DEVICE_2 0x8000 /* Device address 2 */ -#define M66592_DEVICE_3 0xC000 /* Device address 3 */ -#define M66592_MAXP 0x007F /* b6-0: Maxpacket size of ep0 */ +#define M66592_DEVSEL 0xC000 /* b15-14: Device address select */ +#define M66592_DEVICE_0 0x0000 /* Device address 0 */ +#define M66592_DEVICE_1 0x4000 /* Device address 1 */ +#define M66592_DEVICE_2 0x8000 /* Device address 2 */ +#define M66592_DEVICE_3 0xC000 /* Device address 3 */ +#define M66592_MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */ #define M66592_DCPCTR 0x60 -#define M66592_BSTS 0x8000 /* b15: Buffer status */ -#define M66592_SUREQ 0x4000 /* b14: Send USB request */ -#define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ -#define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ -#define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ -#define M66592_CCPL 0x0004 /* b2: control transfer complete */ -#define M66592_PID 0x0003 /* b1-0: Response PID */ -#define M66592_PID_STALL 0x0002 /* STALL */ -#define M66592_PID_BUF 0x0001 /* BUF */ -#define M66592_PID_NAK 0x0000 /* NAK */ +#define M66592_BSTS 0x8000 /* b15: Buffer status */ +#define M66592_SUREQ 0x4000 /* b14: Send USB request */ +#define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ +#define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ +#define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ +#define M66592_CCPL 0x0004 /* b2: Enable control transfer complete */ +#define M66592_PID 0x0003 /* b1-0: Response PID */ +#define M66592_PID_STALL 0x0002 /* STALL */ +#define M66592_PID_BUF 0x0001 /* BUF */ +#define M66592_PID_NAK 0x0000 /* NAK */ #define M66592_PIPESEL 0x64 -#define M66592_PIPENM 0x0007 /* b2-0: Pipe select */ -#define M66592_PIPE0 0x0000 /* PIPE 0 */ -#define M66592_PIPE1 0x0001 /* PIPE 1 */ -#define M66592_PIPE2 0x0002 /* PIPE 2 */ -#define M66592_PIPE3 0x0003 /* PIPE 3 */ -#define M66592_PIPE4 0x0004 /* PIPE 4 */ -#define M66592_PIPE5 0x0005 /* PIPE 5 */ -#define M66592_PIPE6 0x0006 /* PIPE 6 */ -#define M66592_PIPE7 0x0007 /* PIPE 7 */ +#define M66592_PIPENM 0x0007 /* b2-0: Pipe select */ +#define M66592_PIPE0 0x0000 /* PIPE 0 */ +#define M66592_PIPE1 0x0001 /* PIPE 1 */ +#define M66592_PIPE2 0x0002 /* PIPE 2 */ +#define M66592_PIPE3 0x0003 /* PIPE 3 */ +#define M66592_PIPE4 0x0004 /* PIPE 4 */ +#define M66592_PIPE5 0x0005 /* PIPE 5 */ +#define M66592_PIPE6 0x0006 /* PIPE 6 */ +#define M66592_PIPE7 0x0007 /* PIPE 7 */ #define M66592_PIPECFG 0x66 -#define M66592_TYP 0xC000 /* b15-14: Transfer type */ -#define M66592_ISO 0xC000 /* Isochronous */ -#define M66592_INT 0x8000 /* Interrupt */ -#define M66592_BULK 0x4000 /* Bulk */ -#define M66592_BFRE 0x0400 /* b10: Buffer ready interrupt mode */ -#define M66592_DBLB 0x0200 /* b9: Double buffer mode select */ -#define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode */ -#define M66592_SHTNAK 0x0080 /* b7: Transfer end NAK */ -#define M66592_DIR 0x0010 /* b4: Transfer direction select */ -#define M66592_DIR_H_OUT 0x0010 /* HOST OUT */ -#define M66592_DIR_P_IN 0x0010 /* PERI IN */ -#define M66592_DIR_H_IN 0x0000 /* HOST IN */ -#define M66592_DIR_P_OUT 0x0000 /* PERI OUT */ -#define M66592_EPNUM 0x000F /* b3-0: Eendpoint number select */ -#define M66592_EP1 0x0001 -#define M66592_EP2 0x0002 -#define M66592_EP3 0x0003 -#define M66592_EP4 0x0004 -#define M66592_EP5 0x0005 -#define M66592_EP6 0x0006 -#define M66592_EP7 0x0007 -#define M66592_EP8 0x0008 -#define M66592_EP9 0x0009 -#define M66592_EP10 0x000A -#define M66592_EP11 0x000B -#define M66592_EP12 0x000C -#define M66592_EP13 0x000D -#define M66592_EP14 0x000E -#define M66592_EP15 0x000F +#define M66592_TYP 0xC000 /* b15-14: Transfer type */ +#define M66592_ISO 0xC000 /* Isochronous */ +#define M66592_INT 0x8000 /* Interrupt */ +#define M66592_BULK 0x4000 /* Bulk */ +#define M66592_BFRE 0x0400 /* b10: Buffer ready interrupt mode select */ +#define M66592_DBLB 0x0200 /* b9: Double buffer mode select */ +#define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode select */ +#define M66592_SHTNAK 0x0080 /* b7: Transfer end NAK */ +#define M66592_DIR 0x0010 /* b4: Transfer direction select */ +#define M66592_DIR_H_OUT 0x0010 /* HOST OUT */ +#define M66592_DIR_P_IN 0x0010 /* PERI IN */ +#define M66592_DIR_H_IN 0x0000 /* HOST IN */ +#define M66592_DIR_P_OUT 0x0000 /* PERI OUT */ +#define M66592_EPNUM 0x000F /* b3-0: Eendpoint number select */ +#define M66592_EP1 0x0001 +#define M66592_EP2 0x0002 +#define M66592_EP3 0x0003 +#define M66592_EP4 0x0004 +#define M66592_EP5 0x0005 +#define M66592_EP6 0x0006 +#define M66592_EP7 0x0007 +#define M66592_EP8 0x0008 +#define M66592_EP9 0x0009 +#define M66592_EP10 0x000A +#define M66592_EP11 0x000B +#define M66592_EP12 0x000C +#define M66592_EP13 0x000D +#define M66592_EP14 0x000E +#define M66592_EP15 0x000F #define M66592_PIPEBUF 0x68 -#define M66592_BUFSIZE 0x7C00 /* b14-10: Pipe buffer size */ -#define M66592_BUF_SIZE(x) ((((x) / 64) - 1) << 10) -#define M66592_BUFNMB 0x00FF /* b7-0: Pipe buffer number */ +#define M66592_BUFSIZE 0x7C00 /* b14-10: Pipe buffer size */ +#define M66592_BUF_SIZE(x) ((((x) / 64) - 1) << 10) +#define M66592_BUFNMB 0x00FF /* b7-0: Pipe buffer number */ #define M66592_PIPEMAXP 0x6A -#define M66592_MXPS 0x07FF /* b10-0: Maxpacket size */ +#define M66592_MXPS 0x07FF /* b10-0: Maxpacket size */ #define M66592_PIPEPERI 0x6C -#define M66592_IFIS 0x1000 /* b12: ISO in-buffer flush mode */ -#define M66592_IITV 0x0007 /* b2-0: ISO interval */ +#define M66592_IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */ +#define M66592_IITV 0x0007 /* b2-0: Isochronous interval */ #define M66592_PIPE1CTR 0x70 #define M66592_PIPE2CTR 0x72 @@ -401,17 +401,19 @@ #define M66592_PIPE5CTR 0x78 #define M66592_PIPE6CTR 0x7A #define M66592_PIPE7CTR 0x7C -#define M66592_BSTS 0x8000 /* b15: Buffer status */ -#define M66592_INBUFM 0x4000 /* b14: IN buffer monitor (PIPE 1-5) */ -#define M66592_ACLRM 0x0200 /* b9: Out buffer auto clear mode */ -#define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ -#define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ -#define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ -#define M66592_PID 0x0003 /* b1-0: Response PID */ +#define M66592_BSTS 0x8000 /* b15: Buffer status */ +#define M66592_INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */ +#define M66592_ACLRM 0x0200 /* b9: Out buffer auto clear mode */ +#define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ +#define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ +#define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ +#define M66592_PID 0x0003 /* b1-0: Response PID */ #define M66592_INVALID_REG 0x7E +#define __iomem + #define get_pipectr_addr(pipenum) (M66592_PIPE1CTR + (pipenum - 1) * 2) #define M66592_MAX_SAMPLING 10 @@ -447,7 +449,7 @@ struct m66592_ep { struct m66592 *m66592; struct list_head queue; - unsigned busy:1; + unsigned busy:1; unsigned internal_ccpl:1; /* use only control */ /* this member can able to after m66592_enable */ @@ -475,7 +477,7 @@ struct m66592 { struct m66592_ep *epaddr2ep[16]; struct usb_request *ep0_req; /* for internal request */ - u16 ep0_data; /* for internal request */ + u16 *ep0_buf; /* for internal request */ struct timer_list timer; @@ -525,8 +527,8 @@ static inline u16 m66592_read(struct m66592 *m66592, unsigned long offset) } static inline void m66592_read_fifo(struct m66592 *m66592, - unsigned long offset, - void *buf, unsigned long len) + unsigned long offset, + void *buf, unsigned long len) { unsigned long fifoaddr = (unsigned long)m66592->reg + offset; @@ -541,8 +543,8 @@ static inline void m66592_write(struct m66592 *m66592, u16 val, } static inline void m66592_write_fifo(struct m66592 *m66592, - unsigned long offset, - void *buf, unsigned long len) + unsigned long offset, + void *buf, unsigned long len) { unsigned long fifoaddr = (unsigned long)m66592->reg + offset; unsigned long odd = len & 0x0001; @@ -556,7 +558,7 @@ static inline void m66592_write_fifo(struct m66592 *m66592, } static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, - unsigned long offset) + unsigned long offset) { u16 tmp; tmp = m66592_read(m66592, offset); diff --git a/trunk/drivers/usb/gadget/serial.c b/trunk/drivers/usb/gadget/serial.c index 9cd98e73dc1d..38138bb9ddb0 100644 --- a/trunk/drivers/usb/gadget/serial.c +++ b/trunk/drivers/usb/gadget/serial.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -259,7 +258,7 @@ static const char *EP_IN_NAME; static const char *EP_OUT_NAME; static const char *EP_NOTIFY_NAME; -static struct mutex gs_open_close_lock[GS_NUM_PORTS]; +static struct semaphore gs_open_close_sem[GS_NUM_PORTS]; static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE; static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE; @@ -596,7 +595,7 @@ static int __init gs_module_init(void) tty_set_operations(gs_tty_driver, &gs_tty_ops); for (i=0; i < GS_NUM_PORTS; i++) - mutex_init(&gs_open_close_lock[i]); + sema_init(&gs_open_close_sem[i], 1); retval = tty_register_driver(gs_tty_driver); if (retval) { @@ -636,7 +635,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) struct gs_port *port; struct gs_dev *dev; struct gs_buf *buf; - struct mutex *mtx; + struct semaphore *sem; int ret; port_num = tty->index; @@ -657,10 +656,10 @@ static int gs_open(struct tty_struct *tty, struct file *file) return -ENODEV; } - mtx = &gs_open_close_lock[port_num]; - if (mutex_lock_interruptible(mtx)) { + sem = &gs_open_close_sem[port_num]; + if (down_interruptible(sem)) { printk(KERN_ERR - "gs_open: (%d,%p,%p) interrupted waiting for mutex\n", + "gs_open: (%d,%p,%p) interrupted waiting for semaphore\n", port_num, tty, file); return -ERESTARTSYS; } @@ -755,12 +754,12 @@ static int gs_open(struct tty_struct *tty, struct file *file) exit_unlock_port: spin_unlock_irqrestore(&port->port_lock, flags); - mutex_unlock(mtx); + up(sem); return ret; exit_unlock_dev: spin_unlock_irqrestore(&dev->dev_lock, flags); - mutex_unlock(mtx); + up(sem); return ret; } @@ -782,7 +781,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) static void gs_close(struct tty_struct *tty, struct file *file) { struct gs_port *port = tty->driver_data; - struct mutex *mtx; + struct semaphore *sem; if (port == NULL) { printk(KERN_ERR "gs_close: NULL port pointer\n"); @@ -791,8 +790,8 @@ static void gs_close(struct tty_struct *tty, struct file *file) gs_debug("gs_close: (%d,%p,%p)\n", port->port_num, tty, file); - mtx = &gs_open_close_lock[port->port_num]; - mutex_lock(mtx); + sem = &gs_open_close_sem[port->port_num]; + down(sem); spin_lock_irq(&port->port_lock); @@ -847,7 +846,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) exit: spin_unlock_irq(&port->port_lock); - mutex_unlock(mtx); + up(sem); } /* diff --git a/trunk/drivers/usb/host/isp116x-hcd.c b/trunk/drivers/usb/host/isp116x-hcd.c index 5c851a36de72..46873f2534b5 100644 --- a/trunk/drivers/usb/host/isp116x-hcd.c +++ b/trunk/drivers/usb/host/isp116x-hcd.c @@ -228,6 +228,7 @@ static void preproc_atl_queue(struct isp116x *isp116x) struct urb, urb_list); ptd = &ep->ptd; len = ep->length; + spin_lock(&urb->lock); ep->data = (unsigned char *)urb->transfer_buffer + urb->actual_length; @@ -263,6 +264,7 @@ static void preproc_atl_queue(struct isp116x *isp116x) | PTD_EP(ep->epnum); ptd->len = PTD_LEN(len) | PTD_DIR(dir); ptd->faddr = PTD_FA(usb_pipedevice(urb->pipe)); + spin_unlock(&urb->lock); if (!ep->active) { ptd->mps |= PTD_LAST_MSK; isp116x->atl_last_dir = dir; @@ -272,61 +274,6 @@ static void preproc_atl_queue(struct isp116x *isp116x) } } -/* - Take done or failed requests out of schedule. Give back - processed urbs. -*/ -static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, - struct urb *urb) -__releases(isp116x->lock) __acquires(isp116x->lock) -{ - unsigned i; - - urb->hcpriv = NULL; - ep->error_count = 0; - - if (usb_pipecontrol(urb->pipe)) - ep->nextpid = USB_PID_SETUP; - - urb_dbg(urb, "Finish"); - - spin_unlock(&isp116x->lock); - usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb); - spin_lock(&isp116x->lock); - - /* take idle endpoints out of the schedule */ - if (!list_empty(&ep->hep->urb_list)) - return; - - /* async deschedule */ - if (!list_empty(&ep->schedule)) { - list_del_init(&ep->schedule); - return; - } - - /* periodic deschedule */ - DBG("deschedule qh%d/%p branch %d\n", ep->period, ep, ep->branch); - for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) { - struct isp116x_ep *temp; - struct isp116x_ep **prev = &isp116x->periodic[i]; - - while (*prev && ((temp = *prev) != ep)) - prev = &temp->next; - if (*prev) - *prev = ep->next; - isp116x->load[i] -= ep->load; - } - ep->branch = PERIODIC_SIZE; - isp116x_to_hcd(isp116x)->self.bandwidth_allocated -= - ep->load / ep->period; - - /* switch irq type? */ - if (!--isp116x->periodic_count) { - isp116x->irqenb &= ~HCuPINT_SOF; - isp116x->irqenb |= HCuPINT_ATL; - } -} - /* Analyze transfer results, handle partial transfers and errors */ @@ -337,7 +284,6 @@ static void postproc_atl_queue(struct isp116x *isp116x) struct usb_device *udev; struct ptd *ptd; int short_not_ok; - int status; u8 cc; for (ep = isp116x->atl_active; ep; ep = ep->active) { @@ -348,7 +294,7 @@ static void postproc_atl_queue(struct isp116x *isp116x) ptd = &ep->ptd; cc = PTD_GET_CC(ptd); short_not_ok = 1; - status = -EINPROGRESS; + spin_lock(&urb->lock); /* Data underrun is special. For allowed underrun we clear the error and continue as normal. For @@ -356,36 +302,47 @@ static void postproc_atl_queue(struct isp116x *isp116x) immediately while for control transfer, we do a STATUS stage. */ if (cc == TD_DATAUNDERRUN) { - if (!(urb->transfer_flags & URB_SHORT_NOT_OK) || - usb_pipecontrol(urb->pipe)) { - DBG("Allowed or control data underrun\n"); + if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) { + DBG("Allowed data underrun\n"); cc = TD_CC_NOERROR; short_not_ok = 0; } else { ep->error_count = 1; - usb_settoggle(udev, ep->epnum, - ep->nextpid == USB_PID_OUT, - PTD_GET_TOGGLE(ptd)); + if (usb_pipecontrol(urb->pipe)) + ep->nextpid = USB_PID_ACK; + else + usb_settoggle(udev, ep->epnum, + ep->nextpid == + USB_PID_OUT, + PTD_GET_TOGGLE(ptd)); urb->actual_length += PTD_GET_COUNT(ptd); - status = cc_to_error[TD_DATAUNDERRUN]; - goto done; + urb->status = cc_to_error[TD_DATAUNDERRUN]; + spin_unlock(&urb->lock); + continue; } } + /* Keep underrun error through the STATUS stage */ + if (urb->status == cc_to_error[TD_DATAUNDERRUN]) + cc = TD_DATAUNDERRUN; if (cc != TD_CC_NOERROR && cc != TD_NOTACCESSED && (++ep->error_count >= 3 || cc == TD_CC_STALL || cc == TD_DATAOVERRUN)) { - status = cc_to_error[cc]; + if (urb->status == -EINPROGRESS) + urb->status = cc_to_error[cc]; if (ep->nextpid == USB_PID_ACK) ep->nextpid = 0; - goto done; + spin_unlock(&urb->lock); + continue; } /* According to usb spec, zero-length Int transfer signals finishing of the urb. Hey, does this apply only for IN endpoints? */ if (usb_pipeint(urb->pipe) && !PTD_GET_LEN(ptd)) { - status = 0; - goto done; + if (urb->status == -EINPROGRESS) + urb->status = 0; + spin_unlock(&urb->lock); + continue; } /* Relax after previously failed, but later succeeded @@ -424,8 +381,8 @@ static void postproc_atl_queue(struct isp116x *isp116x) /* All data for this URB is transferred, let's finish */ if (usb_pipecontrol(urb->pipe)) ep->nextpid = USB_PID_ACK; - else - status = 0; + else if (urb->status == -EINPROGRESS) + urb->status = 0; break; case USB_PID_SETUP: if (PTD_GET_ACTIVE(ptd) @@ -445,27 +402,69 @@ static void postproc_atl_queue(struct isp116x *isp116x) if (PTD_GET_ACTIVE(ptd) || (cc != TD_CC_NOERROR && cc < 0x0E)) break; - if ((urb->transfer_flags & URB_SHORT_NOT_OK) && - urb->actual_length < - urb->transfer_buffer_length) - status = -EREMOTEIO; - else - status = 0; + if (urb->status == -EINPROGRESS) + urb->status = 0; ep->nextpid = 0; break; default: BUG(); } + spin_unlock(&urb->lock); + } +} - done: - if (status != -EINPROGRESS) { - spin_lock(&urb->lock); - if (urb->status == -EINPROGRESS) - urb->status = status; - spin_unlock(&urb->lock); - } - if (urb->status != -EINPROGRESS) - finish_request(isp116x, ep, urb); +/* + Take done or failed requests out of schedule. Give back + processed urbs. +*/ +static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, + struct urb *urb) +__releases(isp116x->lock) __acquires(isp116x->lock) +{ + unsigned i; + + urb->hcpriv = NULL; + ep->error_count = 0; + + if (usb_pipecontrol(urb->pipe)) + ep->nextpid = USB_PID_SETUP; + + urb_dbg(urb, "Finish"); + + spin_unlock(&isp116x->lock); + usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb); + spin_lock(&isp116x->lock); + + /* take idle endpoints out of the schedule */ + if (!list_empty(&ep->hep->urb_list)) + return; + + /* async deschedule */ + if (!list_empty(&ep->schedule)) { + list_del_init(&ep->schedule); + return; + } + + /* periodic deschedule */ + DBG("deschedule qh%d/%p branch %d\n", ep->period, ep, ep->branch); + for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) { + struct isp116x_ep *temp; + struct isp116x_ep **prev = &isp116x->periodic[i]; + + while (*prev && ((temp = *prev) != ep)) + prev = &temp->next; + if (*prev) + *prev = ep->next; + isp116x->load[i] -= ep->load; + } + ep->branch = PERIODIC_SIZE; + isp116x_to_hcd(isp116x)->self.bandwidth_allocated -= + ep->load / ep->period; + + /* switch irq type? */ + if (!--isp116x->periodic_count) { + isp116x->irqenb &= ~HCuPINT_SOF; + isp116x->irqenb |= HCuPINT_ATL; } } @@ -571,6 +570,9 @@ static void start_atl_transfers(struct isp116x *isp116x) */ static void finish_atl_transfers(struct isp116x *isp116x) { + struct isp116x_ep *ep; + struct urb *urb; + if (!isp116x->atl_active) return; /* Fifo not ready? */ @@ -580,6 +582,16 @@ static void finish_atl_transfers(struct isp116x *isp116x) atomic_inc(&isp116x->atl_finishing); unpack_fifo(isp116x); postproc_atl_queue(isp116x); + for (ep = isp116x->atl_active; ep; ep = ep->active) { + urb = + container_of(ep->hep->urb_list.next, struct urb, urb_list); + /* USB_PID_ACK check here avoids finishing of + control transfers, for which TD_DATAUNDERRUN + occured, while URB_SHORT_NOT_OK was set */ + if (urb && urb->status != -EINPROGRESS + && ep->nextpid != USB_PID_ACK) + finish_request(isp116x, ep, urb); + } atomic_dec(&isp116x->atl_finishing); } @@ -809,12 +821,15 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, } /* in case of unlink-during-submit */ + spin_lock(&urb->lock); if (urb->status != -EINPROGRESS) { + spin_unlock(&urb->lock); finish_request(isp116x, ep, urb); ret = 0; goto fail; } urb->hcpriv = hep; + spin_unlock(&urb->lock); start_atl_transfers(isp116x); fail: diff --git a/trunk/drivers/usb/host/r8a66597-hcd.c b/trunk/drivers/usb/host/r8a66597-hcd.c index d60f1985320c..a7a7070c6e2a 100644 --- a/trunk/drivers/usb/host/r8a66597-hcd.c +++ b/trunk/drivers/usb/host/r8a66597-hcd.c @@ -35,8 +35,10 @@ #include #include #include -#include -#include + +#include +#include +#include #include "../core/hcd.h" #include "r8a66597.h" @@ -52,21 +54,16 @@ static const char hcd_name[] = "r8a66597_hcd"; /* module parameters */ static unsigned short clock = XTAL12; module_param(clock, ushort, 0644); -MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " - "(default=0)"); - +MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0(default=0)"); static unsigned short vif = LDRV; module_param(vif, ushort, 0644); MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0(default=32768)"); - -static unsigned short endian; +static unsigned short endian = 0; module_param(endian, ushort, 0644); -MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)"); - +MODULE_PARM_DESC(endian, "data endian: big=256, little=0(default=0)"); static unsigned short irq_sense = INTL; module_param(irq_sense, ushort, 0644); -MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0 " - "(default=32)"); +MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0(default=32)"); static void packet_write(struct r8a66597 *r8a66597, u16 pipenum); static int r8a66597_get_frame(struct usb_hcd *hcd); @@ -311,7 +308,7 @@ static int make_r8a66597_device(struct r8a66597 *r8a66597, struct r8a66597_device *dev; int usb_address = urb->setup_packet[2]; /* urb->pipe is address 0 */ - dev = kzalloc(sizeof(struct r8a66597_device), GFP_ATOMIC); + dev = kzalloc(sizeof(struct r8a66597_device), GFP_KERNEL); if (dev == NULL) return -ENOMEM; @@ -614,33 +611,33 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597, u16 array[R8A66597_MAX_NUM_PIPE], i = 0, min; memset(array, 0, sizeof(array)); - switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { - case USB_ENDPOINT_XFER_BULK: + switch(ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_BULK: if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) array[i++] = 4; else { array[i++] = 3; array[i++] = 5; } - break; - case USB_ENDPOINT_XFER_INT: + break; + case USB_ENDPOINT_XFER_INT: if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { array[i++] = 6; array[i++] = 7; array[i++] = 8; } else array[i++] = 9; - break; - case USB_ENDPOINT_XFER_ISOC: + break; + case USB_ENDPOINT_XFER_ISOC: if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) array[i++] = 2; else array[i++] = 1; - break; - default: - err("Illegal type"); - return 0; - } + break; + default: + err("Illegal type"); + return 0; + } i = 1; min = array[0]; @@ -657,7 +654,7 @@ static u16 get_r8a66597_type(__u8 type) { u16 r8a66597_type; - switch (type) { + switch(type) { case USB_ENDPOINT_XFER_BULK: r8a66597_type = R8A66597_BULK; break; @@ -877,7 +874,7 @@ static void r8a66597_usb_preconnect(struct r8a66597 *r8a66597, int port) { r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION) | (1 << USB_PORT_FEAT_C_CONNECTION); - r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); + r8a66597_write(r8a66597, (u16)~DTCH, get_intsts_reg(port)); r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); } @@ -920,7 +917,7 @@ static void prepare_setup_packet(struct r8a66597 *r8a66597, r8a66597_write(r8a66597, make_devsel(td->address) | td->maxpacket, DCPMAXP); - r8a66597_write(r8a66597, ~(SIGN | SACK), INTSTS1); + r8a66597_write(r8a66597, (u16)~(SIGN | SACK), INTSTS1); for (i = 0; i < 4; i++) { r8a66597_write(r8a66597, p[i], setup_addr); @@ -951,18 +948,19 @@ static void prepare_packet_read(struct r8a66597 *r8a66597, pipe_irq_disable(r8a66597, td->pipenum); pipe_setting(r8a66597, td); pipe_stop(r8a66597, td->pipe); - r8a66597_write(r8a66597, ~(1 << td->pipenum), BRDYSTS); + r8a66597_write(r8a66597, (u16)~(1 << td->pipenum), + BRDYSTS); if (td->pipe->pipetre) { r8a66597_write(r8a66597, TRCLR, - td->pipe->pipetre); + td->pipe->pipetre); r8a66597_write(r8a66597, - (urb->transfer_buffer_length - + td->maxpacket - 1) - / td->maxpacket, - td->pipe->pipetrn); + (urb->transfer_buffer_length + + td->maxpacket - 1) + / td->maxpacket, + td->pipe->pipetrn); r8a66597_bset(r8a66597, TRENB, - td->pipe->pipetre); + td->pipe->pipetre); } pipe_start(r8a66597, td->pipe); @@ -993,7 +991,7 @@ static void prepare_packet_write(struct r8a66597 *r8a66597, if (td->pipe->pipetre) r8a66597_bclr(r8a66597, TRENB, td->pipe->pipetre); } - r8a66597_write(r8a66597, ~(1 << td->pipenum), BRDYSTS); + r8a66597_write(r8a66597, (u16)~(1 << td->pipenum), BRDYSTS); fifo_change_from_pipe(r8a66597, td->pipe); tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); @@ -1011,21 +1009,21 @@ static void prepare_status_packet(struct r8a66597 *r8a66597, struct urb *urb = td->urb; r8a66597_pipe_toggle(r8a66597, td->pipe, 1); - pipe_stop(r8a66597, td->pipe); if (urb->setup_packet[0] & USB_ENDPOINT_DIR_MASK) { r8a66597_bset(r8a66597, R8A66597_DIR, DCPCFG); r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL); r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); - r8a66597_write(r8a66597, ~BEMP0, BEMPSTS); - r8a66597_write(r8a66597, BCLR, CFIFOCTR); - r8a66597_write(r8a66597, BVAL, CFIFOCTR); + r8a66597_write(r8a66597, BVAL | BCLR, CFIFOCTR); + r8a66597_write(r8a66597, (u16)~BEMP0, BEMPSTS); enable_irq_empty(r8a66597, 0); } else { r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG); r8a66597_mdfy(r8a66597, 0, ISEL | CURPIPE, CFIFOSEL); r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); r8a66597_write(r8a66597, BCLR, CFIFOCTR); + r8a66597_write(r8a66597, (u16)~BRDY0, BRDYSTS); + r8a66597_write(r8a66597, (u16)~BEMP0, BEMPSTS); enable_irq_ready(r8a66597, 0); } enable_irq_nrdy(r8a66597, 0); @@ -1271,7 +1269,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) /* write fifo */ if (pipenum > 0) - r8a66597_write(r8a66597, ~(1 << pipenum), BEMPSTS); + r8a66597_write(r8a66597, (u16)~(1 << pipenum), BEMPSTS); if (urb->transfer_buffer) { r8a66597_write_fifo(r8a66597, td->pipe->fifoaddr, buf, size); if (!usb_pipebulk(urb->pipe) || td->maxpacket != size) @@ -1364,7 +1362,7 @@ static void irq_pipe_ready(struct r8a66597 *r8a66597) mask = r8a66597_read(r8a66597, BRDYSTS) & r8a66597_read(r8a66597, BRDYENB); - r8a66597_write(r8a66597, ~mask, BRDYSTS); + r8a66597_write(r8a66597, (u16)~mask, BRDYSTS); if (mask & BRDY0) { td = r8a66597_get_td(r8a66597, 0); if (td && td->type == USB_PID_IN) @@ -1399,7 +1397,7 @@ static void irq_pipe_empty(struct r8a66597 *r8a66597) mask = r8a66597_read(r8a66597, BEMPSTS) & r8a66597_read(r8a66597, BEMPENB); - r8a66597_write(r8a66597, ~mask, BEMPSTS); + r8a66597_write(r8a66597, (u16)~mask, BEMPSTS); if (mask & BEMP0) { cfifo_change(r8a66597, 0); td = r8a66597_get_td(r8a66597, 0); @@ -1436,7 +1434,7 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597) mask = r8a66597_read(r8a66597, NRDYSTS) & r8a66597_read(r8a66597, NRDYENB); - r8a66597_write(r8a66597, ~mask, NRDYSTS); + r8a66597_write(r8a66597, (u16)~mask, NRDYSTS); if (mask & NRDY0) { cfifo_change(r8a66597, 0); set_urb_error(r8a66597, 0); @@ -1490,14 +1488,14 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) mask0 = intsts0 & intenb0 & (BEMP | NRDY | BRDY); if (mask2) { if (mask2 & ATTCH) { - r8a66597_write(r8a66597, ~ATTCH, INTSTS2); + r8a66597_write(r8a66597, (u16)~ATTCH, INTSTS2); r8a66597_bclr(r8a66597, ATTCHE, INTENB2); /* start usb bus sampling */ start_root_hub_sampling(r8a66597, 1); } if (mask2 & DTCH) { - r8a66597_write(r8a66597, ~DTCH, INTSTS2); + r8a66597_write(r8a66597, (u16)~DTCH, INTSTS2); r8a66597_bclr(r8a66597, DTCHE, INTENB2); r8a66597_usb_disconnect(r8a66597, 1); } @@ -1505,24 +1503,24 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) if (mask1) { if (mask1 & ATTCH) { - r8a66597_write(r8a66597, ~ATTCH, INTSTS1); + r8a66597_write(r8a66597, (u16)~ATTCH, INTSTS1); r8a66597_bclr(r8a66597, ATTCHE, INTENB1); /* start usb bus sampling */ start_root_hub_sampling(r8a66597, 0); } if (mask1 & DTCH) { - r8a66597_write(r8a66597, ~DTCH, INTSTS1); + r8a66597_write(r8a66597, (u16)~DTCH, INTSTS1); r8a66597_bclr(r8a66597, DTCHE, INTENB1); r8a66597_usb_disconnect(r8a66597, 0); } if (mask1 & SIGN) { - r8a66597_write(r8a66597, ~SIGN, INTSTS1); + r8a66597_write(r8a66597, (u16)~SIGN, INTSTS1); set_urb_error(r8a66597, 0); check_next_phase(r8a66597); } if (mask1 & SACK) { - r8a66597_write(r8a66597, ~SACK, INTSTS1); + r8a66597_write(r8a66597, (u16)~SACK, INTSTS1); check_next_phase(r8a66597); } } @@ -1665,9 +1663,13 @@ static int check_pipe_config(struct r8a66597 *r8a66597, struct urb *urb) static int r8a66597_start(struct usb_hcd *hcd) { struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); + int ret; hcd->state = HC_STATE_RUNNING; - return enable_controller(r8a66597); + if ((ret = enable_controller(r8a66597)) < 0) + return ret; + + return 0; } static void r8a66597_stop(struct usb_hcd *hcd) @@ -1694,12 +1696,13 @@ static void set_address_zero(struct r8a66597 *r8a66597, struct urb *urb) static struct r8a66597_td *r8a66597_make_td(struct r8a66597 *r8a66597, struct urb *urb, - struct usb_host_endpoint *hep) + struct usb_host_endpoint *hep, + gfp_t mem_flags) { struct r8a66597_td *td; u16 pipenum; - td = kzalloc(sizeof(struct r8a66597_td), GFP_ATOMIC); + td = kzalloc(sizeof(struct r8a66597_td), mem_flags); if (td == NULL) return NULL; @@ -1738,8 +1741,7 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, } if (!hep->hcpriv) { - hep->hcpriv = kzalloc(sizeof(struct r8a66597_pipe), - GFP_ATOMIC); + hep->hcpriv = kzalloc(sizeof(struct r8a66597_pipe), mem_flags); if (!hep->hcpriv) { ret = -ENOMEM; goto error; @@ -1753,7 +1755,7 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, init_pipe_config(r8a66597, urb); set_address_zero(r8a66597, urb); - td = r8a66597_make_td(r8a66597, urb, hep); + td = r8a66597_make_td(r8a66597, urb, hep, mem_flags); if (td == NULL) { ret = -ENOMEM; goto error; diff --git a/trunk/drivers/usb/host/r8a66597.h b/trunk/drivers/usb/host/r8a66597.h index fe9ceb077d9b..97c2a71ac7a1 100644 --- a/trunk/drivers/usb/host/r8a66597.h +++ b/trunk/drivers/usb/host/r8a66597.h @@ -203,14 +203,14 @@ #define DTLN 0x0FFF /* b11-0: FIFO received data length */ /* Interrupt Enable Register 0 */ -#define VBSE 0x8000 /* b15: VBUS interrupt */ -#define RSME 0x4000 /* b14: Resume interrupt */ -#define SOFE 0x2000 /* b13: Frame update interrupt */ -#define DVSE 0x1000 /* b12: Device state transition interrupt */ -#define CTRE 0x0800 /* b11: Control transfer stage transition interrupt */ -#define BEMPE 0x0400 /* b10: Buffer empty interrupt */ -#define NRDYE 0x0200 /* b9: Buffer not ready interrupt */ -#define BRDYE 0x0100 /* b8: Buffer ready interrupt */ +#define VBSE 0x8000 /* b15: VBUS interrupt */ +#define RSME 0x4000 /* b14: Resume interrupt */ +#define SOFE 0x2000 /* b13: Frame update interrupt */ +#define DVSE 0x1000 /* b12: Device state transition interrupt */ +#define CTRE 0x0800 /* b11: Control transfer stage transition interrupt */ +#define BEMPE 0x0400 /* b10: Buffer empty interrupt */ +#define NRDYE 0x0200 /* b9: Buffer not ready interrupt */ +#define BRDYE 0x0100 /* b8: Buffer ready interrupt */ /* Interrupt Enable Register 1 */ #define OVRCRE 0x8000 /* b15: Over-current interrupt */ @@ -268,16 +268,16 @@ #define SOF_DISABLE 0x0000 /* SOF OUT Disable */ /* Interrupt Status Register 0 */ -#define VBINT 0x8000 /* b15: VBUS interrupt */ -#define RESM 0x4000 /* b14: Resume interrupt */ -#define SOFR 0x2000 /* b13: SOF frame update interrupt */ -#define DVST 0x1000 /* b12: Device state transition interrupt */ -#define CTRT 0x0800 /* b11: Control transfer stage transition interrupt */ -#define BEMP 0x0400 /* b10: Buffer empty interrupt */ -#define NRDY 0x0200 /* b9: Buffer not ready interrupt */ -#define BRDY 0x0100 /* b8: Buffer ready interrupt */ -#define VBSTS 0x0080 /* b7: VBUS input port */ -#define DVSQ 0x0070 /* b6-4: Device state */ +#define VBINT 0x8000 /* b15: VBUS interrupt */ +#define RESM 0x4000 /* b14: Resume interrupt */ +#define SOFR 0x2000 /* b13: SOF frame update interrupt */ +#define DVST 0x1000 /* b12: Device state transition interrupt */ +#define CTRT 0x0800 /* b11: Control transfer stage transition interrupt */ +#define BEMP 0x0400 /* b10: Buffer empty interrupt */ +#define NRDY 0x0200 /* b9: Buffer not ready interrupt */ +#define BRDY 0x0100 /* b8: Buffer ready interrupt */ +#define VBSTS 0x0080 /* b7: VBUS input port */ +#define DVSQ 0x0070 /* b6-4: Device state */ #define DS_SPD_CNFG 0x0070 /* Suspend Configured */ #define DS_SPD_ADDR 0x0060 /* Suspend Address */ #define DS_SPD_DFLT 0x0050 /* Suspend Default */ @@ -315,10 +315,13 @@ /* Micro Frame Number Register */ #define UFRNM 0x0007 /* b2-0: Micro frame number */ +/* USB Address / Low Power Status Recovery Register */ +//#define USBADDR 0x007F /* b6-0: USB address */ + /* Default Control Pipe Maxpacket Size Register */ /* Pipe Maxpacket Size Register */ -#define DEVSEL 0xF000 /* b15-14: Device address select */ -#define MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */ +#define DEVSEL 0xF000 /* b15-14: Device address select */ +#define MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */ /* Default Control Pipe Control Register */ #define BSTS 0x8000 /* b15: Buffer status */ @@ -363,21 +366,21 @@ #define MXPS 0x07FF /* b10-0: Maxpacket size */ /* Pipe Cycle Configuration Register */ -#define IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */ -#define IITV 0x0007 /* b2-0: Isochronous interval */ +#define IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */ +#define IITV 0x0007 /* b2-0: Isochronous interval */ /* Pipex Control Register */ -#define BSTS 0x8000 /* b15: Buffer status */ -#define INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */ -#define CSCLR 0x2000 /* b13: complete-split status clear */ -#define CSSTS 0x1000 /* b12: complete-split status */ -#define ATREPM 0x0400 /* b10: Auto repeat mode */ -#define ACLRM 0x0200 /* b9: Out buffer auto clear mode */ -#define SQCLR 0x0100 /* b8: Sequence toggle bit clear */ -#define SQSET 0x0080 /* b7: Sequence toggle bit set */ -#define SQMON 0x0040 /* b6: Sequence toggle bit monitor */ -#define PBUSY 0x0020 /* b5: pipe busy */ -#define PID 0x0003 /* b1-0: Response PID */ +#define BSTS 0x8000 /* b15: Buffer status */ +#define INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */ +#define CSCLR 0x2000 /* b13: complete-split status clear */ +#define CSSTS 0x1000 /* b12: complete-split status */ +#define ATREPM 0x0400 /* b10: Auto repeat mode */ +#define ACLRM 0x0200 /* b9: Out buffer auto clear mode */ +#define SQCLR 0x0100 /* b8: Sequence toggle bit clear */ +#define SQSET 0x0080 /* b7: Sequence toggle bit set */ +#define SQMON 0x0040 /* b6: Sequence toggle bit monitor */ +#define PBUSY 0x0020 /* b5: pipe busy */ +#define PID 0x0003 /* b1-0: Response PID */ /* PIPExTRE */ #define TRENB 0x0200 /* b9: Transaction counter enable */ @@ -404,15 +407,15 @@ #define make_devsel(addr) (addr << 12) struct r8a66597_pipe_info { - u16 pipenum; - u16 address; /* R8A66597 HCD usb addres */ - u16 epnum; - u16 maxpacket; - u16 type; - u16 bufnum; - u16 buf_bsize; - u16 interval; - u16 dir_in; + u16 pipenum; + u16 address; /* R8A66597 HCD usb addres */ + u16 epnum; + u16 maxpacket; + u16 type; + u16 bufnum; + u16 buf_bsize; + u16 interval; + u16 dir_in; }; struct r8a66597_pipe { diff --git a/trunk/drivers/usb/host/u132-hcd.c b/trunk/drivers/usb/host/u132-hcd.c index 7f765ec038cd..e98df2ee9901 100644 --- a/trunk/drivers/usb/host/u132-hcd.c +++ b/trunk/drivers/usb/host/u132-hcd.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include #include @@ -84,7 +83,7 @@ static DECLARE_WAIT_QUEUE_HEAD(u132_hcd_wait); * u132_module_lock exists to protect access to global variables * */ -static struct mutex u132_module_lock; +static struct semaphore u132_module_lock; static int u132_exiting = 0; static int u132_instances = 0; static struct list_head u132_static_list; @@ -259,10 +258,10 @@ static void u132_hcd_delete(struct kref *kref) struct platform_device *pdev = u132->platform_dev; struct usb_hcd *hcd = u132_to_hcd(u132); u132->going += 1; - mutex_lock(&u132_module_lock); + down(&u132_module_lock); list_del_init(&u132->u132_list); u132_instances -= 1; - mutex_unlock(&u132_module_lock); + up(&u132_module_lock); dev_warn(&u132->platform_dev->dev, "FREEING the hcd=%p and thus the u13" "2=%p going=%d pdev=%p\n", hcd, u132, u132->going, pdev); usb_put_hcd(hcd); @@ -3112,10 +3111,10 @@ static int __devinit u132_probe(struct platform_device *pdev) int retval = 0; struct u132 *u132 = hcd_to_u132(hcd); hcd->rsrc_start = 0; - mutex_lock(&u132_module_lock); + down(&u132_module_lock); list_add_tail(&u132->u132_list, &u132_static_list); u132->sequence_num = ++u132_instances; - mutex_unlock(&u132_module_lock); + up(&u132_module_lock); u132_u132_init_kref(u132); u132_initialise(u132, pdev); hcd->product_desc = "ELAN U132 Host Controller"; @@ -3217,7 +3216,7 @@ static int __init u132_hcd_init(void) INIT_LIST_HEAD(&u132_static_list); u132_instances = 0; u132_exiting = 0; - mutex_init(&u132_module_lock); + init_MUTEX(&u132_module_lock); if (usb_disabled()) return -ENODEV; printk(KERN_INFO "driver %s built at %s on %s\n", hcd_name, __TIME__, @@ -3233,9 +3232,9 @@ static void __exit u132_hcd_exit(void) { struct u132 *u132; struct u132 *temp; - mutex_lock(&u132_module_lock); + down(&u132_module_lock); u132_exiting += 1; - mutex_unlock(&u132_module_lock); + up(&u132_module_lock); list_for_each_entry_safe(u132, temp, &u132_static_list, u132_list) { platform_device_unregister(u132->platform_dev); } platform_driver_unregister(&u132_platform_driver); diff --git a/trunk/drivers/usb/host/uhci-q.c b/trunk/drivers/usb/host/uhci-q.c index 3bb908ca38e9..4aed305982ec 100644 --- a/trunk/drivers/usb/host/uhci-q.c +++ b/trunk/drivers/usb/host/uhci-q.c @@ -827,10 +827,8 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, * If direction is "send", change the packet ID from SETUP (0x2D) * to OUT (0xE1). Else change it from SETUP to IN (0x69) and * set Short Packet Detect (SPD) for all data packets. - * - * 0-length transfers always get treated as "send". */ - if (usb_pipeout(urb->pipe) || len == 0) + if (usb_pipeout(urb->pipe)) destination ^= (USB_PID_SETUP ^ USB_PID_OUT); else { destination ^= (USB_PID_SETUP ^ USB_PID_IN); @@ -841,12 +839,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, * Build the DATA TDs */ while (len > 0) { - int pktsze = maxsze; - - if (len <= pktsze) { /* The last data packet */ - pktsze = len; - status &= ~TD_CTRL_SPD; - } + int pktsze = min(len, maxsze); td = uhci_alloc_td(uhci); if (!td) @@ -873,10 +866,20 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, goto nomem; *plink = LINK_TO_TD(td); - /* Change direction for the status transaction */ - destination ^= (USB_PID_IN ^ USB_PID_OUT); + /* + * It's IN if the pipe is an output pipe or we're not expecting + * data back. + */ + destination &= ~TD_TOKEN_PID_MASK; + if (usb_pipeout(urb->pipe) || !urb->transfer_buffer_length) + destination |= USB_PID_IN; + else + destination |= USB_PID_OUT; + destination |= TD_TOKEN_TOGGLE; /* End in Data1 */ + status &= ~TD_CTRL_SPD; + uhci_add_td_to_urbp(td, urbp); uhci_fill_td(td, status | TD_CTRL_IOC, destination | uhci_explen(0), 0); @@ -1182,18 +1185,10 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) } } - /* Did we receive a short packet? */ } else if (len < uhci_expected_length(td_token(td))) { - /* For control transfers, go to the status TD if - * this isn't already the last data TD */ - if (qh->type == USB_ENDPOINT_XFER_CONTROL) { - if (td->list.next != urbp->td_list.prev) - ret = 1; - } - - /* For bulk and interrupt, this may be an error */ - else if (urb->transfer_flags & URB_SHORT_NOT_OK) + /* We received a short packet */ + if (urb->transfer_flags & URB_SHORT_NOT_OK) ret = -EREMOTEIO; /* Fixup needed only if this isn't the URB's last TD */ @@ -1213,6 +1208,10 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) err: if (ret < 0) { + /* In case a control transfer gets an error + * during the setup stage */ + urb->actual_length = max(urb->actual_length, 0); + /* Note that the queue has stopped and save * the next toggle value */ qh->element = UHCI_PTR_TERM; @@ -1490,25 +1489,9 @@ __acquires(uhci->lock) { struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; - if (qh->type == USB_ENDPOINT_XFER_CONTROL) { - - /* urb->actual_length < 0 means the setup transaction didn't - * complete successfully. Either it failed or the URB was - * unlinked first. Regardless, don't confuse people with a - * negative length. */ - urb->actual_length = max(urb->actual_length, 0); - - /* Report erroneous short transfers */ - if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && - urb->actual_length < - urb->transfer_buffer_length && - urb->status == 0)) - urb->status = -EREMOTEIO; - } - /* When giving back the first URB in an Isochronous queue, * reinitialize the QH's iso-related members for the next URB. */ - else if (qh->type == USB_ENDPOINT_XFER_ISOC && + if (qh->type == USB_ENDPOINT_XFER_ISOC && urbp->node.prev == &qh->queue && urbp->node.next != &qh->queue) { struct urb *nurb = list_entry(urbp->node.next, diff --git a/trunk/drivers/usb/image/mdc800.c b/trunk/drivers/usb/image/mdc800.c index d1131a87a5b1..36502a06f73a 100644 --- a/trunk/drivers/usb/image/mdc800.c +++ b/trunk/drivers/usb/image/mdc800.c @@ -284,9 +284,9 @@ static void mdc800_usb_irq (struct urb *urb) int data_received=0, wake_up; unsigned char* b=urb->transfer_buffer; struct mdc800_data* mdc800=urb->context; - int status = urb->status; - if (status >= 0) { + if (urb->status >= 0) + { //dbg ("%i %i %i %i %i %i %i %i \n",b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7]); @@ -324,7 +324,7 @@ static void mdc800_usb_irq (struct urb *urb) || ((mdc800->camera_request_ready == 3) && (mdc800->camera_busy)) || - (status < 0) + (urb->status < 0) ); if (wake_up) @@ -376,12 +376,15 @@ static int mdc800_usb_waitForIRQ (int mode, int msec) static void mdc800_usb_write_notify (struct urb *urb) { struct mdc800_data* mdc800=urb->context; - int status = urb->status; - if (status != 0) - err ("writing command fails (status=%i)", status); + if (urb->status != 0) + { + err ("writing command fails (status=%i)", urb->status); + } else + { mdc800->state=READY; + } mdc800->written = 1; wake_up (&mdc800->write_wait); } @@ -393,9 +396,9 @@ static void mdc800_usb_write_notify (struct urb *urb) static void mdc800_usb_download_notify (struct urb *urb) { struct mdc800_data* mdc800=urb->context; - int status = urb->status; - if (status == 0) { + if (urb->status == 0) + { /* Fill output buffer with these data */ memcpy (mdc800->out, urb->transfer_buffer, 64); mdc800->out_count=64; @@ -405,8 +408,10 @@ static void mdc800_usb_download_notify (struct urb *urb) { mdc800->state=READY; } - } else { - err ("request bytes fails (status:%i)", status); + } + else + { + err ("request bytes fails (status:%i)", urb->status); } mdc800->downloaded = 1; wake_up (&mdc800->download_wait); @@ -644,9 +649,9 @@ static int mdc800_device_open (struct inode* inode, struct file *file) retval=0; mdc800->irq_urb->dev = mdc800->dev; - retval = usb_submit_urb (mdc800->irq_urb, GFP_KERNEL); - if (retval) { - err ("request USB irq fails (submit_retval=%i).", retval); + if (usb_submit_urb (mdc800->irq_urb, GFP_KERNEL)) + { + err ("request USB irq fails (submit_retval=%i urb_status=%i).",retval, mdc800->irq_urb->status); errn = -EIO; goto error_out; } @@ -693,7 +698,6 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l { size_t left=len, sts=len; /* single transfer size */ char __user *ptr = buf; - int retval; mutex_lock(&mdc800->io_lock); if (mdc800->state == NOT_CONNECTED) @@ -733,9 +737,9 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l /* Download -> Request new bytes */ mdc800->download_urb->dev = mdc800->dev; - retval = usb_submit_urb (mdc800->download_urb, GFP_KERNEL); - if (retval) { - err ("Can't submit download urb (retval=%i)",retval); + if (usb_submit_urb (mdc800->download_urb, GFP_KERNEL)) + { + err ("Can't submit download urb (status=%i)",mdc800->download_urb->status); mutex_unlock(&mdc800->io_lock); return len-left; } @@ -784,7 +788,6 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l static ssize_t mdc800_device_write (struct file *file, const char __user *buf, size_t len, loff_t *pos) { size_t i=0; - int retval; mutex_lock(&mdc800->io_lock); if (mdc800->state != READY) @@ -851,9 +854,9 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s mdc800->state=WORKING; memcpy (mdc800->write_urb->transfer_buffer, mdc800->in,8); mdc800->write_urb->dev = mdc800->dev; - retval = usb_submit_urb (mdc800->write_urb, GFP_KERNEL); - if (retval) { - err ("submitting write urb fails (retval=%i)", retval); + if (usb_submit_urb (mdc800->write_urb, GFP_KERNEL)) + { + err ("submitting write urb fails (status=%i)", mdc800->write_urb->status); mutex_unlock(&mdc800->io_lock); return -EIO; } diff --git a/trunk/drivers/usb/image/microtek.c b/trunk/drivers/usb/image/microtek.c index 768b2c11a231..51bd80d2b8cc 100644 --- a/trunk/drivers/usb/image/microtek.c +++ b/trunk/drivers/usb/image/microtek.c @@ -189,7 +189,7 @@ static struct usb_driver mts_usb_driver = { #define MTS_DEBUG_INT() \ do { MTS_DEBUG_GOT_HERE(); \ MTS_DEBUG("transfer = 0x%x context = 0x%x\n",(int)transfer,(int)context ); \ - MTS_DEBUG("status = 0x%x data-length = 0x%x sent = 0x%x\n",transfer->status,(int)context->data_length, (int)transfer->actual_length ); \ + MTS_DEBUG("status = 0x%x data-length = 0x%x sent = 0x%x\n",(int)transfer->status,(int)context->data_length, (int)transfer->actual_length ); \ mts_debug_dump(context->instance);\ } while(0) #else @@ -393,6 +393,8 @@ void mts_int_submit_urb (struct urb* transfer, context ); + transfer->status = 0; + res = usb_submit_urb( transfer, GFP_ATOMIC ); if ( unlikely(res) ) { MTS_INT_ERROR( "could not submit URB! Error was %d\n",(int)res ); @@ -442,13 +444,12 @@ static void mts_get_status( struct urb *transfer ) static void mts_data_done( struct urb* transfer ) /* Interrupt context! */ { - int status = transfer->status; MTS_INT_INIT(); if ( context->data_length != transfer->actual_length ) { context->srb->resid = context->data_length - transfer->actual_length; - } else if ( unlikely(status) ) { - context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; + } else if ( unlikely(transfer->status) ) { + context->srb->result = (transfer->status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; } mts_get_status(transfer); @@ -460,11 +461,10 @@ static void mts_data_done( struct urb* transfer ) static void mts_command_done( struct urb *transfer ) /* Interrupt context! */ { - int status = transfer->status; MTS_INT_INIT(); - if ( unlikely(status) ) { - if (status == -ENOENT) { + if ( unlikely(transfer->status) ) { + if (transfer->status == -ENOENT) { /* We are being killed */ MTS_DEBUG_GOT_HERE(); context->srb->result = DID_ABORT<<16; @@ -502,13 +502,12 @@ static void mts_command_done( struct urb *transfer ) static void mts_do_sg (struct urb* transfer) { struct scatterlist * sg; - int status = transfer->status; MTS_INT_INIT(); MTS_DEBUG("Processing fragment %d of %d\n", context->fragment,context->srb->use_sg); - if (unlikely(status)) { - context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; + if (unlikely(transfer->status)) { + context->srb->result = (transfer->status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; mts_transfer_cleanup(transfer); } diff --git a/trunk/drivers/usb/misc/adutux.c b/trunk/drivers/usb/misc/adutux.c index e9fdbc8997b3..d72c42e5f22d 100644 --- a/trunk/drivers/usb/misc/adutux.c +++ b/trunk/drivers/usb/misc/adutux.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #ifdef CONFIG_USB_DEBUG @@ -81,7 +80,7 @@ MODULE_DEVICE_TABLE(usb, device_table); /* Structure to hold all of our device specific stuff */ struct adu_device { - struct mutex mtx; /* locks this structure */ + struct semaphore sem; /* locks this structure */ struct usb_device* udev; /* save off the usb device pointer */ struct usb_interface* interface; unsigned char minor; /* the starting minor number for this device */ @@ -179,18 +178,17 @@ static void adu_delete(struct adu_device *dev) static void adu_interrupt_in_callback(struct urb *urb) { struct adu_device *dev = urb->context; - int status = urb->status; - dbg(4," %s : enter, status %d", __FUNCTION__, status); + dbg(4," %s : enter, status %d", __FUNCTION__, urb->status); adu_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); spin_lock(&dev->buflock); - if (status != 0) { - if ((status != -ENOENT) && (status != -ECONNRESET)) { + if (urb->status != 0) { + if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET)) { dbg(1," %s : nonzero status received: %d", - __FUNCTION__, status); + __FUNCTION__, urb->status); } goto exit; } @@ -218,22 +216,21 @@ static void adu_interrupt_in_callback(struct urb *urb) wake_up_interruptible(&dev->read_wait); adu_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); - dbg(4," %s : leave, status %d", __FUNCTION__, status); + dbg(4," %s : leave, status %d", __FUNCTION__, urb->status); } static void adu_interrupt_out_callback(struct urb *urb) { struct adu_device *dev = urb->context; - int status = urb->status; - dbg(4," %s : enter, status %d", __FUNCTION__, status); + dbg(4," %s : enter, status %d", __FUNCTION__, urb->status); adu_debug_data(5,__FUNCTION__, urb->actual_length, urb->transfer_buffer); - if (status != 0) { - if ((status != -ENOENT) && - (status != -ECONNRESET)) { + if (urb->status != 0) { + if ((urb->status != -ENOENT) && + (urb->status != -ECONNRESET)) { dbg(1, " %s :nonzero status received: %d", - __FUNCTION__, status); + __FUNCTION__, urb->status); } goto exit; } @@ -243,7 +240,7 @@ static void adu_interrupt_out_callback(struct urb *urb) adu_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); - dbg(4," %s : leave, status %d", __FUNCTION__, status); + dbg(4," %s : leave, status %d", __FUNCTION__, urb->status); } static int adu_open(struct inode *inode, struct file *file) @@ -272,8 +269,8 @@ static int adu_open(struct inode *inode, struct file *file) } /* lock this device */ - if ((retval = mutex_lock_interruptible(&dev->mtx))) { - dbg(2, "%s : mutex lock failed", __FUNCTION__); + if ((retval = down_interruptible(&dev->sem))) { + dbg(2, "%s : sem down failed", __FUNCTION__); goto exit_no_device; } @@ -302,7 +299,7 @@ static int adu_open(struct inode *inode, struct file *file) if (retval) --dev->open_count; } - mutex_unlock(&dev->mtx); + up(&dev->sem); exit_no_device: dbg(2,"%s : leave, return value %d ", __FUNCTION__, retval); @@ -350,7 +347,7 @@ static int adu_release(struct inode *inode, struct file *file) } /* lock our device */ - mutex_lock(&dev->mtx); /* not interruptible */ + down(&dev->sem); /* not interruptible */ if (dev->open_count <= 0) { dbg(1," %s : device not opened", __FUNCTION__); @@ -360,7 +357,7 @@ static int adu_release(struct inode *inode, struct file *file) if (dev->udev == NULL) { /* the device was unplugged before the file was released */ - mutex_unlock(&dev->mtx); + up(&dev->sem); adu_delete(dev); dev = NULL; } else { @@ -370,7 +367,7 @@ static int adu_release(struct inode *inode, struct file *file) exit: if (dev) - mutex_unlock(&dev->mtx); + up(&dev->sem); dbg(2," %s : leave, return value %d", __FUNCTION__, retval); return retval; } @@ -393,7 +390,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, dev = file->private_data; dbg(2," %s : dev=%p", __FUNCTION__, dev); /* lock this object */ - if (mutex_lock_interruptible(&dev->mtx)) + if (down_interruptible(&dev->sem)) return -ERESTARTSYS; /* verify that the device wasn't unplugged */ @@ -525,7 +522,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, exit: /* unlock the device */ - mutex_unlock(&dev->mtx); + up(&dev->sem); dbg(2," %s : leave, return value %d", __FUNCTION__, retval); return retval; @@ -546,7 +543,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, dev = file->private_data; /* lock this object */ - retval = mutex_lock_interruptible(&dev->mtx); + retval = down_interruptible(&dev->sem); if (retval) goto exit_nolock; @@ -574,9 +571,9 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, retval = -EINTR; goto exit; } - mutex_unlock(&dev->mtx); + up(&dev->sem); timeout = interruptible_sleep_on_timeout(&dev->write_wait, timeout); - retval = mutex_lock_interruptible(&dev->mtx); + retval = down_interruptible(&dev->sem); if (retval) { retval = bytes_written ? bytes_written : retval; goto exit_nolock; @@ -641,7 +638,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, exit: /* unlock the device */ - mutex_unlock(&dev->mtx); + up(&dev->sem); exit_nolock: dbg(2," %s : leave, return value %d", __FUNCTION__, retval); @@ -701,7 +698,7 @@ static int adu_probe(struct usb_interface *interface, goto exit; } - mutex_init(&dev->mtx); + init_MUTEX(&dev->sem); spin_lock_init(&dev->buflock); dev->udev = udev; init_waitqueue_head(&dev->read_wait); @@ -838,16 +835,16 @@ static void adu_disconnect(struct usb_interface *interface) usb_deregister_dev(interface, &adu_class); dev->minor = 0; - mutex_lock(&dev->mtx); /* not interruptible */ + down(&dev->sem); /* not interruptible */ /* if the device is not opened, then we clean up right now */ dbg(2," %s : open count %d", __FUNCTION__, dev->open_count); if (!dev->open_count) { - mutex_unlock(&dev->mtx); + up(&dev->sem); adu_delete(dev); } else { dev->udev = NULL; - mutex_unlock(&dev->mtx); + up(&dev->sem); } dev_info(&interface->dev, "ADU device adutux%d now disconnected", diff --git a/trunk/drivers/usb/misc/appledisplay.c b/trunk/drivers/usb/misc/appledisplay.c index b09c83568c1a..cf70c16f0e3f 100644 --- a/trunk/drivers/usb/misc/appledisplay.c +++ b/trunk/drivers/usb/misc/appledisplay.c @@ -88,10 +88,9 @@ static void appledisplay_complete(struct urb *urb) { struct appledisplay *pdata = urb->context; unsigned long flags; - int status = urb->status; int retval; - switch (status) { + switch (urb->status) { case 0: /* success */ break; @@ -103,12 +102,12 @@ static void appledisplay_complete(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* This urb is terminated, clean up */ - dbg("%s - urb shuttingdown with status: %d", - __FUNCTION__, status); + dbg("%s - urb shutting down with status: %d", + __FUNCTION__, urb->status); return; default: dbg("%s - nonzero urb status received: %d", - __FUNCTION__, status); + __FUNCTION__, urb->status); goto exit; } diff --git a/trunk/drivers/usb/misc/auerswald.c b/trunk/drivers/usb/misc/auerswald.c index df7e1ecc810a..42d4e6454a77 100644 --- a/trunk/drivers/usb/misc/auerswald.c +++ b/trunk/drivers/usb/misc/auerswald.c @@ -862,16 +862,14 @@ static void auerswald_ctrlread_wretcomplete (struct urb * urb) pauerbuf_t bp = (pauerbuf_t) urb->context; pauerswald_t cp; int ret; - int status = urb->status; - dbg ("auerswald_ctrlread_wretcomplete called"); - dbg ("complete with status: %d", status); + dbg ("complete with status: %d", urb->status); cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); /* check if it is possible to advance */ - if (!auerswald_status_retry(status) || !cp->usbdev) { + if (!auerswald_status_retry (urb->status) || !cp->usbdev) { /* reuse the buffer */ - err ("control dummy: transmission error %d, can not retry", status); + err ("control dummy: transmission error %d, can not retry", urb->status); auerbuf_releasebuf (bp); /* Wake up all processes waiting for a buffer */ wake_up (&cp->bufferwait); @@ -904,23 +902,21 @@ static void auerswald_ctrlread_complete (struct urb * urb) pauerswald_t cp; pauerscon_t scp; pauerbuf_t bp = (pauerbuf_t) urb->context; - int status = urb->status; int ret; - dbg ("auerswald_ctrlread_complete called"); cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); /* check if there is valid data in this urb */ - if (status) { - dbg ("complete with non-zero status: %d", status); + if (urb->status) { + dbg ("complete with non-zero status: %d", urb->status); /* should we do a retry? */ - if (!auerswald_status_retry(status) + if (!auerswald_status_retry (urb->status) || !cp->usbdev || (cp->version < AUV_RETRY) || (bp->retries >= AU_RETRIES)) { /* reuse the buffer */ - err ("control read: transmission error %d, can not retry", status); + err ("control read: transmission error %d, can not retry", urb->status); auerbuf_releasebuf (bp); /* Wake up all processes waiting for a buffer */ wake_up (&cp->bufferwait); @@ -978,13 +974,12 @@ static void auerswald_int_complete (struct urb * urb) unsigned int channelid; unsigned int bytecount; int ret; - int status = urb->status; pauerbuf_t bp = NULL; pauerswald_t cp = (pauerswald_t) urb->context; dbg ("%s called", __FUNCTION__); - switch (status) { + switch (urb->status) { case 0: /* success */ break; @@ -992,10 +987,10 @@ static void auerswald_int_complete (struct urb * urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, status); + dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); return; default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, status); + dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); goto exit; } diff --git a/trunk/drivers/usb/misc/ftdi-elan.c b/trunk/drivers/usb/misc/ftdi-elan.c index 538b535e955b..e0f122e131d7 100644 --- a/trunk/drivers/usb/misc/ftdi-elan.c +++ b/trunk/drivers/usb/misc/ftdi-elan.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -65,7 +64,7 @@ static struct workqueue_struct *respond_queue; * ftdi_module_lock exists to protect access to global variables * */ -static struct mutex ftdi_module_lock; +static struct semaphore ftdi_module_lock; static int ftdi_instances = 0; static struct list_head ftdi_static_list; /* @@ -200,10 +199,10 @@ static void ftdi_elan_delete(struct kref *kref) dev_warn(&ftdi->udev->dev, "FREEING ftdi=%p\n", ftdi); usb_put_dev(ftdi->udev); ftdi->disconnected += 1; - mutex_lock(&ftdi_module_lock); + down(&ftdi_module_lock); list_del_init(&ftdi->ftdi_list); ftdi_instances -= 1; - mutex_unlock(&ftdi_module_lock); + up(&ftdi_module_lock); kfree(ftdi->bulk_in_buffer); ftdi->bulk_in_buffer = NULL; } @@ -747,12 +746,10 @@ static ssize_t ftdi_elan_read(struct file *file, char __user *buffer, static void ftdi_elan_write_bulk_callback(struct urb *urb) { struct usb_ftdi *ftdi = (struct usb_ftdi *)urb->context; - int status = urb->status; - - if (status && !(status == -ENOENT || status == -ECONNRESET || - status == -ESHUTDOWN)) { + if (urb->status && !(urb->status == -ENOENT || urb->status == + -ECONNRESET || urb->status == -ESHUTDOWN)) { dev_err(&ftdi->udev->dev, "urb=%p write bulk status received: %" - "d\n", urb, status); + "d\n", urb, urb->status); } usb_buffer_free(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma); @@ -2783,10 +2780,10 @@ static int ftdi_elan_probe(struct usb_interface *interface, return -ENOMEM; } memset(ftdi, 0x00, sizeof(struct usb_ftdi)); - mutex_lock(&ftdi_module_lock); + down(&ftdi_module_lock); list_add_tail(&ftdi->ftdi_list, &ftdi_static_list); ftdi->sequence_num = ++ftdi_instances; - mutex_unlock(&ftdi_module_lock); + up(&ftdi_module_lock); ftdi_elan_init_kref(ftdi); init_MUTEX(&ftdi->sw_lock); ftdi->udev = usb_get_dev(interface_to_usbdev(interface)); @@ -2912,7 +2909,7 @@ static int __init ftdi_elan_init(void) int result; printk(KERN_INFO "driver %s built at %s on %s\n", ftdi_elan_driver.name, __TIME__, __DATE__); - mutex_init(&ftdi_module_lock); + init_MUTEX(&ftdi_module_lock); INIT_LIST_HEAD(&ftdi_static_list); status_queue = create_singlethread_workqueue("ftdi-status-control"); if (!status_queue) diff --git a/trunk/drivers/usb/misc/iowarrior.c b/trunk/drivers/usb/misc/iowarrior.c index 46d9f27ec173..28548d186712 100644 --- a/trunk/drivers/usb/misc/iowarrior.c +++ b/trunk/drivers/usb/misc/iowarrior.c @@ -158,10 +158,9 @@ static void iowarrior_callback(struct urb *urb) int read_idx; int aux_idx; int offset; - int status = urb->status; - int retval; + int status; - switch (status) { + switch (urb->status) { case 0: /* success */ break; @@ -214,10 +213,10 @@ static void iowarrior_callback(struct urb *urb) wake_up_interruptible(&dev->read_wait); exit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status) dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); + __FUNCTION__, status); } @@ -227,15 +226,13 @@ static void iowarrior_callback(struct urb *urb) static void iowarrior_write_callback(struct urb *urb) { struct iowarrior *dev; - int status = urb->status; - dev = (struct iowarrior *)urb->context; /* sync/async unlink faults aren't errors */ - if (status && - !(status == -ENOENT || - status == -ECONNRESET || status == -ESHUTDOWN)) { + if (urb->status && + !(urb->status == -ENOENT || + urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) { dbg("%s - nonzero write bulk status received: %d", - __func__, status); + __func__, urb->status); } /* free up our allocated buffer */ usb_buffer_free(urb->dev, urb->transfer_buffer_length, diff --git a/trunk/drivers/usb/misc/ldusb.c b/trunk/drivers/usb/misc/ldusb.c index 8208496dfc63..5e950b90c541 100644 --- a/trunk/drivers/usb/misc/ldusb.c +++ b/trunk/drivers/usb/misc/ldusb.c @@ -219,17 +219,16 @@ static void ld_usb_interrupt_in_callback(struct urb *urb) struct ld_usb *dev = urb->context; size_t *actual_buffer; unsigned int next_ring_head; - int status = urb->status; int retval; - if (status) { - if (status == -ENOENT || - status == -ECONNRESET || - status == -ESHUTDOWN) { + if (urb->status) { + if (urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN) { goto exit; } else { dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n", - __FUNCTION__, status); + __FUNCTION__, urb->status); spin_lock(&dev->rbsl); goto resubmit; /* maybe we can recover */ } @@ -276,15 +275,14 @@ static void ld_usb_interrupt_in_callback(struct urb *urb) static void ld_usb_interrupt_out_callback(struct urb *urb) { struct ld_usb *dev = urb->context; - int status = urb->status; /* sync/async unlink faults aren't errors */ - if (status && !(status == -ENOENT || - status == -ECONNRESET || - status == -ESHUTDOWN)) + if (urb->status && !(urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN)) dbg_info(&dev->intf->dev, "%s - nonzero write interrupt status received: %d\n", - __FUNCTION__, status); + __FUNCTION__, urb->status); dev->interrupt_out_busy = 0; wake_up_interruptible(&dev->write_wait); diff --git a/trunk/drivers/usb/misc/legousbtower.c b/trunk/drivers/usb/misc/legousbtower.c index 561970b889a5..2ed0daea894c 100644 --- a/trunk/drivers/usb/misc/legousbtower.c +++ b/trunk/drivers/usb/misc/legousbtower.c @@ -742,20 +742,19 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t static void tower_interrupt_in_callback (struct urb *urb) { struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; - int status = urb->status; int retval; - dbg(4, "%s: enter, status %d", __FUNCTION__, status); + dbg(4, "%s: enter, status %d", __FUNCTION__, urb->status); lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); - if (status) { - if (status == -ENOENT || - status == -ECONNRESET || - status == -ESHUTDOWN) { + if (urb->status) { + if (urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN) { goto exit; } else { - dbg(1, "%s: nonzero status received: %d", __FUNCTION__, status); + dbg(1, "%s: nonzero status received: %d", __FUNCTION__, urb->status); goto resubmit; /* maybe we can recover */ } } @@ -789,7 +788,7 @@ static void tower_interrupt_in_callback (struct urb *urb) wake_up_interruptible (&dev->read_wait); lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); - dbg(4, "%s: leave, status %d", __FUNCTION__, status); + dbg(4, "%s: leave, status %d", __FUNCTION__, urb->status); } @@ -799,24 +798,23 @@ static void tower_interrupt_in_callback (struct urb *urb) static void tower_interrupt_out_callback (struct urb *urb) { struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; - int status = urb->status; - dbg(4, "%s: enter, status %d", __FUNCTION__, status); + dbg(4, "%s: enter, status %d", __FUNCTION__, urb->status); lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); /* sync/async unlink faults aren't errors */ - if (status && !(status == -ENOENT || - status == -ECONNRESET || - status == -ESHUTDOWN)) { + if (urb->status && !(urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN)) { dbg(1, "%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __FUNCTION__, urb->status); } dev->interrupt_out_busy = 0; wake_up_interruptible(&dev->write_wait); lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); - dbg(4, "%s: leave, status %d", __FUNCTION__, status); + dbg(4, "%s: leave, status %d", __FUNCTION__, urb->status); } diff --git a/trunk/drivers/usb/misc/phidgetkit.c b/trunk/drivers/usb/misc/phidgetkit.c index aa9bcceabe74..371bf2b1197d 100644 --- a/trunk/drivers/usb/misc/phidgetkit.c +++ b/trunk/drivers/usb/misc/phidgetkit.c @@ -305,10 +305,9 @@ static void interfacekit_irq(struct urb *urb) struct interfacekit *kit = urb->context; unsigned char *buffer = kit->data; int i, level, sensor; - int retval; - int status = urb->status; + int status; - switch (status) { + switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: /* unlink */ @@ -378,11 +377,11 @@ static void interfacekit_irq(struct urb *urb) schedule_delayed_work(&kit->do_notify, 0); resubmit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - err("can't resubmit intr, %s-%s/interfacekit0, retval %d", + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status) + err("can't resubmit intr, %s-%s/interfacekit0, status %d", kit->udev->bus->bus_name, - kit->udev->devpath, retval); + kit->udev->devpath, status); } static void do_notify(struct work_struct *work) diff --git a/trunk/drivers/usb/misc/phidgetmotorcontrol.c b/trunk/drivers/usb/misc/phidgetmotorcontrol.c index df0ebcdb9d6a..5727e1ea2f91 100644 --- a/trunk/drivers/usb/misc/phidgetmotorcontrol.c +++ b/trunk/drivers/usb/misc/phidgetmotorcontrol.c @@ -95,10 +95,9 @@ static void motorcontrol_irq(struct urb *urb) struct motorcontrol *mc = urb->context; unsigned char *buffer = mc->data; int i, level; - int retval; - int status = urb->status;; + int status; - switch (status) { + switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: /* unlink */ @@ -152,12 +151,12 @@ static void motorcontrol_irq(struct urb *urb) schedule_delayed_work(&mc->do_notify, 0); resubmit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status) dev_err(&mc->intf->dev, - "can't resubmit intr, %s-%s/motorcontrol0, retval %d", + "can't resubmit intr, %s-%s/motorcontrol0, status %d", mc->udev->bus->bus_name, - mc->udev->devpath, retval); + mc->udev->devpath, status); } static void do_notify(struct work_struct *work) diff --git a/trunk/drivers/usb/misc/usblcd.c b/trunk/drivers/usb/misc/usblcd.c index 719842032712..504f7221b0d0 100644 --- a/trunk/drivers/usb/misc/usblcd.c +++ b/trunk/drivers/usb/misc/usblcd.c @@ -176,17 +176,16 @@ static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u static void lcd_write_bulk_callback(struct urb *urb) { struct usb_lcd *dev; - int status = urb->status; dev = (struct usb_lcd *)urb->context; /* sync/async unlink faults aren't errors */ - if (status && - !(status == -ENOENT || - status == -ECONNRESET || - status == -ESHUTDOWN)) { + if (urb->status && + !(urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN)) { dbg("USBLCD: %s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __FUNCTION__, urb->status); } /* free up our allocated buffer */ diff --git a/trunk/drivers/usb/misc/usbtest.c b/trunk/drivers/usb/misc/usbtest.c index e901d31e051b..fb321864a92d 100644 --- a/trunk/drivers/usb/misc/usbtest.c +++ b/trunk/drivers/usb/misc/usbtest.c @@ -768,8 +768,8 @@ static void ctrl_complete (struct urb *urb) /* some faults are allowed, not required */ if (subcase->expected > 0 && ( - ((status == -subcase->expected /* happened */ - || status == 0)))) /* didn't */ + ((urb->status == -subcase->expected /* happened */ + || urb->status == 0)))) /* didn't */ status = 0; /* sometimes more than one fault is allowed */ else if (subcase->number == 12 && status == -EPIPE) diff --git a/trunk/drivers/usb/misc/uss720.c b/trunk/drivers/usb/misc/uss720.c index 2734fe2b9c43..1a60f9c473ad 100644 --- a/trunk/drivers/usb/misc/uss720.c +++ b/trunk/drivers/usb/misc/uss720.c @@ -111,13 +111,12 @@ static void async_complete(struct urb *urb) struct uss720_async_request *rq; struct parport *pp; struct parport_uss720_private *priv; - int status = urb->status; rq = urb->context; priv = rq->priv; pp = priv->pp; - if (status) { - err("async_complete: urb error %d", status); + if (urb->status) { + err("async_complete: urb error %d", urb->status); } else if (rq->dr.bRequest == 3) { memcpy(priv->reg, rq->reg, sizeof(priv->reg)); #if 0 diff --git a/trunk/drivers/usb/serial/io_ti.c b/trunk/drivers/usb/serial/io_ti.c index b8670905bc3a..0d3903691e8c 100644 --- a/trunk/drivers/usb/serial/io_ti.c +++ b/trunk/drivers/usb/serial/io_ti.c @@ -2794,14 +2794,16 @@ static void edge_shutdown (struct usb_serial *serial) dbg ("%s", __FUNCTION__); - for (i = 0; i < serial->num_ports; ++i) { + for (i=0; i < serial->num_ports; ++i) { edge_port = usb_get_serial_port_data(serial->port[i]); edge_remove_sysfs_attrs(edge_port->port); - edge_buf_free(edge_port->ep_out_buf); - kfree(edge_port); + if (edge_port) { + edge_buf_free(edge_port->ep_out_buf); + kfree(edge_port); + } usb_set_serial_port_data(serial->port[i], NULL); } - kfree(usb_get_serial_data(serial)); + kfree (usb_get_serial_data(serial)); usb_set_serial_data(serial, NULL); } diff --git a/trunk/drivers/usb/serial/mos7720.c b/trunk/drivers/usb/serial/mos7720.c index 01e811becec4..231b584f6d0f 100644 --- a/trunk/drivers/usb/serial/mos7720.c +++ b/trunk/drivers/usb/serial/mos7720.c @@ -110,6 +110,11 @@ static void mos7720_interrupt_callback(struct urb *urb) dbg("%s"," : Entering\n"); + if (!urb) { + dbg("%s","Invalid Pointer !!!!:\n"); + return; + } + switch (status) { case 0: /* success */ diff --git a/trunk/drivers/usb/serial/mos7840.c b/trunk/drivers/usb/serial/mos7840.c index f76480f1455d..37f41f576d3d 100644 --- a/trunk/drivers/usb/serial/mos7840.c +++ b/trunk/drivers/usb/serial/mos7840.c @@ -436,6 +436,11 @@ static void mos7840_control_callback(struct urb *urb) int result = 0; int status = urb->status; + if (!urb) { + dbg("%s", "Invalid Pointer !!!!:\n"); + return; + } + mos7840_port = (struct moschip_port *)urb->context; switch (status) { @@ -520,6 +525,10 @@ static void mos7840_interrupt_callback(struct urb *urb) int status = urb->status; dbg("%s", " : Entering\n"); + if (!urb) { + dbg("%s", "Invalid Pointer !!!!:\n"); + return; + } switch (status) { case 0: @@ -667,6 +676,11 @@ static void mos7840_bulk_in_callback(struct urb *urb) struct tty_struct *tty; int status = urb->status; + if (!urb) { + dbg("%s", "Invalid Pointer !!!!:\n"); + return; + } + if (status) { dbg("nonzero read bulk status received: %d", status); return; @@ -739,6 +753,11 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) int status = urb->status; int i; + if (!urb) { + dbg("%s", "Invalid Pointer !!!!:\n"); + return; + } + mos7840_port = (struct moschip_port *)urb->context; spin_lock(&mos7840_port->pool_lock); for (i = 0; i < NUM_URBS; i++) { diff --git a/trunk/drivers/usb/serial/sierra.c b/trunk/drivers/usb/serial/sierra.c index 0794ccdebfd4..e7db20343d1a 100644 --- a/trunk/drivers/usb/serial/sierra.c +++ b/trunk/drivers/usb/serial/sierra.c @@ -1,7 +1,7 @@ /* USB Driver for Sierra Wireless - Copyright (C) 2006, 2007 Kevin Lloyd + Copyright (C) 2006 Kevin Lloyd IMPORTANT DISCLAIMER: This driver is not commercially supported by Sierra Wireless. Use at your own risk. @@ -12,9 +12,10 @@ Portions based on the option driver by Matthias Urlichs Whom based his on the Keyspan driver by Hugh Blemings + */ -#define DRIVER_VERSION "v.1.2.5b" +#define DRIVER_VERSION "v.1.0.6" #define DRIVER_AUTHOR "Kevin Lloyd " #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" @@ -27,98 +28,23 @@ #include #include -#define SWIMS_USB_REQUEST_SetMode 0x0B -#define SWIMS_USB_REQUEST_TYPE_SetMode 0x40 -#define SWIMS_USB_INDEX_SetMode 0x0000 -#define SWIMS_SET_MODE_Modem 0x0001 - -/* per port private data */ -#define N_IN_URB 4 -#define N_OUT_URB 4 -#define IN_BUFLEN 4096 - -static int debug; - -enum devicetype { - DEVICE_3_PORT = 0, - DEVICE_1_PORT = 1, - DEVICE_INSTALLER = 2, -}; - -int sierra_set_power_state(struct usb_device *udev, __u16 swiState) -{ - int result; - dev_dbg(&udev->dev, "%s", "SET POWER STATE"); - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x00, /* __u8 request */ - 0x40, /* __u8 request type */ - swiState, /* __u16 value */ - 0, /* __u16 index */ - NULL, /* void *data */ - 0, /* __u16 size */ - USB_CTRL_SET_TIMEOUT); /* int timeout */ - return result; -} - -int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode) -{ - int result; - dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH"); - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - SWIMS_USB_REQUEST_SetMode, /* __u8 request */ - SWIMS_USB_REQUEST_TYPE_SetMode, /* __u8 request type */ - eSocMode, /* __u16 value */ - SWIMS_USB_INDEX_SetMode, /* __u16 index */ - NULL, /* void *data */ - 0, /* __u16 size */ - USB_CTRL_SET_TIMEOUT); /* int timeout */ - return result; -} - -int sierra_probe(struct usb_interface *iface, const struct usb_device_id *id) -{ - int result; - struct usb_device *udev; - - udev = usb_get_dev(interface_to_usbdev(iface)); - - /* Check if in installer mode */ - if (id->driver_info == DEVICE_INSTALLER) { - dev_dbg(&udev->dev, "%s", "FOUND DEVICE(SW)\n"); - result = sierra_set_ms_mode(udev, SWIMS_SET_MODE_Modem); - /*We do not want to bind to the device when in installer mode*/ - return -EIO; - } - - return usb_serial_probe(iface, id); -} static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ - { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ + { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */ { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ - { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ - { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ - { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ + { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ - { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ - { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ - { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ - { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ - { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ - { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */ - - { USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */ - { USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */ - { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER}, + { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ + { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */ { } }; MODULE_DEVICE_TABLE(usb, id_table); @@ -132,36 +58,35 @@ static struct usb_device_id id_table_1port [] = { static struct usb_device_id id_table_3port [] = { { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ - { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ + { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */ { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ - { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U*/ - { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ - { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ + { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ - { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ - { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ - { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ - { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ - { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880E */ - { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881E */ { } }; static struct usb_driver sierra_driver = { .name = "sierra", - .probe = sierra_probe, + .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, .id_table = id_table, .no_dynamic_id = 1, }; +static int debug; + +/* per port private data */ +#define N_IN_URB 4 +#define N_OUT_URB 4 +#define IN_BUFLEN 4096 + struct sierra_port_private { spinlock_t lock; /* lock the structure */ int outstanding_urbs; /* number of out urbs in flight */ @@ -496,6 +421,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) int i; struct urb *urb; int result; + __u16 set_mode_dzero = 0x0000; portdata = usb_get_serial_port_data(port); @@ -531,6 +457,12 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) port->tty->low_latency = 1; + /* set mode to D0 */ + result = usb_control_msg(serial->dev, + usb_rcvctrlpipe(serial->dev, 0), + 0x00, 0x40, set_mode_dzero, 0, NULL, + 0, USB_CTRL_SET_TIMEOUT); + sierra_send_setup(port); /* start up the interrupt endpoint if we have one */ @@ -578,9 +510,6 @@ static int sierra_startup(struct usb_serial *serial) dbg("%s", __FUNCTION__); - /*Set Device mode to D0 */ - sierra_set_power_state(serial->dev, 0x0000); - /* Now setup per port private data */ for (i = 0; i < serial->num_ports; i++) { port = serial->port[i]; diff --git a/trunk/drivers/usb/storage/dpcm.c b/trunk/drivers/usb/storage/dpcm.c index 9a410b5a6e5b..1628cb258562 100644 --- a/trunk/drivers/usb/storage/dpcm.c +++ b/trunk/drivers/usb/storage/dpcm.c @@ -46,43 +46,43 @@ */ int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) { - int ret; + int ret; - if (srb == NULL) - return USB_STOR_TRANSPORT_ERROR; + if(srb == NULL) + return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("dpcm_transport: LUN=%d\n", srb->device->lun); + US_DEBUGP("dpcm_transport: LUN=%d\n", srb->device->lun); - switch (srb->device->lun) { - case 0: + switch(srb->device->lun) { + case 0: - /* - * LUN 0 corresponds to the CompactFlash card reader. - */ - ret = usb_stor_CB_transport(srb, us); - break; + /* + * LUN 0 corresponds to the CompactFlash card reader. + */ + ret = usb_stor_CB_transport(srb, us); + break; #ifdef CONFIG_USB_STORAGE_SDDR09 - case 1: + case 1: - /* - * LUN 1 corresponds to the SmartMedia card reader. - */ + /* + * LUN 1 corresponds to the SmartMedia card reader. + */ - /* - * Set the LUN to 0 (just in case). - */ - srb->device->lun = 0; us->srb->device->lun = 0; - ret = sddr09_transport(srb, us); - srb->device->lun = 1; us->srb->device->lun = 1; - break; + /* + * Set the LUN to 0 (just in case). + */ + srb->device->lun = 0; us->srb->device->lun = 0; + ret = sddr09_transport(srb, us); + srb->device->lun = 1; us->srb->device->lun = 1; + break; #endif - default: - US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->device->lun); - ret = USB_STOR_TRANSPORT_ERROR; - break; - } - return ret; + default: + US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->device->lun); + ret = USB_STOR_TRANSPORT_ERROR; + break; + } + return ret; } diff --git a/trunk/drivers/usb/storage/onetouch.c b/trunk/drivers/usb/storage/onetouch.c index dfd42fe9e5f0..d35369392fed 100644 --- a/trunk/drivers/usb/storage/onetouch.c +++ b/trunk/drivers/usb/storage/onetouch.c @@ -57,10 +57,9 @@ static void usb_onetouch_irq(struct urb *urb) struct usb_onetouch *onetouch = urb->context; signed char *data = onetouch->data; struct input_dev *dev = onetouch->dev; - int status = urb->status; - int retval; + int status; - switch (status) { + switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: /* unlink */ @@ -76,11 +75,11 @@ static void usb_onetouch_irq(struct urb *urb) input_sync(dev); resubmit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("can't resubmit intr, %s-%s/input0, retval %d", + status = usb_submit_urb (urb, GFP_ATOMIC); + if (status) + err ("can't resubmit intr, %s-%s/input0, status %d", onetouch->udev->bus->bus_name, - onetouch->udev->devpath, retval); + onetouch->udev->devpath, status); } static int usb_onetouch_open(struct input_dev *dev) diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index a624e72f81dc..b6bf31a97b60 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -313,13 +313,6 @@ UNUSUAL_DEV( 0x04b0, 0x0301, 0x0010, 0x0010, US_SC_DEVICE, US_PR_DEVICE,NULL, US_FL_NOT_LOCKABLE ), -/* Reported by Stefan de Konink */ -UNUSUAL_DEV( 0x04b0, 0x0401, 0x0200, 0x0200, - "NIKON", - "NIKON DSC D100", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - /* Reported by Andreas Bockhold */ UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, "NIKON", @@ -1391,17 +1384,6 @@ UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110, US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, 0 ), -/* Reported by Kevin Lloyd - * Entry is needed for the initializer function override, - * which instructs the device to load as a modem - * device. - */ -UNUSUAL_DEV( 0x1199, 0x0fff, 0x0000, 0x9999, - "Sierra Wireless", - "USB MMC Storage", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_DEVICE), - /* Reported by Jaco Kroon * The usb-storage module found on the Digitech GNX4 (and supposedly other * devices) misbehaves and causes a bunch of invalid I/O errors. diff --git a/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index 13990697b5c1..0c7bf75732ea 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -2913,6 +2913,10 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, int node, len, i, j, ret; u32 mem, chip_id; + /* Do not attach when we have a serial console. */ + if (!con_is_present()) + return -ENXIO; + /* * Map memory-mapped registers. */ diff --git a/trunk/drivers/video/backlight/cr_bllcd.c b/trunk/drivers/video/backlight/cr_bllcd.c index 1b3f6586bc9f..e9bbc3455c94 100644 --- a/trunk/drivers/video/backlight/cr_bllcd.c +++ b/trunk/drivers/video/backlight/cr_bllcd.c @@ -174,7 +174,7 @@ static int cr_backlight_probe(struct platform_device *pdev) struct cr_panel *crp; u8 dev_en; - crp = kzalloc(sizeof(*crp), GFP_KERNEL); + crp = kzalloc(sizeof(crp), GFP_KERNEL); if (crp == NULL) return -ENOMEM; diff --git a/trunk/drivers/video/igafb.c b/trunk/drivers/video/igafb.c index b87ea21d3d78..eb1a4812ad1d 100644 --- a/trunk/drivers/video/igafb.c +++ b/trunk/drivers/video/igafb.c @@ -379,6 +379,10 @@ int __init igafb_init(void) if (fb_get_options("igafb", NULL)) return -ENODEV; + /* Do not attach when we have a serial console. */ + if (!con_is_present()) + return -ENXIO; + pdev = pci_get_device(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682, 0); if (pdev == NULL) { diff --git a/trunk/fs/afs/rxrpc.c b/trunk/fs/afs/rxrpc.c index 8ccee9ee1d9d..1b36f45076ad 100644 --- a/trunk/fs/afs/rxrpc.c +++ b/trunk/fs/afs/rxrpc.c @@ -792,7 +792,6 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len) { struct msghdr msg; struct iovec iov[1]; - int n; _enter(""); @@ -807,20 +806,22 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len) msg.msg_flags = 0; call->state = AFS_CALL_AWAIT_ACK; - n = rxrpc_kernel_send_data(call->rxcall, &msg, len); - if (n >= 0) { + switch (rxrpc_kernel_send_data(call->rxcall, &msg, len)) { + case 0: _leave(" [replied]"); return; - } - if (n == -ENOMEM) { + + case -ENOMEM: _debug("oom"); rxrpc_kernel_abort_call(call->rxcall, RX_USER_ABORT); + default: + rxrpc_kernel_end_call(call->rxcall); + call->rxcall = NULL; + call->type->destructor(call); + afs_free_call(call); + _leave(" [error]"); + return; } - rxrpc_kernel_end_call(call->rxcall); - call->rxcall = NULL; - call->type->destructor(call); - afs_free_call(call); - _leave(" [error]"); } /* diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index 0e5ec371ce72..02ebb1f1d3b0 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -2221,7 +2221,7 @@ block_page_mkwrite(struct vm_area_struct *vma, struct page *page, lock_page(page); size = i_size_read(inode); if ((page->mapping != inode->i_mapping) || - (page_offset(page) > size)) { + ((page->index << PAGE_CACHE_SHIFT) > size)) { /* page got truncated out from underneath us */ goto out_unlock; } diff --git a/trunk/fs/ecryptfs/mmap.c b/trunk/fs/ecryptfs/mmap.c index e4ab7bc14efe..7d5a43cb0d5c 100644 --- a/trunk/fs/ecryptfs/mmap.c +++ b/trunk/fs/ecryptfs/mmap.c @@ -409,7 +409,8 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, if (!PageUptodate(page)) rc = ecryptfs_do_readpage(file, page, page->index); if (page->index != 0) { - loff_t end_of_prev_pg_pos = page_offset(page) - 1; + loff_t end_of_prev_pg_pos = + (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1); if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) { rc = ecryptfs_truncate(file->f_path.dentry, @@ -735,7 +736,7 @@ static int ecryptfs_commit_write(struct file *file, struct page *page, goto out; } inode->i_blocks = lower_inode->i_blocks; - pos = page_offset(page) + to; + pos = (page->index << PAGE_CACHE_SHIFT) + to; if (pos > i_size_read(inode)) { i_size_write(inode, pos); ecryptfs_printk(KERN_DEBUG, "Expanded file size to " diff --git a/trunk/fs/ocfs2/mmap.c b/trunk/fs/ocfs2/mmap.c index 98756156d298..ee64749e2eeb 100644 --- a/trunk/fs/ocfs2/mmap.c +++ b/trunk/fs/ocfs2/mmap.c @@ -89,7 +89,7 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, { int ret; struct address_space *mapping = inode->i_mapping; - loff_t pos = page_offset(page); + loff_t pos = page->index << PAGE_CACHE_SHIFT; unsigned int len = PAGE_CACHE_SIZE; pgoff_t last_index; struct page *locked_page = NULL; diff --git a/trunk/fs/splice.c b/trunk/fs/splice.c index 0a0973218084..22496d2a73fa 100644 --- a/trunk/fs/splice.c +++ b/trunk/fs/splice.c @@ -594,7 +594,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, ret = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL); if (unlikely(ret)) - goto out_release; + goto out; } ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); @@ -650,9 +650,8 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, */ mark_page_accessed(page); out: - unlock_page(page); -out_release: page_cache_release(page); + unlock_page(page); out_ret: return ret; } diff --git a/trunk/include/asm-ia64/hw_irq.h b/trunk/include/asm-ia64/hw_irq.h index efa1b8f7251d..c054d7a9aaa7 100644 --- a/trunk/include/asm-ia64/hw_irq.h +++ b/trunk/include/asm-ia64/hw_irq.h @@ -90,27 +90,13 @@ enum { extern __u8 isa_irq_to_vector_map[16]; #define isa_irq_to_vector(x) isa_irq_to_vector_map[(x)] -struct irq_cfg { - ia64_vector vector; - cpumask_t domain; -}; -extern spinlock_t vector_lock; -extern struct irq_cfg irq_cfg[NR_IRQS]; -#define irq_to_domain(x) irq_cfg[(x)].domain -DECLARE_PER_CPU(int[IA64_NUM_VECTORS], vector_irq); - extern struct hw_interrupt_type irq_type_ia64_lsapic; /* CPU-internal interrupt controller */ -extern int bind_irq_vector(int irq, int vector, cpumask_t domain); extern int assign_irq_vector (int irq); /* allocate a free vector */ extern void free_irq_vector (int vector); extern int reserve_irq_vector (int vector); -extern void __setup_vector_irq(int cpu); -extern int reassign_irq_vector(int irq, int cpu); extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); -extern int check_irq_used (int irq); -extern void destroy_and_reserve_irq (unsigned int irq); static inline void ia64_resend_irq(unsigned int vector) { @@ -127,7 +113,7 @@ extern irq_desc_t irq_desc[NR_IRQS]; static inline unsigned int __ia64_local_vector_to_irq (ia64_vector vec) { - return __get_cpu_var(vector_irq)[vec]; + return (unsigned int) vec; } #endif @@ -145,7 +131,7 @@ __ia64_local_vector_to_irq (ia64_vector vec) static inline ia64_vector irq_to_vector (int irq) { - return irq_cfg[irq].vector; + return (ia64_vector) irq; } /* diff --git a/trunk/include/asm-ia64/iosapic.h b/trunk/include/asm-ia64/iosapic.h index b8f712859140..421cb6b62a7c 100644 --- a/trunk/include/asm-ia64/iosapic.h +++ b/trunk/include/asm-ia64/iosapic.h @@ -47,21 +47,19 @@ #define IOSAPIC_MASK_SHIFT 16 #define IOSAPIC_MASK (1< #include -#define NR_VECTORS 256 - -#if (NR_VECTORS + 32 * NR_CPUS) < 1024 -#define NR_IRQS (NR_VECTORS + 32 * NR_CPUS) -#else -#define NR_IRQS 1024 -#endif +#define NR_IRQS 256 +#define NR_IRQ_VECTORS NR_IRQS static __inline__ int irq_canonicalize (int irq) diff --git a/trunk/include/asm-ia64/rwsem.h b/trunk/include/asm-ia64/rwsem.h index 8aba06a7b038..2d1640cc240a 100644 --- a/trunk/include/asm-ia64/rwsem.h +++ b/trunk/include/asm-ia64/rwsem.h @@ -21,10 +21,6 @@ #ifndef _ASM_IA64_RWSEM_H #define _ASM_IA64_RWSEM_H -#ifndef _LINUX_RWSEM_H -#error "Please don't include directly, use instead." -#endif - #include #include diff --git a/trunk/include/asm-ia64/unistd.h b/trunk/include/asm-ia64/unistd.h index 315f8de950a2..441c9e001776 100644 --- a/trunk/include/asm-ia64/unistd.h +++ b/trunk/include/asm-ia64/unistd.h @@ -292,7 +292,7 @@ #define __NR_sync_file_range 1300 #define __NR_tee 1301 #define __NR_vmsplice 1302 -#define __NR_fallocate 1303 +/* 1303 reserved for move_pages */ #define __NR_getcpu 1304 #define __NR_epoll_pwait 1305 #define __NR_utimensat 1306 diff --git a/trunk/include/asm-m68k/io.h b/trunk/include/asm-m68k/io.h index 47bb9cf107b7..5e0fcf41804d 100644 --- a/trunk/include/asm-m68k/io.h +++ b/trunk/include/asm-m68k/io.h @@ -27,7 +27,6 @@ #include #include -#include #ifdef CONFIG_ATARI #include @@ -153,16 +152,6 @@ static inline u16 __iomem *isa_itw(unsigned long addr) default: return NULL; /* avoid warnings, just in case */ } } -static inline u32 __iomem *isa_itl(unsigned long addr) -{ - switch(ISA_TYPE) - { -#ifdef CONFIG_AMIGA_PCMCIA - case AG_ISA: return (u32 __iomem *)AG_ISA_IO_W(addr); -#endif - default: return 0; /* avoid warnings, just in case */ - } -} static inline u8 __iomem *isa_mtb(unsigned long addr) { switch(ISA_TYPE) @@ -199,10 +188,8 @@ static inline u16 __iomem *isa_mtw(unsigned long addr) #define isa_inb(port) in_8(isa_itb(port)) #define isa_inw(port) (ISA_SEX ? in_be16(isa_itw(port)) : in_le16(isa_itw(port))) -#define isa_inl(port) (ISA_SEX ? in_be32(isa_itl(port)) : in_le32(isa_itl(port))) #define isa_outb(val,port) out_8(isa_itb(port),(val)) #define isa_outw(val,port) (ISA_SEX ? out_be16(isa_itw(port),(val)) : out_le16(isa_itw(port),(val))) -#define isa_outl(val,port) (ISA_SEX ? out_be32(isa_itl(port),(val)) : out_le32(isa_itl(port),(val))) #define isa_readb(p) in_8(isa_mtb((unsigned long)(p))) #define isa_readw(p) \ @@ -247,15 +234,6 @@ static inline void isa_delay(void) #define isa_outsw(port, buf, nr) \ (ISA_SEX ? raw_outsw(isa_itw(port), (u16 *)(buf), (nr)) : \ raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr))) - -#define isa_insl(port, buf, nr) \ - (ISA_SEX ? raw_insl(isa_itl(port), (u32 *)(buf), (nr)) : \ - raw_insw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1)) - -#define isa_outsl(port, buf, nr) \ - (ISA_SEX ? raw_outsl(isa_itl(port), (u32 *)(buf), (nr)) : \ - raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1)) - #endif /* CONFIG_ISA */ @@ -268,16 +246,14 @@ static inline void isa_delay(void) #define inw_p isa_inw_p #define outw isa_outw #define outw_p isa_outw_p -#define inl isa_inl -#define inl_p isa_inl_p -#define outl isa_outl -#define outl_p isa_outl_p +#define inl isa_inw +#define inl_p isa_inw_p +#define outl isa_outw +#define outl_p isa_outw_p #define insb isa_insb #define insw isa_insw -#define insl isa_insl #define outsb isa_outsb #define outsw isa_outsw -#define outsl isa_outsl #define readb isa_readb #define readw isa_readw #define writeb isa_writeb @@ -286,6 +262,8 @@ static inline void isa_delay(void) #if defined(CONFIG_PCI) +#define inl(port) in_le32(port) +#define outl(val,port) out_le32((port),(val)) #define readl(addr) in_le32(addr) #define writel(val,addr) out_le32((addr),(val)) @@ -304,8 +282,6 @@ static inline void isa_delay(void) #define outb(val,port) out_8((port),(val)) #define inw(port) in_le16(port) #define outw(val,port) out_le16((port),(val)) -#define inl(port) in_le32(port) -#define outl(val,port) out_le32((port),(val)) #else /* @@ -330,35 +306,20 @@ static inline void isa_delay(void) #endif #endif /* CONFIG_PCI */ -#if !defined(CONFIG_ISA) && !defined(CONFIG_PCI) +#if !defined(CONFIG_ISA) && !defined(CONFIG_PCI) && defined(CONFIG_HP300) /* - * We need to define dummy functions for GENERIC_IOMAP support. + * We need to define dummy functions otherwise drivers/serial/8250.c doesn't link */ -#define inb(port) 0xff -#define inb_p(port) 0xff -#define outb(val,port) ((void)0) -#define outb_p(val,port) ((void)0) -#define inw(port) 0xffff -#define outw(val,port) ((void)0) -#define inl(port) 0xffffffffUL -#define outl(val,port) ((void)0) - -#define insb(port,buf,nr) ((void)0) -#define outsb(port,buf,nr) ((void)0) -#define insw(port,buf,nr) ((void)0) -#define outsw(port,buf,nr) ((void)0) -#define insl(port,buf,nr) ((void)0) -#define outsl(port,buf,nr) ((void)0) +#define inb(port) 0xff +#define inb_p(port) 0xff +#define outb(val,port) do { } while (0) +#define outb_p(val,port) do { } while (0) /* * These should be valid on any ioremap()ed region */ #define readb(addr) in_8(addr) #define writeb(val,addr) out_8((addr),(val)) -#define readw(addr) in_le16(addr) -#define writew(val,addr) out_le16((addr),(val)) -#endif -#if !defined(CONFIG_PCI) #define readl(addr) in_le32(addr) #define writel(val,addr) out_le32((addr),(val)) #endif @@ -390,18 +351,6 @@ extern void dma_cache_wback_inv(unsigned long start, unsigned long size); extern void dma_cache_wback(unsigned long start, unsigned long size); extern void dma_cache_inv(unsigned long start, unsigned long size); -static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count) -{ - __builtin_memset((void __force *) addr, val, count); -} -static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count) -{ - __builtin_memcpy(dst, (void __force *) src, count); -} -static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count) -{ - __builtin_memcpy((void __force *) dst, src, count); -} #ifndef CONFIG_SUN3 #define IO_SPACE_LIMIT 0xffff diff --git a/trunk/include/asm-m68k/raw_io.h b/trunk/include/asm-m68k/raw_io.h index 91c623f0994c..811ccd25d4a6 100644 --- a/trunk/include/asm-m68k/raw_io.h +++ b/trunk/include/asm-m68k/raw_io.h @@ -49,16 +49,10 @@ extern void __iounmap(void *addr, unsigned long size); #define raw_inb in_8 #define raw_inw in_be16 #define raw_inl in_be32 -#define __raw_readb in_8 -#define __raw_readw in_be16 -#define __raw_readl in_be32 #define raw_outb(val,port) out_8((port),(val)) #define raw_outw(val,port) out_be16((port),(val)) #define raw_outl(val,port) out_be32((port),(val)) -#define __raw_writeb(val,addr) out_8((addr),(val)) -#define __raw_writew(val,addr) out_be16((addr),(val)) -#define __raw_writel(val,addr) out_be32((addr),(val)) static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len) { @@ -342,6 +336,8 @@ static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf, : "d0", "a0", "a1", "d6"); } +#define __raw_writel raw_outl + #endif /* __KERNEL__ */ #endif /* _RAW_IO_H */ diff --git a/trunk/include/asm-mips/atomic.h b/trunk/include/asm-mips/atomic.h index 7d8003769a44..1b60624dab7e 100644 --- a/trunk/include/asm-mips/atomic.h +++ b/trunk/include/asm-mips/atomic.h @@ -138,7 +138,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v) { unsigned long result; - smp_llsc_mb(); + smp_mb(); if (cpu_has_llsc && R10000_LLSC_WAR) { unsigned long temp; @@ -181,7 +181,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v) raw_local_irq_restore(flags); } - smp_llsc_mb(); + smp_mb(); return result; } @@ -190,7 +190,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) { unsigned long result; - smp_llsc_mb(); + smp_mb(); if (cpu_has_llsc && R10000_LLSC_WAR) { unsigned long temp; @@ -233,7 +233,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) raw_local_irq_restore(flags); } - smp_llsc_mb(); + smp_mb(); return result; } @@ -250,7 +250,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) { unsigned long result; - smp_llsc_mb(); + smp_mb(); if (cpu_has_llsc && R10000_LLSC_WAR) { unsigned long temp; @@ -302,7 +302,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) raw_local_irq_restore(flags); } - smp_llsc_mb(); + smp_mb(); return result; } @@ -519,7 +519,7 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v) { unsigned long result; - smp_llsc_mb(); + smp_mb(); if (cpu_has_llsc && R10000_LLSC_WAR) { unsigned long temp; @@ -562,7 +562,7 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v) raw_local_irq_restore(flags); } - smp_llsc_mb(); + smp_mb(); return result; } @@ -571,7 +571,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) { unsigned long result; - smp_llsc_mb(); + smp_mb(); if (cpu_has_llsc && R10000_LLSC_WAR) { unsigned long temp; @@ -614,7 +614,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) raw_local_irq_restore(flags); } - smp_llsc_mb(); + smp_mb(); return result; } @@ -631,7 +631,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) { unsigned long result; - smp_llsc_mb(); + smp_mb(); if (cpu_has_llsc && R10000_LLSC_WAR) { unsigned long temp; @@ -683,7 +683,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) raw_local_irq_restore(flags); } - smp_llsc_mb(); + smp_mb(); return result; } @@ -791,11 +791,10 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) * atomic*_return operations are serializing but not the non-*_return * versions. */ -#define smp_mb__before_atomic_dec() smp_llsc_mb() -#define smp_mb__after_atomic_dec() smp_llsc_mb() -#define smp_mb__before_atomic_inc() smp_llsc_mb() -#define smp_mb__after_atomic_inc() smp_llsc_mb() +#define smp_mb__before_atomic_dec() smp_mb() +#define smp_mb__after_atomic_dec() smp_mb() +#define smp_mb__before_atomic_inc() smp_mb() +#define smp_mb__after_atomic_inc() smp_mb() #include - #endif /* _ASM_ATOMIC_H */ diff --git a/trunk/include/asm-mips/barrier.h b/trunk/include/asm-mips/barrier.h index 9d8cfbb5e796..ed82631b0017 100644 --- a/trunk/include/asm-mips/barrier.h +++ b/trunk/include/asm-mips/barrier.h @@ -121,11 +121,6 @@ #else #define __WEAK_ORDERING_MB " \n" #endif -#if defined(CONFIG_WEAK_REORDERING_BEYOND_LLSC) && defined(CONFIG_SMP) -#define __WEAK_LLSC_MB " sync \n" -#else -#define __WEAK_LLSC_MB " \n" -#endif #define smp_mb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory") #define smp_rmb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory") @@ -134,8 +129,4 @@ #define set_mb(var, value) \ do { var = value; smp_mb(); } while (0) -#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") -#define smp_llsc_rmb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") -#define smp_llsc_wmb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") - #endif /* __ASM_BARRIER_H */ diff --git a/trunk/include/asm-mips/bitops.h b/trunk/include/asm-mips/bitops.h index 148bc79557f1..d9e81af53f78 100644 --- a/trunk/include/asm-mips/bitops.h +++ b/trunk/include/asm-mips/bitops.h @@ -38,8 +38,8 @@ /* * clear_bit() doesn't provide any barrier for the compiler. */ -#define smp_mb__before_clear_bit() smp_llsc_mb() -#define smp_mb__after_clear_bit() smp_llsc_mb() +#define smp_mb__before_clear_bit() smp_mb() +#define smp_mb__after_clear_bit() smp_mb() /* * set_bit - Atomically set a bit in memory @@ -289,7 +289,7 @@ static inline int test_and_set_bit(unsigned long nr, raw_local_irq_restore(flags); } - smp_llsc_mb(); + smp_mb(); return res != 0; } @@ -377,7 +377,7 @@ static inline int test_and_clear_bit(unsigned long nr, raw_local_irq_restore(flags); } - smp_llsc_mb(); + smp_mb(); return res != 0; } @@ -445,7 +445,7 @@ static inline int test_and_change_bit(unsigned long nr, raw_local_irq_restore(flags); } - smp_llsc_mb(); + smp_mb(); return res != 0; } diff --git a/trunk/include/asm-mips/ds1216.h b/trunk/include/asm-mips/ds1216.h new file mode 100644 index 000000000000..1ff8b73f7a6a --- /dev/null +++ b/trunk/include/asm-mips/ds1216.h @@ -0,0 +1,31 @@ +#ifndef _DS1216_H +#define _DS1216_H + +extern volatile unsigned char *ds1216_base; +unsigned long ds1216_get_cmos_time(void); +int ds1216_set_rtc_mmss(unsigned long nowtime); + +#define DS1216_SEC_BYTE 1 +#define DS1216_MIN_BYTE 2 +#define DS1216_HOUR_BYTE 3 +#define DS1216_HOUR_MASK (0x1f) +#define DS1216_AMPM_MASK (1<<5) +#define DS1216_1224_MASK (1<<7) +#define DS1216_DAY_BYTE 4 +#define DS1216_DAY_MASK (0x7) +#define DS1216_DATE_BYTE 5 +#define DS1216_DATE_MASK (0x3f) +#define DS1216_MONTH_BYTE 6 +#define DS1216_MONTH_MASK (0x1f) +#define DS1216_YEAR_BYTE 7 + +#define DS1216_SEC(buf) (buf[DS1216_SEC_BYTE]) +#define DS1216_MIN(buf) (buf[DS1216_MIN_BYTE]) +#define DS1216_HOUR(buf) (buf[DS1216_HOUR_BYTE] & DS1216_HOUR_MASK) +#define DS1216_AMPM(buf) (buf[DS1216_HOUR_BYTE] & DS1216_AMPM_MASK) +#define DS1216_1224(buf) (buf[DS1216_HOUR_BYTE] & DS1216_1224_MASK) +#define DS1216_DATE(buf) (buf[DS1216_DATE_BYTE] & DS1216_DATE_MASK) +#define DS1216_MONTH(buf) (buf[DS1216_MONTH_BYTE] & DS1216_MONTH_MASK) +#define DS1216_YEAR(buf) (buf[DS1216_YEAR_BYTE]) + +#endif diff --git a/trunk/include/asm-mips/futex.h b/trunk/include/asm-mips/futex.h index b623882bce19..47e5679c2353 100644 --- a/trunk/include/asm-mips/futex.h +++ b/trunk/include/asm-mips/futex.h @@ -29,7 +29,7 @@ " .set mips3 \n" \ "2: sc $1, %2 \n" \ " beqzl $1, 1b \n" \ - __WEAK_LLSC_MB \ + __WEAK_ORDERING_MB \ "3: \n" \ " .set pop \n" \ " .set mips0 \n" \ @@ -55,7 +55,7 @@ " .set mips3 \n" \ "2: sc $1, %2 \n" \ " beqz $1, 1b \n" \ - __WEAK_LLSC_MB \ + __WEAK_ORDERING_MB \ "3: \n" \ " .set pop \n" \ " .set mips0 \n" \ @@ -152,7 +152,7 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) " .set mips3 \n" "2: sc $1, %1 \n" " beqzl $1, 1b \n" - __WEAK_LLSC_MB + __WEAK_ORDERING_MB "3: \n" " .set pop \n" " .section .fixup,\"ax\" \n" @@ -179,7 +179,7 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) " .set mips3 \n" "2: sc $1, %1 \n" " beqz $1, 1b \n" - __WEAK_LLSC_MB + __WEAK_ORDERING_MB "3: \n" " .set pop \n" " .section .fixup,\"ax\" \n" diff --git a/trunk/include/asm-mips/gfx.h b/trunk/include/asm-mips/gfx.h new file mode 100644 index 000000000000..37235e41a6fd --- /dev/null +++ b/trunk/include/asm-mips/gfx.h @@ -0,0 +1,55 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * This is the user-visible SGI GFX interface. + * + * This must be used verbatim into the GNU libc. It does not include + * any kernel-only bits on it. + * + * miguel@nuclecu.unam.mx + */ +#ifndef _ASM_GFX_H +#define _ASM_GFX_H + +/* The iocls, yes, they do not make sense, but such is life */ +#define GFX_BASE 100 +#define GFX_GETNUM_BOARDS (GFX_BASE + 1) +#define GFX_GETBOARD_INFO (GFX_BASE + 2) +#define GFX_ATTACH_BOARD (GFX_BASE + 3) +#define GFX_DETACH_BOARD (GFX_BASE + 4) +#define GFX_IS_MANAGED (GFX_BASE + 5) + +#define GFX_MAPALL (GFX_BASE + 10) +#define GFX_LABEL (GFX_BASE + 11) + +#define GFX_INFO_NAME_SIZE 16 +#define GFX_INFO_LABEL_SIZE 16 + +struct gfx_info { + char name [GFX_INFO_NAME_SIZE]; /* board name */ + char label [GFX_INFO_LABEL_SIZE]; /* label name */ + unsigned short int xpmax, ypmax; /* screen resolution */ + unsigned int lenght; /* size of a complete gfx_info for this board */ +}; + +struct gfx_getboardinfo_args { + unsigned int board; /* board number. starting from zero */ + void *buf; /* pointer to gfx_info */ + unsigned int len; /* buffer size of buf */ +}; + +struct gfx_attach_board_args { + unsigned int board; /* board number, starting from zero */ + void *vaddr; /* address where the board registers should be mapped */ +}; + +#ifdef __KERNEL__ +/* umap.c */ +extern void remove_mapping (struct vm_area_struct *vma, struct task_struct *, unsigned long, unsigned long); +extern void *vmalloc_uncached (unsigned long size); +extern int vmap_page_range (struct vm_area_struct *vma, unsigned long from, unsigned long size, unsigned long vaddr); +#endif + +#endif /* _ASM_GFX_H */ diff --git a/trunk/include/asm-mips/mach-cobalt/cpu-feature-overrides.h b/trunk/include/asm-mips/mach-cobalt/cpu-feature-overrides.h index d38f069d9e95..c6dfa59d1986 100644 --- a/trunk/include/asm-mips/mach-cobalt/cpu-feature-overrides.h +++ b/trunk/include/asm-mips/mach-cobalt/cpu-feature-overrides.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2006, 07 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) */ #ifndef __ASM_COBALT_CPU_FEATURE_OVERRIDES_H #define __ASM_COBALT_CPU_FEATURE_OVERRIDES_H @@ -46,8 +46,6 @@ #define cpu_has_ic_fills_f_dc 0 #define cpu_icache_snoops_remote_store 0 #define cpu_has_dsp 0 -#define cpu_has_mipsmt 0 -#define cpu_has_userlocal 0 #define cpu_has_mips32r1 0 #define cpu_has_mips32r2 0 diff --git a/trunk/include/asm-mips/mach-excite/cpu-feature-overrides.h b/trunk/include/asm-mips/mach-excite/cpu-feature-overrides.h index 07f4322c235d..0d31854222f9 100644 --- a/trunk/include/asm-mips/mach-excite/cpu-feature-overrides.h +++ b/trunk/include/asm-mips/mach-excite/cpu-feature-overrides.h @@ -4,7 +4,6 @@ * for more details. * * Copyright (C) 2004 Thomas Koeller - * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org) */ #ifndef __ASM_MACH_EXCITE_CPU_FEATURE_OVERRIDES_H #define __ASM_MACH_EXCITE_CPU_FEATURE_OVERRIDES_H @@ -28,8 +27,6 @@ #define cpu_has_ic_fills_f_dc 0 #define cpu_has_dsp 0 #define cpu_icache_snoops_remote_store 0 -#define cpu_has_mipsmt 0 -#define cpu_has_userlocal 0 #define cpu_has_nofpuex 0 #define cpu_has_64bits 1 diff --git a/trunk/include/asm-mips/mach-ip22/cpu-feature-overrides.h b/trunk/include/asm-mips/mach-ip22/cpu-feature-overrides.h index 9c8735158da1..f7c5dc8a5336 100644 --- a/trunk/include/asm-mips/mach-ip22/cpu-feature-overrides.h +++ b/trunk/include/asm-mips/mach-ip22/cpu-feature-overrides.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003, 07 Ralf Baechle + * Copyright (C) 2003 Ralf Baechle */ #ifndef __ASM_MACH_IP22_CPU_FEATURE_OVERRIDES_H #define __ASM_MACH_IP22_CPU_FEATURE_OVERRIDES_H @@ -30,8 +30,6 @@ #define cpu_has_ic_fills_f_dc 0 #define cpu_has_dsp 0 -#define cpu_has_mipsmt 0 -#define cpu_has_userlocal 0 #define cpu_has_nofpuex 0 #define cpu_has_64bits 1 diff --git a/trunk/include/asm-mips/mach-ip27/cpu-feature-overrides.h b/trunk/include/asm-mips/mach-ip27/cpu-feature-overrides.h index fe076380c189..a071974b67bb 100644 --- a/trunk/include/asm-mips/mach-ip27/cpu-feature-overrides.h +++ b/trunk/include/asm-mips/mach-ip27/cpu-feature-overrides.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003, 07 Ralf Baechle + * Copyright (C) 2003 Ralf Baechle */ #ifndef __ASM_MACH_IP27_CPU_FEATURE_OVERRIDES_H #define __ASM_MACH_IP27_CPU_FEATURE_OVERRIDES_H @@ -27,8 +27,6 @@ #define cpu_has_ic_fills_f_dc 0 #define cpu_has_dsp 0 #define cpu_icache_snoops_remote_store 1 -#define cpu_has_mipsmt 0 -#define cpu_has_userlocal 0 #define cpu_has_nofpuex 0 #define cpu_has_64bits 1 diff --git a/trunk/include/asm-mips/mach-ip32/cpu-feature-overrides.h b/trunk/include/asm-mips/mach-ip32/cpu-feature-overrides.h index 6782fccebe8d..2a3de092bf13 100644 --- a/trunk/include/asm-mips/mach-ip32/cpu-feature-overrides.h +++ b/trunk/include/asm-mips/mach-ip32/cpu-feature-overrides.h @@ -4,7 +4,7 @@ * for more details. * * Copyright (C) 2005 Ilya A. Volynets-Evenbakh - * Copyright (C) 2005, 07 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) */ #ifndef __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H #define __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H @@ -38,8 +38,6 @@ #define cpu_has_ic_fills_f_dc 0 #define cpu_has_dsp 0 #define cpu_has_4k_cache 1 -#define cpu_has_mipsmt 0 -#define cpu_has_userlocal 0 #define cpu_has_mips32r1 0 diff --git a/trunk/include/asm-mips/mach-qemu/cpu-feature-overrides.h b/trunk/include/asm-mips/mach-qemu/cpu-feature-overrides.h index d2daaed235d5..529445dacedb 100644 --- a/trunk/include/asm-mips/mach-qemu/cpu-feature-overrides.h +++ b/trunk/include/asm-mips/mach-qemu/cpu-feature-overrides.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003, 07 Ralf Baechle + * Copyright (C) 2003 Ralf Baechle */ #ifndef __ASM_MACH_QEMU_CPU_FEATURE_OVERRIDES_H #define __ASM_MACH_QEMU_CPU_FEATURE_OVERRIDES_H @@ -24,7 +24,6 @@ #define cpu_has_ic_fills_f_dc 0 #define cpu_has_dsp 0 -#define cpu_has_mipsmt 0 #define cpu_has_nofpuex 0 #define cpu_has_64bits 0 diff --git a/trunk/include/asm-mips/mach-rm/cpu-feature-overrides.h b/trunk/include/asm-mips/mach-rm/cpu-feature-overrides.h index ccf543363537..7e07283140a3 100644 --- a/trunk/include/asm-mips/mach-rm/cpu-feature-overrides.h +++ b/trunk/include/asm-mips/mach-rm/cpu-feature-overrides.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003, 04, 07 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2003, 2004 Ralf Baechle * * SNI RM200 C apparently was only shipped with R4600 V2.0 and R5000 processors. */ @@ -32,8 +32,6 @@ #define cpu_has_dsp 0 #define cpu_has_nofpuex 0 #define cpu_has_64bits 1 -#define cpu_has_mipsmt 0 -#define cpu_has_userlocal 0 #define cpu_has_mips32r1 0 #define cpu_has_mips32r2 0 diff --git a/trunk/include/asm-mips/mach-sibyte/cpu-feature-overrides.h b/trunk/include/asm-mips/mach-sibyte/cpu-feature-overrides.h index 63d5bf649af1..a25968f277a2 100644 --- a/trunk/include/asm-mips/mach-sibyte/cpu-feature-overrides.h +++ b/trunk/include/asm-mips/mach-sibyte/cpu-feature-overrides.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003, 04, 07 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2003, 2004 Ralf Baechle */ #ifndef __ASM_MACH_SIBYTE_CPU_FEATURE_OVERRIDES_H #define __ASM_MACH_SIBYTE_CPU_FEATURE_OVERRIDES_H @@ -26,8 +26,6 @@ #define cpu_has_dc_aliases 0 #define cpu_has_ic_fills_f_dc 0 #define cpu_has_dsp 0 -#define cpu_has_mipsmt 0 -#define cpu_has_userlocal 0 #define cpu_icache_snoops_remote_store 0 #define cpu_has_nofpuex 0 diff --git a/trunk/include/asm-mips/mach-yosemite/cpu-feature-overrides.h b/trunk/include/asm-mips/mach-yosemite/cpu-feature-overrides.h index 470e5e9e10d6..42cebb7ce7a6 100644 --- a/trunk/include/asm-mips/mach-yosemite/cpu-feature-overrides.h +++ b/trunk/include/asm-mips/mach-yosemite/cpu-feature-overrides.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003, 04, 07 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2003, 2004 Ralf Baechle */ #ifndef __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H #define __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H @@ -26,8 +26,6 @@ #define cpu_has_dc_aliases 0 #define cpu_has_ic_fills_f_dc 0 #define cpu_has_dsp 0 -#define cpu_has_mipsmt 0 -#define cpu_has_userlocal 0 #define cpu_icache_snoops_remote_store 0 #define cpu_has_nofpuex 0 diff --git a/trunk/include/asm-mips/spinlock.h b/trunk/include/asm-mips/spinlock.h index bb897016c491..35e431cd796b 100644 --- a/trunk/include/asm-mips/spinlock.h +++ b/trunk/include/asm-mips/spinlock.h @@ -67,7 +67,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) : "memory"); } - smp_llsc_mb(); + smp_mb(); } static inline void __raw_spin_unlock(raw_spinlock_t *lock) @@ -118,7 +118,7 @@ static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock) : "memory"); } - smp_llsc_mb(); + smp_mb(); return res == 0; } @@ -183,7 +183,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) : "memory"); } - smp_llsc_mb(); + smp_mb(); } /* Note the use of sub, not subu which will make the kernel die with an @@ -193,7 +193,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw) { unsigned int tmp; - smp_llsc_mb(); + smp_mb(); if (R10000_LLSC_WAR) { __asm__ __volatile__( @@ -262,7 +262,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) : "memory"); } - smp_llsc_mb(); + smp_mb(); } static inline void __raw_write_unlock(raw_rwlock_t *rw) @@ -293,7 +293,7 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw) " .set reorder \n" " beqzl %1, 1b \n" " nop \n" - __WEAK_LLSC_MB + __WEAK_ORDERING_MB " li %2, 1 \n" "2: \n" : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) @@ -310,7 +310,7 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw) " beqz %1, 1b \n" " nop \n" " .set reorder \n" - __WEAK_LLSC_MB + __WEAK_ORDERING_MB " li %2, 1 \n" "2: \n" : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) @@ -336,7 +336,7 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) " sc %1, %0 \n" " beqzl %1, 1b \n" " nop \n" - __WEAK_LLSC_MB + __WEAK_ORDERING_MB " li %2, 1 \n" " .set reorder \n" "2: \n" @@ -354,7 +354,7 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) " beqz %1, 3f \n" " li %2, 1 \n" "2: \n" - __WEAK_LLSC_MB + __WEAK_ORDERING_MB " .subsection 2 \n" "3: b 1b \n" " li %2, 0 \n" diff --git a/trunk/include/asm-mips/system.h b/trunk/include/asm-mips/system.h index 8d0b1cd4a45e..76339165bc20 100644 --- a/trunk/include/asm-mips/system.h +++ b/trunk/include/asm-mips/system.h @@ -117,7 +117,7 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) raw_local_irq_restore(flags); /* implies memory barrier */ } - smp_llsc_mb(); + smp_mb(); return retval; } @@ -165,7 +165,7 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val) raw_local_irq_restore(flags); /* implies memory barrier */ } - smp_llsc_mb(); + smp_mb(); return retval; } @@ -246,7 +246,7 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old, raw_local_irq_restore(flags); /* implies memory barrier */ } - smp_llsc_mb(); + smp_mb(); return retval; } @@ -352,7 +352,7 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old, raw_local_irq_restore(flags); /* implies memory barrier */ } - smp_llsc_mb(); + smp_mb(); return retval; } @@ -470,6 +470,6 @@ extern int stop_a_enabled; */ #define __ARCH_WANT_UNLOCKED_CTXSW -extern unsigned long arch_align_stack(unsigned long sp); +#define arch_align_stack(x) (x) #endif /* _ASM_SYSTEM_H */ diff --git a/trunk/include/asm-powerpc/of_device.h b/trunk/include/asm-powerpc/of_device.h index ec2a8a2c737c..e9af49eb1aa8 100644 --- a/trunk/include/asm-powerpc/of_device.h +++ b/trunk/include/asm-powerpc/of_device.h @@ -3,12 +3,14 @@ #ifdef __KERNEL__ #include -#include +#include +#include + /* * The of_device is a kind of "base class" that is a superset of * struct device for use by devices attached to an OF node and - * probed using OF properties. + * probed using OF properties */ struct of_device { @@ -16,14 +18,24 @@ struct of_device u64 dma_mask; /* DMA mask */ struct device dev; /* Generic device interface */ }; +#define to_of_device(d) container_of(d, struct of_device, dev) + +extern const struct of_device_id *of_match_node( + const struct of_device_id *matches, const struct device_node *node); +extern const struct of_device_id *of_match_device( + const struct of_device_id *matches, const struct of_device *dev); + +extern struct of_device *of_dev_get(struct of_device *dev); +extern void of_dev_put(struct of_device *dev); + +extern int of_device_register(struct of_device *ofdev); +extern void of_device_unregister(struct of_device *ofdev); +extern void of_release_dev(struct device *dev); extern ssize_t of_device_get_modalias(struct of_device *ofdev, char *str, ssize_t len); extern int of_device_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); -/* This is just here during the transition */ -#include - #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_OF_DEVICE_H */ diff --git a/trunk/include/asm-powerpc/of_platform.h b/trunk/include/asm-powerpc/of_platform.h index 80e6fad28b4f..217eafb167e9 100644 --- a/trunk/include/asm-powerpc/of_platform.h +++ b/trunk/include/asm-powerpc/of_platform.h @@ -1,5 +1,3 @@ -#ifndef _ASM_POWERPC_OF_PLATFORM_H -#define _ASM_POWERPC_OF_PLATFORM_H /* * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. * @@ -11,8 +9,37 @@ * */ -/* This is just here during the transition */ -#include +#include + +/* + * The of_platform_bus_type is a bus type used by drivers that do not + * attach to a macio or similar bus but still use OF probing + * mechanism + */ +extern struct bus_type of_platform_bus_type; + +/* + * An of_platform_driver driver is attached to a basic of_device on + * the "platform bus" (of_platform_bus_type) + */ +struct of_platform_driver +{ + char *name; + struct of_device_id *match_table; + struct module *owner; + + int (*probe)(struct of_device* dev, + const struct of_device_id *match); + int (*remove)(struct of_device* dev); + + int (*suspend)(struct of_device* dev, pm_message_t state); + int (*resume)(struct of_device* dev); + int (*shutdown)(struct of_device* dev); + + struct device_driver driver; +}; +#define to_of_platform_driver(drv) \ + container_of(drv,struct of_platform_driver, driver) /* Platform drivers register/unregister */ extern int of_register_platform_driver(struct of_platform_driver *drv); @@ -29,6 +56,5 @@ extern int of_platform_bus_probe(struct device_node *root, struct of_device_id *matches, struct device *parent); +extern struct of_device *of_find_device_by_node(struct device_node *np); extern struct of_device *of_find_device_by_phandle(phandle ph); - -#endif /* _ASM_POWERPC_OF_PLATFORM_H */ diff --git a/trunk/include/asm-powerpc/oprofile_impl.h b/trunk/include/asm-powerpc/oprofile_impl.h index 938fefb4c4bc..8d6b47f7b300 100644 --- a/trunk/include/asm-powerpc/oprofile_impl.h +++ b/trunk/include/asm-powerpc/oprofile_impl.h @@ -39,16 +39,14 @@ struct op_system_config { /* Per-arch configuration */ struct op_powerpc_model { - int (*reg_setup) (struct op_counter_config *, + void (*reg_setup) (struct op_counter_config *, struct op_system_config *, int num_counters); - int (*cpu_setup) (struct op_counter_config *); - int (*start) (struct op_counter_config *); - int (*global_start) (struct op_counter_config *); + void (*cpu_setup) (struct op_counter_config *); + void (*start) (struct op_counter_config *); + void (*global_start) (struct op_counter_config *); void (*stop) (void); void (*global_stop) (void); - int (*sync_start)(void); - int (*sync_stop)(void); void (*handle_interrupt) (struct pt_regs *, struct op_counter_config *); int num_counters; diff --git a/trunk/include/asm-powerpc/pmi.h b/trunk/include/asm-powerpc/pmi.h index 2259d4ce3846..cb0f8aa43088 100644 --- a/trunk/include/asm-powerpc/pmi.h +++ b/trunk/include/asm-powerpc/pmi.h @@ -55,13 +55,13 @@ typedef struct { struct pmi_handler { struct list_head node; u8 type; - void (*handle_pmi_message) (pmi_message_t); + void (*handle_pmi_message) (struct of_device *, pmi_message_t); }; -int pmi_register_handler(struct pmi_handler *); -void pmi_unregister_handler(struct pmi_handler *); +void pmi_register_handler(struct of_device *, struct pmi_handler *); +void pmi_unregister_handler(struct of_device *, struct pmi_handler *); -int pmi_send_message(pmi_message_t); +void pmi_send_message(struct of_device *, pmi_message_t); #endif /* __KERNEL__ */ #endif /* _POWERPC_PMI_H */ diff --git a/trunk/include/asm-powerpc/prom.h b/trunk/include/asm-powerpc/prom.h index 6e391c9894ce..1632baa17dc6 100644 --- a/trunk/include/asm-powerpc/prom.h +++ b/trunk/include/asm-powerpc/prom.h @@ -21,13 +21,6 @@ #include #include -#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1 -#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1 - -#define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l)) -#define of_prop_cmp(s1, s2) strcmp((s1), (s2)) -#define of_node_cmp(s1, s2) strcasecmp((s1), (s2)) - /* Definitions used by the flattened device tree */ #define OF_DT_HEADER 0xd00dfeed /* marker */ #define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ @@ -104,6 +97,10 @@ struct device_node { extern struct device_node *of_chosen; +/* flag descriptions */ +#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */ +#define OF_DETACHED 2 /* node has been detached from the device tree */ + static inline int of_node_check_flag(struct device_node *n, unsigned long flag) { return test_bit(flag, &n->_flags); @@ -123,7 +120,31 @@ static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_e } +/* New style node lookup */ +extern struct device_node *of_find_node_by_name(struct device_node *from, + const char *name); +#define for_each_node_by_name(dn, name) \ + for (dn = of_find_node_by_name(NULL, name); dn; \ + dn = of_find_node_by_name(dn, name)) +extern struct device_node *of_find_node_by_type(struct device_node *from, + const char *type); +#define for_each_node_by_type(dn, type) \ + for (dn = of_find_node_by_type(NULL, type); dn; \ + dn = of_find_node_by_type(dn, type)) +extern struct device_node *of_find_compatible_node(struct device_node *from, + const char *type, const char *compat); +#define for_each_compatible_node(dn, type, compatible) \ + for (dn = of_find_compatible_node(NULL, type, compatible); dn; \ + dn = of_find_compatible_node(dn, type, compatible)) +extern struct device_node *of_find_node_by_path(const char *path); +extern struct device_node *of_find_node_by_phandle(phandle handle); extern struct device_node *of_find_all_nodes(struct device_node *prev); +extern struct device_node *of_get_parent(const struct device_node *node); +extern struct device_node *of_get_next_child(const struct device_node *node, + struct device_node *prev); +extern struct property *of_find_property(const struct device_node *np, + const char *name, + int *lenp); extern struct device_node *of_node_get(struct device_node *node); extern void of_node_put(struct device_node *node); @@ -145,9 +166,17 @@ extern void of_detach_node(const struct device_node *); extern void finish_device_tree(void); extern void unflatten_device_tree(void); extern void early_init_devtree(void *); +extern int of_device_is_compatible(const struct device_node *device, + const char *); #define device_is_compatible(d, c) of_device_is_compatible((d), (c)) extern int machine_is_compatible(const char *compat); +extern const void *of_get_property(const struct device_node *node, + const char *name, + int *lenp); +#define get_property(a, b, c) of_get_property((a), (b), (c)) extern void print_properties(struct device_node *node); +extern int of_n_addr_cells(struct device_node* np); +extern int of_n_size_cells(struct device_node* np); extern int prom_n_intr_cells(struct device_node* np); extern void prom_get_irq_senses(unsigned char *senses, int off, int max); extern int prom_add_property(struct device_node* np, struct property* prop); @@ -201,6 +230,7 @@ static inline unsigned long of_read_ulong(const u32 *cell, int size) /* Translate an OF address block into a CPU physical address */ +#define OF_BAD_ADDR ((u64)-1) extern u64 of_translate_address(struct device_node *np, const u32 *addr); /* Extract an address from a device, returns the region size and @@ -327,11 +357,5 @@ extern int of_irq_to_resource(struct device_node *dev, int index, */ extern void __iomem *of_iomap(struct device_node *device, int index); -/* - * NB: This is here while we transition from using asm/prom.h - * to linux/of.h - */ -#include - #endif /* __KERNEL__ */ #endif /* _POWERPC_PROM_H */ diff --git a/trunk/include/asm-powerpc/spu.h b/trunk/include/asm-powerpc/spu.h index 8836c0f1f2f7..eedc828cef2d 100644 --- a/trunk/include/asm-powerpc/spu.h +++ b/trunk/include/asm-powerpc/spu.h @@ -107,10 +107,10 @@ struct spu_runqueue; struct device_node; enum spu_utilization_state { - SPU_UTIL_USER, SPU_UTIL_SYSTEM, + SPU_UTIL_USER, SPU_UTIL_IOWAIT, - SPU_UTIL_IDLE_LOADED, + SPU_UTIL_IDLE, SPU_UTIL_MAX }; @@ -121,9 +121,9 @@ struct spu { unsigned long problem_phys; struct spu_problem __iomem *problem; struct spu_priv2 __iomem *priv2; - struct list_head cbe_list; + struct list_head list; + struct list_head sched_list; struct list_head full_list; - enum { SPU_FREE, SPU_USED } alloc_state; int number; unsigned int irqs[3]; u32 node; @@ -137,7 +137,6 @@ struct spu { struct spu_runqueue *rq; unsigned long long timestamp; pid_t pid; - pid_t tgid; int class_0_pending; spinlock_t register_lock; @@ -166,14 +165,11 @@ struct spu { struct sys_device sysdev; - int has_mem_affinity; - struct list_head aff_list; - struct { /* protected by interrupt reentrancy */ - enum spu_utilization_state util_state; - unsigned long long tstamp; - unsigned long long times[SPU_UTIL_MAX]; + enum spu_utilization_state utilization_state; + unsigned long tstamp; /* time of last ctx switch */ + unsigned long times[SPU_UTIL_MAX]; unsigned long long vol_ctx_switch; unsigned long long invol_ctx_switch; unsigned long long min_flt; @@ -185,29 +181,13 @@ struct spu { } stats; }; -struct cbe_spu_info { - struct mutex list_mutex; - struct list_head spus; - int n_spus; - int nr_active; - atomic_t reserved_spus; -}; - -extern struct cbe_spu_info cbe_spu_info[]; - -void spu_init_channels(struct spu *spu); +struct spu *spu_alloc(void); +struct spu *spu_alloc_node(int node); +void spu_free(struct spu *spu); int spu_irq_class_0_bottom(struct spu *spu); int spu_irq_class_1_bottom(struct spu *spu); void spu_irq_setaffinity(struct spu *spu, int cpu); -#ifdef CONFIG_KEXEC -void crash_register_spus(struct list_head *list); -#else -static inline void crash_register_spus(struct list_head *list) -{ -} -#endif - extern void spu_invalidate_slbs(struct spu *spu); extern void spu_associate_mm(struct spu *spu, struct mm_struct *mm); @@ -215,20 +195,6 @@ extern void spu_associate_mm(struct spu *spu, struct mm_struct *mm); struct mm_struct; extern void spu_flush_all_slbs(struct mm_struct *mm); -/* This interface allows a profiler (e.g., OProfile) to store a ref - * to spu context information that it creates. This caching technique - * avoids the need to recreate this information after a save/restore operation. - * - * Assumes the caller has already incremented the ref count to - * profile_info; then spu_context_destroy must call kref_put - * on prof_info_kref. - */ -void spu_set_profile_private_kref(struct spu_context *ctx, - struct kref *prof_info_kref, - void ( * prof_info_release) (struct kref *kref)); - -void *spu_get_profile_private_kref(struct spu_context *ctx); - /* system callbacks from the SPU */ struct spu_syscall_block { u64 nr_ret; @@ -240,8 +206,7 @@ extern long spu_sys_callback(struct spu_syscall_block *s); struct file; extern struct spufs_calls { asmlinkage long (*create_thread)(const char __user *name, - unsigned int flags, mode_t mode, - struct file *neighbor); + unsigned int flags, mode_t mode); asmlinkage long (*spu_run)(struct file *filp, __u32 __user *unpc, __u32 __user *ustatus); struct module *owner; @@ -268,10 +233,8 @@ struct spu_coredump_calls { #define SPU_CREATE_GANG 0x0002 #define SPU_CREATE_NOSCHED 0x0004 #define SPU_CREATE_ISOLATE 0x0008 -#define SPU_CREATE_AFFINITY_SPU 0x0010 -#define SPU_CREATE_AFFINITY_MEM 0x0020 -#define SPU_CREATE_FLAG_ALL 0x003f /* mask of all valid flags */ +#define SPU_CREATE_FLAG_ALL 0x000f /* mask of all valid flags */ #ifdef CONFIG_SPU_FS_MODULE @@ -440,7 +403,6 @@ struct spu_priv2 { #define MFC_CNTL_RESUME_DMA_QUEUE (0ull << 0) #define MFC_CNTL_SUSPEND_DMA_QUEUE (1ull << 0) #define MFC_CNTL_SUSPEND_DMA_QUEUE_MASK (1ull << 0) -#define MFC_CNTL_SUSPEND_MASK (1ull << 4) #define MFC_CNTL_NORMAL_DMA_QUEUE_OPERATION (0ull << 8) #define MFC_CNTL_SUSPEND_IN_PROGRESS (1ull << 8) #define MFC_CNTL_SUSPEND_COMPLETE (3ull << 8) diff --git a/trunk/include/asm-powerpc/spu_csa.h b/trunk/include/asm-powerpc/spu_csa.h index e87794d5d4ea..c48ae185c874 100644 --- a/trunk/include/asm-powerpc/spu_csa.h +++ b/trunk/include/asm-powerpc/spu_csa.h @@ -50,12 +50,6 @@ #define SPU_STOPPED_STATUS_P_I 8 #define SPU_STOPPED_STATUS_R 9 -/* - * Definitions for software decrementer status flag. - */ -#define SPU_DECR_STATUS_RUNNING 0x1 -#define SPU_DECR_STATUS_WRAPPED 0x2 - #ifndef __ASSEMBLY__ /** * spu_reg128 - generic 128-bit register definition. @@ -69,7 +63,7 @@ struct spu_reg128 { * @gprs: Array of saved registers. * @fpcr: Saved floating point status control register. * @decr: Saved decrementer value. - * @decr_status: Indicates software decrementer status flags. + * @decr_status: Indicates decrementer run status. * @ppu_mb: Saved PPU mailbox data. * @ppuint_mb: Saved PPU interrupting mailbox data. * @tag_mask: Saved tag group mask. diff --git a/trunk/include/asm-sh/clock.h b/trunk/include/asm-sh/clock.h index b550a27a7042..386d797d86b7 100644 --- a/trunk/include/asm-sh/clock.h +++ b/trunk/include/asm-sh/clock.h @@ -14,7 +14,6 @@ struct clk_ops { void (*disable)(struct clk *clk); void (*recalc)(struct clk *clk); int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id); - long (*round_rate)(struct clk *clk, unsigned long rate); }; struct clk { diff --git a/trunk/include/asm-sh/hw_irq.h b/trunk/include/asm-sh/hw_irq.h index 20d42959f52a..4ca3f765bacc 100644 --- a/trunk/include/asm-sh/hw_irq.h +++ b/trunk/include/asm-sh/hw_irq.h @@ -1,7 +1,6 @@ #ifndef __ASM_SH_HW_IRQ_H #define __ASM_SH_HW_IRQ_H -#include #include extern atomic_t irq_err_count; @@ -23,6 +22,7 @@ struct intc2_desc { }; void register_intc2_controller(struct intc2_desc *); +void init_IRQ_intc2(void); struct ipr_data { unsigned char irq; @@ -40,82 +40,11 @@ struct ipr_desc { }; void register_ipr_controller(struct ipr_desc *); +void init_IRQ_ipr(void); /* * Enable individual interrupt mode for external IPR IRQs. */ -void __init ipr_irq_enable_irlm(void); - -typedef unsigned char intc_enum; - -struct intc_vect { - intc_enum enum_id; - unsigned short vect; -}; - -#define INTC_VECT(enum_id, vect) { enum_id, vect } - -struct intc_prio { - intc_enum enum_id; - unsigned char priority; -}; - -#define INTC_PRIO(enum_id, prio) { enum_id, prio } - -struct intc_group { - intc_enum enum_id; - intc_enum *enum_ids; -}; - -#define INTC_GROUP(enum_id, ids...) { enum_id, (intc_enum []) { ids, 0 } } - -struct intc_mask_reg { - unsigned long set_reg, clr_reg, reg_width; - intc_enum enum_ids[32]; -}; - -struct intc_prio_reg { - unsigned long reg, reg_width, field_width; - intc_enum enum_ids[16]; -}; - -struct intc_sense_reg { - unsigned long reg, reg_width, field_width; - intc_enum enum_ids[16]; -}; - -struct intc_desc { - struct intc_vect *vectors; - unsigned int nr_vectors; - struct intc_group *groups; - unsigned int nr_groups; - struct intc_prio *priorities; - unsigned int nr_priorities; - struct intc_mask_reg *mask_regs; - unsigned int nr_mask_regs; - struct intc_prio_reg *prio_regs; - unsigned int nr_prio_regs; - struct intc_sense_reg *sense_regs; - unsigned int nr_sense_regs; - struct irq_chip chip; -}; - -#define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a) -#define DECLARE_INTC_DESC(symbol, chipname, vectors, groups, \ - priorities, mask_regs, prio_regs, sense_regs) \ -struct intc_desc symbol = { \ - _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \ - _INTC_ARRAY(priorities), \ - _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \ - _INTC_ARRAY(sense_regs), \ - .chip.name = chipname, \ -} - -void __init register_intc_controller(struct intc_desc *desc); - -void __init plat_irq_setup(void); - -enum { IRQ_MODE_IRQ, IRQ_MODE_IRL7654, IRQ_MODE_IRL3210 }; -void __init plat_irq_setup_pins(int mode); +void ipr_irq_enable_irlm(void); #endif /* __ASM_SH_HW_IRQ_H */ diff --git a/trunk/include/asm-sh/se7722.h b/trunk/include/asm-sh/se7722.h index e0e89fcb8388..b3b31e4725c6 100644 --- a/trunk/include/asm-sh/se7722.h +++ b/trunk/include/asm-sh/se7722.h @@ -81,32 +81,36 @@ /* IRQ */ #define IRQ0_IRQ 32 #define IRQ1_IRQ 33 +#define INTC_ICR0 0xA4140000UL +#define INTC_ICR1 0xA414001CUL + +#define INTMSK0 0xa4140044 +#define INTMSKCLR0 0xa4140064 +#define INTC_INTPRI0 0xa4140010 #define IRQ01_MODE 0xb1800000 #define IRQ01_STS 0xb1800004 #define IRQ01_MASK 0xb1800008 +#define EXT_BIT (0x3fc0) /* SH IRQ1 */ +#define MRSHPC_BIT0 (0x0004) /* SH IRQ1 */ +#define MRSHPC_BIT1 (0x0008) /* SH IRQ1 */ +#define MRSHPC_BIT2 (0x0010) /* SH IRQ1 */ +#define MRSHPC_BIT3 (0x0020) /* SH IRQ1 */ +#define SMC_BIT (0x0002) /* SH IRQ0 */ +#define USB_BIT (0x0001) /* SH IRQ0 */ + +#define MRSHPC_IRQ3 11 +#define MRSHPC_IRQ2 12 +#define MRSHPC_IRQ1 13 +#define MRSHPC_IRQ0 14 +#define SMC_IRQ 10 +#define EXT_IRQ 5 +#define USB_IRQ 6 -/* Bits in IRQ01_* registers */ - -#define SE7722_FPGA_IRQ_USB 0 /* IRQ0 */ -#define SE7722_FPGA_IRQ_SMC 1 /* IRQ0 */ -#define SE7722_FPGA_IRQ_MRSHPC0 2 /* IRQ1 */ -#define SE7722_FPGA_IRQ_MRSHPC1 3 /* IRQ1 */ -#define SE7722_FPGA_IRQ_MRSHPC2 4 /* IRQ1 */ -#define SE7722_FPGA_IRQ_MRSHPC3 5 /* IRQ1 */ - -#define SE7722_FPGA_IRQ_NR 6 -#define SE7722_FPGA_IRQ_BASE 110 - -#define MRSHPC_IRQ3 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC3) -#define MRSHPC_IRQ2 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC2) -#define MRSHPC_IRQ1 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC1) -#define MRSHPC_IRQ0 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC0) -#define SMC_IRQ (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_SMC) -#define USB_IRQ (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_USB) /* arch/sh/boards/se/7722/irq.c */ void init_se7722_IRQ(void); +int se7722_irq_demux(int); #define __IO_PREFIX se7722 #include diff --git a/trunk/include/asm-sh/unistd.h b/trunk/include/asm-sh/unistd.h index b182b1cb05fd..77bcb09d6ac8 100644 --- a/trunk/include/asm-sh/unistd.h +++ b/trunk/include/asm-sh/unistd.h @@ -332,9 +332,8 @@ #define __NR_signalfd 321 #define __NR_timerfd 322 #define __NR_eventfd 323 -#define __NR_fallocate 324 -#define NR_syscalls 325 +#define NR_syscalls 324 #ifdef __KERNEL__ diff --git a/trunk/include/asm-sh64/unistd.h b/trunk/include/asm-sh64/unistd.h index 1a5197f369b2..ea3adc600b41 100644 --- a/trunk/include/asm-sh64/unistd.h +++ b/trunk/include/asm-sh64/unistd.h @@ -374,11 +374,10 @@ #define __NR_signalfd 349 #define __NR_timerfd 350 #define __NR_eventfd 351 -#define __NR_fallocate 352 #ifdef __KERNEL__ -#define NR_syscalls 353 +#define NR_syscalls 352 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/trunk/include/asm-sparc/device.h b/trunk/include/asm-sparc/device.h index 4a56d84d69c4..d8f9872b0e2d 100644 --- a/trunk/include/asm-sparc/device.h +++ b/trunk/include/asm-sparc/device.h @@ -3,17 +3,5 @@ * * This file is released under the GPLv2 */ -#ifndef _ASM_SPARC_DEVICE_H -#define _ASM_SPARC_DEVICE_H - -struct device_node; -struct of_device; - -struct dev_archdata { - struct device_node *prom_node; - struct of_device *op; -}; - -#endif /* _ASM_SPARC_DEVICE_H */ - +#include diff --git a/trunk/include/asm-sparc/fb.h b/trunk/include/asm-sparc/fb.h index c73ca081e1f5..c7df38030992 100644 --- a/trunk/include/asm-sparc/fb.h +++ b/trunk/include/asm-sparc/fb.h @@ -1,20 +1,11 @@ #ifndef _ASM_FB_H_ #define _ASM_FB_H_ #include -#include #define fb_pgprotect(...) do {} while (0) static inline int fb_is_primary_device(struct fb_info *info) { - struct device *dev = info->device; - struct device_node *node; - - node = dev->archdata.prom_node; - if (node && - node == of_console_device) - return 1; - return 0; } diff --git a/trunk/include/asm-sparc/of_device.h b/trunk/include/asm-sparc/of_device.h index e5f5aedc2293..7cb00c1b09c6 100644 --- a/trunk/include/asm-sparc/of_device.h +++ b/trunk/include/asm-sparc/of_device.h @@ -3,9 +3,13 @@ #ifdef __KERNEL__ #include -#include #include #include +#include + +extern struct bus_type ebus_bus_type; +extern struct bus_type sbus_bus_type; +extern struct bus_type of_bus_type; /* * The of_device is a kind of "base class" that is a superset of @@ -26,13 +30,50 @@ struct of_device int portid; int clock_freq; }; +#define to_of_device(d) container_of(d, struct of_device, dev) extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size); -/* These are just here during the transition */ -#include -#include +extern struct of_device *of_find_device_by_node(struct device_node *); + +extern const struct of_device_id *of_match_device( + const struct of_device_id *matches, const struct of_device *dev); + +extern struct of_device *of_dev_get(struct of_device *dev); +extern void of_dev_put(struct of_device *dev); + +/* + * An of_platform_driver driver is attached to a basic of_device on + * the ISA, EBUS, and SBUS busses on sparc64. + */ +struct of_platform_driver +{ + char *name; + struct of_device_id *match_table; + struct module *owner; + + int (*probe)(struct of_device* dev, const struct of_device_id *match); + int (*remove)(struct of_device* dev); + + int (*suspend)(struct of_device* dev, pm_message_t state); + int (*resume)(struct of_device* dev); + int (*shutdown)(struct of_device* dev); + + struct device_driver driver; +}; +#define to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver) + +extern int of_register_driver(struct of_platform_driver *drv, + struct bus_type *bus); +extern void of_unregister_driver(struct of_platform_driver *drv); +extern int of_device_register(struct of_device *ofdev); +extern void of_device_unregister(struct of_device *ofdev); +extern struct of_device *of_platform_device_create(struct device_node *np, + const char *bus_id, + struct device *parent, + struct bus_type *bus); +extern void of_release_dev(struct device *dev); #endif /* __KERNEL__ */ #endif /* _ASM_SPARC_OF_DEVICE_H */ diff --git a/trunk/include/asm-sparc/of_platform.h b/trunk/include/asm-sparc/of_platform.h deleted file mode 100644 index 64a230064ef2..000000000000 --- a/trunk/include/asm-sparc/of_platform.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _ASM_SPARC_OF_PLATFORM_H -#define _ASM_SPARC_OF_PLATFORM_H -/* - * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. - * - * Modified for Sparc by merging parts of asm-sparc/of_device.h - * by Stephen Rothwell - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -/* This is just here during the transition */ -#include - -extern struct bus_type ebus_bus_type; -extern struct bus_type sbus_bus_type; -extern struct bus_type of_platform_bus_type; -#define of_bus_type of_platform_bus_type /* for compatibility */ - -extern int of_register_driver(struct of_platform_driver *drv, - struct bus_type *bus); -extern void of_unregister_driver(struct of_platform_driver *drv); -extern struct of_device *of_platform_device_create(struct device_node *np, - const char *bus_id, - struct device *parent, - struct bus_type *bus); - -#endif /* _ASM_SPARC_OF_PLATFORM_H */ diff --git a/trunk/include/asm-sparc/oplib.h b/trunk/include/asm-sparc/oplib.h index 17ba82ee220a..91691e52c058 100644 --- a/trunk/include/asm-sparc/oplib.h +++ b/trunk/include/asm-sparc/oplib.h @@ -158,6 +158,32 @@ extern void prom_putchar(char character); extern void prom_printf(char *fmt, ...); extern void prom_write(const char *buf, unsigned int len); +/* Query for input device type */ + +enum prom_input_device { + PROMDEV_IKBD, /* input from keyboard */ + PROMDEV_ITTYA, /* input from ttya */ + PROMDEV_ITTYB, /* input from ttyb */ + PROMDEV_IRSC, /* input from rsc */ + PROMDEV_IVCONS, /* input from virtual-console */ + PROMDEV_I_UNK, +}; + +extern enum prom_input_device prom_query_input_device(void); + +/* Query for output device type */ + +enum prom_output_device { + PROMDEV_OSCREEN, /* to screen */ + PROMDEV_OTTYA, /* to ttya */ + PROMDEV_OTTYB, /* to ttyb */ + PROMDEV_ORSC, /* to rsc */ + PROMDEV_OVCONS, /* to virtual-console */ + PROMDEV_O_UNK, +}; + +extern enum prom_output_device prom_query_output_device(void); + /* Multiprocessor operations... */ /* Start the CPU with the given device tree node, context table, and context diff --git a/trunk/include/asm-sparc/prom.h b/trunk/include/asm-sparc/prom.h index 350676c589f9..9ea105ebe2ff 100644 --- a/trunk/include/asm-sparc/prom.h +++ b/trunk/include/asm-sparc/prom.h @@ -2,6 +2,7 @@ #define _SPARC_PROM_H #ifdef __KERNEL__ + /* * Definitions for talking to the Open Firmware PROM on * Power Macintosh computers. @@ -16,17 +17,11 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ + #include #include #include -#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 2 -#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1 - -#define of_compat_cmp(s1, s2, l) strncmp((s1), (s2), (l)) -#define of_prop_cmp(s1, s2) strcasecmp((s1), (s2)) -#define of_node_cmp(s1, s2) strcmp((s1), (s2)) - typedef u32 phandle; typedef u32 ihandle; @@ -60,34 +55,53 @@ struct device_node { unsigned int unique_id; }; +/* flag descriptions */ +#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */ + #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags) #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags) +#define OF_BAD_ADDR ((u64)-1) + +static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de) +{ + dn->pde = de; +} + +extern struct device_node *of_find_node_by_name(struct device_node *from, + const char *name); +#define for_each_node_by_name(dn, name) \ + for (dn = of_find_node_by_name(NULL, name); dn; \ + dn = of_find_node_by_name(dn, name)) +extern struct device_node *of_find_node_by_type(struct device_node *from, + const char *type); +#define for_each_node_by_type(dn, type) \ + for (dn = of_find_node_by_type(NULL, type); dn; \ + dn = of_find_node_by_type(dn, type)) +extern struct device_node *of_find_compatible_node(struct device_node *from, + const char *type, const char *compat); +extern struct device_node *of_find_node_by_path(const char *path); +extern struct device_node *of_find_node_by_phandle(phandle handle); +extern struct device_node *of_get_parent(const struct device_node *node); +extern struct device_node *of_get_next_child(const struct device_node *node, + struct device_node *prev); +extern struct property *of_find_property(const struct device_node *np, + const char *name, + int *lenp); +extern int of_device_is_compatible(const struct device_node *device, + const char *); +extern const void *of_get_property(const struct device_node *node, + const char *name, + int *lenp); +#define get_property(node,name,lenp) of_get_property(node,name,lenp) extern int of_set_property(struct device_node *node, const char *name, void *val, int len); extern int of_getintprop_default(struct device_node *np, const char *name, int def); +extern int of_n_addr_cells(struct device_node *np); +extern int of_n_size_cells(struct device_node *np); extern void prom_build_devicetree(void); -/* Dummy ref counting routines - to be implemented later */ -static inline struct device_node *of_node_get(struct device_node *node) -{ - return node; -} -static inline void of_node_put(struct device_node *node) -{ -} - -/* - * NB: This is here while we transition from using asm/prom.h - * to linux/of.h - */ -#include - -extern struct device_node *of_console_device; -extern char *of_console_path; -extern char *of_console_options; - #endif /* __KERNEL__ */ #endif /* _SPARC_PROM_H */ diff --git a/trunk/include/asm-sparc/unistd.h b/trunk/include/asm-sparc/unistd.h index 029b3e0d5e4c..64471bcd96f9 100644 --- a/trunk/include/asm-sparc/unistd.h +++ b/trunk/include/asm-sparc/unistd.h @@ -1,3 +1,4 @@ +/* $Id: unistd.h,v 1.74 2002/02/08 03:57:18 davem Exp $ */ #ifndef _SPARC_UNISTD_H #define _SPARC_UNISTD_H @@ -8,7 +9,7 @@ * think of right now to force the arguments into fixed registers * before the trap into the system call with gcc 'asm' statements. * - * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * * SunOS compatibility based upon preliminary work which is: * @@ -329,9 +330,8 @@ #define __NR_signalfd 311 #define __NR_timerfd 312 #define __NR_eventfd 313 -#define __NR_fallocate 314 -#define NR_SYSCALLS 315 +#define NR_SYSCALLS 314 #ifdef __KERNEL__ #define __ARCH_WANT_IPC_PARSE_VERSION diff --git a/trunk/include/asm-sparc64/fb.h b/trunk/include/asm-sparc64/fb.h index 389012e5fbad..d6cd3a175fc3 100644 --- a/trunk/include/asm-sparc64/fb.h +++ b/trunk/include/asm-sparc64/fb.h @@ -3,7 +3,6 @@ #include #include #include -#include static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, unsigned long off) @@ -13,14 +12,6 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, static inline int fb_is_primary_device(struct fb_info *info) { - struct device *dev = info->device; - struct device_node *node; - - node = dev->archdata.prom_node; - if (node && - node == of_console_device) - return 1; - return 0; } diff --git a/trunk/include/asm-sparc64/of_device.h b/trunk/include/asm-sparc64/of_device.h index 46d69b3223c5..60e9173c9acb 100644 --- a/trunk/include/asm-sparc64/of_device.h +++ b/trunk/include/asm-sparc64/of_device.h @@ -3,9 +3,14 @@ #ifdef __KERNEL__ #include -#include #include #include +#include + +extern struct bus_type isa_bus_type; +extern struct bus_type ebus_bus_type; +extern struct bus_type sbus_bus_type; +extern struct bus_type of_bus_type; /* * The of_device is a kind of "base class" that is a superset of @@ -26,13 +31,50 @@ struct of_device int portid; int clock_freq; }; +#define to_of_device(d) container_of(d, struct of_device, dev) extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size); -/* These are just here during the transition */ -#include -#include +extern struct of_device *of_find_device_by_node(struct device_node *); + +extern const struct of_device_id *of_match_device( + const struct of_device_id *matches, const struct of_device *dev); + +extern struct of_device *of_dev_get(struct of_device *dev); +extern void of_dev_put(struct of_device *dev); + +/* + * An of_platform_driver driver is attached to a basic of_device on + * the ISA, EBUS, and SBUS busses on sparc64. + */ +struct of_platform_driver +{ + char *name; + struct of_device_id *match_table; + struct module *owner; + + int (*probe)(struct of_device* dev, const struct of_device_id *match); + int (*remove)(struct of_device* dev); + + int (*suspend)(struct of_device* dev, pm_message_t state); + int (*resume)(struct of_device* dev); + int (*shutdown)(struct of_device* dev); + + struct device_driver driver; +}; +#define to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver) + +extern int of_register_driver(struct of_platform_driver *drv, + struct bus_type *bus); +extern void of_unregister_driver(struct of_platform_driver *drv); +extern int of_device_register(struct of_device *ofdev); +extern void of_device_unregister(struct of_device *ofdev); +extern struct of_device *of_platform_device_create(struct device_node *np, + const char *bus_id, + struct device *parent, + struct bus_type *bus); +extern void of_release_dev(struct device *dev); #endif /* __KERNEL__ */ #endif /* _ASM_SPARC64_OF_DEVICE_H */ diff --git a/trunk/include/asm-sparc64/of_platform.h b/trunk/include/asm-sparc64/of_platform.h deleted file mode 100644 index f7c1f17c7d52..000000000000 --- a/trunk/include/asm-sparc64/of_platform.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _ASM_SPARC64_OF_PLATFORM_H -#define _ASM_SPARC64_OF_PLATFORM_H -/* - * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. - * - * Modified for Sparc by merging parts of asm-sparc/of_device.h - * by Stephen Rothwell - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -/* This is just here during the transition */ -#include - -extern struct bus_type isa_bus_type; -extern struct bus_type ebus_bus_type; -extern struct bus_type sbus_bus_type; -extern struct bus_type of_platform_bus_type; -#define of_bus_type of_platform_bus_type /* for compatibility */ - -extern int of_register_driver(struct of_platform_driver *drv, - struct bus_type *bus); -extern void of_unregister_driver(struct of_platform_driver *drv); -extern struct of_device *of_platform_device_create(struct device_node *np, - const char *bus_id, - struct device *parent, - struct bus_type *bus); - -#endif /* _ASM_SPARC64_OF_PLATFORM_H */ diff --git a/trunk/include/asm-sparc64/oplib.h b/trunk/include/asm-sparc64/oplib.h index 3f23c5dc5f21..992f9f7a476c 100644 --- a/trunk/include/asm-sparc64/oplib.h +++ b/trunk/include/asm-sparc64/oplib.h @@ -140,6 +140,32 @@ extern void prom_putchar(char character); extern void prom_printf(const char *fmt, ...); extern void prom_write(const char *buf, unsigned int len); +/* Query for input device type */ + +enum prom_input_device { + PROMDEV_IKBD, /* input from keyboard */ + PROMDEV_ITTYA, /* input from ttya */ + PROMDEV_ITTYB, /* input from ttyb */ + PROMDEV_IRSC, /* input from rsc */ + PROMDEV_IVCONS, /* input from virtual-console */ + PROMDEV_I_UNK, +}; + +extern enum prom_input_device prom_query_input_device(void); + +/* Query for output device type */ + +enum prom_output_device { + PROMDEV_OSCREEN, /* to screen */ + PROMDEV_OTTYA, /* to ttya */ + PROMDEV_OTTYB, /* to ttyb */ + PROMDEV_ORSC, /* to rsc */ + PROMDEV_OVCONS, /* to virtual-console */ + PROMDEV_O_UNK, +}; + +extern enum prom_output_device prom_query_output_device(void); + /* Multiprocessor operations... */ #ifdef CONFIG_SMP /* Start the CPU with the given device tree node at the passed program @@ -293,8 +319,6 @@ extern int prom_inst2pkg(int); extern int prom_service_exists(const char *service_name); extern void prom_sun4v_guest_soft_state(void); -extern int prom_ihandle2path(int handle, char *buffer, int bufsize); - /* Client interface level routines. */ extern void prom_set_trap_table(unsigned long tba); extern void prom_set_trap_table_sun4v(unsigned long tba, unsigned long mmfsa); diff --git a/trunk/include/asm-sparc64/parport.h b/trunk/include/asm-sparc64/parport.h index 600afe5ae2e3..23cc63f049a8 100644 --- a/trunk/include/asm-sparc64/parport.h +++ b/trunk/include/asm-sparc64/parport.h @@ -8,9 +8,8 @@ #define _ASM_SPARC64_PARPORT_H 1 #include +#include #include -#include -#include #define PARPORT_PC_MAX_PORTS PARPORT_MAX @@ -36,12 +35,8 @@ static struct sparc_ebus_info { unsigned int addr; unsigned int count; int lock; - - struct parport *port; } sparc_ebus_dmas[PARPORT_PC_MAX_PORTS]; -static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS); - static __inline__ int request_dma(unsigned int dmanr, const char *device_id) { if (dmanr >= PARPORT_PC_MAX_PORTS) @@ -103,145 +98,117 @@ static __inline__ unsigned int get_dma_residue(unsigned int dmanr) return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info); } -static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id *match) +static int ebus_ecpp_p(struct linux_ebus_device *edev) { - unsigned long base = op->resource[0].start; - unsigned long config = op->resource[1].start; - unsigned long d_base = op->resource[2].start; - unsigned long d_len; - struct device_node *parent; - struct parport *p; - int slot, err; - - parent = op->node->parent; - if (!strcmp(parent->name, "dma")) { - p = parport_pc_probe_port(base, base + 0x400, - op->irqs[0], PARPORT_DMA_NOFIFO, - op->dev.parent); - if (!p) - return -ENOMEM; - dev_set_drvdata(&op->dev, p); - return 0; + if (!strcmp(edev->prom_node->name, "ecpp")) + return 1; + if (!strcmp(edev->prom_node->name, "parallel")) { + const char *compat; + + compat = of_get_property(edev->prom_node, + "compatible", NULL); + if (compat && + (!strcmp(compat, "ecpp") || + !strcmp(compat, "ns87317-ecpp") || + !strcmp(compat + 13, "ecpp"))) + return 1; } - - for (slot = 0; slot < PARPORT_PC_MAX_PORTS; slot++) { - if (!test_and_set_bit(slot, dma_slot_map)) - break; - } - err = -ENODEV; - if (slot >= PARPORT_PC_MAX_PORTS) - goto out_err; - - spin_lock_init(&sparc_ebus_dmas[slot].info.lock); - - d_len = (op->resource[2].end - d_base) + 1UL; - sparc_ebus_dmas[slot].info.regs = - of_ioremap(&op->resource[2], 0, d_len, "ECPP DMA"); - - if (!sparc_ebus_dmas[slot].info.regs) - goto out_clear_map; - - sparc_ebus_dmas[slot].info.flags = 0; - sparc_ebus_dmas[slot].info.callback = NULL; - sparc_ebus_dmas[slot].info.client_cookie = NULL; - sparc_ebus_dmas[slot].info.irq = 0xdeadbeef; - strcpy(sparc_ebus_dmas[slot].info.name, "parport"); - if (ebus_dma_register(&sparc_ebus_dmas[slot].info)) - goto out_unmap_regs; - - ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 1); - - /* Configure IRQ to Push Pull, Level Low */ - /* Enable ECP, set bit 2 of the CTR first */ - outb(0x04, base + 0x02); - ns87303_modify(config, PCR, - PCR_EPP_ENABLE | - PCR_IRQ_ODRAIN, - PCR_ECP_ENABLE | - PCR_ECP_CLK_ENA | - PCR_IRQ_POLAR); - - /* CTR bit 5 controls direction of port */ - ns87303_modify(config, PTR, - 0, PTR_LPT_REG_DIR); - - p = parport_pc_probe_port(base, base + 0x400, - op->irqs[0], - slot, - op->dev.parent); - err = -ENOMEM; - if (!p) - goto out_disable_irq; - - dev_set_drvdata(&op->dev, p); - return 0; - -out_disable_irq: - ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0); - ebus_dma_unregister(&sparc_ebus_dmas[slot].info); - -out_unmap_regs: - of_iounmap(&op->resource[2], sparc_ebus_dmas[slot].info.regs, d_len); - -out_clear_map: - clear_bit(slot, dma_slot_map); - -out_err: - return err; } -static int __devexit ecpp_remove(struct of_device *op) +static int parport_isa_probe(int count) { - struct parport *p = dev_get_drvdata(&op->dev); - int slot = p->dma; - - parport_pc_unregister_port(p); - - if (slot != PARPORT_DMA_NOFIFO) { - unsigned long d_base = op->resource[2].start; - unsigned long d_len; - - d_len = (op->resource[2].end - d_base) + 1UL; - - ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0); - ebus_dma_unregister(&sparc_ebus_dmas[slot].info); - of_iounmap(&op->resource[2], - sparc_ebus_dmas[slot].info.regs, - d_len); - clear_bit(slot, dma_slot_map); + struct sparc_isa_bridge *isa_br; + struct sparc_isa_device *isa_dev; + + for_each_isa(isa_br) { + for_each_isadev(isa_dev, isa_br) { + struct sparc_isa_device *child; + unsigned long base; + + if (strcmp(isa_dev->prom_node->name, "dma")) + continue; + + child = isa_dev->child; + while (child) { + if (!strcmp(child->prom_node->name, "parallel")) + break; + child = child->next; + } + if (!child) + continue; + + base = child->resource.start; + + /* No DMA, see commentary in + * asm-sparc64/floppy.h:isa_floppy_init() + */ + if (parport_pc_probe_port(base, base + 0x400, + child->irq, PARPORT_DMA_NOFIFO, + &child->bus->self->dev)) + count++; + } } - return 0; + return count; } -static struct of_device_id ecpp_match[] = { - { - .name = "ecpp", - }, - { - .name = "parallel", - .compatible = "ecpp", - }, - { - .name = "parallel", - .compatible = "ns87317-ecpp", - }, - {}, -}; - -static struct of_platform_driver ecpp_driver = { - .name = "ecpp", - .match_table = ecpp_match, - .probe = ecpp_probe, - .remove = __devexit_p(ecpp_remove), -}; - -static int parport_pc_find_nonpci_ports(int autoirq, int autodma) +static int parport_pc_find_nonpci_ports (int autoirq, int autodma) { - of_register_driver(&ecpp_driver, &of_bus_type); + struct linux_ebus *ebus; + struct linux_ebus_device *edev; + int count = 0; + + for_each_ebus(ebus) { + for_each_ebusdev(edev, ebus) { + if (ebus_ecpp_p(edev)) { + unsigned long base = edev->resource[0].start; + unsigned long config = edev->resource[1].start; + unsigned long d_base = edev->resource[2].start; + unsigned long d_len; + + spin_lock_init(&sparc_ebus_dmas[count].info.lock); + d_len = (edev->resource[2].end - + d_base) + 1; + sparc_ebus_dmas[count].info.regs = + ioremap(d_base, d_len); + if (!sparc_ebus_dmas[count].info.regs) + continue; + sparc_ebus_dmas[count].info.flags = 0; + sparc_ebus_dmas[count].info.callback = NULL; + sparc_ebus_dmas[count].info.client_cookie = NULL; + sparc_ebus_dmas[count].info.irq = 0xdeadbeef; + strcpy(sparc_ebus_dmas[count].info.name, "parport"); + if (ebus_dma_register(&sparc_ebus_dmas[count].info)) + continue; + ebus_dma_irq_enable(&sparc_ebus_dmas[count].info, 1); + + /* Configure IRQ to Push Pull, Level Low */ + /* Enable ECP, set bit 2 of the CTR first */ + outb(0x04, base + 0x02); + ns87303_modify(config, PCR, + PCR_EPP_ENABLE | + PCR_IRQ_ODRAIN, + PCR_ECP_ENABLE | + PCR_ECP_CLK_ENA | + PCR_IRQ_POLAR); + + /* CTR bit 5 controls direction of port */ + ns87303_modify(config, PTR, + 0, PTR_LPT_REG_DIR); + + if (parport_pc_probe_port(base, base + 0x400, + edev->irqs[0], + count, + &ebus->self->dev)) + count++; + } + } + } - return 0; + count = parport_isa_probe(count); + + return count; } #endif /* !(_ASM_SPARC64_PARPORT_H */ diff --git a/trunk/include/asm-sparc64/power.h b/trunk/include/asm-sparc64/power.h new file mode 100644 index 000000000000..94495c1ac4f6 --- /dev/null +++ b/trunk/include/asm-sparc64/power.h @@ -0,0 +1,7 @@ +#ifndef _SPARC64_POWER_H +#define _SPARC64_POWER_H + +extern void wake_up_powerd(void); +extern int start_powerd(void); + +#endif /* !(_SPARC64_POWER_H) */ diff --git a/trunk/include/asm-sparc64/prom.h b/trunk/include/asm-sparc64/prom.h index 31dcb92fbae0..b4df3042add0 100644 --- a/trunk/include/asm-sparc64/prom.h +++ b/trunk/include/asm-sparc64/prom.h @@ -2,6 +2,7 @@ #define _SPARC64_PROM_H #ifdef __KERNEL__ + /* * Definitions for talking to the Open Firmware PROM on * Power Macintosh computers. @@ -16,17 +17,11 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ + #include #include #include -#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 2 -#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1 - -#define of_compat_cmp(s1, s2, l) strncmp((s1), (s2), (l)) -#define of_prop_cmp(s1, s2) strcasecmp((s1), (s2)) -#define of_node_cmp(s1, s2) strcmp((s1), (s2)) - typedef u32 phandle; typedef u32 ihandle; @@ -68,35 +63,54 @@ struct of_irq_controller { void *data; }; +/* flag descriptions */ +#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */ + #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags) #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags) +#define OF_BAD_ADDR ((u64)-1) + +static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de) +{ + dn->pde = de; +} + +extern struct device_node *of_find_node_by_name(struct device_node *from, + const char *name); +#define for_each_node_by_name(dn, name) \ + for (dn = of_find_node_by_name(NULL, name); dn; \ + dn = of_find_node_by_name(dn, name)) +extern struct device_node *of_find_node_by_type(struct device_node *from, + const char *type); +#define for_each_node_by_type(dn, type) \ + for (dn = of_find_node_by_type(NULL, type); dn; \ + dn = of_find_node_by_type(dn, type)) +extern struct device_node *of_find_compatible_node(struct device_node *from, + const char *type, const char *compat); +extern struct device_node *of_find_node_by_path(const char *path); +extern struct device_node *of_find_node_by_phandle(phandle handle); extern struct device_node *of_find_node_by_cpuid(int cpuid); +extern struct device_node *of_get_parent(const struct device_node *node); +extern struct device_node *of_get_next_child(const struct device_node *node, + struct device_node *prev); +extern struct property *of_find_property(const struct device_node *np, + const char *name, + int *lenp); +extern int of_device_is_compatible(const struct device_node *device, + const char *); +extern const void *of_get_property(const struct device_node *node, + const char *name, + int *lenp); +#define get_property(node,name,lenp) of_get_property(node,name,lenp) extern int of_set_property(struct device_node *node, const char *name, void *val, int len); extern int of_getintprop_default(struct device_node *np, const char *name, int def); +extern int of_n_addr_cells(struct device_node *np); +extern int of_n_size_cells(struct device_node *np); extern void prom_build_devicetree(void); -/* Dummy ref counting routines - to be implemented later */ -static inline struct device_node *of_node_get(struct device_node *node) -{ - return node; -} -static inline void of_node_put(struct device_node *node) -{ -} - -/* - * NB: This is here while we transition from using asm/prom.h - * to linux/of.h - */ -#include - -extern struct device_node *of_console_device; -extern char *of_console_path; -extern char *of_console_options; - #endif /* __KERNEL__ */ #endif /* _SPARC64_PROM_H */ diff --git a/trunk/include/asm-sparc64/system.h b/trunk/include/asm-sparc64/system.h index 64891cb10f05..409067408eec 100644 --- a/trunk/include/asm-sparc64/system.h +++ b/trunk/include/asm-sparc64/system.h @@ -115,8 +115,14 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \ #ifndef __ASSEMBLY__ extern void sun_do_break(void); +extern int serial_console; extern int stop_a_enabled; +static __inline__ int con_is_present(void) +{ + return serial_console ? 0 : 1; +} + extern void synchronize_user_stack(void); extern void __flushw_user(void); diff --git a/trunk/include/asm-sparc64/unistd.h b/trunk/include/asm-sparc64/unistd.h index cb751b4d0f56..53e96ed9c024 100644 --- a/trunk/include/asm-sparc64/unistd.h +++ b/trunk/include/asm-sparc64/unistd.h @@ -1,3 +1,4 @@ +/* $Id: unistd.h,v 1.50 2002/02/08 03:57:18 davem Exp $ */ #ifndef _SPARC64_UNISTD_H #define _SPARC64_UNISTD_H @@ -8,7 +9,7 @@ * think of right now to force the arguments into fixed registers * before the trap into the system call with gcc 'asm' statements. * - * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * * SunOS compatibility based upon preliminary work which is: * @@ -331,9 +332,8 @@ #define __NR_signalfd 311 #define __NR_timerfd 312 #define __NR_eventfd 313 -#define __NR_fallocate 314 -#define NR_SYSCALLS 315 +#define NR_SYSCALLS 314 #ifdef __KERNEL__ /* sysconf options, for SunOS compatibility */ diff --git a/trunk/include/asm-sparc64/vio.h b/trunk/include/asm-sparc64/vio.h index f7417e91b170..c0a8d4ed5bcb 100644 --- a/trunk/include/asm-sparc64/vio.h +++ b/trunk/include/asm-sparc64/vio.h @@ -275,8 +275,6 @@ struct vio_dev { char compat[VIO_MAX_COMPAT_LEN]; int compat_len; - u64 dev_no; - unsigned long channel_id; unsigned int tx_irq; diff --git a/trunk/include/linux/async_tx.h b/trunk/include/linux/async_tx.h index bdca3f1b3213..ff1255079fa1 100644 --- a/trunk/include/linux/async_tx.h +++ b/trunk/include/linux/async_tx.h @@ -51,6 +51,10 @@ struct dma_chan_ref { * @ASYNC_TX_ACK: immediately ack the descriptor, precludes setting up a * dependency chain * @ASYNC_TX_DEP_ACK: ack the dependency descriptor. Useful for chaining. + * @ASYNC_TX_KMAP_SRC: if the transaction is to be performed synchronously + * take an atomic mapping (KM_USER0) on the source page(s) + * @ASYNC_TX_KMAP_DST: if the transaction is to be performed synchronously + * take an atomic mapping (KM_USER0) on the dest page(s) */ enum async_tx_flags { ASYNC_TX_XOR_ZERO_DST = (1 << 0), @@ -58,6 +62,8 @@ enum async_tx_flags { ASYNC_TX_ASSUME_COHERENT = (1 << 2), ASYNC_TX_ACK = (1 << 3), ASYNC_TX_DEP_ACK = (1 << 4), + ASYNC_TX_KMAP_SRC = (1 << 5), + ASYNC_TX_KMAP_DST = (1 << 6), }; #ifdef CONFIG_DMA_ENGINE diff --git a/trunk/include/linux/clocksource.h b/trunk/include/linux/clocksource.h index 16ea3374dddf..bf297b03a4e4 100644 --- a/trunk/include/linux/clocksource.h +++ b/trunk/include/linux/clocksource.h @@ -67,12 +67,6 @@ struct clocksource { unsigned long flags; cycle_t (*vread)(void); void (*resume)(void); -#ifdef CONFIG_IA64 - void *fsys_mmio; /* used by fsyscall asm code */ -#define CLKSRC_FSYS_MMIO_SET(mmio, addr) ((mmio) = (addr)) -#else -#define CLKSRC_FSYS_MMIO_SET(mmio, addr) do { } while (0) -#endif /* timekeeping specific data, ignore */ cycle_t cycle_interval; diff --git a/trunk/include/linux/dcookies.h b/trunk/include/linux/dcookies.h index 98c69ab80c84..0fe7cdf326f7 100644 --- a/trunk/include/linux/dcookies.h +++ b/trunk/include/linux/dcookies.h @@ -12,7 +12,6 @@ #ifdef CONFIG_PROFILING -#include #include struct dcookie_user; diff --git a/trunk/include/linux/elf-em.h b/trunk/include/linux/elf-em.h index 5834e843a946..0311bad838b1 100644 --- a/trunk/include/linux/elf-em.h +++ b/trunk/include/linux/elf-em.h @@ -20,8 +20,7 @@ #define EM_PARISC 15 /* HPPA */ #define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ #define EM_PPC 20 /* PowerPC */ -#define EM_PPC64 21 /* PowerPC64 */ -#define EM_SPU 23 /* Cell BE SPU */ +#define EM_PPC64 21 /* PowerPC64 */ #define EM_SH 42 /* SuperH */ #define EM_SPARCV9 43 /* SPARC v9 64-bit */ #define EM_IA_64 50 /* HP/Intel IA-64 */ diff --git a/trunk/include/linux/i2c-id.h b/trunk/include/linux/i2c-id.h index b69014865714..aa83d4163096 100644 --- a/trunk/include/linux/i2c-id.h +++ b/trunk/include/linux/i2c-id.h @@ -115,10 +115,9 @@ #define I2C_DRIVERID_KS0127 86 /* Samsung ks0127 video decoder */ #define I2C_DRIVERID_TLV320AIC23B 87 /* TI TLV320AIC23B audio codec */ #define I2C_DRIVERID_ISL1208 88 /* Intersil ISL1208 RTC */ -#define I2C_DRIVERID_WM8731 89 /* Wolfson WM8731 audio codec */ -#define I2C_DRIVERID_WM8750 90 /* Wolfson WM8750 audio codec */ -#define I2C_DRIVERID_WM8753 91 /* Wolfson WM8753 audio codec */ -#define I2C_DRIVERID_LM4857 92 /* LM4857 Audio Amplifier */ +#define I2C_DRIVERID_WM8731 89 /* Wolfson WM8731 audio codec */ +#define I2C_DRIVERID_WM8750 90 /* Wolfson WM8750 audio codec */ +#define I2C_DRIVERID_WM8753 91 /* Wolfson WM8753 audio codec */ #define I2C_DRIVERID_I2CDEV 900 #define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ diff --git a/trunk/include/linux/input.h b/trunk/include/linux/input.h index e02c6a66b2ba..18c98b543030 100644 --- a/trunk/include/linux/input.h +++ b/trunk/include/linux/input.h @@ -344,8 +344,7 @@ struct input_absinfo { #define KEY_BRIGHTNESSUP 225 #define KEY_MEDIA 226 -#define KEY_SWITCHVIDEOMODE 227 /* Cycle between available video - outputs (Monitor/LCD/TV-out/etc) */ +#define KEY_SWITCHVIDEOMODE 227 #define KEY_KBDILLUMTOGGLE 228 #define KEY_KBDILLUMDOWN 229 #define KEY_KBDILLUMUP 230 diff --git a/trunk/include/linux/ioprio.h b/trunk/include/linux/ioprio.h index baf29387cab4..2eaa142cd061 100644 --- a/trunk/include/linux/ioprio.h +++ b/trunk/include/linux/ioprio.h @@ -53,14 +53,6 @@ static inline int task_ioprio(struct task_struct *task) return IOPRIO_NORM; } -static inline int task_ioprio_class(struct task_struct *task) -{ - if (ioprio_valid(task->ioprio)) - return IOPRIO_PRIO_CLASS(task->ioprio); - - return IOPRIO_CLASS_BE; -} - static inline int task_nice_ioprio(struct task_struct *task) { return (task_nice(task) + 20) / 5; diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index be5a43928c84..47cd2a1c5544 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -323,7 +323,6 @@ enum ata_completion_errors { AC_ERR_INVALID = (1 << 7), /* invalid argument */ AC_ERR_OTHER = (1 << 8), /* unknown */ AC_ERR_NODEV_HINT = (1 << 9), /* polling device detection hint */ - AC_ERR_NCQ = (1 << 10), /* marker for offending NCQ qc */ }; /* forward declarations */ @@ -531,7 +530,6 @@ struct ata_port { unsigned int cbl; /* cable type; ATA_CBL_xxx */ unsigned int hw_sata_spd_limit; unsigned int sata_spd_limit; /* SATA PHY speed limit */ - unsigned int sata_spd; /* current SATA PHY speed */ /* record runtime error info, protected by host lock */ struct ata_eh_info eh_info; @@ -565,9 +563,6 @@ struct ata_port { pm_message_t pm_mesg; int *pm_result; - struct timer_list fastdrain_timer; - unsigned long fastdrain_cnt; - void *private_data; #ifdef CONFIG_ATA_ACPI @@ -624,8 +619,9 @@ struct ata_port_operations { u8 (*irq_on) (struct ata_port *); u8 (*irq_ack) (struct ata_port *ap, unsigned int chk_drq); - int (*scr_read) (struct ata_port *ap, unsigned int sc_reg, u32 *val); - int (*scr_write) (struct ata_port *ap, unsigned int sc_reg, u32 val); + u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); + void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, + u32 val); int (*port_suspend) (struct ata_port *ap, pm_message_t mesg); int (*port_resume) (struct ata_port *ap); @@ -768,8 +764,7 @@ extern unsigned int ata_dev_try_classify(struct ata_port *, unsigned int, u8 *); */ extern void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf); -extern void ata_tf_to_fis(const struct ata_taskfile *tf, - u8 pmp, int is_cmd, u8 *fis); +extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp); extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device); extern void ata_std_dev_select (struct ata_port *ap, unsigned int device); @@ -914,21 +909,27 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, /* * ata_eh_info helpers */ -extern void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...); -extern void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...); -extern void ata_ehi_clear_desc(struct ata_eh_info *ehi); - -static inline void ata_ehi_schedule_probe(struct ata_eh_info *ehi) +#define ata_ehi_push_desc(ehi, fmt, args...) do { \ + (ehi)->desc_len += scnprintf((ehi)->desc + (ehi)->desc_len, \ + ATA_EH_DESC_LEN - (ehi)->desc_len, \ + fmt , ##args); \ +} while (0) + +#define ata_ehi_clear_desc(ehi) do { \ + (ehi)->desc[0] = '\0'; \ + (ehi)->desc_len = 0; \ +} while (0) + +static inline void __ata_ehi_hotplugged(struct ata_eh_info *ehi) { - ehi->flags |= ATA_EHI_RESUME_LINK; + ehi->flags |= ATA_EHI_HOTPLUGGED | ATA_EHI_RESUME_LINK; ehi->action |= ATA_EH_SOFTRESET; ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1; } static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi) { - ata_ehi_schedule_probe(ehi); - ehi->flags |= ATA_EHI_HOTPLUGGED; + __ata_ehi_hotplugged(ehi); ehi->err_mask |= AC_ERR_ATA_BUS; } diff --git a/trunk/include/linux/of.h b/trunk/include/linux/of.h deleted file mode 100644 index 47734ffd9745..000000000000 --- a/trunk/include/linux/of.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef _LINUX_OF_H -#define _LINUX_OF_H -/* - * Definitions for talking to the Open Firmware PROM on - * Power Macintosh and other computers. - * - * Copyright (C) 1996-2005 Paul Mackerras. - * - * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp. - * Updates for SPARC64 by David S. Miller - * Derived from PowerPC and Sparc prom.h files by Stephen Rothwell, IBM Corp. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include - -#include -#include - -/* flag descriptions */ -#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */ -#define OF_DETACHED 2 /* node has been detached from the device tree */ - -#define OF_BAD_ADDR ((u64)-1) - -extern struct device_node *of_find_node_by_name(struct device_node *from, - const char *name); -#define for_each_node_by_name(dn, name) \ - for (dn = of_find_node_by_name(NULL, name); dn; \ - dn = of_find_node_by_name(dn, name)) -extern struct device_node *of_find_node_by_type(struct device_node *from, - const char *type); -#define for_each_node_by_type(dn, type) \ - for (dn = of_find_node_by_type(NULL, type); dn; \ - dn = of_find_node_by_type(dn, type)) -extern struct device_node *of_find_compatible_node(struct device_node *from, - const char *type, const char *compat); -#define for_each_compatible_node(dn, type, compatible) \ - for (dn = of_find_compatible_node(NULL, type, compatible); dn; \ - dn = of_find_compatible_node(dn, type, compatible)) -extern struct device_node *of_find_node_by_path(const char *path); -extern struct device_node *of_find_node_by_phandle(phandle handle); -extern struct device_node *of_get_parent(const struct device_node *node); -extern struct device_node *of_get_next_child(const struct device_node *node, - struct device_node *prev); -extern struct property *of_find_property(const struct device_node *np, - const char *name, - int *lenp); -extern int of_device_is_compatible(const struct device_node *device, - const char *); -extern const void *of_get_property(const struct device_node *node, - const char *name, - int *lenp); -#define get_property(a, b, c) of_get_property((a), (b), (c)) -extern int of_n_addr_cells(struct device_node *np); -extern int of_n_size_cells(struct device_node *np); - -#endif /* _LINUX_OF_H */ diff --git a/trunk/include/linux/of_device.h b/trunk/include/linux/of_device.h deleted file mode 100644 index 91bf84b9d144..000000000000 --- a/trunk/include/linux/of_device.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _LINUX_OF_DEVICE_H -#define _LINUX_OF_DEVICE_H -#ifdef __KERNEL__ - -#include -#include -#include - -#include - -#define to_of_device(d) container_of(d, struct of_device, dev) - -extern const struct of_device_id *of_match_node( - const struct of_device_id *matches, const struct device_node *node); -extern const struct of_device_id *of_match_device( - const struct of_device_id *matches, const struct of_device *dev); - -extern struct of_device *of_dev_get(struct of_device *dev); -extern void of_dev_put(struct of_device *dev); - -extern int of_device_register(struct of_device *ofdev); -extern void of_device_unregister(struct of_device *ofdev); -extern void of_release_dev(struct device *dev); - -#endif /* __KERNEL__ */ -#endif /* _LINUX_OF_DEVICE_H */ diff --git a/trunk/include/linux/of_platform.h b/trunk/include/linux/of_platform.h deleted file mode 100644 index 5fd44e63fb26..000000000000 --- a/trunk/include/linux/of_platform.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _LINUX_OF_PLATFORM_H -#define _LINUX_OF_PLATFORM_H -/* - * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include - -/* - * The of_platform_bus_type is a bus type used by drivers that do not - * attach to a macio or similar bus but still use OF probing - * mechanism - */ -extern struct bus_type of_platform_bus_type; - -/* - * An of_platform_driver driver is attached to a basic of_device on - * the "platform bus" (of_platform_bus_type) (or ISA, EBUS and SBUS - * busses on sparc). - */ -struct of_platform_driver -{ - char *name; - struct of_device_id *match_table; - struct module *owner; - - int (*probe)(struct of_device* dev, - const struct of_device_id *match); - int (*remove)(struct of_device* dev); - - int (*suspend)(struct of_device* dev, pm_message_t state); - int (*resume)(struct of_device* dev); - int (*shutdown)(struct of_device* dev); - - struct device_driver driver; -}; -#define to_of_platform_driver(drv) \ - container_of(drv,struct of_platform_driver, driver) - -#include - -extern struct of_device *of_find_device_by_node(struct device_node *np); - -extern int of_bus_type_init(struct bus_type *bus, const char *name); - -#endif /* _LINUX_OF_PLATFORM_H */ diff --git a/trunk/include/linux/oprofile.h b/trunk/include/linux/oprofile.h index 041bb31100f4..0d514b252454 100644 --- a/trunk/include/linux/oprofile.h +++ b/trunk/include/linux/oprofile.h @@ -17,26 +17,6 @@ #include #include -/* Each escaped entry is prefixed by ESCAPE_CODE - * then one of the following codes, then the - * relevant data. - * These #defines live in this file so that arch-specific - * buffer sync'ing code can access them. - */ -#define ESCAPE_CODE ~0UL -#define CTX_SWITCH_CODE 1 -#define CPU_SWITCH_CODE 2 -#define COOKIE_SWITCH_CODE 3 -#define KERNEL_ENTER_SWITCH_CODE 4 -#define KERNEL_EXIT_SWITCH_CODE 5 -#define MODULE_LOADED_CODE 6 -#define CTX_TGID_CODE 7 -#define TRACE_BEGIN_CODE 8 -#define TRACE_END_CODE 9 -#define XEN_ENTER_SWITCH_CODE 10 -#define SPU_PROFILING_CODE 11 -#define SPU_CTX_SWITCH_CODE 12 - struct super_block; struct dentry; struct file_operations; @@ -55,14 +35,6 @@ struct oprofile_operations { int (*start)(void); /* Stop delivering interrupts. */ void (*stop)(void); - /* Arch-specific buffer sync functions. - * Return value = 0: Success - * Return value = -1: Failure - * Return value = 1: Run generic sync function - */ - int (*sync_start)(void); - int (*sync_stop)(void); - /* Initiate a stack backtrace. Optional. */ void (*backtrace)(struct pt_regs * const regs, unsigned int depth); /* CPU identification string. */ @@ -83,13 +55,6 @@ int oprofile_arch_init(struct oprofile_operations * ops); */ void oprofile_arch_exit(void); -/** - * Add data to the event buffer. - * The data passed is free-form, but typically consists of - * file offsets, dcookies, context information, and ESCAPE codes. - */ -void add_event_entry(unsigned long data); - /** * Add a sample. This may be called from any context. Pass * smp_processor_id() as cpu. diff --git a/trunk/include/linux/serio.h b/trunk/include/linux/serio.h index 9f3825014674..d9377ce9ffd1 100644 --- a/trunk/include/linux/serio.h +++ b/trunk/include/linux/serio.h @@ -210,6 +210,5 @@ static inline void serio_unpin_driver(struct serio *serio) #define SERIO_TOUCHRIGHT 0x32 #define SERIO_TOUCHWIN 0x33 #define SERIO_TAOSEVM 0x34 -#define SERIO_FUJITSU 0x35 #endif diff --git a/trunk/include/linux/slab.h b/trunk/include/linux/slab.h index d859354b9e51..7d0ecc1659f0 100644 --- a/trunk/include/linux/slab.h +++ b/trunk/include/linux/slab.h @@ -40,7 +40,7 @@ */ #define ZERO_SIZE_PTR ((void *)16) -#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \ +#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) < \ (unsigned long)ZERO_SIZE_PTR) /* diff --git a/trunk/include/linux/slub_def.h b/trunk/include/linux/slub_def.h index 124270df8734..07f7e4cbcee3 100644 --- a/trunk/include/linux/slub_def.h +++ b/trunk/include/linux/slub_def.h @@ -160,7 +160,7 @@ static inline struct kmem_cache *kmalloc_slab(size_t size) #define SLUB_DMA __GFP_DMA #else /* Disable DMA functionality */ -#define SLUB_DMA (__force gfp_t)0 +#define SLUB_DMA 0 #endif void *kmem_cache_alloc(struct kmem_cache *, gfp_t); diff --git a/trunk/include/linux/spi/ads7846.h b/trunk/include/linux/spi/ads7846.h index 334d31411629..3387e44dfd13 100644 --- a/trunk/include/linux/spi/ads7846.h +++ b/trunk/include/linux/spi/ads7846.h @@ -16,20 +16,6 @@ struct ads7846_platform_data { u16 vref_delay_usecs; /* 0 for external vref; etc */ int keep_vref_on:1; /* set to keep vref on for differential * measurements as well */ - - /* Settling time of the analog signals; a function of Vcc and the - * capacitance on the X/Y drivers. If set to non-zero, two samples - * are taken with settle_delay us apart, and the second one is used. - * ~150 uSec with 0.01uF caps. - */ - u16 settle_delay_usecs; - - /* If set to non-zero, after samples are taken this delay is applied - * and penirq is rechecked, to help avoid false events. This value - * is affected by the material used to build the touch layer. - */ - u16 penirq_recheck_delay_usecs; - u16 x_plate_ohms; u16 y_plate_ohms; diff --git a/trunk/include/linux/syscalls.h b/trunk/include/linux/syscalls.h index 61def7c8fbb3..7a8b1e3322e0 100644 --- a/trunk/include/linux/syscalls.h +++ b/trunk/include/linux/syscalls.h @@ -549,7 +549,7 @@ asmlinkage long sys_inotify_rm_watch(int fd, u32 wd); asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus); asmlinkage long sys_spu_create(const char __user *name, - unsigned int flags, mode_t mode, int fd); + unsigned int flags, mode_t mode); asmlinkage long sys_mknodat(int dfd, const char __user * filename, int mode, unsigned dev); diff --git a/trunk/include/linux/timex.h b/trunk/include/linux/timex.h index 37ac3ff90faf..da929dbbea2a 100644 --- a/trunk/include/linux/timex.h +++ b/trunk/include/linux/timex.h @@ -224,6 +224,66 @@ static inline int ntp_synced(void) __x < 0 ? -(-__x >> __s) : __x >> __s; \ }) + +#ifdef CONFIG_TIME_INTERPOLATION + +#define TIME_SOURCE_CPU 0 +#define TIME_SOURCE_MMIO64 1 +#define TIME_SOURCE_MMIO32 2 +#define TIME_SOURCE_FUNCTION 3 + +/* For proper operations time_interpolator clocks must run slightly slower + * than the standard clock since the interpolator may only correct by having + * time jump forward during a tick. A slower clock is usually a side effect + * of the integer divide of the nanoseconds in a second by the frequency. + * The accuracy of the division can be increased by specifying a shift. + * However, this may cause the clock not to be slow enough. + * The interpolator will self-tune the clock by slowing down if no + * resets occur or speeding up if the time jumps per analysis cycle + * become too high. + * + * Setting jitter compensates for a fluctuating timesource by comparing + * to the last value read from the timesource to insure that an earlier value + * is not returned by a later call. The price to pay + * for the compensation is that the timer routines are not as scalable anymore. + */ + +struct time_interpolator { + u16 source; /* time source flags */ + u8 shift; /* increases accuracy of multiply by shifting. */ + /* Note that bits may be lost if shift is set too high */ + u8 jitter; /* if set compensate for fluctuations */ + u32 nsec_per_cyc; /* set by register_time_interpolator() */ + void *addr; /* address of counter or function */ + cycles_t mask; /* mask the valid bits of the counter */ + unsigned long offset; /* nsec offset at last update of interpolator */ + u64 last_counter; /* counter value in units of the counter at last update */ + cycles_t last_cycle; /* Last timer value if TIME_SOURCE_JITTER is set */ + u64 frequency; /* frequency in counts/second */ + long drift; /* drift in parts-per-million (or -1) */ + unsigned long skips; /* skips forward */ + unsigned long ns_skipped; /* nanoseconds skipped */ + struct time_interpolator *next; +}; + +extern void register_time_interpolator(struct time_interpolator *); +extern void unregister_time_interpolator(struct time_interpolator *); +extern void time_interpolator_reset(void); +extern unsigned long time_interpolator_get_offset(void); +extern void time_interpolator_update(long delta_nsec); + +#else /* !CONFIG_TIME_INTERPOLATION */ + +static inline void time_interpolator_reset(void) +{ +} + +static inline void time_interpolator_update(long delta_nsec) +{ +} + +#endif /* !CONFIG_TIME_INTERPOLATION */ + #define TICK_LENGTH_SHIFT 32 #ifdef CONFIG_NO_HZ diff --git a/trunk/include/linux/videodev2.h b/trunk/include/linux/videodev2.h index c66c8a3410b9..d16a2b57dc81 100644 --- a/trunk/include/linux/videodev2.h +++ b/trunk/include/linux/videodev2.h @@ -60,7 +60,6 @@ #include /* need __user */ #else #define __user -#include #endif #include diff --git a/trunk/include/sound/ak4xxx-adda.h b/trunk/include/sound/ak4xxx-adda.h index fd0a6c46f497..aa49dda4f410 100644 --- a/trunk/include/sound/ak4xxx-adda.h +++ b/trunk/include/sound/ak4xxx-adda.h @@ -43,7 +43,6 @@ struct snd_ak4xxx_ops { struct snd_akm4xxx_dac_channel { char *name; /* mixer volume name */ unsigned int num_channels; - char *switch_name; /* mixer switch*/ }; /* ADC labels and channels */ diff --git a/trunk/include/sound/cs46xx.h b/trunk/include/sound/cs46xx.h index 353910ce9755..685928e6f65a 100644 --- a/trunk/include/sound/cs46xx.h +++ b/trunk/include/sound/cs46xx.h @@ -1723,10 +1723,6 @@ struct snd_cs46xx { struct snd_cs46xx_pcm *playback_pcm; unsigned int play_ctl; #endif - -#ifdef CONFIG_PM - u32 *saved_regs; -#endif }; int snd_cs46xx_create(struct snd_card *card, diff --git a/trunk/include/sound/cs46xx_dsp_spos.h b/trunk/include/sound/cs46xx_dsp_spos.h index d9da9e59cf37..da934def31e9 100644 --- a/trunk/include/sound/cs46xx_dsp_spos.h +++ b/trunk/include/sound/cs46xx_dsp_spos.h @@ -107,7 +107,6 @@ struct dsp_scb_descriptor { char scb_name[DSP_MAX_SCB_NAME]; u32 address; int index; - u32 *data; struct dsp_scb_descriptor * sub_list_ptr; struct dsp_scb_descriptor * next_scb_ptr; @@ -128,7 +127,6 @@ struct dsp_task_descriptor { int size; u32 address; int index; - u32 *data; }; struct dsp_pcm_channel_descriptor { diff --git a/trunk/include/sound/emu10k1.h b/trunk/include/sound/emu10k1.h index 529d0a564367..23e45a4cf0e4 100644 --- a/trunk/include/sound/emu10k1.h +++ b/trunk/include/sound/emu10k1.h @@ -1120,16 +1120,6 @@ /************************************************************************************************/ /* EMU1010m HANA Destinations */ /************************************************************************************************/ -/* 32-bit destinations of signal in the Hana FPGA. Destinations are either - * physical outputs of Hana, or outputs going to Alice2 (audigy) for capture - * - 16 x EMU_DST_ALICE2_EMU32_X. - */ -/* EMU32 = 32-bit serial channel between Alice2 (audigy) and Hana (FPGA) */ -/* EMU_DST_ALICE2_EMU32_X - data channels from Hana to Alice2 used for capture. - * Which data is fed into a EMU_DST_ALICE2_EMU32_X channel in Hana depends on - * setup of mixer control for each destination - see emumixer.c - - * snd_emu1010_output_enum_ctls[], snd_emu1010_input_enum_ctls[] - */ #define EMU_DST_ALICE2_EMU32_0 0x000f /* 16 EMU32 channels to Alice2 +0 to +0xf */ #define EMU_DST_ALICE2_EMU32_1 0x0000 /* 16 EMU32 channels to Alice2 +0 to +0xf */ #define EMU_DST_ALICE2_EMU32_2 0x0001 /* 16 EMU32 channels to Alice2 +0 to +0xf */ @@ -1209,12 +1199,6 @@ /************************************************************************************************/ /* EMU1010m HANA Sources */ /************************************************************************************************/ -/* 32-bit sources of signal in the Hana FPGA. The sources are routed to - * destinations using mixer control for each destination - see emumixer.c - * Sources are either physical inputs of FPGA, - * or outputs from Alice (audigy) - 16 x EMU_SRC_ALICE_EMU32A + - * 16 x EMU_SRC_ALICE_EMU32B - */ #define EMU_SRC_SILENCE 0x0000 /* Silence */ #define EMU_SRC_DOCK_MIC_A1 0x0100 /* Audio Dock Mic A, 1st or 48kHz only */ #define EMU_SRC_DOCK_MIC_A2 0x0101 /* Audio Dock Mic A, 2nd or 96kHz */ diff --git a/trunk/include/sound/sb.h b/trunk/include/sound/sb.h index 3ad854b397d2..2dd5c8e5b4fe 100644 --- a/trunk/include/sound/sb.h +++ b/trunk/include/sound/sb.h @@ -38,7 +38,6 @@ enum sb_hw_type { SB_HW_ALS100, /* Avance Logic ALS100 chip */ SB_HW_ALS4000, /* Avance Logic ALS4000 chip */ SB_HW_DT019X, /* Diamond Tech. DT-019X / Avance Logic ALS-007 */ - SB_HW_CS5530, /* Cyrix/NatSemi 5530 VSA1 */ }; #define SB_OPEN_PCM 0x01 diff --git a/trunk/include/sound/version.h b/trunk/include/sound/version.h index 6bbcfefd2c38..8e5b2f0f5946 100644 --- a/trunk/include/sound/version.h +++ b/trunk/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h. Generated by alsa/ksync script. */ #define CONFIG_SND_VERSION "1.0.14" -#define CONFIG_SND_DATE " (Fri Jul 20 09:12:58 2007 UTC)" +#define CONFIG_SND_DATE " (Thu May 31 09:03:25 2007 UTC)" diff --git a/trunk/include/sound/wavefront_fx.h b/trunk/include/sound/wavefront_fx.h new file mode 100644 index 000000000000..cec92b141796 --- /dev/null +++ b/trunk/include/sound/wavefront_fx.h @@ -0,0 +1,9 @@ +#ifndef __SOUND_WAVEFRONT_FX_H +#define __SOUND_WAVEFRONT_FX_H + +extern int snd_wavefront_fx_detect (snd_wavefront_t *); +extern void snd_wavefront_fx_ioctl (snd_synth_t *sdev, + unsigned int cmd, + unsigned long arg); + +#endif __SOUND_WAVEFRONT_FX_H diff --git a/trunk/kernel/ksysfs.c b/trunk/kernel/ksysfs.c index d0e5c48e18c7..2565e1b6dd7b 100644 --- a/trunk/kernel/ksysfs.c +++ b/trunk/kernel/ksysfs.c @@ -65,8 +65,8 @@ KERNEL_ATTR_RO(kexec_crash_loaded); /* * Make /sys/kernel/notes give the raw contents of our kernel .notes section. */ -extern const void __start_notes __attribute__((weak)); -extern const void __stop_notes __attribute__((weak)); +extern const char __start_notes __attribute__((weak)); +extern const char __stop_notes __attribute__((weak)); #define notes_size (&__stop_notes - &__start_notes) static ssize_t notes_read(struct kobject *kobj, struct bin_attribute *bin_attr, diff --git a/trunk/kernel/time.c b/trunk/kernel/time.c index 5b81da08bbdb..ffe19149d770 100644 --- a/trunk/kernel/time.c +++ b/trunk/kernel/time.c @@ -57,14 +57,17 @@ EXPORT_SYMBOL(sys_tz); */ asmlinkage long sys_time(time_t __user * tloc) { - time_t i; - struct timespec tv; + /* + * We read xtime.tv_sec atomically - it's updated + * atomically by update_wall_time(), so no need to + * even read-lock the xtime seqlock: + */ + time_t i = xtime.tv_sec; - getnstimeofday(&tv); - i = tv.tv_sec; + smp_rmb(); /* sys_time() results are coherent */ if (tloc) { - if (put_user(i,tloc)) + if (put_user(i, tloc)) i = -EFAULT; } return i; @@ -133,6 +136,7 @@ static inline void warp_clock(void) write_seqlock_irq(&xtime_lock); wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60; xtime.tv_sec += sys_tz.tz_minuteswest * 60; + time_interpolator_reset(); write_sequnlock_irq(&xtime_lock); clock_was_set(); } @@ -305,6 +309,92 @@ struct timespec timespec_trunc(struct timespec t, unsigned gran) } EXPORT_SYMBOL(timespec_trunc); +#ifdef CONFIG_TIME_INTERPOLATION +void getnstimeofday (struct timespec *tv) +{ + unsigned long seq,sec,nsec; + + do { + seq = read_seqbegin(&xtime_lock); + sec = xtime.tv_sec; + nsec = xtime.tv_nsec+time_interpolator_get_offset(); + } while (unlikely(read_seqretry(&xtime_lock, seq))); + + while (unlikely(nsec >= NSEC_PER_SEC)) { + nsec -= NSEC_PER_SEC; + ++sec; + } + tv->tv_sec = sec; + tv->tv_nsec = nsec; +} +EXPORT_SYMBOL_GPL(getnstimeofday); + +int do_settimeofday (struct timespec *tv) +{ + time_t wtm_sec, sec = tv->tv_sec; + long wtm_nsec, nsec = tv->tv_nsec; + + if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) + return -EINVAL; + + write_seqlock_irq(&xtime_lock); + { + wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); + wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); + + set_normalized_timespec(&xtime, sec, nsec); + set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); + + time_adjust = 0; /* stop active adjtime() */ + time_status |= STA_UNSYNC; + time_maxerror = NTP_PHASE_LIMIT; + time_esterror = NTP_PHASE_LIMIT; + time_interpolator_reset(); + } + write_sequnlock_irq(&xtime_lock); + clock_was_set(); + return 0; +} +EXPORT_SYMBOL(do_settimeofday); + +void do_gettimeofday (struct timeval *tv) +{ + unsigned long seq, nsec, usec, sec, offset; + do { + seq = read_seqbegin(&xtime_lock); + offset = time_interpolator_get_offset(); + sec = xtime.tv_sec; + nsec = xtime.tv_nsec; + } while (unlikely(read_seqretry(&xtime_lock, seq))); + + usec = (nsec + offset) / 1000; + + while (unlikely(usec >= USEC_PER_SEC)) { + usec -= USEC_PER_SEC; + ++sec; + } + + tv->tv_sec = sec; + tv->tv_usec = usec; + + /* + * Make sure xtime.tv_sec [returned by sys_time()] always + * follows the gettimeofday() result precisely. This + * condition is extremely unlikely, it can hit at most + * once per second: + */ + if (unlikely(xtime.tv_sec != tv->tv_sec)) { + unsigned long flags; + + write_seqlock_irqsave(&xtime_lock, flags); + update_wall_time(); + write_sequnlock_irqrestore(&xtime_lock, flags); + } +} +EXPORT_SYMBOL(do_gettimeofday); + +#else /* CONFIG_TIME_INTERPOLATION */ + #ifndef CONFIG_GENERIC_TIME /* * Simulate gettimeofday using do_gettimeofday which only allows a timeval @@ -320,6 +410,7 @@ void getnstimeofday(struct timespec *tv) } EXPORT_SYMBOL_GPL(getnstimeofday); #endif +#endif /* CONFIG_TIME_INTERPOLATION */ /* Converts Gregorian date to seconds since 1970-01-01 00:00:00. * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 diff --git a/trunk/kernel/time/ntp.c b/trunk/kernel/time/ntp.c index b5e352597cbb..438c6b723ee2 100644 --- a/trunk/kernel/time/ntp.c +++ b/trunk/kernel/time/ntp.c @@ -116,6 +116,11 @@ void second_overflow(void) if (xtime.tv_sec % 86400 == 0) { xtime.tv_sec--; wall_to_monotonic.tv_sec++; + /* + * The timer interpolator will make time change + * gradually instead of an immediate jump by one second + */ + time_interpolator_update(-NSEC_PER_SEC); time_state = TIME_OOP; printk(KERN_NOTICE "Clock: inserting leap second " "23:59:60 UTC\n"); @@ -125,6 +130,11 @@ void second_overflow(void) if ((xtime.tv_sec + 1) % 86400 == 0) { xtime.tv_sec++; wall_to_monotonic.tv_sec--; + /* + * Use of time interpolator for a gradual change of + * time + */ + time_interpolator_update(NSEC_PER_SEC); time_state = TIME_WAIT; printk(KERN_NOTICE "Clock: deleting leap second " "23:59:59 UTC\n"); diff --git a/trunk/kernel/time/timekeeping.c b/trunk/kernel/time/timekeeping.c index 88c81026e003..89698776613e 100644 --- a/trunk/kernel/time/timekeeping.c +++ b/trunk/kernel/time/timekeeping.c @@ -466,6 +466,10 @@ void update_wall_time(void) second_overflow(); } + /* interpolator bits */ + time_interpolator_update(clock->xtime_interval + >> clock->shift); + /* accumulate error between NTP and clock interval */ clock->error += current_tick_length(); clock->error -= clock->xtime_interval << (TICK_LENGTH_SHIFT - clock->shift); diff --git a/trunk/kernel/timer.c b/trunk/kernel/timer.c index 6ce1952eea7d..d1e8b975c7ae 100644 --- a/trunk/kernel/timer.c +++ b/trunk/kernel/timer.c @@ -1349,6 +1349,194 @@ void __init init_timers(void) open_softirq(TIMER_SOFTIRQ, run_timer_softirq, NULL); } +#ifdef CONFIG_TIME_INTERPOLATION + +struct time_interpolator *time_interpolator __read_mostly; +static struct time_interpolator *time_interpolator_list __read_mostly; +static DEFINE_SPINLOCK(time_interpolator_lock); + +static inline cycles_t time_interpolator_get_cycles(unsigned int src) +{ + unsigned long (*x)(void); + + switch (src) + { + case TIME_SOURCE_FUNCTION: + x = time_interpolator->addr; + return x(); + + case TIME_SOURCE_MMIO64 : + return readq_relaxed((void __iomem *)time_interpolator->addr); + + case TIME_SOURCE_MMIO32 : + return readl_relaxed((void __iomem *)time_interpolator->addr); + + default: return get_cycles(); + } +} + +static inline u64 time_interpolator_get_counter(int writelock) +{ + unsigned int src = time_interpolator->source; + + if (time_interpolator->jitter) + { + cycles_t lcycle; + cycles_t now; + + do { + lcycle = time_interpolator->last_cycle; + now = time_interpolator_get_cycles(src); + if (lcycle && time_after(lcycle, now)) + return lcycle; + + /* When holding the xtime write lock, there's no need + * to add the overhead of the cmpxchg. Readers are + * force to retry until the write lock is released. + */ + if (writelock) { + time_interpolator->last_cycle = now; + return now; + } + /* Keep track of the last timer value returned. The use of cmpxchg here + * will cause contention in an SMP environment. + */ + } while (unlikely(cmpxchg(&time_interpolator->last_cycle, lcycle, now) != lcycle)); + return now; + } + else + return time_interpolator_get_cycles(src); +} + +void time_interpolator_reset(void) +{ + time_interpolator->offset = 0; + time_interpolator->last_counter = time_interpolator_get_counter(1); +} + +#define GET_TI_NSECS(count,i) (((((count) - i->last_counter) & (i)->mask) * (i)->nsec_per_cyc) >> (i)->shift) + +unsigned long time_interpolator_get_offset(void) +{ + /* If we do not have a time interpolator set up then just return zero */ + if (!time_interpolator) + return 0; + + return time_interpolator->offset + + GET_TI_NSECS(time_interpolator_get_counter(0), time_interpolator); +} + +#define INTERPOLATOR_ADJUST 65536 +#define INTERPOLATOR_MAX_SKIP 10*INTERPOLATOR_ADJUST + +void time_interpolator_update(long delta_nsec) +{ + u64 counter; + unsigned long offset; + + /* If there is no time interpolator set up then do nothing */ + if (!time_interpolator) + return; + + /* + * The interpolator compensates for late ticks by accumulating the late + * time in time_interpolator->offset. A tick earlier than expected will + * lead to a reset of the offset and a corresponding jump of the clock + * forward. Again this only works if the interpolator clock is running + * slightly slower than the regular clock and the tuning logic insures + * that. + */ + + counter = time_interpolator_get_counter(1); + offset = time_interpolator->offset + + GET_TI_NSECS(counter, time_interpolator); + + if (delta_nsec < 0 || (unsigned long) delta_nsec < offset) + time_interpolator->offset = offset - delta_nsec; + else { + time_interpolator->skips++; + time_interpolator->ns_skipped += delta_nsec - offset; + time_interpolator->offset = 0; + } + time_interpolator->last_counter = counter; + + /* Tuning logic for time interpolator invoked every minute or so. + * Decrease interpolator clock speed if no skips occurred and an offset is carried. + * Increase interpolator clock speed if we skip too much time. + */ + if (jiffies % INTERPOLATOR_ADJUST == 0) + { + if (time_interpolator->skips == 0 && time_interpolator->offset > tick_nsec) + time_interpolator->nsec_per_cyc--; + if (time_interpolator->ns_skipped > INTERPOLATOR_MAX_SKIP && time_interpolator->offset == 0) + time_interpolator->nsec_per_cyc++; + time_interpolator->skips = 0; + time_interpolator->ns_skipped = 0; + } +} + +static inline int +is_better_time_interpolator(struct time_interpolator *new) +{ + if (!time_interpolator) + return 1; + return new->frequency > 2*time_interpolator->frequency || + (unsigned long)new->drift < (unsigned long)time_interpolator->drift; +} + +void +register_time_interpolator(struct time_interpolator *ti) +{ + unsigned long flags; + + /* Sanity check */ + BUG_ON(ti->frequency == 0 || ti->mask == 0); + + ti->nsec_per_cyc = ((u64)NSEC_PER_SEC << ti->shift) / ti->frequency; + spin_lock(&time_interpolator_lock); + write_seqlock_irqsave(&xtime_lock, flags); + if (is_better_time_interpolator(ti)) { + time_interpolator = ti; + time_interpolator_reset(); + } + write_sequnlock_irqrestore(&xtime_lock, flags); + + ti->next = time_interpolator_list; + time_interpolator_list = ti; + spin_unlock(&time_interpolator_lock); +} + +void +unregister_time_interpolator(struct time_interpolator *ti) +{ + struct time_interpolator *curr, **prev; + unsigned long flags; + + spin_lock(&time_interpolator_lock); + prev = &time_interpolator_list; + for (curr = *prev; curr; curr = curr->next) { + if (curr == ti) { + *prev = curr->next; + break; + } + prev = &curr->next; + } + + write_seqlock_irqsave(&xtime_lock, flags); + if (ti == time_interpolator) { + /* we lost the best time-interpolator: */ + time_interpolator = NULL; + /* find the next-best interpolator */ + for (curr = time_interpolator_list; curr; curr = curr->next) + if (is_better_time_interpolator(curr)) + time_interpolator = curr; + time_interpolator_reset(); + } + write_sequnlock_irqrestore(&xtime_lock, flags); + spin_unlock(&time_interpolator_lock); +} +#endif /* CONFIG_TIME_INTERPOLATION */ + /** * msleep - sleep safely even with waitqueue interruptions * @msecs: Time in milliseconds to sleep for diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 40954fb81598..43cb3b3e1679 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -138,7 +138,7 @@ static unsigned long __meminitdata dma_reserve; #endif /* CONFIG_MEMORY_HOTPLUG_RESERVE */ unsigned long __initdata required_kernelcore; unsigned long __initdata required_movablecore; - unsigned long __meminitdata zone_movable_pfn[MAX_NUMNODES]; + unsigned long __initdata zone_movable_pfn[MAX_NUMNODES]; /* movable_zone is the "real" zone pages in ZONE_MOVABLE are taken from */ int movable_zone; diff --git a/trunk/net/netfilter/nf_conntrack_helper.c b/trunk/net/netfilter/nf_conntrack_helper.c index ca10df40784f..b1179dd3d8c3 100644 --- a/trunk/net/netfilter/nf_conntrack_helper.c +++ b/trunk/net/netfilter/nf_conntrack_helper.c @@ -194,7 +194,7 @@ static struct nf_ct_ext_type helper_extend __read_mostly = { .id = NF_CT_EXT_HELPER, }; -int nf_conntrack_helper_init(void) +int nf_conntrack_helper_init() { int err; @@ -216,7 +216,7 @@ int nf_conntrack_helper_init(void) return err; } -void nf_conntrack_helper_fini(void) +void nf_conntrack_helper_fini() { nf_ct_extend_unregister(&helper_extend); nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_vmalloc, diff --git a/trunk/scripts/Lindent b/trunk/scripts/Lindent index 9468ec7971db..7d8d8896e309 100755 --- a/trunk/scripts/Lindent +++ b/trunk/scripts/Lindent @@ -1,2 +1,2 @@ #!/bin/sh -indent -npro -kr -i8 -ts8 -sob -l80 -ss -ncs -cp1 "$@" +indent -npro -kr -i8 -ts8 -sob -l80 -ss -ncs "$@" diff --git a/trunk/scripts/mod/modpost.c b/trunk/scripts/mod/modpost.c index 5ab7914d30ef..04579a517900 100644 --- a/trunk/scripts/mod/modpost.c +++ b/trunk/scripts/mod/modpost.c @@ -1076,7 +1076,6 @@ static int initexit_section_ref_ok(const char *name) ".plt", /* seen on ARCH=um build on x86_64. Harmless */ ".smp_locks", ".stab", - ".m68k_fixup", NULL }; /* Start of section names */ diff --git a/trunk/sound/Kconfig b/trunk/sound/Kconfig index e48b9b37d228..9ea473823418 100644 --- a/trunk/sound/Kconfig +++ b/trunk/sound/Kconfig @@ -65,8 +65,6 @@ source "sound/arm/Kconfig" source "sound/mips/Kconfig" -source "sound/sh/Kconfig" - # the following will depend on the order of config. # here assuming USB is defined before ALSA source "sound/usb/Kconfig" diff --git a/trunk/sound/Makefile b/trunk/sound/Makefile index 3ead922bd9c6..b7c7fb7c24c8 100644 --- a/trunk/sound/Makefile +++ b/trunk/sound/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_SOUND) += soundcore.o obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o obj-$(CONFIG_SOUND_PRIME) += oss/ obj-$(CONFIG_DMASOUND) += oss/ -obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ soc/ +obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ soc/ obj-$(CONFIG_SND_AOA) += aoa/ # This one must be compilable even if sound is configured out diff --git a/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c b/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c index 028852374f21..ded516717940 100644 --- a/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c +++ b/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c @@ -661,7 +661,7 @@ static struct transfer_info onyx_transfers[] = { .tag = 2, }, #ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE - /* Once alsa gets supports for this kind of thing we can add it... */ +Once alsa gets supports for this kind of thing we can add it... { /* digital compressed output */ .formats = SNDRV_PCM_FMTBIT_COMPRESSED_16BE, @@ -713,7 +713,7 @@ static int onyx_prepare(struct codec_info_item *cii, if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) { /* mute and lock analog output */ onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v); - if (onyx_write_register(onyx, + if (onyx_write_register(onyx ONYX_REG_DAC_CONTROL, v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT)) goto out_unlock; diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index 59b29cd482ae..a96733a5beb8 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -1487,7 +1487,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) snd_pcm_stream_lock_irq(substream); /* resume pause */ - if (substream->runtime->status->state == SNDRV_PCM_STATE_PAUSED) + if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) snd_pcm_pause(substream, 0); /* pre-start/stop - all running streams are changed to DRAINING state */ diff --git a/trunk/sound/core/seq/seq_instr.c b/trunk/sound/core/seq/seq_instr.c index 5efe6523a589..f30d171b6d96 100644 --- a/trunk/sound/core/seq/seq_instr.c +++ b/trunk/sound/core/seq/seq_instr.c @@ -109,7 +109,7 @@ void snd_seq_instr_list_free(struct snd_seq_kinstr_list **list_ptr) spin_lock_irqsave(&list->lock, flags); while (instr->use) { spin_unlock_irqrestore(&list->lock, flags); - schedule_timeout(1); + schedule_timeout_interruptible(1); spin_lock_irqsave(&list->lock, flags); } spin_unlock_irqrestore(&list->lock, flags); @@ -199,7 +199,7 @@ int snd_seq_instr_list_free_cond(struct snd_seq_kinstr_list *list, instr = flist; flist = instr->next; while (instr->use) - schedule_timeout(1); + schedule_timeout_interruptible(1); if (snd_seq_instr_free(instr, atomic)<0) snd_printk(KERN_WARNING "instrument free problem\n"); instr = next; @@ -555,7 +555,7 @@ static int instr_free(struct snd_seq_kinstr_ops *ops, SNDRV_SEQ_INSTR_NOTIFY_REMOVE); while (instr->use) { spin_unlock_irqrestore(&list->lock, flags); - schedule_timeout(1); + schedule_timeout_interruptible(1); spin_lock_irqsave(&list->lock, flags); } spin_unlock_irqrestore(&list->lock, flags); diff --git a/trunk/sound/core/timer.c b/trunk/sound/core/timer.c index f2bbacedd567..67520b3c0042 100644 --- a/trunk/sound/core/timer.c +++ b/trunk/sound/core/timer.c @@ -1549,11 +1549,9 @@ static int snd_timer_user_info(struct file *file, int err = 0; tu = file->private_data; - if (!tu->timeri) - return -EBADFD; + snd_assert(tu->timeri != NULL, return -ENXIO); t = tu->timeri->timer; - if (!t) - return -EBADFD; + snd_assert(t != NULL, return -ENXIO); info = kzalloc(sizeof(*info), GFP_KERNEL); if (! info) @@ -1581,11 +1579,9 @@ static int snd_timer_user_params(struct file *file, int err; tu = file->private_data; - if (!tu->timeri) - return -EBADFD; + snd_assert(tu->timeri != NULL, return -ENXIO); t = tu->timeri->timer; - if (!t) - return -EBADFD; + snd_assert(t != NULL, return -ENXIO); if (copy_from_user(¶ms, _params, sizeof(params))) return -EFAULT; if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) { @@ -1679,8 +1675,7 @@ static int snd_timer_user_status(struct file *file, struct snd_timer_status status; tu = file->private_data; - if (!tu->timeri) - return -EBADFD; + snd_assert(tu->timeri != NULL, return -ENXIO); memset(&status, 0, sizeof(status)); status.tstamp = tu->tstamp; status.resolution = snd_timer_resolution(tu->timeri); @@ -1700,8 +1695,7 @@ static int snd_timer_user_start(struct file *file) struct snd_timer_user *tu; tu = file->private_data; - if (!tu->timeri) - return -EBADFD; + snd_assert(tu->timeri != NULL, return -ENXIO); snd_timer_stop(tu->timeri); tu->timeri->lost = 0; tu->last_resolution = 0; @@ -1714,8 +1708,7 @@ static int snd_timer_user_stop(struct file *file) struct snd_timer_user *tu; tu = file->private_data; - if (!tu->timeri) - return -EBADFD; + snd_assert(tu->timeri != NULL, return -ENXIO); return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0; } @@ -1725,8 +1718,7 @@ static int snd_timer_user_continue(struct file *file) struct snd_timer_user *tu; tu = file->private_data; - if (!tu->timeri) - return -EBADFD; + snd_assert(tu->timeri != NULL, return -ENXIO); tu->timeri->lost = 0; return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0; } @@ -1737,8 +1729,7 @@ static int snd_timer_user_pause(struct file *file) struct snd_timer_user *tu; tu = file->private_data; - if (!tu->timeri) - return -EBADFD; + snd_assert(tu->timeri != NULL, return -ENXIO); return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0; } diff --git a/trunk/sound/drivers/dummy.c b/trunk/sound/drivers/dummy.c index 4360ae9de19c..a0f28f51fc7e 100644 --- a/trunk/sound/drivers/dummy.c +++ b/trunk/sound/drivers/dummy.c @@ -659,7 +659,7 @@ static struct platform_driver snd_dummy_driver = { }, }; -static void snd_dummy_unregister_all(void) +static void __init_or_module snd_dummy_unregister_all(void) { int i; diff --git a/trunk/sound/drivers/mpu401/mpu401.c b/trunk/sound/drivers/mpu401/mpu401.c index 67c6e9745418..1d563e515c17 100644 --- a/trunk/sound/drivers/mpu401/mpu401.c +++ b/trunk/sound/drivers/mpu401/mpu401.c @@ -228,7 +228,7 @@ static struct pnp_driver snd_mpu401_pnp_driver = { static struct pnp_driver snd_mpu401_pnp_driver; #endif -static void snd_mpu401_unregister_all(void) +static void __init_or_module snd_mpu401_unregister_all(void) { int i; diff --git a/trunk/sound/drivers/portman2x4.c b/trunk/sound/drivers/portman2x4.c index 0eb9b5cebfcd..497cafb57d9b 100644 --- a/trunk/sound/drivers/portman2x4.c +++ b/trunk/sound/drivers/portman2x4.c @@ -833,7 +833,7 @@ static struct platform_driver snd_portman_driver = { /********************************************************************* * module init stuff *********************************************************************/ -static void snd_portman_unregister_all(void) +static void __init_or_module snd_portman_unregister_all(void) { int i; diff --git a/trunk/sound/drivers/serial-u16550.c b/trunk/sound/drivers/serial-u16550.c index d3e6a20edd38..838a4277929d 100644 --- a/trunk/sound/drivers/serial-u16550.c +++ b/trunk/sound/drivers/serial-u16550.c @@ -998,7 +998,7 @@ static struct platform_driver snd_serial_driver = { }, }; -static void snd_serial_unregister_all(void) +static void __init_or_module snd_serial_unregister_all(void) { int i; diff --git a/trunk/sound/drivers/virmidi.c b/trunk/sound/drivers/virmidi.c index 915c86773c21..46f3d3486067 100644 --- a/trunk/sound/drivers/virmidi.c +++ b/trunk/sound/drivers/virmidi.c @@ -145,7 +145,7 @@ static struct platform_driver snd_virmidi_driver = { }, }; -static void snd_virmidi_unregister_all(void) +static void __init_or_module snd_virmidi_unregister_all(void) { int i; diff --git a/trunk/sound/i2c/other/ak4xxx-adda.c b/trunk/sound/i2c/other/ak4xxx-adda.c index fd335159f849..8805110017a7 100644 --- a/trunk/sound/i2c/other/ak4xxx-adda.c +++ b/trunk/sound/i2c/other/ak4xxx-adda.c @@ -481,8 +481,8 @@ static int ak4xxx_switch_get(struct snd_kcontrol *kcontrol, int addr = AK_GET_ADDR(kcontrol->private_value); int shift = AK_GET_SHIFT(kcontrol->private_value); int invert = AK_GET_INVERT(kcontrol->private_value); - /* we observe the (1<value.integer.value[0] = (val & (1<num_dacs; ) { - /* mute control for Revolution 7.1 - AK4381 */ - if (ak->type == SND_AK4381 - && ak->dac_info[mixer_ch].switch_name) { - memset(&knew, 0, sizeof(knew)); - knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - knew.count = 1; - knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; - knew.name = ak->dac_info[mixer_ch].switch_name; - knew.info = ak4xxx_switch_info; - knew.get = ak4xxx_switch_get; - knew.put = ak4xxx_switch_put; - knew.access = 0; - /* register 1, bit 0 (SMUTE): 0 = normal operation, - 1 = mute */ - knew.private_value = - AK_COMPOSE(idx/2, 1, 0, 0) | AK_INVERT; - err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak)); - if (err < 0) - return err; - } memset(&knew, 0, sizeof(knew)); if (! ak->dac_info || ! ak->dac_info[mixer_ch].name) { knew.name = "DAC Volume"; diff --git a/trunk/sound/isa/Kconfig b/trunk/sound/isa/Kconfig index ea5084abe60f..cf3803cd579c 100644 --- a/trunk/sound/isa/Kconfig +++ b/trunk/sound/isa/Kconfig @@ -1,5 +1,8 @@ # ALSA ISA drivers +menu "ISA devices" + depends on SND!=n && ISA && ISA_DMA_API + config SND_AD1848_LIB tristate select SND_PCM @@ -8,22 +11,6 @@ config SND_CS4231_LIB tristate select SND_PCM -config SND_SB_COMMON - tristate - -config SND_SB8_DSP - tristate - select SND_PCM - select SND_SB_COMMON - -config SND_SB16_DSP - tristate - select SND_PCM - select SND_SB_COMMON - -menu "ISA devices" - depends on SND!=n && ISA && ISA_DMA_API - config SND_ADLIB tristate "AdLib FM card" depends on SND @@ -68,7 +55,7 @@ config SND_ALS100 select ISAPNP select SND_OPL3_LIB select SND_MPU401_UART - select SND_SB16_DSP + select SND_PCM help Say Y here to include support for soundcards based on Avance Logic ALS100, ALS110, ALS120 and ALS200 chips. @@ -94,7 +81,6 @@ config SND_CMI8330 tristate "C-Media CMI8330" depends on SND select SND_AD1848_LIB - select SND_SB16_DSP help Say Y here to include support for soundcards based on the C-Media CMI8330 chip. @@ -146,7 +132,7 @@ config SND_DT019X select ISAPNP select SND_OPL3_LIB select SND_MPU401_UART - select SND_SB16_DSP + select SND_PCM help Say Y here to include support for soundcards based on the Diamond Technologies DT-019X or Avance Logic ALS-007 chips. @@ -159,7 +145,7 @@ config SND_ES968 depends on SND && PNP && ISA select ISAPNP select SND_MPU401_UART - select SND_SB8_DSP + select SND_PCM help Say Y here to include support for ESS AudioDrive ES968 chips. @@ -335,7 +321,7 @@ config SND_SB8 depends on SND select SND_OPL3_LIB select SND_RAWMIDI - select SND_SB8_DSP + select SND_PCM help Say Y here to include support for Creative Sound Blaster 1.0/ 2.0/Pro (8-bit) or 100% compatible soundcards. @@ -348,7 +334,7 @@ config SND_SB16 depends on SND select SND_OPL3_LIB select SND_MPU401_UART - select SND_SB16_DSP + select SND_PCM help Say Y here to include support for Sound Blaster 16 soundcards (including the Plug and Play version). @@ -361,7 +347,7 @@ config SND_SBAWE depends on SND select SND_OPL3_LIB select SND_MPU401_UART - select SND_SB16_DSP + select SND_PCM help Say Y here to include support for Sound Blaster AWE soundcards (including the Plug and Play version). diff --git a/trunk/sound/isa/ad1848/ad1848_lib.c b/trunk/sound/isa/ad1848/ad1848_lib.c index 1bc2e3fd5721..8094282c2ae1 100644 --- a/trunk/sound/isa/ad1848/ad1848_lib.c +++ b/trunk/sound/isa/ad1848/ad1848_lib.c @@ -245,7 +245,7 @@ static void snd_ad1848_mce_down(struct snd_ad1848 *chip) snd_printk(KERN_ERR "mce_down - auto calibration time out (2)\n"); return; } - time = schedule_timeout(time); + time = schedule_timeout_interruptible(time); spin_lock_irqsave(&chip->reg_lock, flags); } #if 0 @@ -258,7 +258,7 @@ static void snd_ad1848_mce_down(struct snd_ad1848 *chip) snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n"); return; } - time = schedule_timeout(time); + time = schedule_timeout_interruptible(time); spin_lock_irqsave(&chip->reg_lock, flags); } spin_unlock_irqrestore(&chip->reg_lock, flags); diff --git a/trunk/sound/isa/opl3sa2.c b/trunk/sound/isa/opl3sa2.c index e70db32991d9..4f6800b43b0e 100644 --- a/trunk/sound/isa/opl3sa2.c +++ b/trunk/sound/isa/opl3sa2.c @@ -164,8 +164,6 @@ static struct pnp_card_device_id snd_opl3sa2_pnpids[] = { { .id = "YMH0801", .devs = { { "YMH0021" } } }, /* NeoMagic MagicWave 3DX */ { .id = "NMX2200", .devs = { { "YMH2210" } } }, - /* NeoMagic MagicWave 3D */ - { .id = "NMX2200", .devs = { { "NMX2210" } } }, /* --- */ { .id = "" } /* end */ }; diff --git a/trunk/sound/isa/opti9xx/opti92x-ad1848.c b/trunk/sound/isa/opti9xx/opti92x-ad1848.c index 049d479ce2b3..60c120ffb9de 100644 --- a/trunk/sound/isa/opti9xx/opti92x-ad1848.c +++ b/trunk/sound/isa/opti9xx/opti92x-ad1848.c @@ -1927,12 +1927,10 @@ static struct snd_card *snd_opti9xx_card_new(void) static int __devinit snd_opti9xx_isa_match(struct device *devptr, unsigned int dev) { -#ifdef CONFIG_PNP if (snd_opti9xx_pnp_is_probed) return 0; if (isapnp) return 0; -#endif return 1; } @@ -2098,7 +2096,6 @@ static int __init alsa_card_opti9xx_init(void) pnp_register_card_driver(&opti9xx_pnpc_driver); if (snd_opti9xx_pnp_is_probed) return 0; - pnp_unregister_card_driver(&opti9xx_pnpc_driver); #endif return isa_register_driver(&snd_opti9xx_driver, 1); } diff --git a/trunk/sound/isa/sb/Makefile b/trunk/sound/isa/sb/Makefile index 556e66928029..fd9d9c5726fc 100644 --- a/trunk/sound/isa/sb/Makefile +++ b/trunk/sound/isa/sb/Makefile @@ -22,13 +22,14 @@ snd-es968-objs := es968.o sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) # Toplevel Module Dependency -obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o -obj-$(CONFIG_SND_SB16_DSP) += snd-sb16-dsp.o -obj-$(CONFIG_SND_SB8_DSP) += snd-sb8-dsp.o -obj-$(CONFIG_SND_SB8) += snd-sb8.o -obj-$(CONFIG_SND_SB16) += snd-sb16.o -obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o -obj-$(CONFIG_SND_ES968) += snd-es968.o +obj-$(CONFIG_SND_ALS100) += snd-sb16-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_CMI8330) += snd-sb16-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_DT019X) += snd-sb16-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_SB8) += snd-sb8.o snd-sb8-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_SB16) += snd-sb16.o snd-sb16-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o snd-sb16-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_ES968) += snd-es968.o snd-sb8-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_ALS4000) += snd-sb-common.o ifeq ($(CONFIG_SND_SB16_CSP),y) obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o diff --git a/trunk/sound/isa/sb/sb16_main.c b/trunk/sound/isa/sb/sb16_main.c index 5d4d3aafe2d5..383911b9e74d 100644 --- a/trunk/sound/isa/sb/sb16_main.c +++ b/trunk/sound/isa/sb/sb16_main.c @@ -563,11 +563,6 @@ static int snd_sb16_playback_open(struct snd_pcm_substream *substream) __open_ok: if (chip->hardware == SB_HW_ALS100) runtime->hw.rate_max = 48000; - if (chip->hardware == SB_HW_CS5530) { - runtime->hw.buffer_bytes_max = 32 * 1024; - runtime->hw.periods_min = 2; - runtime->hw.rate_min = 44100; - } if (chip->mode & SB_RATE_LOCK) runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate; chip->playback_substream = substream; @@ -638,11 +633,6 @@ static int snd_sb16_capture_open(struct snd_pcm_substream *substream) __open_ok: if (chip->hardware == SB_HW_ALS100) runtime->hw.rate_max = 48000; - if (chip->hardware == SB_HW_CS5530) { - runtime->hw.buffer_bytes_max = 32 * 1024; - runtime->hw.periods_min = 2; - runtime->hw.rate_min = 44100; - } if (chip->mode & SB_RATE_LOCK) runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate; chip->capture_substream = substream; diff --git a/trunk/sound/isa/sb/sb_common.c b/trunk/sound/isa/sb/sb_common.c index efa9d5c2558a..3094f3852167 100644 --- a/trunk/sound/isa/sb/sb_common.c +++ b/trunk/sound/isa/sb/sb_common.c @@ -128,7 +128,7 @@ static int snd_sbdsp_probe(struct snd_sb * chip) minor = version & 0xff; snd_printdd("SB [0x%lx]: DSP chip found, version = %i.%i\n", chip->port, major, minor); - + switch (chip->hardware) { case SB_HW_AUTO: switch (major) { @@ -168,9 +168,6 @@ static int snd_sbdsp_probe(struct snd_sb * chip) case SB_HW_DT019X: str = "(DT019X/ALS007)"; break; - case SB_HW_CS5530: - str = "16 (CS5530)"; - break; default: return -ENODEV; } diff --git a/trunk/sound/isa/sb/sb_mixer.c b/trunk/sound/isa/sb/sb_mixer.c index 3d4befcff28e..490b1ca5cf58 100644 --- a/trunk/sound/isa/sb/sb_mixer.c +++ b/trunk/sound/isa/sb/sb_mixer.c @@ -821,7 +821,6 @@ int snd_sbmixer_new(struct snd_sb *chip) break; case SB_HW_16: case SB_HW_ALS100: - case SB_HW_CS5530: if ((err = snd_sbmixer_init(chip, snd_sb16_controls, ARRAY_SIZE(snd_sb16_controls), @@ -951,7 +950,6 @@ void snd_sbmixer_suspend(struct snd_sb *chip) break; case SB_HW_16: case SB_HW_ALS100: - case SB_HW_CS5530: save_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs)); break; case SB_HW_ALS4000: @@ -977,7 +975,6 @@ void snd_sbmixer_resume(struct snd_sb *chip) break; case SB_HW_16: case SB_HW_ALS100: - case SB_HW_CS5530: restore_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs)); break; case SB_HW_ALS4000: diff --git a/trunk/sound/isa/sscape.c b/trunk/sound/isa/sscape.c index cbad2a51cbaa..9ea417bcf3e5 100644 --- a/trunk/sound/isa/sscape.c +++ b/trunk/sound/isa/sscape.c @@ -382,7 +382,7 @@ static int obp_startup_ack(struct soundscape *s, unsigned timeout) unsigned long flags; unsigned char x; - schedule_timeout(1); + schedule_timeout_interruptible(1); spin_lock_irqsave(&s->lock, flags); x = inb(HOST_DATA_IO(s->io_base)); @@ -409,7 +409,7 @@ static int host_startup_ack(struct soundscape *s, unsigned timeout) unsigned long flags; unsigned char x; - schedule_timeout(1); + schedule_timeout_interruptible(1); spin_lock_irqsave(&s->lock, flags); x = inb(HOST_DATA_IO(s->io_base)); diff --git a/trunk/sound/isa/wavefront/wavefront_synth.c b/trunk/sound/isa/wavefront/wavefront_synth.c index bacc51c86587..78020d832e04 100644 --- a/trunk/sound/isa/wavefront/wavefront_synth.c +++ b/trunk/sound/isa/wavefront/wavefront_synth.c @@ -1780,7 +1780,7 @@ wavefront_should_cause_interrupt (snd_wavefront_t *dev, outb (val,port); spin_unlock_irq(&dev->irq_lock); while (1) { - if ((timeout = schedule_timeout(timeout)) == 0) + if ((timeout = schedule_timeout_interruptible(timeout)) == 0) return; if (dev->irq_ok) return; diff --git a/trunk/sound/pci/Kconfig b/trunk/sound/pci/Kconfig index c6b44102aa5b..61e35ecc57b8 100644 --- a/trunk/sound/pci/Kconfig +++ b/trunk/sound/pci/Kconfig @@ -33,7 +33,6 @@ config SND_ALS4000 select SND_OPL3_LIB select SND_MPU401_UART select SND_PCM - select SND_SB_COMMON help Say Y here to include support for soundcards based on Avance Logic ALS4000 chips. @@ -216,16 +215,6 @@ config SND_CS46XX_NEW_DSP This works better than the old code, so say Y. -config SND_CS5530 - tristate "CS5530 Audio" - depends on SND && ISA_DMA_API - select SND_SB16_DSP - help - Say Y here to include support for audio on Cyrix/NatSemi CS5530 chips. - - To compile this driver as a module, choose M here: the module - will be called snd-cs5530. - config SND_CS5535AUDIO tristate "CS5535/CS5536 Audio" depends on SND && X86 && !X86_64 diff --git a/trunk/sound/pci/Makefile b/trunk/sound/pci/Makefile index cd76e0293d06..e06736da9ef1 100644 --- a/trunk/sound/pci/Makefile +++ b/trunk/sound/pci/Makefile @@ -12,7 +12,6 @@ snd-azt3328-objs := azt3328.o snd-bt87x-objs := bt87x.o snd-cmipci-objs := cmipci.o snd-cs4281-objs := cs4281.o -snd-cs5530-objs := cs5530.o snd-ens1370-objs := ens1370.o snd-ens1371-objs := ens1371.o snd-es1938-objs := es1938.o @@ -37,7 +36,6 @@ obj-$(CONFIG_SND_AZT3328) += snd-azt3328.o obj-$(CONFIG_SND_BT87X) += snd-bt87x.o obj-$(CONFIG_SND_CMIPCI) += snd-cmipci.o obj-$(CONFIG_SND_CS4281) += snd-cs4281.o -obj-$(CONFIG_SND_CS5530) += snd-cs5530.o obj-$(CONFIG_SND_ENS1370) += snd-ens1370.o obj-$(CONFIG_SND_ENS1371) += snd-ens1371.o obj-$(CONFIG_SND_ES1938) += snd-es1938.o diff --git a/trunk/sound/pci/ali5451/ali5451.c b/trunk/sound/pci/ali5451/ali5451.c index 05b4c8696941..41543a4933e7 100644 --- a/trunk/sound/pci/ali5451/ali5451.c +++ b/trunk/sound/pci/ali5451/ali5451.c @@ -239,7 +239,7 @@ struct snd_ali_image { struct snd_ali { - int irq; + unsigned long irq; unsigned long port; unsigned char revision; @@ -731,7 +731,8 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec) return; } - for (count = 0; count <= 50000; count++) { + count = 0; + while (count++ <= 50000) { snd_ali_delay(codec, 6); bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); R2 = bval & 0x1F; @@ -2342,7 +2343,7 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, strcpy(card->driver, "ALI5451"); strcpy(card->shortname, "ALI 5451"); - sprintf(card->longname, "%s at 0x%lx, irq %i", + sprintf(card->longname, "%s at 0x%lx, irq %li", card->shortname, codec->port, codec->irq); snd_ali_printk("register card.\n"); diff --git a/trunk/sound/pci/als300.c b/trunk/sound/pci/als300.c index 48cc39b771d9..8afcb98ca7bb 100644 --- a/trunk/sound/pci/als300.c +++ b/trunk/sound/pci/als300.c @@ -88,8 +88,8 @@ #define PLAYBACK_BLOCK_COUNTER 0x9A #define RECORD_BLOCK_COUNTER 0x9B -#define DEBUG_CALLS 0 -#define DEBUG_PLAY_REC 0 +#define DEBUG_CALLS 1 +#define DEBUG_PLAY_REC 1 #if DEBUG_CALLS #define snd_als300_dbgcalls(format, args...) printk(format, ##args) @@ -733,8 +733,7 @@ static int __devinit snd_als300_create(struct snd_card *card, snd_als300_init(chip); - err = snd_als300_ac97(chip); - if (err < 0) { + if (snd_als300_ac97(chip) < 0) { snd_printk(KERN_WARNING "Could not create ac97\n"); snd_als300_free(chip); return err; diff --git a/trunk/sound/pci/ca0106/ca0106_main.c b/trunk/sound/pci/ca0106/ca0106_main.c index fcab8fb97e38..9fd7b8a5b75e 100644 --- a/trunk/sound/pci/ca0106/ca0106_main.c +++ b/trunk/sound/pci/ca0106/ca0106_main.c @@ -168,25 +168,6 @@ MODULE_PARM_DESC(subsystem, "Force card subsystem model."); #include "ca0106.h" static struct snd_ca0106_details ca0106_chip_details[] = { - /* Sound Blaster X-Fi Extreme Audio. This does not have an AC97. 53SB079000000 */ - /* It is really just a normal SB Live 24bit. */ - /* - * CTRL:CA0111-WTLF - * ADC: WM8775SEDS - * DAC: CS4382-KQZ - */ - /* Tested: - * Playback on front, rear, center/lfe speakers - * Capture from Mic in. - * Not-Tested: - * Capture from Line in. - * Playback to digital out. - */ - { .serial = 0x10121102, - .name = "X-Fi Extreme Audio [SB0790]", - .gpio_type = 1, - .i2c_adc = 1 } , - /* New Dell Sound Blaster Live! 7.1 24bit. This does not have an AC97. */ /* AudigyLS[SB0310] */ { .serial = 0x10021102, .name = "AudigyLS [SB0310]", diff --git a/trunk/sound/pci/cs46xx/cs46xx_lib.c b/trunk/sound/pci/cs46xx/cs46xx_lib.c index 71d7aab9d869..bef1f6d1859c 100644 --- a/trunk/sound/pci/cs46xx/cs46xx_lib.c +++ b/trunk/sound/pci/cs46xx/cs46xx_lib.c @@ -2897,10 +2897,6 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip) } #endif -#ifdef CONFIG_PM - kfree(chip->saved_regs); -#endif - pci_disable_device(chip->pci); kfree(chip); return 0; @@ -3144,23 +3140,6 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip) /* * start and load DSP */ - -static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip) -{ - unsigned int tmp; - - snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); - - tmp = snd_cs46xx_peek(chip, BA1_PFIE); - tmp &= ~0x0000f03f; - snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ - - tmp = snd_cs46xx_peek(chip, BA1_CIE); - tmp &= ~0x0000003f; - tmp |= 0x00000001; - snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ -} - int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) { unsigned int tmp; @@ -3235,7 +3214,19 @@ int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) snd_cs46xx_proc_start(chip); - cs46xx_enable_stream_irqs(chip); + /* + * Enable interrupts on the part. + */ + snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); + + tmp = snd_cs46xx_peek(chip, BA1_PFIE); + tmp &= ~0x0000f03f; + snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ + + tmp = snd_cs46xx_peek(chip, BA1_CIE); + tmp &= ~0x0000003f; + tmp |= 0x00000001; + snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ #ifndef CONFIG_SND_CS46XX_NEW_DSP /* set the attenuation to 0dB */ @@ -3674,19 +3665,11 @@ static struct cs_card_type __devinitdata cards[] = { * APM support */ #ifdef CONFIG_PM -static unsigned int saved_regs[] = { - BA0_ACOSV, - BA0_ASER_FADDR, - BA0_ASER_MASTER, - BA1_PVOL, - BA1_CVOL, -}; - int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) { struct snd_card *card = pci_get_drvdata(pci); struct snd_cs46xx *chip = card->private_data; - int i, amp_saved; + int amp_saved; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); chip->in_suspend = 1; @@ -3697,10 +3680,6 @@ int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); - /* save some registers */ - for (i = 0; i < ARRAY_SIZE(saved_regs); i++) - chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]); - amp_saved = chip->amplifier; /* turn off amp */ chip->amplifier_ctrl(chip, -chip->amplifier); @@ -3719,7 +3698,7 @@ int snd_cs46xx_resume(struct pci_dev *pci) { struct snd_card *card = pci_get_drvdata(pci); struct snd_cs46xx *chip = card->private_data; - int i, amp_saved; + int amp_saved; pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); @@ -3737,16 +3716,6 @@ int snd_cs46xx_resume(struct pci_dev *pci) snd_cs46xx_chip_init(chip); - snd_cs46xx_reset(chip); -#ifdef CONFIG_SND_CS46XX_NEW_DSP - cs46xx_dsp_resume(chip); - /* restore some registers */ - for (i = 0; i < ARRAY_SIZE(saved_regs); i++) - snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]); -#else - snd_cs46xx_download_image(chip); -#endif - #if 0 snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, chip->ac97_general_purpose); @@ -3761,13 +3730,6 @@ int snd_cs46xx_resume(struct pci_dev *pci) snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); - /* reset playback/capture */ - snd_cs46xx_set_play_sample_rate(chip, 8000); - snd_cs46xx_set_capture_sample_rate(chip, 8000); - snd_cs46xx_proc_start(chip); - - cs46xx_enable_stream_irqs(chip); - if (amp_saved) chip->amplifier_ctrl(chip, 1); /* turn amp on */ else @@ -3934,15 +3896,6 @@ int __devinit snd_cs46xx_create(struct snd_card *card, snd_cs46xx_proc_init(card, chip); -#ifdef CONFIG_PM - chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) * - ARRAY_SIZE(saved_regs), GFP_KERNEL); - if (!chip->saved_regs) { - snd_cs46xx_free(chip); - return -ENOMEM; - } -#endif - chip->active_ctrl(chip, -1); /* disable CLKRUN */ snd_card_set_dev(card, &pci->dev); diff --git a/trunk/sound/pci/cs46xx/cs46xx_lib.h b/trunk/sound/pci/cs46xx/cs46xx_lib.h index 20dcd72f06c1..f75750c2bd24 100644 --- a/trunk/sound/pci/cs46xx/cs46xx_lib.h +++ b/trunk/sound/pci/cs46xx/cs46xx_lib.h @@ -86,9 +86,6 @@ static inline unsigned int snd_cs46xx_peekBA0(struct snd_cs46xx *chip, unsigned struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip); void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip); int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module); -#ifdef CONFIG_PM -int cs46xx_dsp_resume(struct snd_cs46xx * chip); -#endif struct dsp_symbol_entry *cs46xx_dsp_lookup_symbol (struct snd_cs46xx * chip, char * symbol_name, int symbol_type); #ifdef CONFIG_PROC_FS diff --git a/trunk/sound/pci/cs46xx/dsp_spos.c b/trunk/sound/pci/cs46xx/dsp_spos.c index 590b35d91df2..336e77e2600c 100644 --- a/trunk/sound/pci/cs46xx/dsp_spos.c +++ b/trunk/sound/pci/cs46xx/dsp_spos.c @@ -306,59 +306,13 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip) mutex_unlock(&chip->spos_mutex); } -static int dsp_load_parameter(struct snd_cs46xx *chip, - struct dsp_segment_desc *parameter) -{ - u32 doffset, dsize; - - if (!parameter) { - snd_printdd("dsp_spos: module got no parameter segment\n"); - return 0; - } - - doffset = (parameter->offset * 4 + DSP_PARAMETER_BYTE_OFFSET); - dsize = parameter->size * 4; - - snd_printdd("dsp_spos: " - "downloading parameter data to chip (%08x-%08x)\n", - doffset,doffset + dsize); - if (snd_cs46xx_download (chip, parameter->data, doffset, dsize)) { - snd_printk(KERN_ERR "dsp_spos: " - "failed to download parameter data to DSP\n"); - return -EINVAL; - } - return 0; -} - -static int dsp_load_sample(struct snd_cs46xx *chip, - struct dsp_segment_desc *sample) -{ - u32 doffset, dsize; - - if (!sample) { - snd_printdd("dsp_spos: module got no sample segment\n"); - return 0; - } - - doffset = (sample->offset * 4 + DSP_SAMPLE_BYTE_OFFSET); - dsize = sample->size * 4; - - snd_printdd("dsp_spos: downloading sample data to chip (%08x-%08x)\n", - doffset,doffset + dsize); - - if (snd_cs46xx_download (chip,sample->data,doffset,dsize)) { - snd_printk(KERN_ERR "dsp_spos: failed to sample data to DSP\n"); - return -EINVAL; - } - return 0; -} - int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; struct dsp_segment_desc * code = get_segment_desc (module,SEGTYPE_SP_PROGRAM); + struct dsp_segment_desc * parameter = get_segment_desc (module,SEGTYPE_SP_PARAMETER); + struct dsp_segment_desc * sample = get_segment_desc (module,SEGTYPE_SP_SAMPLE); u32 doffset, dsize; - int err; if (ins->nmodules == DSP_MAX_MODULES - 1) { snd_printk(KERN_ERR "dsp_spos: to many modules loaded into DSP\n"); @@ -372,20 +326,49 @@ int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * m snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, DSP_PARAMETER_BYTE_SIZE); } - err = dsp_load_parameter(chip, get_segment_desc(module, - SEGTYPE_SP_PARAMETER)); - if (err < 0) - return err; + if (parameter == NULL) { + snd_printdd("dsp_spos: module got no parameter segment\n"); + } else { + if (ins->nmodules > 0) { + snd_printk(KERN_WARNING "dsp_spos: WARNING current parameter data may be overwriten!\n"); + } + + doffset = (parameter->offset * 4 + DSP_PARAMETER_BYTE_OFFSET); + dsize = parameter->size * 4; + + snd_printdd("dsp_spos: downloading parameter data to chip (%08x-%08x)\n", + doffset,doffset + dsize); + + if (snd_cs46xx_download (chip, parameter->data, doffset, dsize)) { + snd_printk(KERN_ERR "dsp_spos: failed to download parameter data to DSP\n"); + return -EINVAL; + } + } if (ins->nmodules == 0) { snd_printdd("dsp_spos: clearing sample area\n"); snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, DSP_SAMPLE_BYTE_SIZE); } - err = dsp_load_sample(chip, get_segment_desc(module, - SEGTYPE_SP_SAMPLE)); - if (err < 0) - return err; + if (sample == NULL) { + snd_printdd("dsp_spos: module got no sample segment\n"); + } else { + if (ins->nmodules > 0) { + snd_printk(KERN_WARNING "dsp_spos: WARNING current sample data may be overwriten\n"); + } + + doffset = (sample->offset * 4 + DSP_SAMPLE_BYTE_OFFSET); + dsize = sample->size * 4; + + snd_printdd("dsp_spos: downloading sample data to chip (%08x-%08x)\n", + doffset,doffset + dsize); + + if (snd_cs46xx_download (chip,sample->data,doffset,dsize)) { + snd_printk(KERN_ERR "dsp_spos: failed to sample data to DSP\n"); + return -EINVAL; + } + } + if (ins->nmodules == 0) { snd_printdd("dsp_spos: clearing code area\n"); @@ -1003,10 +986,7 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size) return NULL; } - if (name) - strcpy(ins->tasks[ins->ntask].task_name, name); - else - strcpy(ins->tasks[ins->ntask].task_name, "(NULL)"); + strcpy(ins->tasks[ins->ntask].task_name,name); ins->tasks[ins->ntask].address = dest; ins->tasks[ins->ntask].size = size; @@ -1015,8 +995,7 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size) desc = (ins->tasks + ins->ntask); ins->ntask++; - if (name) - add_symbol (chip,name,dest,SYMBOL_PARAMETER); + add_symbol (chip,name,dest,SYMBOL_PARAMETER); return desc; } @@ -1027,7 +1006,6 @@ cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 desc = _map_scb (chip,name,dest); if (desc) { - desc->data = scb_data; _dsp_create_scb(chip,scb_data,dest); } else { snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n"); @@ -1045,7 +1023,6 @@ cs46xx_dsp_create_task_tree (struct snd_cs46xx *chip, char * name, u32 * task_da desc = _map_task_tree (chip,name,dest,size); if (desc) { - desc->data = task_data; _dsp_create_task_tree(chip,task_data,dest,size); } else { snd_printk(KERN_ERR "dsp_spos: failed to map TASK\n"); @@ -1343,10 +1320,8 @@ int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip) 0x0000ffff }; - if (!cs46xx_dsp_create_task_tree(chip, NULL, - (u32 *)&mix2_ostream_spb, - WRITE_BACK_SPB, 2)) - goto _fail_end; + /* dirty hack ... */ + _dsp_create_task_tree (chip,(u32 *)&mix2_ostream_spb,WRITE_BACK_SPB,2); } /* input sample converter */ @@ -1647,6 +1622,7 @@ static int cs46xx_dsp_async_init (struct snd_cs46xx *chip, return 0; } + static void cs46xx_dsp_disable_spdif_hw (struct snd_cs46xx *chip) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; @@ -1918,61 +1894,3 @@ int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right) return 0; } - -#ifdef CONFIG_PM -int cs46xx_dsp_resume(struct snd_cs46xx * chip) -{ - struct dsp_spos_instance * ins = chip->dsp_spos_instance; - int i, err; - - /* clear parameter, sample and code areas */ - snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, - DSP_PARAMETER_BYTE_SIZE); - snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, - DSP_SAMPLE_BYTE_SIZE); - snd_cs46xx_clear_BA1(chip, DSP_CODE_BYTE_OFFSET, DSP_CODE_BYTE_SIZE); - - for (i = 0; i < ins->nmodules; i++) { - struct dsp_module_desc *module = &ins->modules[i]; - struct dsp_segment_desc *seg; - u32 doffset, dsize; - - seg = get_segment_desc(module, SEGTYPE_SP_PARAMETER); - err = dsp_load_parameter(chip, seg); - if (err < 0) - return err; - - seg = get_segment_desc(module, SEGTYPE_SP_SAMPLE); - err = dsp_load_sample(chip, seg); - if (err < 0) - return err; - - seg = get_segment_desc(module, SEGTYPE_SP_PROGRAM); - if (!seg) - continue; - - doffset = seg->offset * 4 + module->load_address * 4 - + DSP_CODE_BYTE_OFFSET; - dsize = seg->size * 4; - err = snd_cs46xx_download(chip, - ins->code.data + module->load_address, - doffset, dsize); - if (err < 0) - return err; - } - - for (i = 0; i < ins->ntask; i++) { - struct dsp_task_descriptor *t = &ins->tasks[i]; - _dsp_create_task_tree(chip, t->data, t->address, t->size); - } - - for (i = 0; i < ins->nscb; i++) { - struct dsp_scb_descriptor *s = &ins->scbs[i]; - if (s->deleted) - continue; - _dsp_create_scb(chip, s->data, s->address); - } - - return 0; -} -#endif diff --git a/trunk/sound/pci/cs5530.c b/trunk/sound/pci/cs5530.c deleted file mode 100644 index 240a0a462209..000000000000 --- a/trunk/sound/pci/cs5530.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * cs5530.c - Initialisation code for Cyrix/NatSemi VSA1 softaudio - * - * (C) Copyright 2007 Ash Willis - * (C) Copyright 2003 Red Hat Inc - * - * This driver was ported (shamelessly ripped ;) from oss/kahlua.c but I did - * mess with it a bit. The chip seems to have to have trouble with full duplex - * mode. If we're recording in 8bit 8000kHz, say, and we then attempt to - * simultaneously play back audio at 16bit 44100kHz, the device actually plays - * back in the same format in which it is capturing. By forcing the chip to - * always play/capture in 16/44100, we can let alsa-lib convert the samples and - * that way we can hack up some full duplex audio. - * - * XpressAudio(tm) is used on the Cyrix MediaGX (now NatSemi Geode) systems. - * The older version (VSA1) provides fairly good soundblaster emulation - * although there are a couple of bugs: large DMA buffers break record, - * and the MPU event handling seems suspect. VSA2 allows the native driver - * to control the AC97 audio engine directly and requires a different driver. - * - * Thanks to National Semiconductor for providing the needed information - * on the XpressAudio(tm) internals. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * TO DO: - * Investigate whether we can portably support Cognac (5520) in the - * same manner. - */ - -#include -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Ash Willis"); -MODULE_DESCRIPTION("CS5530 Audio"); -MODULE_LICENSE("GPL"); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; - -struct snd_cs5530 { - struct snd_card *card; - struct pci_dev *pci; - struct snd_sb *sb; - unsigned long pci_base; -}; - -static struct pci_device_id snd_cs5530_ids[] = { - {PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID, - PCI_ANY_ID, 0, 0}, - {0,} -}; - -MODULE_DEVICE_TABLE(pci, snd_cs5530_ids); - -static int snd_cs5530_free(struct snd_cs5530 *chip) -{ - pci_release_regions(chip->pci); - pci_disable_device(chip->pci); - kfree(chip); - return 0; -} - -static int snd_cs5530_dev_free(struct snd_device *device) -{ - struct snd_cs5530 *chip = device->device_data; - return snd_cs5530_free(chip); -} - -static void __devexit snd_cs5530_remove(struct pci_dev *pci) -{ - snd_card_free(pci_get_drvdata(pci)); - pci_set_drvdata(pci, NULL); -} - -static u8 __devinit snd_cs5530_mixer_read(unsigned long io, u8 reg) -{ - outb(reg, io + 4); - udelay(20); - reg = inb(io + 5); - udelay(20); - return reg; -} - -static int __devinit snd_cs5530_create(struct snd_card *card, - struct pci_dev *pci, - struct snd_cs5530 **rchip) -{ - struct snd_cs5530 *chip; - unsigned long sb_base; - u8 irq, dma8, dma16 = 0; - u16 map; - void __iomem *mem; - int err; - - static struct snd_device_ops ops = { - .dev_free = snd_cs5530_dev_free, - }; - *rchip = NULL; - - err = pci_enable_device(pci); - if (err < 0) - return err; - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) { - pci_disable_device(pci); - return -ENOMEM; - } - - chip->card = card; - chip->pci = pci; - - err = pci_request_regions(pci, "CS5530"); - if (err < 0) { - kfree(chip); - pci_disable_device(pci); - return err; - } - chip->pci_base = pci_resource_start(pci, 0); - - mem = ioremap_nocache(chip->pci_base, pci_resource_len(pci, 0)); - if (mem == NULL) { - kfree(chip); - pci_disable_device(pci); - return -EBUSY; - } - - map = readw(mem + 0x18); - iounmap(mem); - - /* Map bits - 0:1 * 0x20 + 0x200 = sb base - 2 sb enable - 3 adlib enable - 5 MPU enable 0x330 - 6 MPU enable 0x300 - - The other bits may be used internally so must be masked */ - - sb_base = 0x220 + 0x20 * (map & 3); - - if (map & (1<<2)) - printk(KERN_INFO "CS5530: XpressAudio at 0x%lx\n", sb_base); - else { - printk(KERN_ERR "Could not find XpressAudio!\n"); - snd_cs5530_free(chip); - return -ENODEV; - } - - if (map & (1<<5)) - printk(KERN_INFO "CS5530: MPU at 0x300\n"); - else if (map & (1<<6)) - printk(KERN_INFO "CS5530: MPU at 0x330\n"); - - irq = snd_cs5530_mixer_read(sb_base, 0x80) & 0x0F; - dma8 = snd_cs5530_mixer_read(sb_base, 0x81); - - if (dma8 & 0x20) - dma16 = 5; - else if (dma8 & 0x40) - dma16 = 6; - else if (dma8 & 0x80) - dma16 = 7; - else { - printk(KERN_ERR "CS5530: No 16bit DMA enabled\n"); - snd_cs5530_free(chip); - return -ENODEV; - } - - if (dma8 & 0x01) - dma8 = 0; - else if (dma8 & 02) - dma8 = 1; - else if (dma8 & 0x08) - dma8 = 3; - else { - printk(KERN_ERR "CS5530: No 8bit DMA enabled\n"); - snd_cs5530_free(chip); - return -ENODEV; - } - - if (irq & 1) - irq = 9; - else if (irq & 2) - irq = 5; - else if (irq & 4) - irq = 7; - else if (irq & 8) - irq = 10; - else { - printk(KERN_ERR "CS5530: SoundBlaster IRQ not set\n"); - snd_cs5530_free(chip); - return -ENODEV; - } - - printk(KERN_INFO "CS5530: IRQ: %d DMA8: %d DMA16: %d\n", irq, dma8, - dma16); - - err = snd_sbdsp_create(card, sb_base, irq, snd_sb16dsp_interrupt, dma8, - dma16, SB_HW_CS5530, &chip->sb); - if (err < 0) { - printk(KERN_ERR "CS5530: Could not create SoundBlaster\n"); - snd_cs5530_free(chip); - return err; - } - - err = snd_sb16dsp_pcm(chip->sb, 0, &chip->sb->pcm); - if (err < 0) { - printk(KERN_ERR "CS5530: Could not create PCM\n"); - snd_cs5530_free(chip); - return err; - } - - err = snd_sbmixer_new(chip->sb); - if (err < 0) { - printk(KERN_ERR "CS5530: Could not create Mixer\n"); - snd_cs5530_free(chip); - return err; - } - - err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); - if (err < 0) { - snd_cs5530_free(chip); - return err; - } - - snd_card_set_dev(card, &pci->dev); - *rchip = chip; - return 0; -} - -static int __devinit snd_cs5530_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) -{ - static int dev; - struct snd_card *card; - struct snd_cs5530 *chip = NULL; - int err; - - if (dev >= SNDRV_CARDS) - return -ENODEV; - if (!enable[dev]) { - dev++; - return -ENOENT; - } - - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - - if (card == NULL) - return -ENOMEM; - - err = snd_cs5530_create(card, pci, &chip); - if (err < 0) { - snd_card_free(card); - return err; - } - - strcpy(card->driver, "CS5530"); - strcpy(card->shortname, "CS5530 Audio"); - sprintf(card->longname, "%s at 0x%lx", card->shortname, chip->pci_base); - - err = snd_card_register(card); - if (err < 0) { - snd_card_free(card); - return err; - } - pci_set_drvdata(pci, card); - dev++; - return 0; -} - -static struct pci_driver driver = { - .name = "CS5530_Audio", - .id_table = snd_cs5530_ids, - .probe = snd_cs5530_probe, - .remove = __devexit_p(snd_cs5530_remove), -}; - -static int __init alsa_card_cs5530_init(void) -{ - return pci_register_driver(&driver); -} - -static void __exit alsa_card_cs5530_exit(void) -{ - pci_unregister_driver(&driver); -} - -module_init(alsa_card_cs5530_init) -module_exit(alsa_card_cs5530_exit) - diff --git a/trunk/sound/pci/emu10k1/emu10k1_main.c b/trunk/sound/pci/emu10k1/emu10k1_main.c index 404ae1be0a4b..4a9b59ad8ab1 100644 --- a/trunk/sound/pci/emu10k1/emu10k1_main.c +++ b/trunk/sound/pci/emu10k1/emu10k1_main.c @@ -51,15 +51,9 @@ #define HANA_FILENAME "emu/hana.fw" #define DOCK_FILENAME "emu/audio_dock.fw" -#define EMU1010B_FILENAME "emu/emu1010b.fw" -#define MICRO_DOCK_FILENAME "emu/micro_dock.fw" -#define EMU1010_NOTEBOOK_FILENAME "emu/emu1010_notebook.fw" MODULE_FIRMWARE(HANA_FILENAME); MODULE_FIRMWARE(DOCK_FILENAME); -MODULE_FIRMWARE(EMU1010B_FILENAME); -MODULE_FIRMWARE(MICRO_DOCK_FILENAME); -MODULE_FIRMWARE(EMU1010_NOTEBOOK_FILENAME); /************************************************************************* @@ -666,12 +660,10 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file return err; } snd_printk(KERN_INFO "firmware size=0x%zx\n", fw_entry->size); -#if 0 if (fw_entry->size != 0x133a4) { snd_printk(KERN_ERR "firmware: %s wrong size.\n",filename); return -EINVAL; } -#endif /* The FPGA is a Xilinx Spartan IIE XC2S50E */ /* GPIO7 -> FPGA PGMN @@ -702,37 +694,6 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file return 0; } -/* - * EMU-1010 - details found out from this driver, official MS Win drivers, - * testing the card: - * - * Audigy2 (aka Alice2): - * --------------------- - * * communication over PCI - * * conversion of 32-bit data coming over EMU32 links from HANA FPGA - * to 2 x 16-bit, using internal DSP instructions - * * slave mode, clock supplied by HANA - * * linked to HANA using: - * 32 x 32-bit serial EMU32 output channels - * 16 x EMU32 input channels - * (?) x I2S I/O channels (?) - * - * FPGA (aka HANA): - * --------------- - * * provides all (?) physical inputs and outputs of the card - * (ADC, DAC, SPDIF I/O, ADAT I/O, etc.) - * * provides clock signal for the card and Alice2 - * * two crystals - for 44.1kHz and 48kHz multiples - * * provides internal routing of signal sources to signal destinations - * * inputs/outputs to Alice2 - see above - * - * Current status of the driver: - * ---------------------------- - * * only 44.1/48kHz supported (the MS Win driver supports up to 192 kHz) - * * PCM device nb. 2: - * 16 x 16-bit playback - snd_emu10k1_fx8010_playback_ops - * 16 x 32-bit capture - snd_emu10k1_capture_efx_ops - */ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) { unsigned int i; @@ -766,7 +727,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */ snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); snd_printdd("reg1=0x%x\n",reg); - if ((reg & 0x3f) == 0x15) { + if (reg == 0x55) { /* FPGA netlist already present so clear it */ /* Return to programming mode */ @@ -774,32 +735,19 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) } snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); snd_printdd("reg2=0x%x\n",reg); - if ((reg & 0x3f) == 0x15) { + if (reg == 0x55) { /* FPGA failed to return to programming mode */ - snd_printk(KERN_INFO "emu1010: FPGA failed to return to programming mode\n"); return -ENODEV; } snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); - if (emu->card_capabilities->emu1010 == 1) { - if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) { - snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME); - return err; - } - } else if (emu->card_capabilities->emu1010 == 2) { - if ((err = snd_emu1010_load_firmware(emu, EMU1010B_FILENAME)) != 0) { - snd_printk(KERN_INFO "emu1010: Loading Firmware file %s failed\n", EMU1010B_FILENAME); - return err; - } - } else if (emu->card_capabilities->emu1010 == 3) { - if ((err = snd_emu1010_load_firmware(emu, EMU1010_NOTEBOOK_FILENAME)) != 0) { - snd_printk(KERN_INFO "emu1010: Loading Firmware file %s failed\n", EMU1010_NOTEBOOK_FILENAME); - return err; - } + if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) { + snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME); + return err; } /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); - if ((reg & 0x3f) != 0x15) { + if (reg != 0x55) { /* FPGA failed to be programmed */ snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg=0x%x\n", reg); return -ENODEV; @@ -902,27 +850,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) EMU_DST_ALICE2_EMU32_6, EMU_SRC_DOCK_ADC2_LEFT1); snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_ALICE2_EMU32_7, EMU_SRC_DOCK_ADC2_RIGHT1); - /* Pavel Hofman - setting defaults for 8 more capture channels - * Defaults only, users will set their own values anyways, let's - * just copy/paste. - */ - - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_8, EMU_SRC_DOCK_MIC_A1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_9, EMU_SRC_DOCK_MIC_B1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_A, EMU_SRC_HAMOA_ADC_LEFT2); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_B, EMU_SRC_HAMOA_ADC_LEFT2); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_C, EMU_SRC_DOCK_ADC1_LEFT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_D, EMU_SRC_DOCK_ADC1_RIGHT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_E, EMU_SRC_DOCK_ADC2_LEFT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_F, EMU_SRC_DOCK_ADC2_RIGHT1); #endif #if 0 /* Original */ @@ -1016,27 +943,16 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) /* Return to Audio Dock programming mode */ snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); - if (emu->card_capabilities->emu1010 == 1) { - if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { - return err; - } - } else if (emu->card_capabilities->emu1010 == 2) { - if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { - return err; - } - } else if (emu->card_capabilities->emu1010 == 3) { - if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { - return err; - } + if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { + return err; } - snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ® ); snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg); /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg); - if ((reg & 0x3f) != 0x15) { + if (reg != 0x55) { /* FPGA failed to be programmed */ snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); return 0; @@ -1311,15 +1227,9 @@ static struct snd_emu_chip_details emu_chip_details[] = { .emu10k2_chip = 1, .ca0108_chip = 1, .ca_cardbus_chip = 1, - .spk71 = 1 , - .emu1010 = 3} , - {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102, - .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM????]", - .id = "EMU1010", - .emu10k2_chip = 1, - .ca0108_chip = 1, - .spk71 = 1 , - .emu1010 = 2} , + .spi_dac = 1, + .i2c_adc = 1, + .spk71 = 1} , {.vendor = 0x1102, .device = 0x0008, .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", .id = "Audigy2", @@ -1753,13 +1663,12 @@ int __devinit snd_emu10k1_create(struct snd_card *card, emu->fx8010.extout_mask = extout_mask; emu->enable_ir = enable_ir; - if (emu->card_capabilities->ca_cardbus_chip) { - if ((err = snd_emu10k1_cardbus_init(emu)) < 0) - goto error; - } if (emu->card_capabilities->ecard) { if ((err = snd_emu10k1_ecard_init(emu)) < 0) goto error; + } else if (emu->card_capabilities->ca_cardbus_chip) { + if ((err = snd_emu10k1_cardbus_init(emu)) < 0) + goto error; } else if (emu->card_capabilities->emu1010) { if ((err = snd_emu10k1_emu1010_init(emu)) < 0) { snd_emu10k1_free(emu); @@ -1905,10 +1814,10 @@ void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu) void snd_emu10k1_resume_init(struct snd_emu10k1 *emu) { - if (emu->card_capabilities->ca_cardbus_chip) - snd_emu10k1_cardbus_init(emu); if (emu->card_capabilities->ecard) snd_emu10k1_ecard_init(emu); + else if (emu->card_capabilities->ca_cardbus_chip) + snd_emu10k1_cardbus_init(emu); else if (emu->card_capabilities->emu1010) snd_emu10k1_emu1010_init(emu); else diff --git a/trunk/sound/pci/emu10k1/emufx.c b/trunk/sound/pci/emu10k1/emufx.c index 7206c0fa06f2..c02012cccd8e 100644 --- a/trunk/sound/pci/emu10k1/emufx.c +++ b/trunk/sound/pci/emu10k1/emufx.c @@ -1123,11 +1123,6 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF; } -/* - * Used for emu1010 - conversion from 32-bit capture inputs from HANA - * to 2 x 16-bit registers in audigy - their values are read via DMA. - * Conversion is performed by Audigy DSP instructions of FX8010. - */ static int snd_emu10k1_audigy_dsp_convert_32_to_2x16( struct snd_emu10k1_fx8010_code *icode, u32 *ptr, int tmp, int bit_shifter16, @@ -1198,11 +1193,7 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); #if 1 - /* PCM front Playback Volume (independent from stereo mix) - * playback = 0 + ( gpr * FXBUS_PCM_LEFT_FRONT >> 31) - * where gpr contains attenuation from corresponding mixer control - * (snd_emu10k1_init_stereo_control) - */ + /* PCM front Playback Volume (independent from stereo mix) */ A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT)); snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100); @@ -1558,7 +1549,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) if (emu->card_capabilities->emu1010) { snd_printk("EMU inputs on\n"); - /* Capture 16 (originally 8) channels of S32_LE sound */ + /* Capture 8 channels of S32_LE sound */ /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */ /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */ @@ -1569,11 +1560,6 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) ); /* Right ADC in 1 of 2 */ gpr_map[gpr++] = 0x00000000; - /* Delaying by one sample: instead of copying the input - * value A_P16VIN to output A_FXBUS2 as in the first channel, - * we use an auxiliary register, delaying the value by one - * sample - */ snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) ); A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000); gpr_map[gpr++] = 0x00000000; @@ -1597,66 +1583,6 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) gpr_map[gpr++] = 0x00000000; snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) ); A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000); - /* Pavel Hofman - we still have voices, A_FXBUS2s, and - * A_P16VINs available - - * let's add 8 more capture channels - total of 16 - */ - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x10)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x12)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x14)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x16)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x18)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x1a)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x1c)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x1e)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf), - A_C_00000000, A_C_00000000); #if 0 for (z = 4; z < 8; z++) { diff --git a/trunk/sound/pci/emu10k1/emumixer.c b/trunk/sound/pci/emu10k1/emumixer.c index 7b2c1dcc5337..4db6e1ca1665 100644 --- a/trunk/sound/pci/emu10k1/emumixer.c +++ b/trunk/sound/pci/emu10k1/emumixer.c @@ -77,10 +77,6 @@ static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol, return 0; } -/* - * Items labels in enum mixer controls assigning source data to - * each destination - */ static char *emu1010_src_texts[] = { "Silence", "Dock Mic A", @@ -137,9 +133,6 @@ static char *emu1010_src_texts[] = { "DSP 31", }; -/* - * List of data sources available for each destination - */ static unsigned int emu1010_src_regs[] = { EMU_SRC_SILENCE,/* 0 */ EMU_SRC_DOCK_MIC_A1, /* 1 */ @@ -196,10 +189,6 @@ static unsigned int emu1010_src_regs[] = { EMU_SRC_ALICE_EMU32B+0xf, /* 52 */ }; -/* - * Data destinations - physical EMU outputs. - * Each destination has an enum mixer control to choose a data source - */ static unsigned int emu1010_output_dst[] = { EMU_DST_DOCK_DAC1_LEFT1, /* 0 */ EMU_DST_DOCK_DAC1_RIGHT1, /* 1 */ @@ -227,11 +216,6 @@ static unsigned int emu1010_output_dst[] = { EMU_DST_HANA_ADAT+7, /* 23 */ }; -/* - * Data destinations - HANA outputs going to Alice2 (audigy) for - * capture (EMU32 + I2S links) - * Each destination has an enum mixer control to choose a data source - */ static unsigned int emu1010_input_dst[] = { EMU_DST_ALICE2_EMU32_0, EMU_DST_ALICE2_EMU32_1, diff --git a/trunk/sound/pci/emu10k1/emupcm.c b/trunk/sound/pci/emu10k1/emupcm.c index eda5cb373ded..ab4f5df5241b 100644 --- a/trunk/sound/pci/emu10k1/emupcm.c +++ b/trunk/sound/pci/emu10k1/emupcm.c @@ -1233,26 +1233,24 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) runtime->hw.rate_min = runtime->hw.rate_max = 48000; spin_lock_irq(&emu->reg_lock); if (emu->card_capabilities->emu1010) { - /* Nb. of channels has been increased to 16 */ - /* TODO + /* TODO * SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE * SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | * SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | * SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 * rate_min = 44100, * rate_max = 192000, - * channels_min = 16, - * channels_max = 16, + * channels_min = 8, + * channels_max = 8, * Need to add mixer control to fix sample rate * - * There are 32 mono channels of 16bits each. + * There are 16 mono channels of 16bits each. * 24bit Audio uses 2x channels over 16bit * 96kHz uses 2x channels over 48kHz * 192kHz uses 4x channels over 48kHz - * So, for 48kHz 24bit, one has 16 channels - * for 96kHz 24bit, one has 8 channels - * for 192kHz 24bit, one has 4 channels - * + * So, for 48kHz 24bit, one has 8 channels + * for 96kHz 24bit, one has 4 channels + * for 192kHz 24bit, one has 2 channels */ #if 1 switch (emu->emu1010.internal_clock) { @@ -1260,15 +1258,13 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) /* For 44.1kHz */ runtime->hw.rates = SNDRV_PCM_RATE_44100; runtime->hw.rate_min = runtime->hw.rate_max = 44100; - runtime->hw.channels_min = - runtime->hw.channels_max = 16; + runtime->hw.channels_min = runtime->hw.channels_max = 8; break; case 1: /* For 48kHz */ runtime->hw.rates = SNDRV_PCM_RATE_48000; runtime->hw.rate_min = runtime->hw.rate_max = 48000; - runtime->hw.channels_min = - runtime->hw.channels_max = 16; + runtime->hw.channels_min = runtime->hw.channels_max = 8; break; }; #endif @@ -1286,7 +1282,7 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) #endif runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; /* efx_voices_mask[0] is expected to be zero - * efx_voices_mask[1] is expected to have 32bits set + * efx_voices_mask[1] is expected to have 16bits set */ } else { runtime->hw.channels_min = runtime->hw.channels_max = 0; @@ -1791,24 +1787,11 @@ int __devinit snd_emu10k1_pcm_efx(struct snd_emu10k1 * emu, int device, struct s /* emu->efx_voices_mask[0] = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; */ if (emu->audigy) { emu->efx_voices_mask[0] = 0; - if (emu->card_capabilities->emu1010) - /* Pavel Hofman - 32 voices will be used for - * capture (write mode) - - * each bit = corresponding voice - */ - emu->efx_voices_mask[1] = 0xffffffff; - else - emu->efx_voices_mask[1] = 0xffff; + emu->efx_voices_mask[1] = 0xffff; } else { emu->efx_voices_mask[0] = 0xffff0000; emu->efx_voices_mask[1] = 0; } - /* For emu1010, the control has to set 32 upper bits (voices) - * out of the 64 bits (voices) to true for the 16-channels capture - * to work correctly. Correct A_FXWC2 initial value (0xffffffff) - * is already defined but the snd_emu10k1_pcm_efx_voices_mask - * control can override this register's value. - */ kctl = snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu); if (!kctl) return -ENOMEM; diff --git a/trunk/sound/pci/ens1370.c b/trunk/sound/pci/ens1370.c index 21cb4268a59b..7c403965153b 100644 --- a/trunk/sound/pci/ens1370.c +++ b/trunk/sound/pci/ens1370.c @@ -1607,8 +1607,8 @@ struct es1371_quirk { unsigned char rev; /* revision */ }; -static int es1371_quirk_lookup(struct ensoniq *ensoniq, - struct es1371_quirk *list) +static int __devinit es1371_quirk_lookup(struct ensoniq *ensoniq, + struct es1371_quirk *list) { while (list->vid != (unsigned short)PCI_ANY_ID) { if (ensoniq->pci->vendor == list->vid && diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index 92bc8b3fa2a0..2fa281cbef91 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -341,9 +341,6 @@ struct azx { unsigned int single_cmd :1; unsigned int polling_mode :1; unsigned int msi :1; - - /* for debugging */ - unsigned int last_cmd; /* last issued command (to sync) */ }; /* driver types */ @@ -469,10 +466,18 @@ static void azx_free_cmd_io(struct azx *chip) } /* send a command */ -static int azx_corb_send_cmd(struct hda_codec *codec, u32 val) +static int azx_corb_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, + unsigned int verb, unsigned int para) { struct azx *chip = codec->bus->private_data; unsigned int wp; + u32 val; + + val = (u32)(codec->addr & 0x0f) << 28; + val |= (u32)direct << 27; + val |= (u32)nid << 20; + val |= verb << 8; + val |= para; /* add command to corb */ wp = azx_readb(chip, CORBWP); @@ -533,12 +538,12 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) } if (! chip->rirb.cmds) return chip->rirb.res; /* the last value */ - schedule_timeout(1); + schedule_timeout_interruptible(1); } while (time_after_eq(timeout, jiffies)); if (chip->msi) { snd_printk(KERN_WARNING "hda_intel: No response from codec, " - "disabling MSI: last cmd=0x%08x\n", chip->last_cmd); + "disabling MSI...\n"); free_irq(chip->irq, chip); chip->irq = -1; pci_disable_msi(chip->pci); @@ -550,15 +555,13 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) if (!chip->polling_mode) { snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, " - "switching to polling mode: last cmd=0x%08x\n", - chip->last_cmd); + "switching to polling mode...\n"); chip->polling_mode = 1; goto again; } snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " - "switching to single_cmd mode: last cmd=0x%08x\n", - chip->last_cmd); + "switching to single_cmd mode...\n"); chip->rirb.rp = azx_readb(chip, RIRBWP); chip->rirb.cmds = 0; /* switch to single_cmd mode */ @@ -578,11 +581,20 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) */ /* send a command */ -static int azx_single_send_cmd(struct hda_codec *codec, u32 val) +static int azx_single_send_cmd(struct hda_codec *codec, hda_nid_t nid, + int direct, unsigned int verb, + unsigned int para) { struct azx *chip = codec->bus->private_data; + u32 val; int timeout = 50; + val = (u32)(codec->addr & 0x0f) << 28; + val |= (u32)direct << 27; + val |= (u32)nid << 20; + val |= verb << 8; + val |= para; + while (timeout--) { /* check ICB busy bit */ if (! (azx_readw(chip, IRS) & ICH6_IRS_BUSY)) { @@ -627,19 +639,10 @@ static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, unsigned int para) { struct azx *chip = codec->bus->private_data; - u32 val; - - val = (u32)(codec->addr & 0x0f) << 28; - val |= (u32)direct << 27; - val |= (u32)nid << 20; - val |= verb << 8; - val |= para; - chip->last_cmd = val; - if (chip->single_cmd) - return azx_single_send_cmd(codec, val); + return azx_single_send_cmd(codec, nid, direct, verb, para); else - return azx_corb_send_cmd(codec, val); + return azx_corb_send_cmd(codec, nid, direct, verb, para); } /* get a response */ @@ -1785,12 +1788,6 @@ static struct pci_device_id azx_ids[] = { { 0x10de, 0x044b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP65 */ { 0x10de, 0x055c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP67 */ { 0x10de, 0x055d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP67 */ - { 0x10de, 0x07fc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP73 */ - { 0x10de, 0x07fd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP73 */ - { 0x10de, 0x0774, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ - { 0x10de, 0x0775, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ - { 0x10de, 0x0776, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ - { 0x10de, 0x0777, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ { 0, } }; MODULE_DEVICE_TABLE(pci, azx_ids); diff --git a/trunk/sound/pci/hda/hda_proc.c b/trunk/sound/pci/hda/hda_proc.c index ac15066fd300..e313e685f161 100644 --- a/trunk/sound/pci/hda/hda_proc.c +++ b/trunk/sound/pci/hda/hda_proc.c @@ -250,12 +250,6 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id); snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id); snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id); - - if (codec->mfg) - snd_iprintf(buffer, "Modem Function Group: 0x%x\n", codec->mfg); - else - snd_iprintf(buffer, "No Modem Function Group found\n"); - if (! codec->afg) return; snd_iprintf(buffer, "Default PCM:\n"); diff --git a/trunk/sound/pci/hda/patch_analog.c b/trunk/sound/pci/hda/patch_analog.c index 4d7f8d11ad75..0e1a879663fa 100644 --- a/trunk/sound/pci/hda/patch_analog.c +++ b/trunk/sound/pci/hda/patch_analog.c @@ -1,8 +1,7 @@ /* - * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984, - * AD1986A, AD1988 + * HD audio interface patch for AD1981HD, AD1983, AD1986A, AD1988 * - * Copyright (c) 2005-2007 Takashi Iwai + * Copyright (c) 2005 Takashi Iwai * * This driver is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -62,7 +61,7 @@ struct ad198x_spec { int num_channel_mode; /* PCM information */ - struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ + struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ struct mutex amp_mutex; /* PCM volume/mute control mutex */ unsigned int spdif_route; @@ -2775,635 +2774,12 @@ static int patch_ad1988(struct hda_codec *codec) } -/* - * AD1884 / AD1984 - * - * port-B - front line/mic-in - * port-E - aux in/out - * port-F - aux in/out - * port-C - rear line/mic-in - * port-D - rear line/hp-out - * port-A - front line/hp-out - * - * AD1984 = AD1884 + two digital mic-ins - * - * FIXME: - * For simplicity, we share the single DAC for both HP and line-outs - * right now. The inidividual playbacks could be easily implemented, - * but no build-up framework is given, so far. - */ - -static hda_nid_t ad1884_dac_nids[1] = { - 0x04, -}; - -static hda_nid_t ad1884_adc_nids[2] = { - 0x08, 0x09, -}; - -static hda_nid_t ad1884_capsrc_nids[2] = { - 0x0c, 0x0d, -}; - -#define AD1884_SPDIF_OUT 0x02 - -static struct hda_input_mux ad1884_capture_source = { - .num_items = 4, - .items = { - { "Front Mic", 0x0 }, - { "Mic", 0x1 }, - { "CD", 0x2 }, - { "Mix", 0x3 }, - }, -}; - -static struct snd_kcontrol_new ad1884_base_mixers[] = { - HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), - /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ - HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), - /* - HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x20, 0x03, HDA_INPUT), - HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x20, 0x03, HDA_INPUT), - HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Digital Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT), - */ - HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* The multiple "Capture Source" controls confuse alsamixer - * So call somewhat different.. - * FIXME: the controls appear in the "playback" view! - */ - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 2, - .info = ad198x_mux_enum_info, - .get = ad198x_mux_enum_get, - .put = ad198x_mux_enum_put, - }, - /* SPDIF controls */ - HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", - /* identical with ad1983 */ - .info = ad1983_spdif_route_info, - .get = ad1983_spdif_route_get, - .put = ad1983_spdif_route_put, - }, - { } /* end */ -}; - -static struct snd_kcontrol_new ad1984_dmic_mixers[] = { - HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0, - HDA_INPUT), - HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0, - HDA_INPUT), - { } /* end */ -}; - -/* - * initialization verbs - */ -static struct hda_verb ad1884_init_verbs[] = { - /* DACs; mute as default */ - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - /* Port-A (HP) mixer */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* Port-A pin */ - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* HP selector - select DAC2 */ - {0x22, AC_VERB_SET_CONNECT_SEL, 0x1}, - /* Port-D (Line-out) mixer */ - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* Port-D pin */ - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Mono-out mixer */ - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* Mono-out pin */ - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Mono selector */ - {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, - /* Port-B (front mic) pin */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Port-C (rear mic) pin */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Analog mixer; mute as default */ - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - /* Analog Mix output amp */ - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ - /* SPDIF output selector */ - {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ - { } /* end */ -}; - -static int patch_ad1884(struct hda_codec *codec) -{ - struct ad198x_spec *spec; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - mutex_init(&spec->amp_mutex); - codec->spec = spec; - - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids); - spec->multiout.dac_nids = ad1884_dac_nids; - spec->multiout.dig_out_nid = AD1884_SPDIF_OUT; - spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids); - spec->adc_nids = ad1884_adc_nids; - spec->capsrc_nids = ad1884_capsrc_nids; - spec->input_mux = &ad1884_capture_source; - spec->num_mixers = 1; - spec->mixers[0] = ad1884_base_mixers; - spec->num_init_verbs = 1; - spec->init_verbs[0] = ad1884_init_verbs; - spec->spdif_route = 0; - - codec->patch_ops = ad198x_patch_ops; - - return 0; -} - -/* - * Lenovo Thinkpad T61/X61 - */ -static struct hda_input_mux ad1984_thinkpad_capture_source = { - .num_items = 3, - .items = { - { "Mic", 0x0 }, - { "Internal Mic", 0x1 }, - { "Mix", 0x3 }, - }, -}; - -static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = { - HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), - /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ - HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT), - HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* The multiple "Capture Source" controls confuse alsamixer - * So call somewhat different.. - * FIXME: the controls appear in the "playback" view! - */ - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 2, - .info = ad198x_mux_enum_info, - .get = ad198x_mux_enum_get, - .put = ad198x_mux_enum_put, - }, - { } /* end */ -}; - -/* additional verbs */ -static struct hda_verb ad1984_thinkpad_init_verbs[] = { - /* Port-E (docking station mic) pin */ - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* docking mic boost */ - {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Analog mixer - docking mic; mute as default */ - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - /* enable EAPD bit */ - {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, - { } /* end */ -}; - -/* Digial MIC ADC NID 0x05 + 0x06 */ -static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - unsigned int stream_tag, - unsigned int format, - struct snd_pcm_substream *substream) -{ - snd_hda_codec_setup_stream(codec, 0x05 + substream->number, - stream_tag, 0, format); - return 0; -} - -static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - snd_hda_codec_setup_stream(codec, 0x05 + substream->number, - 0, 0, 0); - return 0; -} - -static struct hda_pcm_stream ad1984_pcm_dmic_capture = { - .substreams = 2, - .channels_min = 2, - .channels_max = 2, - .nid = 0x05, - .ops = { - .prepare = ad1984_pcm_dmic_prepare, - .cleanup = ad1984_pcm_dmic_cleanup - }, -}; - -static int ad1984_build_pcms(struct hda_codec *codec) -{ - struct ad198x_spec *spec = codec->spec; - struct hda_pcm *info; - int err; - - err = ad198x_build_pcms(codec); - if (err < 0) - return err; - - info = spec->pcm_rec + codec->num_pcms; - codec->num_pcms++; - info->name = "AD1984 Digital Mic"; - info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture; - return 0; -} - -/* models */ -enum { - AD1984_BASIC, - AD1984_THINKPAD, - AD1984_MODELS -}; - -static const char *ad1984_models[AD1984_MODELS] = { - [AD1984_BASIC] = "basic", - [AD1984_THINKPAD] = "thinkpad", -}; - -static struct snd_pci_quirk ad1984_cfg_tbl[] = { - /* Lenovo Thinkpad T61/X61 */ - SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1984_THINKPAD), - {} -}; - -static int patch_ad1984(struct hda_codec *codec) -{ - struct ad198x_spec *spec; - int board_config, err; - - err = patch_ad1884(codec); - if (err < 0) - return err; - spec = codec->spec; - board_config = snd_hda_check_board_config(codec, AD1984_MODELS, - ad1984_models, ad1984_cfg_tbl); - switch (board_config) { - case AD1984_BASIC: - /* additional digital mics */ - spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers; - codec->patch_ops.build_pcms = ad1984_build_pcms; - break; - case AD1984_THINKPAD: - spec->multiout.dig_out_nid = 0; - spec->input_mux = &ad1984_thinkpad_capture_source; - spec->mixers[0] = ad1984_thinkpad_mixers; - spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs; - break; - } - return 0; -} - - -/* - * AD1882 - * - * port-A - front hp-out - * port-B - front mic-in - * port-C - rear line-in, shared surr-out (3stack) - * port-D - rear line-out - * port-E - rear mic-in, shared clfe-out (3stack) - * port-F - rear surr-out (6stack) - * port-G - rear clfe-out (6stack) - */ - -static hda_nid_t ad1882_dac_nids[3] = { - 0x04, 0x03, 0x05 -}; - -static hda_nid_t ad1882_adc_nids[2] = { - 0x08, 0x09, -}; - -static hda_nid_t ad1882_capsrc_nids[2] = { - 0x0c, 0x0d, -}; - -#define AD1882_SPDIF_OUT 0x02 - -/* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */ -static struct hda_input_mux ad1882_capture_source = { - .num_items = 5, - .items = { - { "Front Mic", 0x1 }, - { "Mic", 0x4 }, - { "Line", 0x2 }, - { "CD", 0x3 }, - { "Mix", 0x7 }, - }, -}; - -static struct snd_kcontrol_new ad1882_base_mixers[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), - HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT), - HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* The multiple "Capture Source" controls confuse alsamixer - * So call somewhat different.. - * FIXME: the controls appear in the "playback" view! - */ - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 2, - .info = ad198x_mux_enum_info, - .get = ad198x_mux_enum_get, - .put = ad198x_mux_enum_put, - }, - /* SPDIF controls */ - HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", - /* identical with ad1983 */ - .info = ad1983_spdif_route_info, - .get = ad1983_spdif_route_get, - .put = ad1983_spdif_route_put, - }, - { } /* end */ -}; - -static struct snd_kcontrol_new ad1882_3stack_mixers[] = { - HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Channel Mode", - .info = ad198x_ch_mode_info, - .get = ad198x_ch_mode_get, - .put = ad198x_ch_mode_put, - }, - { } /* end */ -}; - -static struct snd_kcontrol_new ad1882_6stack_mixers[] = { - HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT), - { } /* end */ -}; - -static struct hda_verb ad1882_ch2_init[] = { - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - { } /* end */ -}; - -static struct hda_verb ad1882_ch4_init[] = { - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - { } /* end */ -}; - -static struct hda_verb ad1882_ch6_init[] = { - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - { } /* end */ -}; - -static struct hda_channel_mode ad1882_modes[3] = { - { 2, ad1882_ch2_init }, - { 4, ad1882_ch4_init }, - { 6, ad1882_ch6_init }, -}; - -/* - * initialization verbs - */ -static struct hda_verb ad1882_init_verbs[] = { - /* DACs; mute as default */ - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - /* Port-A (HP) mixer */ - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* Port-A pin */ - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* HP selector - select DAC2 */ - {0x37, AC_VERB_SET_CONNECT_SEL, 0x1}, - /* Port-D (Line-out) mixer */ - {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* Port-D pin */ - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Mono-out mixer */ - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* Mono-out pin */ - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Port-B (front mic) pin */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ - /* Port-C (line-in) pin */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ - /* Port-C mixer - mute as input */ - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - /* Port-E (mic-in) pin */ - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ - /* Port-E mixer - mute as input */ - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - /* Port-F (surround) */ - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Port-G (CLFE) */ - {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Analog mixer; mute as default */ - /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */ - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, - /* Analog Mix output amp */ - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ - /* SPDIF output selector */ - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ - {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ - { } /* end */ -}; - -/* models */ -enum { - AD1882_3STACK, - AD1882_6STACK, - AD1882_MODELS -}; - -static const char *ad1882_models[AD1986A_MODELS] = { - [AD1882_3STACK] = "3stack", - [AD1882_6STACK] = "6stack", -}; - - -static int patch_ad1882(struct hda_codec *codec) -{ - struct ad198x_spec *spec; - int board_config; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - mutex_init(&spec->amp_mutex); - codec->spec = spec; - - spec->multiout.max_channels = 6; - spec->multiout.num_dacs = 3; - spec->multiout.dac_nids = ad1882_dac_nids; - spec->multiout.dig_out_nid = AD1882_SPDIF_OUT; - spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids); - spec->adc_nids = ad1882_adc_nids; - spec->capsrc_nids = ad1882_capsrc_nids; - spec->input_mux = &ad1882_capture_source; - spec->num_mixers = 1; - spec->mixers[0] = ad1882_base_mixers; - spec->num_init_verbs = 1; - spec->init_verbs[0] = ad1882_init_verbs; - spec->spdif_route = 0; - - codec->patch_ops = ad198x_patch_ops; - - /* override some parameters */ - board_config = snd_hda_check_board_config(codec, AD1882_MODELS, - ad1882_models, NULL); - switch (board_config) { - default: - case AD1882_3STACK: - spec->num_mixers = 2; - spec->mixers[1] = ad1882_3stack_mixers; - spec->channel_mode = ad1882_modes; - spec->num_channel_mode = ARRAY_SIZE(ad1882_modes); - spec->need_dac_fix = 1; - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = 1; - break; - case AD1882_6STACK: - spec->num_mixers = 2; - spec->mixers[1] = ad1882_6stack_mixers; - break; - } - return 0; -} - - /* * patch entries */ struct hda_codec_preset snd_hda_preset_analog[] = { - { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, - { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 }, { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, - { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 }, { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, diff --git a/trunk/sound/pci/hda/patch_atihdmi.c b/trunk/sound/pci/hda/patch_atihdmi.c index 72d3ab9751ac..f8eb4c90f801 100644 --- a/trunk/sound/pci/hda/patch_atihdmi.c +++ b/trunk/sound/pci/hda/patch_atihdmi.c @@ -172,7 +172,6 @@ static int patch_atihdmi(struct hda_codec *codec) */ struct hda_codec_preset snd_hda_preset_atihdmi[] = { { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, - { .id = 0x10027919, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, { .id = 0x1002aa01, .name = "ATI R600 HDMI", .patch = patch_atihdmi }, {} /* terminator */ diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c index 4d8e8af5c819..bef214bcdddf 100644 --- a/trunk/sound/pci/hda/patch_conexant.c +++ b/trunk/sound/pci/hda/patch_conexant.c @@ -801,9 +801,7 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV Series", CXT5045_LAPTOP), SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2120", CXT5045_LAPTOP), SND_PCI_QUIRK(0x103c, 0x30cd, "HP DV Series", CXT5045_LAPTOP), - SND_PCI_QUIRK(0x103c, 0x30d9, "HP Spartan", CXT5045_LAPTOP), SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU), - SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP), SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP), {} }; diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 9a47eec5a27b..4776de93928b 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -94,18 +94,10 @@ enum { ALC262_HP_BPC_D7000_WF, ALC262_BENQ_ED8, ALC262_SONY_ASSAMD, - ALC262_BENQ_T31, ALC262_AUTO, ALC262_MODEL_LAST /* last tag */ }; -/* ALC268 models */ -enum { - ALC268_3ST, - ALC268_AUTO, - ALC268_MODEL_LAST /* last tag */ -}; - /* ALC861 models */ enum { ALC861_3ST, @@ -123,7 +115,6 @@ enum { /* ALC861-VD models */ enum { ALC660VD_3ST, - ALC660VD_3ST_DIG, ALC861VD_3ST, ALC861VD_3ST_DIG, ALC861VD_6ST_DIG, @@ -153,7 +144,6 @@ enum { ALC882_TARGA, ALC882_ASUS_A7J, ALC885_MACPRO, - ALC885_IMAC24, ALC882_AUTO, ALC882_MODEL_LAST, }; @@ -173,8 +163,6 @@ enum { ALC883_LENOVO_101E_2ch, ALC883_LENOVO_NB0763, ALC888_LENOVO_MS7195_DIG, - ALC888_6ST_HP, - ALC888_3ST_HP, ALC883_AUTO, ALC883_MODEL_LAST, }; @@ -724,38 +712,6 @@ static void alc_subsystem_id(struct hda_codec *codec, } } -/* - * Fix-up pin default configurations - */ - -struct alc_pincfg { - hda_nid_t nid; - u32 val; -}; - -static void alc_fix_pincfg(struct hda_codec *codec, - const struct snd_pci_quirk *quirk, - const struct alc_pincfg **pinfix) -{ - const struct alc_pincfg *cfg; - - quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); - if (!quirk) - return; - - cfg = pinfix[quirk->value]; - for (; cfg->nid; cfg++) { - int i; - u32 val = cfg->val; - for (i = 0; i < 4; i++) { - snd_hda_codec_write(codec, cfg->nid, 0, - AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i, - val & 0xff); - val >>= 8; - } - } -} - /* * ALC880 3-stack model * @@ -1922,53 +1878,31 @@ static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) * Pin assignment: * Speaker-out: 0x14 * Mic-In: 0x18 - * Built-in Mic-In: 0x19 - * Line-In: 0x1b - * HP-Out: 0x1a + * Built-in Mic-In: 0x19 (?) + * HP-Out: 0x1b * SPDIF-Out: 0x1e */ +/* seems analog CD is not working */ static struct hda_input_mux alc880_lg_lw_capture_source = { - .num_items = 3, + .num_items = 2, .items = { { "Mic", 0x0 }, { "Internal Mic", 0x1 }, - { "Line In", 0x2 }, }, }; -#define alc880_lg_lw_modes alc880_threestack_modes - static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Channel Mode", - .info = alc_ch_mode_info, - .get = alc_ch_mode_get, - .put = alc_ch_mode_put, - }, { } /* end */ }; static struct hda_verb alc880_lg_lw_init_verbs[] = { - {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ - {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ - {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ - /* set capture source to mic-in */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -1978,6 +1912,7 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = { {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* HP-out */ + {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* mic-in to input */ @@ -2921,11 +2856,11 @@ static struct alc_config_preset alc880_presets[] = { .mixers = { alc880_lg_lw_mixer }, .init_verbs = { alc880_volume_init_verbs, alc880_lg_lw_init_verbs }, - .num_dacs = ARRAY_SIZE(alc880_dac_nids), + .num_dacs = 1, .dac_nids = alc880_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), - .channel_mode = alc880_lg_lw_modes, + .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), + .channel_mode = alc880_2_jack_modes, .input_mux = &alc880_lg_lw_capture_source, .unsol_event = alc880_lg_lw_unsol_event, .init_hook = alc880_lg_lw_automute, @@ -5119,60 +5054,6 @@ static struct hda_verb alc882_macpro_init_verbs[] = { { } }; -/* iMac 24 mixer. */ -static struct snd_kcontrol_new alc885_imac24_mixer[] = { - HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), - HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), - { } /* end */ -}; - -/* iMac 24 init verbs. */ -static struct hda_verb alc885_imac24_init_verbs[] = { - /* Internal speakers: output 0 (0x0c) */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* Internal speakers: output 0 (0x0c) */ - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* Headphone: output 0 (0x0c) */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, - /* Front Mic: input vref at 80% */ - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - { } -}; - -/* Toggle speaker-output according to the hp-jack state */ -static void alc885_imac24_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x14, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x18, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x18, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); -} - -/* Processes unsolicited events. */ -static void alc885_imac24_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - /* Headphone insertion or removal. */ - if ((res >> 26) == ALC880_HP_EVENT) - alc885_imac24_automute(codec); -} - static struct hda_verb alc882_targa_verbs[] = { {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -5393,7 +5274,6 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { [ALC882_ARIMA] = "arima", [ALC882_W2JC] = "w2jc", [ALC885_MACPRO] = "macpro", - [ALC885_IMAC24] = "imac24", [ALC882_AUTO] = "auto", }; @@ -5404,7 +5284,6 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), - SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), {} @@ -5466,19 +5345,6 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc882_ch_modes, .input_mux = &alc882_capture_source, }, - [ALC885_IMAC24] = { - .mixers = { alc885_imac24_mixer }, - .init_verbs = { alc885_imac24_init_verbs }, - .num_dacs = ARRAY_SIZE(alc882_dac_nids), - .dac_nids = alc882_dac_nids, - .dig_out_nid = ALC882_DIGOUT_NID, - .dig_in_nid = ALC882_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), - .channel_mode = alc882_ch_modes, - .input_mux = &alc882_capture_source, - .unsol_event = alc885_imac24_unsol_event, - .init_hook = alc885_imac24_automute, - }, [ALC882_TARGA] = { .mixers = { alc882_targa_mixer, alc882_chmode_mixer, alc882_capture_mixer }, @@ -5512,29 +5378,6 @@ static struct alc_config_preset alc882_presets[] = { }; -/* - * Pin config fixes - */ -enum { - PINFIX_ABIT_AW9D_MAX -}; - -static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { - { 0x15, 0x01080104 }, /* side */ - { 0x16, 0x01011012 }, /* rear */ - { 0x17, 0x01016011 }, /* clfe */ - { } -}; - -static const struct alc_pincfg *alc882_pin_fixes[] = { - [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix, -}; - -static struct snd_pci_quirk alc882_pinfix_tbl[] = { - SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), - {} -}; - /* * BIOS auto configuration */ @@ -5651,9 +5494,6 @@ static int patch_alc882(struct hda_codec *codec) case 0x106b0c00: /* Mac Pro */ board_config = ALC885_MACPRO; break; - case 0x106b1000: /* iMac 24 */ - board_config = ALC885_IMAC24; - break; default: printk(KERN_INFO "hda_codec: Unknown model for ALC882, " "trying auto-probe from BIOS...\n"); @@ -5661,8 +5501,6 @@ static int patch_alc882(struct hda_codec *codec) } } - alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes); - if (board_config == ALC882_AUTO) { /* automatic parse from the BIOS config */ err = alc882_parse_auto_config(codec); @@ -5680,7 +5518,7 @@ static int patch_alc882(struct hda_codec *codec) if (board_config != ALC882_AUTO) setup_preset(spec, &alc882_presets[board_config]); - if (board_config == ALC885_MACPRO || board_config == ALC885_IMAC24) { + if (board_config == ALC885_MACPRO) { alc882_gpio_mute(codec, 0, 0); alc882_gpio_mute(codec, 1, 0); } @@ -6157,84 +5995,6 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc888_6st_hp_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 2, - .info = alc883_mux_enum_info, - .get = alc883_mux_enum_get, - .put = alc883_mux_enum_put, - }, - { } /* end */ -}; - -static struct snd_kcontrol_new alc888_3st_hp_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 2, - .info = alc883_mux_enum_info, - .get = alc883_mux_enum_get, - .put = alc883_mux_enum_put, - }, - { } /* end */ -}; - static struct snd_kcontrol_new alc883_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -6366,42 +6126,6 @@ static struct hda_verb alc888_lenovo_ms7195_verbs[] = { { } /* end */ }; -static struct hda_verb alc888_6st_hp_verbs[] = { - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */ - {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */ - {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */ - { } -}; - -static struct hda_verb alc888_3st_hp_verbs[] = { - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ - {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ - {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ - { } -}; - -static struct hda_verb alc888_3st_hp_2ch_init[] = { - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { } -}; - -static struct hda_verb alc888_3st_hp_6ch_init[] = { - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { } -}; - -static struct hda_channel_mode alc888_3st_hp_modes[2] = { - { 2, alc888_3st_hp_2ch_init }, - { 6, alc888_3st_hp_6ch_init }, -}; - /* toggle front-jack and RCA according to the hp-jack state */ static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) { @@ -6644,14 +6368,11 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { [ALC883_LENOVO_101E_2ch] = "lenovo-101e", [ALC883_LENOVO_NB0763] = "lenovo-nb0763", [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", - [ALC888_6ST_HP] = "6stack-hp", - [ALC888_3ST_HP] = "3stack-hp", [ALC883_AUTO] = "auto", }; static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), - SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), @@ -6660,8 +6381,6 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), @@ -6681,9 +6400,6 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), - SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP), - SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), - SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), {} }; @@ -6868,31 +6584,6 @@ static struct alc_config_preset alc883_presets[] = { .unsol_event = alc883_lenovo_ms7195_unsol_event, .init_hook = alc888_lenovo_ms7195_front_automute, }, - [ALC888_6ST_HP] = { - .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), - .adc_nids = alc883_adc_nids, - .dig_in_nid = ALC883_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), - .channel_mode = alc883_sixstack_modes, - .input_mux = &alc883_capture_source, - }, - [ALC888_3ST_HP] = { - .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), - .adc_nids = alc883_adc_nids, - .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), - .channel_mode = alc888_3st_hp_modes, - .need_dac_fix = 1, - .input_mux = &alc883_capture_source, - }, }; @@ -7166,16 +6857,7 @@ static struct snd_kcontrol_new alc262_sony_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - { } /* end */ -}; + #define alc262_capture_mixer alc882_capture_mixer #define alc262_capture_alt_mixer alc882_capture_alt_mixer @@ -7507,15 +7189,6 @@ static struct hda_verb alc262_EAPD_verbs[] = { {} }; -static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - - {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, - {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, - {} -}; - /* add playback controls from the parsed DAC table */ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) @@ -7911,8 +7584,7 @@ static const char *alc262_models[ALC262_MODEL_LAST] = { [ALC262_HP_BPC] = "hp-bpc", [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", [ALC262_BENQ_ED8] = "benq", - [ALC262_BENQ_T31] = "benq-t31", - [ALC262_SONY_ASSAMD] = "sony-assamd", + [ALC262_BENQ_ED8] = "sony-assamd", [ALC262_AUTO] = "auto", }; @@ -7920,12 +7592,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC), SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC), SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC), SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), @@ -7938,7 +7606,6 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), - SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), @@ -8043,17 +7710,6 @@ static struct alc_config_preset alc262_presets[] = { .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, .unsol_event = alc262_hippo_unsol_event, - }, - [ALC262_BENQ_T31] = { - .mixers = { alc262_benq_t31_mixer }, - .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs }, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x03, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_capture_source, - .unsol_event = alc262_hippo_unsol_event, }, }; @@ -8144,521 +7800,12 @@ static int patch_alc262(struct hda_codec *codec) } /* - * ALC268 channel source setting (2 channel) + * ALC861 channel source setting (2/6 channel selection for 3-stack) */ -#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID -#define alc268_modes alc260_modes - -static hda_nid_t alc268_dac_nids[2] = { - /* front, hp */ - 0x02, 0x03 -}; - -static hda_nid_t alc268_adc_nids[2] = { - /* ADC0-1 */ - 0x08, 0x07 -}; - -static hda_nid_t alc268_adc_nids_alt[1] = { - /* ADC0 */ - 0x08 -}; - -static struct snd_kcontrol_new alc268_base_mixer[] = { - /* output mixer control */ - HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - { } -}; /* - * generic initialization of ADC, input mixers and output mixers - */ -static struct hda_verb alc268_base_init_verbs[] = { - /* Unmute DAC0-1 and set vol = 0 */ - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - /* - * Set up output mixers (0x0c - 0x0e) - */ - /* set vol=0 to output mixers */ - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, - - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - - /* FIXME: use matrix-type input source selection */ - /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */ - /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ - /* Input mixer2 */ - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, - - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, - { } -}; - -/* - * generic initialization of ADC, input mixers and output mixers - */ -static struct hda_verb alc268_volume_init_verbs[] = { - /* set output DAC */ - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - - /* set PCBEEP vol = 0 */ - {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))}, - - { } -}; - -#define alc268_mux_enum_info alc_mux_enum_info -#define alc268_mux_enum_get alc_mux_enum_get - -static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct alc_spec *spec = codec->spec; - const struct hda_input_mux *imux = spec->input_mux; - unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - static hda_nid_t capture_mixers[3] = { 0x23, 0x24 }; - hda_nid_t nid = capture_mixers[adc_idx]; - unsigned int *cur_val = &spec->cur_mux[adc_idx]; - unsigned int i, idx; - - idx = ucontrol->value.enumerated.item[0]; - if (idx >= imux->num_items) - idx = imux->num_items - 1; - if (*cur_val == idx && !codec->in_resume) - return 0; - for (i = 0; i < imux->num_items; i++) { - unsigned int v = (i == idx) ? 0x7000 : 0x7080; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, - v | (imux->items[i].index << 8)); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, - idx ); - } - *cur_val = idx; - return 1; -} - -static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { - HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* The multiple "Capture Source" controls confuse alsamixer - * So call somewhat different.. - * FIXME: the controls appear in the "playback" view! - */ - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 1, - .info = alc268_mux_enum_info, - .get = alc268_mux_enum_get, - .put = alc268_mux_enum_put, - }, - { } /* end */ -}; - -static struct snd_kcontrol_new alc268_capture_mixer[] = { - HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* The multiple "Capture Source" controls confuse alsamixer - * So call somewhat different.. - * FIXME: the controls appear in the "playback" view! - */ - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 2, - .info = alc268_mux_enum_info, - .get = alc268_mux_enum_get, - .put = alc268_mux_enum_put, - }, - { } /* end */ -}; - -static struct hda_input_mux alc268_capture_source = { - .num_items = 4, - .items = { - { "Mic", 0x0 }, - { "Front Mic", 0x1 }, - { "Line", 0x2 }, - { "CD", 0x3 }, - }, -}; - -/* create input playback/capture controls for the given pin */ -static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, - const char *ctlname, int idx) -{ - char name[32]; - int err; - - sprintf(name, "%s Playback Volume", ctlname); - if (nid == 0x14) { - err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(0x02, 3, idx, - HDA_OUTPUT)); - if (err < 0) - return err; - } else if (nid == 0x15) { - err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(0x03, 3, idx, - HDA_OUTPUT)); - if (err < 0) - return err; - } else - return -1; - sprintf(name, "%s Playback Switch", ctlname); - err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); - if (err < 0) - return err; - return 0; -} - -/* add playback controls from the parsed DAC table */ -static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, - const struct auto_pin_cfg *cfg) -{ - hda_nid_t nid; - int err; - - spec->multiout.num_dacs = 2; /* only use one dac */ - spec->multiout.dac_nids = spec->private_dac_nids; - spec->multiout.dac_nids[0] = 2; - spec->multiout.dac_nids[1] = 3; - - nid = cfg->line_out_pins[0]; - if (nid) - alc268_new_analog_output(spec, nid, "Front", 0); - - nid = cfg->speaker_pins[0]; - if (nid == 0x1d) { - err = add_control(spec, ALC_CTL_WIDGET_VOL, - "Speaker Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); - if (err < 0) - return err; - } - nid = cfg->hp_pins[0]; - if (nid) - alc268_new_analog_output(spec, nid, "Headphone", 0); - - nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; - if (nid == 0x16) { - err = add_control(spec, ALC_CTL_WIDGET_MUTE, - "Mono Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT)); - if (err < 0) - return err; - } - return 0; -} - -/* create playback/capture controls for input pins */ -static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, - const struct auto_pin_cfg *cfg) -{ - struct hda_input_mux *imux = &spec->private_imux; - int i, idx1; - - for (i = 0; i < AUTO_PIN_LAST; i++) { - switch(cfg->input_pins[i]) { - case 0x18: - idx1 = 0; /* Mic 1 */ - break; - case 0x19: - idx1 = 1; /* Mic 2 */ - break; - case 0x1a: - idx1 = 2; /* Line In */ - break; - case 0x1c: - idx1 = 3; /* CD */ - break; - default: - continue; - } - imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; - imux->items[imux->num_items].index = idx1; - imux->num_items++; - } - return 0; -} - -static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; - hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; - hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; - unsigned int dac_vol1, dac_vol2; - - if (speaker_nid) { - snd_hda_codec_write(codec, speaker_nid, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); - snd_hda_codec_write(codec, 0x0f, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_IN_UNMUTE(1)); - snd_hda_codec_write(codec, 0x10, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_IN_UNMUTE(1)); - } else { - snd_hda_codec_write(codec, 0x0f, 0, - AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); - snd_hda_codec_write(codec, 0x10, 0, - AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); - } - - dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ - if (line_nid == 0x14) - dac_vol2 = AMP_OUT_ZERO; - else if (line_nid == 0x15) - dac_vol1 = AMP_OUT_ZERO; - if (hp_nid == 0x14) - dac_vol2 = AMP_OUT_ZERO; - else if (hp_nid == 0x15) - dac_vol1 = AMP_OUT_ZERO; - if (line_nid != 0x16 || hp_nid != 0x16 || - spec->autocfg.line_out_pins[1] != 0x16 || - spec->autocfg.line_out_pins[2] != 0x16) - dac_vol1 = dac_vol2 = AMP_OUT_ZERO; - - snd_hda_codec_write(codec, 0x02, 0, - AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); - snd_hda_codec_write(codec, 0x03, 0, - AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); -} - -/* pcm configuration: identiacal with ALC880 */ -#define alc268_pcm_analog_playback alc880_pcm_analog_playback -#define alc268_pcm_analog_capture alc880_pcm_analog_capture -#define alc268_pcm_digital_playback alc880_pcm_digital_playback - -/* - * BIOS auto configuration - */ -static int alc268_parse_auto_config(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - int err; - static hda_nid_t alc268_ignore[] = { 0 }; - - err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc268_ignore); - if (err < 0) - return err; - if (!spec->autocfg.line_outs) - return 0; /* can't find valid BIOS pin config */ - - err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); - if (err < 0) - return err; - err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg); - if (err < 0) - return err; - - spec->multiout.max_channels = 2; - - /* digital only support output */ - if (spec->autocfg.dig_out_pin) - spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; - - if (spec->kctl_alloc) - spec->mixers[spec->num_mixers++] = spec->kctl_alloc; - - spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs; - spec->num_mux_defs = 1; - spec->input_mux = &spec->private_imux; - - return 1; -} - -#define alc268_auto_init_multi_out alc882_auto_init_multi_out -#define alc268_auto_init_hp_out alc882_auto_init_hp_out -#define alc268_auto_init_analog_input alc882_auto_init_analog_input - -/* init callback for auto-configuration model -- overriding the default init */ -static void alc268_auto_init(struct hda_codec *codec) -{ - alc268_auto_init_multi_out(codec); - alc268_auto_init_hp_out(codec); - alc268_auto_init_mono_speaker_out(codec); - alc268_auto_init_analog_input(codec); -} - -/* - * configuration and preset - */ -static const char *alc268_models[ALC268_MODEL_LAST] = { - [ALC268_3ST] = "3stack", - [ALC268_AUTO] = "auto", -}; - -static struct snd_pci_quirk alc268_cfg_tbl[] = { - SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), - {} -}; - -static struct alc_config_preset alc268_presets[] = { - [ALC268_3ST] = { - .mixers = { alc268_base_mixer, alc268_capture_alt_mixer }, - .init_verbs = { alc268_base_init_verbs }, - .num_dacs = ARRAY_SIZE(alc268_dac_nids), - .dac_nids = alc268_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), - .adc_nids = alc268_adc_nids_alt, - .hp_nid = 0x03, - .dig_out_nid = ALC268_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc268_modes), - .channel_mode = alc268_modes, - .input_mux = &alc268_capture_source, - }, -}; - -static int patch_alc268(struct hda_codec *codec) -{ - struct alc_spec *spec; - int board_config; - int err; - - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - codec->spec = spec; - - board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, - alc268_models, - alc268_cfg_tbl); - - if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { - printk(KERN_INFO "hda_codec: Unknown model for ALC268, " - "trying auto-probe from BIOS...\n"); - board_config = ALC268_AUTO; - } - - if (board_config == ALC268_AUTO) { - /* automatic parse from the BIOS config */ - err = alc268_parse_auto_config(codec); - if (err < 0) { - alc_free(codec); - return err; - } else if (!err) { - printk(KERN_INFO - "hda_codec: Cannot set up configuration " - "from BIOS. Using base mode...\n"); - board_config = ALC268_3ST; - } - } - - if (board_config != ALC268_AUTO) - setup_preset(spec, &alc268_presets[board_config]); - - spec->stream_name_analog = "ALC268 Analog"; - spec->stream_analog_playback = &alc268_pcm_analog_playback; - spec->stream_analog_capture = &alc268_pcm_analog_capture; - - spec->stream_name_digital = "ALC268 Digital"; - spec->stream_digital_playback = &alc268_pcm_digital_playback; - - if (board_config == ALC268_AUTO) { - if (!spec->adc_nids && spec->input_mux) { - /* check whether NID 0x07 is valid */ - unsigned int wcap = get_wcaps(codec, 0x07); - - /* get type */ - wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; - if (wcap != AC_WID_AUD_IN) { - spec->adc_nids = alc268_adc_nids_alt; - spec->num_adc_nids = - ARRAY_SIZE(alc268_adc_nids_alt); - spec->mixers[spec->num_mixers] = - alc268_capture_alt_mixer; - spec->num_mixers++; - } else { - spec->adc_nids = alc268_adc_nids; - spec->num_adc_nids = - ARRAY_SIZE(alc268_adc_nids); - spec->mixers[spec->num_mixers] = - alc268_capture_mixer; - spec->num_mixers++; - } - } - } - codec->patch_ops = alc_patch_ops; - if (board_config == ALC268_AUTO) - spec->init_hook = alc268_auto_init; - - return 0; -} - -/* - * ALC861 channel source setting (2/6 channel selection for 3-stack) - */ - -/* - * set the path ways for 2 channel output - * need to set the codec line out and mic 1 pin widgets to inputs + * set the path ways for 2 channel output + * need to set the codec line out and mic 1 pin widgets to inputs */ static struct hda_verb alc861_threestack_ch2_init[] = { /* set pin widget 1Ah (line in) for input */ @@ -9620,21 +8767,13 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), - SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), - SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), - /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) - * Any other models that need this preset? - */ - /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ + SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), - SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), - SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), - SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), {} }; @@ -10325,7 +9464,6 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re */ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { [ALC660VD_3ST] = "3stack-660", - [ALC660VD_3ST_DIG]= "3stack-660-digout", [ALC861VD_3ST] = "3stack", [ALC861VD_3ST_DIG] = "3stack-digout", [ALC861VD_6ST_DIG] = "6stack-digout", @@ -10337,7 +9475,7 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), - SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), + SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST), SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), @@ -10345,7 +9483,6 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS), SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), - SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), {} }; @@ -10362,19 +9499,6 @@ static struct alc_config_preset alc861vd_presets[] = { .channel_mode = alc861vd_3stack_2ch_modes, .input_mux = &alc861vd_capture_source, }, - [ALC660VD_3ST_DIG] = { - .mixers = { alc861vd_3st_mixer }, - .init_verbs = { alc861vd_volume_init_verbs, - alc861vd_3stack_init_verbs }, - .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), - .dac_nids = alc660vd_dac_nids, - .dig_out_nid = ALC861VD_DIGOUT_NID, - .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), - .adc_nids = alc861vd_adc_nids, - .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), - .channel_mode = alc861vd_3stack_2ch_modes, - .input_mux = &alc861vd_capture_source, - }, [ALC861VD_3ST] = { .mixers = { alc861vd_3st_mixer }, .init_verbs = { alc861vd_volume_init_verbs, @@ -11296,7 +10420,7 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, for (i = 0; i < cfg->line_outs; i++) { if (!spec->multiout.dac_nids[i]) continue; - nid = alc880_idx_to_mixer(i); + nid = alc880_idx_to_dac(i); if (i == 2) { /* Center/LFE */ err = add_control(spec, ALC_CTL_WIDGET_VOL, @@ -11519,10 +10643,14 @@ static int alc662_parse_auto_config(struct hda_codec *codec) spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux; - spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs; + if (err < 0) + return err; + else if (err > 0) + /* hack - override the init verbs */ + spec->init_verbs[0] = alc662_auto_init_verbs; spec->mixers[spec->num_mixers] = alc662_capture_mixer; spec->num_mixers++; - return 1; + return err; } /* additional initialization for auto-configuration model */ @@ -11559,7 +10687,7 @@ static int patch_alc662(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (!err) { + } else if (err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -11596,7 +10724,6 @@ static int patch_alc662(struct hda_codec *codec) struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, - { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", .patch = patch_alc861 }, { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, diff --git a/trunk/sound/pci/hda/patch_si3054.c b/trunk/sound/pci/hda/patch_si3054.c index 6d2ecc38905c..43f537ef40bf 100644 --- a/trunk/sound/pci/hda/patch_si3054.c +++ b/trunk/sound/pci/hda/patch_si3054.c @@ -304,12 +304,8 @@ struct hda_codec_preset snd_hda_preset_si3054[] = { { .id = 0x10573055, .name = "Si3054", .patch = patch_si3054 }, { .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 }, { .id = 0x10573155, .name = "Si3054", .patch = patch_si3054 }, - /* VIA HDA on Clevo m540 */ - { .id = 0x11063288, .name = "Si3054", .patch = patch_si3054 }, /* Asus A8J Modem (SM56) */ { .id = 0x15433155, .name = "Si3054", .patch = patch_si3054 }, - /* LG LW20 modem */ - { .id = 0x18540018, .name = "Si3054", .patch = patch_si3054 }, {} }; diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 3f25de72966b..e3964fc4c405 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -44,7 +44,6 @@ enum { enum { STAC_9205_REF, - STAC_M43xx, STAC_9205_MODELS }; @@ -60,19 +59,11 @@ enum { STAC_D945_REF, STAC_D945GTP3, STAC_D945GTP5, - STAC_922X_DELL, - STAC_INTEL_MAC_V1, - STAC_INTEL_MAC_V2, - STAC_INTEL_MAC_V3, - STAC_INTEL_MAC_V4, - STAC_INTEL_MAC_V5, - /* for backward compitability */ STAC_MACMINI, STAC_MACBOOK, STAC_MACBOOK_PRO_V1, STAC_MACBOOK_PRO_V2, STAC_IMAC_INTEL, - STAC_IMAC_INTEL_20, STAC_922X_MODELS }; @@ -219,6 +210,7 @@ static hda_nid_t stac9205_pin_nids[12] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x14, 0x16, 0x17, 0x18, 0x21, 0x22, + }; static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, @@ -334,6 +326,8 @@ static struct snd_kcontrol_new stac9200_mixer[] = { }; static struct snd_kcontrol_new stac925x_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0xe, 0, HDA_OUTPUT), + HDA_CODEC_MUTE("Master Playback Switch", 0xe, 0, HDA_OUTPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Source", @@ -555,78 +549,44 @@ static unsigned int d945gtp5_pin_configs[10] = { 0x02a19320, 0x40000100, }; -static unsigned int intel_mac_v1_pin_configs[10] = { - 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd, - 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240, - 0x400000fc, 0x400000fb, -}; - -static unsigned int intel_mac_v2_pin_configs[10] = { - 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, - 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa, - 0x400000fc, 0x400000fb, -}; - -static unsigned int intel_mac_v3_pin_configs[10] = { - 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, - 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240, - 0x400000fc, 0x400000fb, +static unsigned int macbook_pro_v1_pin_configs[10] = { + 0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010, + 0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e, + 0x02a19320, 0x400000fb }; -static unsigned int intel_mac_v4_pin_configs[10] = { - 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, - 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, +static unsigned int macbook_pro_v2_pin_configs[10] = { + 0x0221401f, 0x90a70120, 0x01813024, 0x01014010, + 0x400000fd, 0x01016011, 0x1345e240, 0x13c5e22e, 0x400000fc, 0x400000fb, }; -static unsigned int intel_mac_v5_pin_configs[10] = { - 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, - 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, +static unsigned int imac_intel_pin_configs[10] = { + 0x0121e230, 0x90a70120, 0x9017e110, 0x400000fe, + 0x400000fd, 0x0181e021, 0x1145e040, 0x400000fa, 0x400000fc, 0x400000fb, }; -static unsigned int stac922x_dell_pin_configs[10] = { - 0x0221121e, 0x408103ff, 0x02a1123e, 0x90100310, - 0x408003f1, 0x0221122f, 0x03451340, 0x40c003f2, - 0x50a003f3, 0x405003f4 -}; - static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_D945_REF] = ref922x_pin_configs, [STAC_D945GTP3] = d945gtp3_pin_configs, [STAC_D945GTP5] = d945gtp5_pin_configs, - [STAC_922X_DELL] = stac922x_dell_pin_configs, - [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs, - [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs, - [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs, - [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs, - [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs, - /* for backward compitability */ - [STAC_MACMINI] = intel_mac_v3_pin_configs, - [STAC_MACBOOK] = intel_mac_v5_pin_configs, - [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs, - [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs, - [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs, - [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs, + [STAC_MACMINI] = macbook_pro_v1_pin_configs, + [STAC_MACBOOK] = macbook_pro_v1_pin_configs, + [STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs, + [STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs, + [STAC_IMAC_INTEL] = imac_intel_pin_configs, }; static const char *stac922x_models[STAC_922X_MODELS] = { [STAC_D945_REF] = "ref", [STAC_D945GTP5] = "5stack", [STAC_D945GTP3] = "3stack", - [STAC_922X_DELL] = "dell", - [STAC_INTEL_MAC_V1] = "intel-mac-v1", - [STAC_INTEL_MAC_V2] = "intel-mac-v2", - [STAC_INTEL_MAC_V3] = "intel-mac-v3", - [STAC_INTEL_MAC_V4] = "intel-mac-v4", - [STAC_INTEL_MAC_V5] = "intel-mac-v5", - /* for backward compitability */ [STAC_MACMINI] = "macmini", [STAC_MACBOOK] = "macbook", [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", [STAC_MACBOOK_PRO_V2] = "macbook-pro", [STAC_IMAC_INTEL] = "imac-intel", - [STAC_IMAC_INTEL_20] = "imac-intel-20", }; static struct snd_pci_quirk stac922x_cfg_tbl[] = { @@ -689,10 +649,7 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { /* other systems */ /* Apple Mac Mini (early 2006) */ SND_PCI_QUIRK(0x8384, 0x7680, - "Mac Mini", STAC_INTEL_MAC_V3), - /* Dell */ - SND_PCI_QUIRK(0x1028, 0x01d7, "Dell XPS M1210", STAC_922X_DELL), - + "Mac Mini", STAC_MACMINI), {} /* terminator */ }; @@ -773,8 +730,7 @@ static unsigned int ref9205_pin_configs[12] = { }; static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { - [STAC_REF] = ref9205_pin_configs, - [STAC_M43xx] = NULL, + ref9205_pin_configs, }; static const char *stac9205_models[STAC_9205_MODELS] = { @@ -785,10 +741,6 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_9205_REF), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01f8, - "Dell Precision", STAC_M43xx), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01ff, - "Dell Precision", STAC_M43xx), {} /* terminator */ }; @@ -818,56 +770,33 @@ static int stac92xx_save_bios_config_regs(struct hda_codec *codec) return 0; } -static void stac92xx_set_config_reg(struct hda_codec *codec, - hda_nid_t pin_nid, unsigned int pin_config) -{ - int i; - snd_hda_codec_write(codec, pin_nid, 0, - AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, - pin_config & 0x000000ff); - snd_hda_codec_write(codec, pin_nid, 0, - AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, - (pin_config & 0x0000ff00) >> 8); - snd_hda_codec_write(codec, pin_nid, 0, - AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, - (pin_config & 0x00ff0000) >> 16); - snd_hda_codec_write(codec, pin_nid, 0, - AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, - pin_config >> 24); - i = snd_hda_codec_read(codec, pin_nid, 0, - AC_VERB_GET_CONFIG_DEFAULT, - 0x00); - snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", - pin_nid, i); -} - static void stac92xx_set_config_regs(struct hda_codec *codec) { int i; struct sigmatel_spec *spec = codec->spec; + unsigned int pin_cfg; - if (!spec->pin_configs) - return; - - for (i = 0; i < spec->num_pins; i++) - stac92xx_set_config_reg(codec, spec->pin_nids[i], - spec->pin_configs[i]); -} + if (! spec->pin_nids || ! spec->pin_configs) + return; -static void stac92xx_enable_gpio_mask(struct hda_codec *codec, - int gpio_mask, int gpio_data) -{ - /* Configure GPIOx as output */ - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_DIRECTION, gpio_mask); - /* Configure GPIOx as CMOS */ - snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000); - /* Assert GPIOx */ - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_DATA, gpio_data); - /* Enable GPIOx */ - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_MASK, gpio_mask); + for (i = 0; i < spec->num_pins; i++) { + snd_hda_codec_write(codec, spec->pin_nids[i], 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, + spec->pin_configs[i] & 0x000000ff); + snd_hda_codec_write(codec, spec->pin_nids[i], 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, + (spec->pin_configs[i] & 0x0000ff00) >> 8); + snd_hda_codec_write(codec, spec->pin_nids[i], 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, + (spec->pin_configs[i] & 0x00ff0000) >> 16); + snd_hda_codec_write(codec, spec->pin_nids[i], 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, + spec->pin_configs[i] >> 24); + pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0, + AC_VERB_GET_CONFIG_DEFAULT, + 0x00); + snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", spec->pin_nids[i], pin_cfg); + } } /* @@ -1239,7 +1168,7 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) * and 9202/925x. For those, dac_nids[] must be hard-coded. */ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, - struct auto_pin_cfg *cfg) + const struct auto_pin_cfg *cfg) { struct sigmatel_spec *spec = codec->spec; int i, j, conn_len = 0; @@ -1264,13 +1193,6 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, } if (j == conn_len) { - if (spec->multiout.num_dacs > 0) { - /* we have already working output pins, - * so let's drop the broken ones again - */ - cfg->line_outs = spec->multiout.num_dacs; - break; - } /* error out, no available DAC found */ snd_printk(KERN_ERR "%s: No available DAC for pin 0x%x\n", @@ -1412,15 +1334,7 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, continue; add_spec_dacs(spec, nid); } - for (i = 0; i < cfg->line_outs; i++) { - nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0, - AC_VERB_GET_CONNECT_LIST, 0) & 0xff; - if (check_in_dac_nids(spec, nid)) - nid = 0; - if (! nid) - continue; - add_spec_dacs(spec, nid); - } + for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) { static const char *pfxs[] = { "Speaker", "External Speaker", "Speaker2", @@ -1977,7 +1891,7 @@ static int patch_stac9200(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; - spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); + spec->num_pins = 8; spec->pin_nids = stac9200_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, stac9200_models, @@ -2027,7 +1941,7 @@ static int patch_stac925x(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; - spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); + spec->num_pins = 8; spec->pin_nids = stac925x_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS, stac925x_models, @@ -2099,41 +2013,29 @@ static int patch_stac922x(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; - spec->num_pins = ARRAY_SIZE(stac922x_pin_nids); + spec->num_pins = 10; spec->pin_nids = stac922x_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, stac922x_models, stac922x_cfg_tbl); - if (spec->board_config == STAC_INTEL_MAC_V3) { + if (spec->board_config == STAC_MACMINI) { spec->gpio_mute = 1; /* Intel Macs have all same PCI SSID, so we need to check * codec SSID to distinguish the exact models */ printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id); switch (codec->subsystem_id) { - - case 0x106b0800: - spec->board_config = STAC_INTEL_MAC_V1; - break; - case 0x106b0600: - case 0x106b0700: - spec->board_config = STAC_INTEL_MAC_V2; + case 0x106b0a00: /* MacBook First generatoin */ + spec->board_config = STAC_MACBOOK; break; - case 0x106b0e00: - case 0x106b0f00: - case 0x106b1600: - case 0x106b1700: - case 0x106b0200: - case 0x106b1e00: - spec->board_config = STAC_INTEL_MAC_V3; + case 0x106b0200: /* MacBook Pro first generation */ + spec->board_config = STAC_MACBOOK_PRO_V1; break; - case 0x106b1a00: - case 0x00000100: - spec->board_config = STAC_INTEL_MAC_V4; + case 0x106b1e00: /* MacBook Pro second generation */ + spec->board_config = STAC_MACBOOK_PRO_V2; break; - case 0x106b0a00: - case 0x106b2200: - spec->board_config = STAC_INTEL_MAC_V5; + case 0x106b0700: /* Intel-based iMac */ + spec->board_config = STAC_IMAC_INTEL; break; } } @@ -2180,13 +2082,6 @@ static int patch_stac922x(struct hda_codec *codec) codec->patch_ops = stac92xx_patch_ops; - /* Fix Mux capture level; max to 2 */ - snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT, - (0 << AC_AMPCAP_OFFSET_SHIFT) | - (2 << AC_AMPCAP_NUM_STEPS_SHIFT) | - (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) | - (0 << AC_AMPCAP_MUTE_SHIFT)); - return 0; } @@ -2200,7 +2095,7 @@ static int patch_stac927x(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; - spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); + spec->num_pins = 14; spec->pin_nids = stac927x_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, stac927x_models, @@ -2246,9 +2141,7 @@ static int patch_stac927x(struct hda_codec *codec) } spec->multiout.dac_nids = spec->dac_nids; - /* GPIO0 High = Enable EAPD */ - stac92xx_enable_gpio_mask(codec, 0x00000001, 0x00000001); - + err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); if (!err) { if (spec->board_config < 0) { @@ -2266,20 +2159,27 @@ static int patch_stac927x(struct hda_codec *codec) codec->patch_ops = stac92xx_patch_ops; + /* Fix Mux capture level; max to 2 */ + snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT, + (0 << AC_AMPCAP_OFFSET_SHIFT) | + (2 << AC_AMPCAP_NUM_STEPS_SHIFT) | + (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) | + (0 << AC_AMPCAP_MUTE_SHIFT)); + return 0; } static int patch_stac9205(struct hda_codec *codec) { struct sigmatel_spec *spec; - int err, gpio_mask, gpio_data; + int err; spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; codec->spec = spec; - spec->num_pins = ARRAY_SIZE(stac9205_pin_nids); + spec->num_pins = 14; spec->pin_nids = stac9205_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, stac9205_models, @@ -2309,21 +2209,19 @@ static int patch_stac9205(struct hda_codec *codec) spec->mixer = stac9205_mixer; spec->multiout.dac_nids = spec->dac_nids; - - if (spec->board_config == STAC_M43xx) { - /* Enable SPDIF in/out */ - stac92xx_set_config_reg(codec, 0x1f, 0x01441030); - stac92xx_set_config_reg(codec, 0x20, 0x1c410030); - - gpio_mask = 0x00000007; /* GPIO0-2 */ - /* GPIO0 High = EAPD, GPIO1 Low = DRM, - * GPIO2 High = Headphone Mute - */ - gpio_data = 0x00000005; - } else - gpio_mask = gpio_data = 0x00000001; /* GPIO0 High = EAPD */ - stac92xx_enable_gpio_mask(codec, gpio_mask, gpio_data); + /* Configure GPIO0 as EAPD output */ + snd_hda_codec_write(codec, codec->afg, 0, + AC_VERB_SET_GPIO_DIRECTION, 0x00000001); + /* Configure GPIO0 as CMOS */ + snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000); + /* Assert GPIO0 high */ + snd_hda_codec_write(codec, codec->afg, 0, + AC_VERB_SET_GPIO_DATA, 0x00000001); + /* Enable GPIO0 */ + snd_hda_codec_write(codec, codec->afg, 0, + AC_VERB_SET_GPIO_MASK, 0x00000001); + err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); if (!err) { if (spec->board_config < 0) { @@ -2358,8 +2256,8 @@ static struct hda_input_mux vaio_mux = { .num_items = 2, .items = { /* { "HP", 0x0 }, */ - { "Mic Jack", 0x1 }, - { "Internal Mic", 0x2 }, + { "Line", 0x1 }, + { "Mic", 0x2 }, { "PCM", 0x3 }, } }; @@ -2370,7 +2268,7 @@ static struct hda_verb vaio_init[] = { {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ + {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */ {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ @@ -2386,7 +2284,7 @@ static struct hda_verb vaio_ar_init[] = { {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ + {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */ {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */ diff --git a/trunk/sound/pci/ice1712/revo.c b/trunk/sound/pci/ice1712/revo.c index d18a31e188a9..690ceb340644 100644 --- a/trunk/sound/pci/ice1712/revo.c +++ b/trunk/sound/pci/ice1712/revo.c @@ -186,12 +186,7 @@ static int revo51_i2c_init(struct snd_ice1712 *ice, #define AK_DAC(xname,xch) { .name = xname, .num_channels = xch } static const struct snd_akm4xxx_dac_channel revo71_front[] = { - { - .name = "PCM Playback Volume", - .num_channels = 2, - /* front channels DAC supports muting */ - .switch_name = "PCM Playback Switch", - }, + AK_DAC("PCM Playback Volume", 2) }; static const struct snd_akm4xxx_dac_channel revo71_surround[] = { diff --git a/trunk/sound/pci/nm256/nm256.c b/trunk/sound/pci/nm256/nm256.c index c7621bd770a6..03b3a4792f73 100644 --- a/trunk/sound/pci/nm256/nm256.c +++ b/trunk/sound/pci/nm256/nm256.c @@ -1533,8 +1533,7 @@ snd_nm256_create(struct snd_card *card, struct pci_dev *pci, printk(KERN_ERR " force the driver to load by " "passing in the module parameter\n"); printk(KERN_ERR " force_ac97=1\n"); - printk(KERN_ERR " or try sb16, opl3sa2, or " - "cs423x drivers instead.\n"); + printk(KERN_ERR " or try sb16 or cs423x drivers instead.\n"); err = -ENXIO; goto __error; } diff --git a/trunk/sound/pci/rme9652/rme9652.c b/trunk/sound/pci/rme9652/rme9652.c index 2de27405a0bd..bd7dbd267ed1 100644 --- a/trunk/sound/pci/rme9652/rme9652.c +++ b/trunk/sound/pci/rme9652/rme9652.c @@ -406,7 +406,7 @@ static snd_pcm_uframes_t rme9652_hw_pointer(struct snd_rme9652 *rme9652) } else if (!frag) return 0; offset -= rme9652->max_jitter; - if ((int)offset < 0) + if (offset < 0) offset += period_size * 2; } else { if (offset > period_size + rme9652->max_jitter) { diff --git a/trunk/sound/pci/via82xx.c b/trunk/sound/pci/via82xx.c index 6ea09df0c73a..50c9f92cfd1b 100644 --- a/trunk/sound/pci/via82xx.c +++ b/trunk/sound/pci/via82xx.c @@ -2098,7 +2098,7 @@ static int snd_via82xx_chip_init(struct via82xx *chip) pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ break; - schedule_timeout(1); + schedule_timeout_uninterruptible(1); } while (time_before(jiffies, end_time)); if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) @@ -2117,7 +2117,7 @@ static int snd_via82xx_chip_init(struct via82xx *chip) chip->ac97_secondary = 1; goto __ac97_ok2; } - schedule_timeout(1); + schedule_timeout_interruptible(1); } while (time_before(jiffies, end_time)); /* This is ok, the most of motherboards have only one codec */ diff --git a/trunk/sound/pci/via82xx_modem.c b/trunk/sound/pci/via82xx_modem.c index 72425e73abae..8cbf8eba4ae9 100644 --- a/trunk/sound/pci/via82xx_modem.c +++ b/trunk/sound/pci/via82xx_modem.c @@ -983,7 +983,7 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip) pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ break; - schedule_timeout(1); + schedule_timeout_uninterruptible(1); } while (time_before(jiffies, end_time)); if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) @@ -1001,7 +1001,7 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip) chip->ac97_secondary = 1; goto __ac97_ok2; } - schedule_timeout(1); + schedule_timeout_interruptible(1); } while (time_before(jiffies, end_time)); /* This is ok, the most of motherboards have only one codec */ diff --git a/trunk/sound/ppc/Kconfig b/trunk/sound/ppc/Kconfig index cacb0b136883..a3fb1496e4dc 100644 --- a/trunk/sound/ppc/Kconfig +++ b/trunk/sound/ppc/Kconfig @@ -33,23 +33,3 @@ config SND_POWERMAC_AUTO_DRC option. endmenu - -menu "ALSA PowerPC devices" - depends on SND!=n && ( PPC64 || PPC32 ) - -config SND_PS3 - tristate "PS3 Audio support" - depends on SND && PS3_PS3AV - select SND_PCM - default m - help - Say Y here to include support for audio on the PS3 - - To compile this driver as a module, choose M here: the module - will be called snd_ps3. - -config SND_PS3_DEFAULT_START_DELAY - int "Startup delay time in ms" - depends on SND_PS3 - default "2000" -endmenu diff --git a/trunk/sound/ppc/Makefile b/trunk/sound/ppc/Makefile index eacee2d0675c..4d95c652c8ca 100644 --- a/trunk/sound/ppc/Makefile +++ b/trunk/sound/ppc/Makefile @@ -6,5 +6,4 @@ snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o # Toplevel Module Dependency -obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o -obj-$(CONFIG_SND_PS3) += snd_ps3.o +obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o diff --git a/trunk/sound/ppc/snd_ps3.c b/trunk/sound/ppc/snd_ps3.c deleted file mode 100644 index 1aa0b467599f..000000000000 --- a/trunk/sound/ppc/snd_ps3.c +++ /dev/null @@ -1,1125 +0,0 @@ -/* - * Audio support for PS3 - * Copyright (C) 2007 Sony Computer Entertainment Inc. - * All rights reserved. - * Copyright 2006, 2007 Sony Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 of the Licence. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "snd_ps3_reg.h" -#include "snd_ps3.h" - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("PS3 sound driver"); -MODULE_AUTHOR("Sony Computer Entertainment Inc."); - -/* module entries */ -static int __init snd_ps3_init(void); -static void __exit snd_ps3_exit(void); - -/* ALSA snd driver ops */ -static int snd_ps3_pcm_open(struct snd_pcm_substream *substream); -static int snd_ps3_pcm_close(struct snd_pcm_substream *substream); -static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream); -static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream, - int cmd); -static snd_pcm_uframes_t snd_ps3_pcm_pointer(struct snd_pcm_substream - *substream); -static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params); -static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream); - - -/* ps3_system_bus_driver entries */ -static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev); -static int snd_ps3_driver_remove(struct ps3_system_bus_device *dev); - -/* address setup */ -static int snd_ps3_map_mmio(void); -static void snd_ps3_unmap_mmio(void); -static int snd_ps3_allocate_irq(void); -static void snd_ps3_free_irq(void); -static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start); - -/* interrupt handler */ -static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id); - - -/* set sampling rate/format */ -static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream); -/* take effect parameter change */ -static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card); -/* initialize avsetting and take it effect */ -static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card); -/* setup dma */ -static int snd_ps3_program_dma(struct snd_ps3_card_info *card, - enum snd_ps3_dma_filltype filltype); -static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info *card); - -static dma_addr_t v_to_bus(struct snd_ps3_card_info *, void *vaddr, int ch); - - -module_init(snd_ps3_init); -module_exit(snd_ps3_exit); - -/* - * global - */ -static struct snd_ps3_card_info the_card; - -static int snd_ps3_start_delay = CONFIG_SND_PS3_DEFAULT_START_DELAY; - -module_param_named(start_delay, snd_ps3_start_delay, uint, 0644); -MODULE_PARM_DESC(start_delay, "time to insert silent data in milisec"); - -static int index = SNDRV_DEFAULT_IDX1; -static char *id = SNDRV_DEFAULT_STR1; - -module_param(index, int, 0444); -MODULE_PARM_DESC(index, "Index value for PS3 soundchip."); -module_param(id, charp, 0444); -MODULE_PARM_DESC(id, "ID string for PS3 soundchip."); - - -/* - * PS3 audio register access - */ -static inline u32 read_reg(unsigned int reg) -{ - return in_be32(the_card.mapped_mmio_vaddr + reg); -} -static inline void write_reg(unsigned int reg, u32 val) -{ - out_be32(the_card.mapped_mmio_vaddr + reg, val); -} -static inline void update_reg(unsigned int reg, u32 or_val) -{ - u32 newval = read_reg(reg) | or_val; - write_reg(reg, newval); -} -static inline void update_mask_reg(unsigned int reg, u32 mask, u32 or_val) -{ - u32 newval = (read_reg(reg) & mask) | or_val; - write_reg(reg, newval); -} - -/* - * ALSA defs - */ -const static struct snd_pcm_hardware snd_ps3_pcm_hw = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_NONINTERLEAVED | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = (SNDRV_PCM_FMTBIT_S16_BE | - SNDRV_PCM_FMTBIT_S24_BE), - .rates = (SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000), - .rate_min = 44100, - .rate_max = 96000, - - .channels_min = 2, /* stereo only */ - .channels_max = 2, - - .buffer_bytes_max = PS3_AUDIO_FIFO_SIZE * 64, - - /* interrupt by four stages */ - .period_bytes_min = PS3_AUDIO_FIFO_STAGE_SIZE * 4, - .period_bytes_max = PS3_AUDIO_FIFO_STAGE_SIZE * 4, - - .periods_min = 16, - .periods_max = 32, /* buffer_size_max/ period_bytes_max */ - - .fifo_size = PS3_AUDIO_FIFO_SIZE -}; - -static struct snd_pcm_ops snd_ps3_pcm_spdif_ops = -{ - .open = snd_ps3_pcm_open, - .close = snd_ps3_pcm_close, - .prepare = snd_ps3_pcm_prepare, - .ioctl = snd_pcm_lib_ioctl, - .trigger = snd_ps3_pcm_trigger, - .pointer = snd_ps3_pcm_pointer, - .hw_params = snd_ps3_pcm_hw_params, - .hw_free = snd_ps3_pcm_hw_free -}; - -static int snd_ps3_verify_dma_stop(struct snd_ps3_card_info *card, - int count, int force_stop) -{ - int dma_ch, done, retries, stop_forced = 0; - uint32_t status; - - for (dma_ch = 0; dma_ch < 8; dma_ch ++) { - retries = count; - do { - status = read_reg(PS3_AUDIO_KICK(dma_ch)) & - PS3_AUDIO_KICK_STATUS_MASK; - switch (status) { - case PS3_AUDIO_KICK_STATUS_DONE: - case PS3_AUDIO_KICK_STATUS_NOTIFY: - case PS3_AUDIO_KICK_STATUS_CLEAR: - case PS3_AUDIO_KICK_STATUS_ERROR: - done = 1; - break; - default: - done = 0; - udelay(10); - } - } while (!done && --retries); - if (!retries && force_stop) { - pr_info("%s: DMA ch %d is not stopped.", - __func__, dma_ch); - /* last resort. force to stop dma. - * NOTE: this cause DMA done interrupts - */ - update_reg(PS3_AUDIO_CONFIG, PS3_AUDIO_CONFIG_CLEAR); - stop_forced = 1; - } - } - return stop_forced; -} - -/* - * wait for all dma is done. - * NOTE: caller should reset card->running before call. - * If not, the interrupt handler will re-start DMA, - * then DMA is never stopped. - */ -static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info *card) -{ - int stop_forced; - /* - * wait for the last dma is done - */ - - /* - * expected maximum DMA done time is 5.7ms + something (DMA itself). - * 5.7ms is from 16bit/sample 2ch 44.1Khz; the time next - * DMA kick event would occur. - */ - stop_forced = snd_ps3_verify_dma_stop(card, 700, 1); - - /* - * clear outstanding interrupts. - */ - update_reg(PS3_AUDIO_INTR_0, 0); - update_reg(PS3_AUDIO_AX_IS, 0); - - /* - *revert CLEAR bit since it will not reset automatically after DMA stop - */ - if (stop_forced) - update_mask_reg(PS3_AUDIO_CONFIG, ~PS3_AUDIO_CONFIG_CLEAR, 0); - /* ensure the hardware sees changes */ - wmb(); -} - -static void snd_ps3_kick_dma(struct snd_ps3_card_info *card) -{ - - update_reg(PS3_AUDIO_KICK(0), PS3_AUDIO_KICK_REQUEST); - /* ensure the hardware sees the change */ - wmb(); -} - -/* - * convert virtual addr to ioif bus addr. - */ -static dma_addr_t v_to_bus(struct snd_ps3_card_info *card, - void * paddr, - int ch) -{ - return card->dma_start_bus_addr[ch] + - (paddr - card->dma_start_vaddr[ch]); -}; - - -/* - * increment ring buffer pointer. - * NOTE: caller must hold write spinlock - */ -static void snd_ps3_bump_buffer(struct snd_ps3_card_info *card, - enum snd_ps3_ch ch, size_t byte_count, - int stage) -{ - if (!stage) - card->dma_last_transfer_vaddr[ch] = - card->dma_next_transfer_vaddr[ch]; - card->dma_next_transfer_vaddr[ch] += byte_count; - if ((card->dma_start_vaddr[ch] + (card->dma_buffer_size / 2)) <= - card->dma_next_transfer_vaddr[ch]) { - card->dma_next_transfer_vaddr[ch] = card->dma_start_vaddr[ch]; - } -} -/* - * setup dmac to send data to audio and attenuate samples on the ring buffer - */ -static int snd_ps3_program_dma(struct snd_ps3_card_info *card, - enum snd_ps3_dma_filltype filltype) -{ - /* this dmac does not support over 4G */ - uint32_t dma_addr; - int fill_stages, dma_ch, stage; - enum snd_ps3_ch ch; - uint32_t ch0_kick_event = 0; /* initialize to mute gcc */ - void *start_vaddr; - unsigned long irqsave; - int silent = 0; - - switch (filltype) { - case SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL: - silent = 1; - /* intentionally fall thru */ - case SND_PS3_DMA_FILLTYPE_FIRSTFILL: - ch0_kick_event = PS3_AUDIO_KICK_EVENT_ALWAYS; - break; - - case SND_PS3_DMA_FILLTYPE_SILENT_RUNNING: - silent = 1; - /* intentionally fall thru */ - case SND_PS3_DMA_FILLTYPE_RUNNING: - ch0_kick_event = PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY; - break; - } - - snd_ps3_verify_dma_stop(card, 700, 0); - fill_stages = 4; - spin_lock_irqsave(&card->dma_lock, irqsave); - for (ch = 0; ch < 2; ch++) { - start_vaddr = card->dma_next_transfer_vaddr[0]; - for (stage = 0; stage < fill_stages; stage ++) { - dma_ch = stage * 2 + ch; - if (silent) - dma_addr = card->null_buffer_start_dma_addr; - else - dma_addr = - v_to_bus(card, - card->dma_next_transfer_vaddr[ch], - ch); - - write_reg(PS3_AUDIO_SOURCE(dma_ch), - (PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY | - dma_addr)); - - /* dst: fixed to 3wire#0 */ - if (ch == 0) - write_reg(PS3_AUDIO_DEST(dma_ch), - (PS3_AUDIO_DEST_TARGET_AUDIOFIFO | - PS3_AUDIO_AO_3W_LDATA(0))); - else - write_reg(PS3_AUDIO_DEST(dma_ch), - (PS3_AUDIO_DEST_TARGET_AUDIOFIFO | - PS3_AUDIO_AO_3W_RDATA(0))); - - /* count always 1 DMA block (1/2 stage = 128 bytes) */ - write_reg(PS3_AUDIO_DMASIZE(dma_ch), 0); - /* bump pointer if needed */ - if (!silent) - snd_ps3_bump_buffer(card, ch, - PS3_AUDIO_DMAC_BLOCK_SIZE, - stage); - - /* kick event */ - if (dma_ch == 0) - write_reg(PS3_AUDIO_KICK(dma_ch), - ch0_kick_event); - else - write_reg(PS3_AUDIO_KICK(dma_ch), - PS3_AUDIO_KICK_EVENT_AUDIO_DMA(dma_ch - - 1) | - PS3_AUDIO_KICK_REQUEST); - } - } - /* ensure the hardware sees the change */ - wmb(); - spin_unlock_irqrestore(&card->dma_lock, irqsave); - - return 0; -} - -/* - * audio mute on/off - * mute_on : 0 output enabled - * 1 mute - */ -static int snd_ps3_mute(int mute_on) -{ - return ps3av_audio_mute(mute_on); -} - -/* - * PCM operators - */ -static int snd_ps3_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); - int pcm_index; - - pcm_index = substream->pcm->device; - /* to retrieve substream/runtime in interrupt handler */ - card->substream = substream; - - runtime->hw = snd_ps3_pcm_hw; - - card->start_delay = snd_ps3_start_delay; - - /* mute off */ - snd_ps3_mute(0); /* this function sleep */ - - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - PS3_AUDIO_FIFO_STAGE_SIZE * 4 * 2); - return 0; -}; - -static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - size_t size; - - /* alloc transport buffer */ - size = params_buffer_bytes(hw_params); - snd_pcm_lib_malloc_pages(substream, size); - return 0; -}; - -static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream, - unsigned int delay_ms) -{ - int ret; - int rate ; - - rate = substream->runtime->rate; - ret = snd_pcm_format_size(substream->runtime->format, - rate * delay_ms / 1000) - * substream->runtime->channels; - - pr_debug(KERN_ERR "%s: time=%d rate=%d bytes=%ld, frames=%d, ret=%d\n", - __func__, - delay_ms, - rate, - snd_pcm_format_size(substream->runtime->format, rate), - rate * delay_ms / 1000, - ret); - - return ret; -}; - -static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); - unsigned long irqsave; - - if (!snd_ps3_set_avsetting(substream)) { - /* some parameter changed */ - write_reg(PS3_AUDIO_AX_IE, - PS3_AUDIO_AX_IE_ASOBEIE(0) | - PS3_AUDIO_AX_IE_ASOBUIE(0)); - /* - * let SPDIF device re-lock with SPDIF signal, - * start with some silence - */ - card->silent = snd_ps3_delay_to_bytes(substream, - card->start_delay) / - (PS3_AUDIO_FIFO_STAGE_SIZE * 4); /* every 4 times */ - } - - /* restart ring buffer pointer */ - spin_lock_irqsave(&card->dma_lock, irqsave); - { - card->dma_buffer_size = runtime->dma_bytes; - - card->dma_last_transfer_vaddr[SND_PS3_CH_L] = - card->dma_next_transfer_vaddr[SND_PS3_CH_L] = - card->dma_start_vaddr[SND_PS3_CH_L] = - runtime->dma_area; - card->dma_start_bus_addr[SND_PS3_CH_L] = runtime->dma_addr; - - card->dma_last_transfer_vaddr[SND_PS3_CH_R] = - card->dma_next_transfer_vaddr[SND_PS3_CH_R] = - card->dma_start_vaddr[SND_PS3_CH_R] = - runtime->dma_area + (runtime->dma_bytes / 2); - card->dma_start_bus_addr[SND_PS3_CH_R] = - runtime->dma_addr + (runtime->dma_bytes / 2); - - pr_debug("%s: vaddr=%p bus=%#lx\n", __func__, - card->dma_start_vaddr[SND_PS3_CH_L], - card->dma_start_bus_addr[SND_PS3_CH_L]); - - } - spin_unlock_irqrestore(&card->dma_lock, irqsave); - - /* ensure the hardware sees the change */ - mb(); - - return 0; -}; - -static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - /* clear outstanding interrupts */ - update_reg(PS3_AUDIO_AX_IS, 0); - - spin_lock(&card->dma_lock); - { - card->running = 1; - } - spin_unlock(&card->dma_lock); - - snd_ps3_program_dma(card, - SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); - snd_ps3_kick_dma(card); - while (read_reg(PS3_AUDIO_KICK(7)) & - PS3_AUDIO_KICK_STATUS_MASK) { - udelay(1); - } - snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_RUNNING); - snd_ps3_kick_dma(card); - break; - - case SNDRV_PCM_TRIGGER_STOP: - spin_lock(&card->dma_lock); - { - card->running = 0; - } - spin_unlock(&card->dma_lock); - snd_ps3_wait_for_dma_stop(card); - break; - default: - break; - - } - - return ret; -}; - -/* - * report current pointer - */ -static snd_pcm_uframes_t snd_ps3_pcm_pointer( - struct snd_pcm_substream *substream) -{ - struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); - size_t bytes; - snd_pcm_uframes_t ret; - - spin_lock(&card->dma_lock); - { - bytes = (size_t)(card->dma_last_transfer_vaddr[SND_PS3_CH_L] - - card->dma_start_vaddr[SND_PS3_CH_L]); - } - spin_unlock(&card->dma_lock); - - ret = bytes_to_frames(substream->runtime, bytes * 2); - - return ret; -}; - -static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream) -{ - int ret; - ret = snd_pcm_lib_free_pages(substream); - return ret; -}; - -static int snd_ps3_pcm_close(struct snd_pcm_substream *substream) -{ - /* mute on */ - snd_ps3_mute(1); - return 0; -}; - -static void snd_ps3_audio_fixup(struct snd_ps3_card_info *card) -{ - /* - * avsetting driver seems to never change the followings - * so, init them here once - */ - - /* no dma interrupt needed */ - write_reg(PS3_AUDIO_INTR_EN_0, 0); - - /* use every 4 buffer empty interrupt */ - update_mask_reg(PS3_AUDIO_AX_IC, - PS3_AUDIO_AX_IC_AASOIMD_MASK, - PS3_AUDIO_AX_IC_AASOIMD_EVERY4); - - /* enable 3wire clocks */ - update_mask_reg(PS3_AUDIO_AO_3WMCTRL, - ~(PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED | - PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED), - 0); - update_reg(PS3_AUDIO_AO_3WMCTRL, - PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT); -} - -/* - * av setting - * NOTE: calling this function may generate audio interrupt. - */ -static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card) -{ - int ret, retries, i; - pr_debug("%s: start\n", __func__); - - ret = ps3av_set_audio_mode(card->avs.avs_audio_ch, - card->avs.avs_audio_rate, - card->avs.avs_audio_width, - card->avs.avs_audio_format, - card->avs.avs_audio_source); - /* - * Reset the following unwanted settings: - */ - - /* disable all 3wire buffers */ - update_mask_reg(PS3_AUDIO_AO_3WMCTRL, - ~(PS3_AUDIO_AO_3WMCTRL_ASOEN(0) | - PS3_AUDIO_AO_3WMCTRL_ASOEN(1) | - PS3_AUDIO_AO_3WMCTRL_ASOEN(2) | - PS3_AUDIO_AO_3WMCTRL_ASOEN(3)), - 0); - wmb(); /* ensure the hardware sees the change */ - /* wait for actually stopped */ - retries = 1000; - while ((read_reg(PS3_AUDIO_AO_3WMCTRL) & - (PS3_AUDIO_AO_3WMCTRL_ASORUN(0) | - PS3_AUDIO_AO_3WMCTRL_ASORUN(1) | - PS3_AUDIO_AO_3WMCTRL_ASORUN(2) | - PS3_AUDIO_AO_3WMCTRL_ASORUN(3))) && - --retries) { - udelay(1); - } - - /* reset buffer pointer */ - for (i = 0; i < 4; i++) { - update_reg(PS3_AUDIO_AO_3WCTRL(i), - PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET); - udelay(10); - } - wmb(); /* ensure the hardware actually start resetting */ - - /* enable 3wire#0 buffer */ - update_reg(PS3_AUDIO_AO_3WMCTRL, PS3_AUDIO_AO_3WMCTRL_ASOEN(0)); - - - /* In 24bit mode,ALSA inserts a zero byte at first byte of per sample */ - update_mask_reg(PS3_AUDIO_AO_3WCTRL(0), - ~PS3_AUDIO_AO_3WCTRL_ASODF, - PS3_AUDIO_AO_3WCTRL_ASODF_LSB); - update_mask_reg(PS3_AUDIO_AO_SPDCTRL(0), - ~PS3_AUDIO_AO_SPDCTRL_SPODF, - PS3_AUDIO_AO_SPDCTRL_SPODF_LSB); - /* ensure all the setting above is written back to register */ - wmb(); - /* avsetting driver altered AX_IE, caller must reset it if you want */ - pr_debug("%s: end\n", __func__); - return ret; -} - -static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card) -{ - int ret; - pr_debug("%s: start\n", __func__); - card->avs.avs_audio_ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2; - card->avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K; - card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; - card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM; - card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL; - - ret = snd_ps3_change_avsetting(card); - - snd_ps3_audio_fixup(card); - - /* to start to generate SPDIF signal, fill data */ - snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); - snd_ps3_kick_dma(card); - pr_debug("%s: end\n", __func__); - return ret; -} - -/* - * set sampling rate according to the substream - */ -static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream) -{ - struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); - struct snd_ps3_avsetting_info avs; - - avs = card->avs; - - pr_debug("%s: called freq=%d width=%d\n", __func__, - substream->runtime->rate, - snd_pcm_format_width(substream->runtime->format)); - - pr_debug("%s: before freq=%d width=%d\n", __func__, - card->avs.avs_audio_rate, card->avs.avs_audio_width); - - /* sample rate */ - switch (substream->runtime->rate) { - case 44100: - avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_44K; - break; - case 48000: - avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K; - break; - case 88200: - avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_88K; - break; - case 96000: - avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_96K; - break; - default: - pr_info("%s: invalid rate %d\n", __func__, - substream->runtime->rate); - return 1; - } - - /* width */ - switch (snd_pcm_format_width(substream->runtime->format)) { - case 16: - avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; - break; - case 24: - avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_24; - break; - default: - pr_info("%s: invalid width %d\n", __func__, - snd_pcm_format_width(substream->runtime->format)); - return 1; - } - - if ((card->avs.avs_audio_width != avs.avs_audio_width) || - (card->avs.avs_audio_rate != avs.avs_audio_rate)) { - card->avs = avs; - snd_ps3_change_avsetting(card); - - pr_debug("%s: after freq=%d width=%d\n", __func__, - card->avs.avs_audio_rate, card->avs.avs_audio_width); - - return 0; - } else - return 1; -} - - - -static int snd_ps3_map_mmio(void) -{ - the_card.mapped_mmio_vaddr = - ioremap(the_card.ps3_dev->m_region->bus_addr, - the_card.ps3_dev->m_region->len); - - if (!the_card.mapped_mmio_vaddr) { - pr_info("%s: ioremap 0 failed p=%#lx l=%#lx \n", - __func__, the_card.ps3_dev->m_region->lpar_addr, - the_card.ps3_dev->m_region->len); - return -ENXIO; - } - - return 0; -}; - -static void snd_ps3_unmap_mmio(void) -{ - iounmap(the_card.mapped_mmio_vaddr); - the_card.mapped_mmio_vaddr = NULL; -} - -static int snd_ps3_allocate_irq(void) -{ - int ret; - u64 lpar_addr, lpar_size; - u64 __iomem *mapped; - - /* FIXME: move this to device_init (H/W probe) */ - - /* get irq outlet */ - ret = lv1_gpu_device_map(1, &lpar_addr, &lpar_size); - if (ret) { - pr_info("%s: device map 1 failed %d\n", __func__, - ret); - return -ENXIO; - } - - mapped = ioremap(lpar_addr, lpar_size); - if (!mapped) { - pr_info("%s: ioremap 1 failed \n", __func__); - return -ENXIO; - } - - the_card.audio_irq_outlet = in_be64(mapped); - - iounmap(mapped); - ret = lv1_gpu_device_unmap(1); - if (ret) - pr_info("%s: unmap 1 failed\n", __func__); - - /* irq */ - ret = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, - the_card.audio_irq_outlet, - &the_card.irq_no); - if (ret) { - pr_info("%s:ps3_alloc_irq failed (%d)\n", __func__, ret); - return ret; - } - - ret = request_irq(the_card.irq_no, snd_ps3_interrupt, IRQF_DISABLED, - SND_PS3_DRIVER_NAME, &the_card); - if (ret) { - pr_info("%s: request_irq failed (%d)\n", __func__, ret); - goto cleanup_irq; - } - - return 0; - - cleanup_irq: - ps3_irq_plug_destroy(the_card.irq_no); - return ret; -}; - -static void snd_ps3_free_irq(void) -{ - free_irq(the_card.irq_no, &the_card); - ps3_irq_plug_destroy(the_card.irq_no); -} - -static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start) -{ - uint64_t val; - int ret; - - val = (ioaddr_start & (0x0fUL << 32)) >> (32 - 20) | - (0x03UL << 24) | - (0x0fUL << 12) | - (PS3_AUDIO_IOID); - - ret = lv1_gpu_attribute(0x100, 0x007, val, 0, 0); - if (ret) - pr_info("%s: gpu_attribute failed %d\n", __func__, - ret); -} - -static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev) -{ - int ret; - u64 lpar_addr, lpar_size; - - BUG_ON(!firmware_has_feature(FW_FEATURE_PS3_LV1)); - BUG_ON(dev->match_id != PS3_MATCH_ID_SOUND); - - the_card.ps3_dev = dev; - - ret = ps3_open_hv_device(dev); - - if (ret) - return -ENXIO; - - /* setup MMIO */ - ret = lv1_gpu_device_map(2, &lpar_addr, &lpar_size); - if (ret) { - pr_info("%s: device map 2 failed %d\n", __func__, ret); - goto clean_open; - } - ps3_mmio_region_init(dev, dev->m_region, lpar_addr, lpar_size, - PAGE_SHIFT); - - ret = snd_ps3_map_mmio(); - if (ret) - goto clean_dev_map; - - /* setup DMA area */ - ps3_dma_region_init(dev, dev->d_region, - PAGE_SHIFT, /* use system page size */ - 0, /* dma type; not used */ - NULL, - _ALIGN_UP(SND_PS3_DMA_REGION_SIZE, PAGE_SIZE)); - dev->d_region->ioid = PS3_AUDIO_IOID; - - ret = ps3_dma_region_create(dev->d_region); - if (ret) { - pr_info("%s: region_create\n", __func__); - goto clean_mmio; - } - - snd_ps3_audio_set_base_addr(dev->d_region->bus_addr); - - /* CONFIG_SND_PS3_DEFAULT_START_DELAY */ - the_card.start_delay = snd_ps3_start_delay; - - /* irq */ - if (snd_ps3_allocate_irq()) { - ret = -ENXIO; - goto clean_dma_region; - } - - /* create card instance */ - the_card.card = snd_card_new(index, id, THIS_MODULE, 0); - if (!the_card.card) { - ret = -ENXIO; - goto clean_irq; - } - - strcpy(the_card.card->driver, "PS3"); - strcpy(the_card.card->shortname, "PS3"); - strcpy(the_card.card->longname, "PS3 sound"); - /* create PCM devices instance */ - /* NOTE:this driver works assuming pcm:substream = 1:1 */ - ret = snd_pcm_new(the_card.card, - "SPDIF", - 0, /* instance index, will be stored pcm.device*/ - 1, /* output substream */ - 0, /* input substream */ - &(the_card.pcm)); - if (ret) - goto clean_card; - - the_card.pcm->private_data = &the_card; - strcpy(the_card.pcm->name, "SPDIF"); - - /* set pcm ops */ - snd_pcm_set_ops(the_card.pcm, SNDRV_PCM_STREAM_PLAYBACK, - &snd_ps3_pcm_spdif_ops); - - the_card.pcm->info_flags = SNDRV_PCM_INFO_NONINTERLEAVED; - /* pre-alloc PCM DMA buffer*/ - ret = snd_pcm_lib_preallocate_pages_for_all(the_card.pcm, - SNDRV_DMA_TYPE_DEV, - &dev->core, - SND_PS3_PCM_PREALLOC_SIZE, - SND_PS3_PCM_PREALLOC_SIZE); - if (ret < 0) { - pr_info("%s: prealloc failed\n", __func__); - goto clean_card; - } - - /* - * allocate null buffer - * its size should be lager than PS3_AUDIO_FIFO_STAGE_SIZE * 2 - * PAGE_SIZE is enogh - */ - if (!(the_card.null_buffer_start_vaddr = - dma_alloc_coherent(&the_card.ps3_dev->core, - PAGE_SIZE, - &the_card.null_buffer_start_dma_addr, - GFP_KERNEL))) { - pr_info("%s: nullbuffer alloc failed\n", __func__); - goto clean_preallocate; - } - pr_debug("%s: null vaddr=%p dma=%#lx\n", __func__, - the_card.null_buffer_start_vaddr, - the_card.null_buffer_start_dma_addr); - /* set default sample rate/word width */ - snd_ps3_init_avsetting(&the_card); - - /* register the card */ - ret = snd_card_register(the_card.card); - if (ret < 0) - goto clean_dma_map; - - pr_info("%s started. start_delay=%dms\n", - the_card.card->longname, the_card.start_delay); - return 0; - -clean_dma_map: - dma_free_coherent(&the_card.ps3_dev->core, - PAGE_SIZE, - the_card.null_buffer_start_vaddr, - the_card.null_buffer_start_dma_addr); -clean_preallocate: - snd_pcm_lib_preallocate_free_for_all(the_card.pcm); -clean_card: - snd_card_free(the_card.card); -clean_irq: - snd_ps3_free_irq(); -clean_dma_region: - ps3_dma_region_free(dev->d_region); -clean_mmio: - snd_ps3_unmap_mmio(); -clean_dev_map: - lv1_gpu_device_unmap(2); -clean_open: - ps3_close_hv_device(dev); - /* - * there is no destructor function to pcm. - * midlayer automatically releases if the card removed - */ - return ret; -}; /* snd_ps3_probe */ - -/* called when module removal */ -static int snd_ps3_driver_remove(struct ps3_system_bus_device *dev) -{ - int ret; - pr_info("%s:start id=%d\n", __func__, dev->match_id); - if (dev->match_id != PS3_MATCH_ID_SOUND) - return -ENXIO; - - /* - * ctl and preallocate buffer will be freed in - * snd_card_free - */ - ret = snd_card_free(the_card.card); - if (ret) - pr_info("%s: ctl freecard=%d\n", __func__, ret); - - dma_free_coherent(&dev->core, - PAGE_SIZE, - the_card.null_buffer_start_vaddr, - the_card.null_buffer_start_dma_addr); - - ps3_dma_region_free(dev->d_region); - - snd_ps3_free_irq(); - snd_ps3_unmap_mmio(); - - lv1_gpu_device_unmap(2); - ps3_close_hv_device(dev); - pr_info("%s:end id=%d\n", __func__, dev->match_id); - return 0; -} /* snd_ps3_remove */ - -static struct ps3_system_bus_driver snd_ps3_bus_driver_info = { - .match_id = PS3_MATCH_ID_SOUND, - .probe = snd_ps3_driver_probe, - .remove = snd_ps3_driver_remove, - .shutdown = snd_ps3_driver_remove, - .core = { - .name = SND_PS3_DRIVER_NAME, - .owner = THIS_MODULE, - }, -}; - - -/* - * Interrupt handler - */ -static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id) -{ - - uint32_t port_intr; - int underflow_occured = 0; - struct snd_ps3_card_info *card = dev_id; - - if (!card->running) { - update_reg(PS3_AUDIO_AX_IS, 0); - update_reg(PS3_AUDIO_INTR_0, 0); - return IRQ_HANDLED; - } - - port_intr = read_reg(PS3_AUDIO_AX_IS); - /* - *serial buffer empty detected (every 4 times), - *program next dma and kick it - */ - if (port_intr & PS3_AUDIO_AX_IE_ASOBEIE(0)) { - write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBEIE(0)); - if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) { - write_reg(PS3_AUDIO_AX_IS, port_intr); - underflow_occured = 1; - } - if (card->silent) { - /* we are still in silent time */ - snd_ps3_program_dma(card, - (underflow_occured) ? - SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL : - SND_PS3_DMA_FILLTYPE_SILENT_RUNNING); - snd_ps3_kick_dma(card); - card->silent --; - } else { - snd_ps3_program_dma(card, - (underflow_occured) ? - SND_PS3_DMA_FILLTYPE_FIRSTFILL : - SND_PS3_DMA_FILLTYPE_RUNNING); - snd_ps3_kick_dma(card); - snd_pcm_period_elapsed(card->substream); - } - } else if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) { - write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBUIE(0)); - /* - * serial out underflow, but buffer empty not detected. - * in this case, fill fifo with 0 to recover. After - * filling dummy data, serial automatically start to - * consume them and then will generate normal buffer - * empty interrupts. - * If both buffer underflow and buffer empty are occured, - * it is better to do nomal data transfer than empty one - */ - snd_ps3_program_dma(card, - SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); - snd_ps3_kick_dma(card); - snd_ps3_program_dma(card, - SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); - snd_ps3_kick_dma(card); - } - /* clear interrupt cause */ - return IRQ_HANDLED; -}; - -/* - * module/subsystem initialize/terminate - */ -static int __init snd_ps3_init(void) -{ - int ret; - - if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) - return -ENXIO; - - memset(&the_card, 0, sizeof(the_card)); - spin_lock_init(&the_card.dma_lock); - - /* register systembus DRIVER, this calls our probe() func */ - ret = ps3_system_bus_driver_register(&snd_ps3_bus_driver_info); - - return ret; -} - -static void __exit snd_ps3_exit(void) -{ - ps3_system_bus_driver_unregister(&snd_ps3_bus_driver_info); -} - -MODULE_ALIAS(PS3_MODULE_ALIAS_SOUND); diff --git a/trunk/sound/ppc/snd_ps3.h b/trunk/sound/ppc/snd_ps3.h deleted file mode 100644 index 4b7e6fbbe500..000000000000 --- a/trunk/sound/ppc/snd_ps3.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Audio support for PS3 - * Copyright (C) 2007 Sony Computer Entertainment Inc. - * All rights reserved. - * Copyright 2006, 2007 Sony Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 of the Licence. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if !defined(_SND_PS3_H_) -#define _SND_PS3_H_ - -#include - -#define SND_PS3_DRIVER_NAME "snd_ps3" - -enum snd_ps3_out_channel { - SND_PS3_OUT_SPDIF_0, - SND_PS3_OUT_SPDIF_1, - SND_PS3_OUT_SERIAL_0, - SND_PS3_OUT_DEVS -}; - -enum snd_ps3_dma_filltype { - SND_PS3_DMA_FILLTYPE_FIRSTFILL, - SND_PS3_DMA_FILLTYPE_RUNNING, - SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL, - SND_PS3_DMA_FILLTYPE_SILENT_RUNNING -}; - -enum snd_ps3_ch { - SND_PS3_CH_L = 0, - SND_PS3_CH_R = 1, - SND_PS3_CH_MAX = 2 -}; - -struct snd_ps3_avsetting_info { - uint32_t avs_audio_ch; /* fixed */ - uint32_t avs_audio_rate; - uint32_t avs_audio_width; - uint32_t avs_audio_format; /* fixed */ - uint32_t avs_audio_source; /* fixed */ -}; -/* - * PS3 audio 'card' instance - * there should be only ONE hardware. - */ -struct snd_ps3_card_info { - struct ps3_system_bus_device *ps3_dev; - struct snd_card *card; - - struct snd_pcm *pcm; - struct snd_pcm_substream *substream; - - /* hvc info */ - u64 audio_lpar_addr; - u64 audio_lpar_size; - - /* registers */ - void __iomem *mapped_mmio_vaddr; - - /* irq */ - u64 audio_irq_outlet; - unsigned int irq_no; - - /* remember avsetting */ - struct snd_ps3_avsetting_info avs; - - /* dma buffer management */ - spinlock_t dma_lock; - /* dma_lock start */ - void * dma_start_vaddr[2]; /* 0 for L, 1 for R */ - dma_addr_t dma_start_bus_addr[2]; - size_t dma_buffer_size; - void * dma_last_transfer_vaddr[2]; - void * dma_next_transfer_vaddr[2]; - int silent; - /* dma_lock end */ - - int running; - - /* null buffer */ - void *null_buffer_start_vaddr; - dma_addr_t null_buffer_start_dma_addr; - - /* start delay */ - unsigned int start_delay; - -}; - - -/* PS3 audio DMAC block size in bytes */ -#define PS3_AUDIO_DMAC_BLOCK_SIZE (128) -/* one stage (stereo) of audio FIFO in bytes */ -#define PS3_AUDIO_FIFO_STAGE_SIZE (256) -/* how many stages the fifo have */ -#define PS3_AUDIO_FIFO_STAGE_COUNT (8) -/* fifo size 128 bytes * 8 stages * stereo (2ch) */ -#define PS3_AUDIO_FIFO_SIZE \ - (PS3_AUDIO_FIFO_STAGE_SIZE * PS3_AUDIO_FIFO_STAGE_COUNT) - -/* PS3 audio DMAC max block count in one dma shot = 128 (0x80) blocks*/ -#define PS3_AUDIO_DMAC_MAX_BLOCKS (PS3_AUDIO_DMASIZE_BLOCKS_MASK + 1) - -#define PS3_AUDIO_NORMAL_DMA_START_CH (0) -#define PS3_AUDIO_NORMAL_DMA_COUNT (8) -#define PS3_AUDIO_NULL_DMA_START_CH \ - (PS3_AUDIO_NORMAL_DMA_START_CH + PS3_AUDIO_NORMAL_DMA_COUNT) -#define PS3_AUDIO_NULL_DMA_COUNT (2) - -#define SND_PS3_MAX_VOL (0x0F) -#define SND_PS3_MIN_VOL (0x00) -#define SND_PS3_MIN_ATT SND_PS3_MIN_VOL -#define SND_PS3_MAX_ATT SND_PS3_MAX_VOL - -#define SND_PS3_PCM_PREALLOC_SIZE \ - (PS3_AUDIO_DMAC_BLOCK_SIZE * PS3_AUDIO_DMAC_MAX_BLOCKS * 4) - -#define SND_PS3_DMA_REGION_SIZE \ - (SND_PS3_PCM_PREALLOC_SIZE + PAGE_SIZE) - -#define PS3_AUDIO_IOID (1UL) - -#endif /* _SND_PS3_H_ */ diff --git a/trunk/sound/ppc/snd_ps3_reg.h b/trunk/sound/ppc/snd_ps3_reg.h deleted file mode 100644 index 03fdee4aaaf2..000000000000 --- a/trunk/sound/ppc/snd_ps3_reg.h +++ /dev/null @@ -1,891 +0,0 @@ -/* - * Audio support for PS3 - * Copyright (C) 2007 Sony Computer Entertainment Inc. - * Copyright 2006, 2007 Sony Corporation - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * interrupt / configure registers - */ - -#define PS3_AUDIO_INTR_0 (0x00000100) -#define PS3_AUDIO_INTR_EN_0 (0x00000140) -#define PS3_AUDIO_CONFIG (0x00000200) - -/* - * DMAC registers - * n:0..9 - */ -#define PS3_AUDIO_DMAC_REGBASE(x) (0x0000210 + 0x20 * (x)) - -#define PS3_AUDIO_KICK(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x00) -#define PS3_AUDIO_SOURCE(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x04) -#define PS3_AUDIO_DEST(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x08) -#define PS3_AUDIO_DMASIZE(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x0C) - -/* - * mute control - */ -#define PS3_AUDIO_AX_MCTRL (0x00004000) -#define PS3_AUDIO_AX_ISBP (0x00004004) -#define PS3_AUDIO_AX_AOBP (0x00004008) -#define PS3_AUDIO_AX_IC (0x00004010) -#define PS3_AUDIO_AX_IE (0x00004014) -#define PS3_AUDIO_AX_IS (0x00004018) - -/* - * three wire serial - * n:0..3 - */ -#define PS3_AUDIO_AO_MCTRL (0x00006000) -#define PS3_AUDIO_AO_3WMCTRL (0x00006004) - -#define PS3_AUDIO_AO_3WCTRL(n) (0x00006200 + 0x200 * (n)) - -/* - * S/PDIF - * n:0..1 - * x:0..11 - * y:0..5 - */ -#define PS3_AUDIO_AO_SPD_REGBASE(n) (0x00007200 + 0x200 * (n)) - -#define PS3_AUDIO_AO_SPDCTRL(n) \ - (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x00) -#define PS3_AUDIO_AO_SPDUB(n, x) \ - (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x04 + 0x04 * (x)) -#define PS3_AUDIO_AO_SPDCS(n, y) \ - (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x34 + 0x04 * (y)) - - -/* - PS3_AUDIO_INTR_0 register tells an interrupt handler which audio - DMA channel triggered the interrupt. The interrupt status for a channel - can be cleared by writing a '1' to the corresponding bit. A new interrupt - cannot be generated until the previous interrupt has been cleared. - - Note that the status reported by PS3_AUDIO_INTR_0 is independent of the - value of PS3_AUDIO_INTR_EN_0. - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0 0 0 0 0 0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C| INTR_0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ -#define PS3_AUDIO_INTR_0_CHAN(n) (1 << ((n) * 2)) -#define PS3_AUDIO_INTR_0_CHAN9 PS3_AUDIO_INTR_0_CHAN(9) -#define PS3_AUDIO_INTR_0_CHAN8 PS3_AUDIO_INTR_0_CHAN(8) -#define PS3_AUDIO_INTR_0_CHAN7 PS3_AUDIO_INTR_0_CHAN(7) -#define PS3_AUDIO_INTR_0_CHAN6 PS3_AUDIO_INTR_0_CHAN(6) -#define PS3_AUDIO_INTR_0_CHAN5 PS3_AUDIO_INTR_0_CHAN(5) -#define PS3_AUDIO_INTR_0_CHAN4 PS3_AUDIO_INTR_0_CHAN(4) -#define PS3_AUDIO_INTR_0_CHAN3 PS3_AUDIO_INTR_0_CHAN(3) -#define PS3_AUDIO_INTR_0_CHAN2 PS3_AUDIO_INTR_0_CHAN(2) -#define PS3_AUDIO_INTR_0_CHAN1 PS3_AUDIO_INTR_0_CHAN(1) -#define PS3_AUDIO_INTR_0_CHAN0 PS3_AUDIO_INTR_0_CHAN(0) - -/* - The PS3_AUDIO_INTR_EN_0 register specifies which DMA channels can generate - an interrupt to the PU. Each bit of PS3_AUDIO_INTR_EN_0 is ANDed with the - corresponding bit in PS3_AUDIO_INTR_0. The resulting bits are OR'd together - to generate the Audio interrupt. - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0 0 0 0 0 0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C| INTR_EN_0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - - Bit assignments are same as PS3_AUDIO_INTR_0 -*/ - -/* - PS3_AUDIO_CONFIG - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 C|0 0 0 0 0 0 0 0| CONFIG - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - -*/ - -/* The CLEAR field cancels all pending transfers, and stops any running DMA - transfers. Any interrupts associated with the canceled transfers - will occur as if the transfer had finished. - Since this bit is designed to recover from DMA related issues - which are caused by unpredictable situations, it is prefered to wait - for normal DMA transfer end without using this bit. -*/ -#define PS3_AUDIO_CONFIG_CLEAR (1 << 8) /* RWIVF */ - -/* - PS3_AUDIO_AX_MCTRL: Audio Port Mute Control Register - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|A|A|A|0 0 0 0 0 0 0|S|S|A|A|A|A| AX_MCTRL - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ - -/* 3 Wire Audio Serial Output Channel Mutes (0..3) */ -#define PS3_AUDIO_AX_MCTRL_ASOMT(n) (1 << (3 - (n))) /* RWIVF */ -#define PS3_AUDIO_AX_MCTRL_ASO3MT (1 << 0) /* RWIVF */ -#define PS3_AUDIO_AX_MCTRL_ASO2MT (1 << 1) /* RWIVF */ -#define PS3_AUDIO_AX_MCTRL_ASO1MT (1 << 2) /* RWIVF */ -#define PS3_AUDIO_AX_MCTRL_ASO0MT (1 << 3) /* RWIVF */ - -/* S/PDIF mutes (0,1)*/ -#define PS3_AUDIO_AX_MCTRL_SPOMT(n) (1 << (5 - (n))) /* RWIVF */ -#define PS3_AUDIO_AX_MCTRL_SPO1MT (1 << 4) /* RWIVF */ -#define PS3_AUDIO_AX_MCTRL_SPO0MT (1 << 5) /* RWIVF */ - -/* All 3 Wire Serial Outputs Mute */ -#define PS3_AUDIO_AX_MCTRL_AASOMT (1 << 13) /* RWIVF */ - -/* All S/PDIF Mute */ -#define PS3_AUDIO_AX_MCTRL_ASPOMT (1 << 14) /* RWIVF */ - -/* All Audio Outputs Mute */ -#define PS3_AUDIO_AX_MCTRL_AAOMT (1 << 15) /* RWIVF */ - -/* - S/PDIF Outputs Buffer Read/Write Pointer Register - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0|0|SPO0B|0|SPO1B|0 0 0 0 0 0 0 0|0|SPO0B|0|SPO1B| AX_ISBP - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - -*/ -/* - S/PDIF Output Channel Read Buffer Numbers - Buffer number is value of field. - Indicates current read access buffer ID from Audio Data - Transfer controller of S/PDIF Output -*/ - -#define PS3_AUDIO_AX_ISBP_SPOBRN_MASK(n) (0x7 << 4 * (1 - (n))) /* R-IUF */ -#define PS3_AUDIO_AX_ISBP_SPO1BRN_MASK (0x7 << 0) /* R-IUF */ -#define PS3_AUDIO_AX_ISBP_SPO0BRN_MASK (0x7 << 4) /* R-IUF */ - -/* -S/PDIF Output Channel Buffer Write Numbers -Indicates current write access buffer ID from bus master. -*/ -#define PS3_AUDIO_AX_ISBP_SPOBWN_MASK(n) (0x7 << 4 * (5 - (n))) /* R-IUF */ -#define PS3_AUDIO_AX_ISBP_SPO1BWN_MASK (0x7 << 16) /* R-IUF */ -#define PS3_AUDIO_AX_ISBP_SPO0BWN_MASK (0x7 << 20) /* R-IUF */ - -/* - 3 Wire Audio Serial Outputs Buffer Read/Write - Pointer Register - Buffer number is value of field - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0|ASO0B|0|ASO1B|0|ASO2B|0|ASO3B|0|ASO0B|0|ASO1B|0|ASO2B|0|ASO3B| AX_AOBP - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ - -/* -3 Wire Audio Serial Output Channel Buffer Read Numbers -Indicates current read access buffer Id from Audio Data Transfer -Controller of 3 Wire Audio Serial Output Channels -*/ -#define PS3_AUDIO_AX_AOBP_ASOBRN_MASK(n) (0x7 << 4 * (3 - (n))) /* R-IUF */ - -#define PS3_AUDIO_AX_AOBP_ASO3BRN_MASK (0x7 << 0) /* R-IUF */ -#define PS3_AUDIO_AX_AOBP_ASO2BRN_MASK (0x7 << 4) /* R-IUF */ -#define PS3_AUDIO_AX_AOBP_ASO1BRN_MASK (0x7 << 8) /* R-IUF */ -#define PS3_AUDIO_AX_AOBP_ASO0BRN_MASK (0x7 << 12) /* R-IUF */ - -/* -3 Wire Audio Serial Output Channel Buffer Write Numbers -Indicates current write access buffer ID from bus master. -*/ -#define PS3_AUDIO_AX_AOBP_ASOBWN_MASK(n) (0x7 << 4 * (7 - (n))) /* R-IUF */ - -#define PS3_AUDIO_AX_AOBP_ASO3BWN_MASK (0x7 << 16) /* R-IUF */ -#define PS3_AUDIO_AX_AOBP_ASO2BWN_MASK (0x7 << 20) /* R-IUF */ -#define PS3_AUDIO_AX_AOBP_ASO1BWN_MASK (0x7 << 24) /* R-IUF */ -#define PS3_AUDIO_AX_AOBP_ASO0BWN_MASK (0x7 << 28) /* R-IUF */ - - - -/* -Audio Port Interrupt Condition Register -For the fields in this register, the following values apply: -0 = Interrupt is generated every interrupt event. -1 = Interrupt is generated every 2 interrupt events. -2 = Interrupt is generated every 4 interrupt events. -3 = Reserved - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0|0 0|SPO|0 0|SPO|0 0|AAS|0 0 0 0 0 0 0 0 0 0 0 0| AX_IC - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ -/* -All 3-Wire Audio Serial Outputs Interrupt Mode -Configures the Interrupt and Signal Notification -condition of all 3-wire Audio Serial Outputs. -*/ -#define PS3_AUDIO_AX_IC_AASOIMD_MASK (0x3 << 12) /* RWIVF */ -#define PS3_AUDIO_AX_IC_AASOIMD_EVERY1 (0x0 << 12) /* RWI-V */ -#define PS3_AUDIO_AX_IC_AASOIMD_EVERY2 (0x1 << 12) /* RW--V */ -#define PS3_AUDIO_AX_IC_AASOIMD_EVERY4 (0x2 << 12) /* RW--V */ - -/* -S/PDIF Output Channel Interrupt Modes -Configures the Interrupt and signal Notification -conditions of S/PDIF output channels. -*/ -#define PS3_AUDIO_AX_IC_SPO1IMD_MASK (0x3 << 16) /* RWIVF */ -#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY1 (0x0 << 16) /* RWI-V */ -#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY2 (0x1 << 16) /* RW--V */ -#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY4 (0x2 << 16) /* RW--V */ - -#define PS3_AUDIO_AX_IC_SPO0IMD_MASK (0x3 << 20) /* RWIVF */ -#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY1 (0x0 << 20) /* RWI-V */ -#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY2 (0x1 << 20) /* RW--V */ -#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY4 (0x2 << 20) /* RW--V */ - -/* -Audio Port interrupt Enable Register -Configures whether to enable or disable each Interrupt Generation. - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0|S|S|0 0|A|A|A|A|0 0 0 0|S|S|0 0|S|S|0 0|A|A|A|A| AX_IE - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - -*/ - -/* -3 Wire Audio Serial Output Channel Buffer Underflow -Interrupt Enables -Select enable/disable of Buffer Underflow Interrupts for -3-Wire Audio Serial Output Channels -DISABLED=Interrupt generation disabled. -*/ -#define PS3_AUDIO_AX_IE_ASOBUIE(n) (1 << (3 - (n))) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO3BUIE (1 << 0) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO2BUIE (1 << 1) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO1BUIE (1 << 2) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO0BUIE (1 << 3) /* RWIVF */ - -/* S/PDIF Output Channel Buffer Underflow Interrupt Enables */ - -#define PS3_AUDIO_AX_IE_SPOBUIE(n) (1 << (7 - (n))) /* RWIVF */ -#define PS3_AUDIO_AX_IE_SPO1BUIE (1 << 6) /* RWIVF */ -#define PS3_AUDIO_AX_IE_SPO0BUIE (1 << 7) /* RWIVF */ - -/* S/PDIF Output Channel One Block Transfer Completion Interrupt Enables */ - -#define PS3_AUDIO_AX_IE_SPOBTCIE(n) (1 << (11 - (n))) /* RWIVF */ -#define PS3_AUDIO_AX_IE_SPO1BTCIE (1 << 10) /* RWIVF */ -#define PS3_AUDIO_AX_IE_SPO0BTCIE (1 << 11) /* RWIVF */ - -/* 3-Wire Audio Serial Output Channel Buffer Empty Interrupt Enables */ - -#define PS3_AUDIO_AX_IE_ASOBEIE(n) (1 << (19 - (n))) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO3BEIE (1 << 16) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO2BEIE (1 << 17) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO1BEIE (1 << 18) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO0BEIE (1 << 19) /* RWIVF */ - -/* S/PDIF Output Channel Buffer Empty Interrupt Enables */ - -#define PS3_AUDIO_AX_IE_SPOBEIE(n) (1 << (23 - (n))) /* RWIVF */ -#define PS3_AUDIO_AX_IE_SPO1BEIE (1 << 22) /* RWIVF */ -#define PS3_AUDIO_AX_IE_SPO0BEIE (1 << 23) /* RWIVF */ - -/* -Audio Port Interrupt Status Register -Indicates Interrupt status, which interrupt has occured, and can clear -each interrupt in this register. -Writing 1b to a field containing 1b clears field and de-asserts interrupt. -Writing 0b to a field has no effect. -Field vaules are the following: -0 - Interrupt hasn't occured. -1 - Interrupt has occured. - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0|S|S|0 0|A|A|A|A|0 0 0 0|S|S|0 0|S|S|0 0|A|A|A|A| AX_IS - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - - Bit assignment are same as AX_IE -*/ - -/* -Audio Output Master Control Register -Configures Master Clock and other master Audio Output Settings - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0|SCKSE|0|SCKSE| MR0 | MR1 |MCL|MCL|0 0 0 0|0 0 0 0 0 0 0 0| AO_MCTRL - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ - -/* -MCLK Output Control -Controls mclko[1] output. -0 - Disable output (fixed at High) -1 - Output clock produced by clock selected -with scksel1 by mr1 -2 - Reserved -3 - Reserved -*/ - -#define PS3_AUDIO_AO_MCTRL_MCLKC1_MASK (0x3 << 12) /* RWIVF */ -#define PS3_AUDIO_AO_MCTRL_MCLKC1_DISABLED (0x0 << 12) /* RWI-V */ -#define PS3_AUDIO_AO_MCTRL_MCLKC1_ENABLED (0x1 << 12) /* RW--V */ -#define PS3_AUDIO_AO_MCTRL_MCLKC1_RESVD2 (0x2 << 12) /* RW--V */ -#define PS3_AUDIO_AO_MCTRL_MCLKC1_RESVD3 (0x3 << 12) /* RW--V */ - -/* -MCLK Output Control -Controls mclko[0] output. -0 - Disable output (fixed at High) -1 - Output clock produced by clock selected -with SCKSEL0 by MR0 -2 - Reserved -3 - Reserved -*/ -#define PS3_AUDIO_AO_MCTRL_MCLKC0_MASK (0x3 << 14) /* RWIVF */ -#define PS3_AUDIO_AO_MCTRL_MCLKC0_DISABLED (0x0 << 14) /* RWI-V */ -#define PS3_AUDIO_AO_MCTRL_MCLKC0_ENABLED (0x1 << 14) /* RW--V */ -#define PS3_AUDIO_AO_MCTRL_MCLKC0_RESVD2 (0x2 << 14) /* RW--V */ -#define PS3_AUDIO_AO_MCTRL_MCLKC0_RESVD3 (0x3 << 14) /* RW--V */ -/* -Master Clock Rate 1 -Sets the divide ration of Master Clock1 (clock output from -mclko[1] for the input clock selected by scksel1. -*/ -#define PS3_AUDIO_AO_MCTRL_MR1_MASK (0xf << 16) -#define PS3_AUDIO_AO_MCTRL_MR1_DEFAULT (0x0 << 16) /* RWI-V */ -/* -Master Clock Rate 0 -Sets the divide ratio of Master Clock0 (clock output from -mclko[0] for the input clock selected by scksel0). -*/ -#define PS3_AUDIO_AO_MCTRL_MR0_MASK (0xf << 20) /* RWIVF */ -#define PS3_AUDIO_AO_MCTRL_MR0_DEFAULT (0x0 << 20) /* RWI-V */ -/* -System Clock Select 0/1 -Selects the system clock to be used as Master Clock 0/1 -Input the system clock that is appropriate for the sampling -rate. -*/ -#define PS3_AUDIO_AO_MCTRL_SCKSEL1_MASK (0x7 << 24) /* RWIVF */ -#define PS3_AUDIO_AO_MCTRL_SCKSEL1_DEFAULT (0x2 << 24) /* RWI-V */ - -#define PS3_AUDIO_AO_MCTRL_SCKSEL0_MASK (0x7 << 28) /* RWIVF */ -#define PS3_AUDIO_AO_MCTRL_SCKSEL0_DEFAULT (0x2 << 28) /* RWI-V */ - - -/* -3-Wire Audio Output Master Control Register -Configures clock, 3-Wire Audio Serial Output Enable, and -other 3-Wire Audio Serial Output Master Settings - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |A|A|A|A|0 0 0|A| ASOSR |0 0 0 0|A|A|A|A|A|A|0|1|0 0 0 0 0 0 0 0| AO_3WMCTRL - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ - - -/* -LRCKO Polarity -0 - Reserved -1 - default -*/ -#define PS3_AUDIO_AO_3WMCTRL_ASOPLRCK (1 << 8) /* RWIVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT (1 << 8) /* RW--V */ - -/* LRCK Output Disable */ - -#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD (1 << 10) /* RWIVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_ENABLED (0 << 10) /* RW--V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED (1 << 10) /* RWI-V */ - -/* Bit Clock Output Disable */ - -#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD (1 << 11) /* RWIVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_ENABLED (0 << 11) /* RW--V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED (1 << 11) /* RWI-V */ - -/* -3-Wire Audio Serial Output Channel 0-3 Operational -Status. Each bit becomes 1 after each 3-Wire Audio -Serial Output Channel N is in action by setting 1 to -asoen. -Each bit becomes 0 after each 3-Wire Audio Serial Output -Channel N is out of action by setting 0 to asoen. -*/ -#define PS3_AUDIO_AO_3WMCTRL_ASORUN(n) (1 << (15 - (n))) /* R-IVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(n) (0 << (15 - (n))) /* R-I-V */ -#define PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(n) (1 << (15 - (n))) /* R---V */ -#define PS3_AUDIO_AO_3WMCTRL_ASORUN0 \ - PS3_AUDIO_AO_3WMCTRL_ASORUN(0) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN0_STOPPED \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(0) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN0_RUNNING \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(0) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN1 \ - PS3_AUDIO_AO_3WMCTRL_ASORUN(1) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN1_STOPPED \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(1) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN1_RUNNING \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(1) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN2 \ - PS3_AUDIO_AO_3WMCTRL_ASORUN(2) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN2_STOPPED \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(2) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN2_RUNNING \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(2) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN3 \ - PS3_AUDIO_AO_3WMCTRL_ASORUN(3) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN3_STOPPED \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(3) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN3_RUNNING \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(3) - -/* -Sampling Rate -Specifies the divide ratio of the bit clock (clock output -from bclko) used by the 3-wire Audio Output Clock, whcih -is applied to the master clock selected by mcksel. -Data output is synchronized with this clock. -*/ -#define PS3_AUDIO_AO_3WMCTRL_ASOSR_MASK (0xf << 20) /* RWIVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV2 (0x1 << 20) /* RWI-V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV4 (0x2 << 20) /* RW--V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV8 (0x4 << 20) /* RW--V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV12 (0x6 << 20) /* RW--V */ - -/* -Master Clock Select -0 - Master Clock 0 -1 - Master Clock 1 -*/ -#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL (1 << 24) /* RWIVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL_CLK0 (0 << 24) /* RWI-V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL_CLK1 (1 << 24) /* RW--V */ - -/* -Enables and disables 4ch 3-Wire Audio Serial Output -operation. Each Bit from 0 to 3 corresponds to an -output channel, which means that each output channel -can be enabled or disabled individually. When -multiple channels are enabled at the same time, output -operations are performed in synchronization. -Bit 0 - Output Channel 0 (SDOUT[0]) -Bit 1 - Output Channel 1 (SDOUT[1]) -Bit 2 - Output Channel 2 (SDOUT[2]) -Bit 3 - Output Channel 3 (SDOUT[3]) -*/ -#define PS3_AUDIO_AO_3WMCTRL_ASOEN(n) (1 << (31 - (n))) /* RWIVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(n) (0 << (31 - (n))) /* RWI-V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(n) (1 << (31 - (n))) /* RW--V */ - -#define PS3_AUDIO_AO_3WMCTRL_ASOEN0 \ - PS3_AUDIO_AO_3WMCTRL_ASOEN(0) /* RWIVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASOEN0_DISABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(0) /* RWI-V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOEN0_ENABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(0) /* RW--V */ -#define PS3_AUDIO_A1_3WMCTRL_ASOEN0 \ - PS3_AUDIO_AO_3WMCTRL_ASOEN(1) /* RWIVF */ -#define PS3_AUDIO_A1_3WMCTRL_ASOEN0_DISABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(1) /* RWI-V */ -#define PS3_AUDIO_A1_3WMCTRL_ASOEN0_ENABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(1) /* RW--V */ -#define PS3_AUDIO_A2_3WMCTRL_ASOEN0 \ - PS3_AUDIO_AO_3WMCTRL_ASOEN(2) /* RWIVF */ -#define PS3_AUDIO_A2_3WMCTRL_ASOEN0_DISABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(2) /* RWI-V */ -#define PS3_AUDIO_A2_3WMCTRL_ASOEN0_ENABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(2) /* RW--V */ -#define PS3_AUDIO_A3_3WMCTRL_ASOEN0 \ - PS3_AUDIO_AO_3WMCTRL_ASOEN(3) /* RWIVF */ -#define PS3_AUDIO_A3_3WMCTRL_ASOEN0_DISABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(3) /* RWI-V */ -#define PS3_AUDIO_A3_3WMCTRL_ASOEN0_ENABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(3) /* RW--V */ - -/* -3-Wire Audio Serial output Channel 0-3 Control Register -Configures settings for 3-Wire Serial Audio Output Channel 0-3 - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|A|0 0 0 0|A|0|ASO|0 0 0|0|0|0|0|0| AO_3WCTRL - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - -*/ -/* -Data Bit Mode -Specifies the number of data bits -0 - 16 bits -1 - reserved -2 - 20 bits -3 - 24 bits -*/ -#define PS3_AUDIO_AO_3WCTRL_ASODB_MASK (0x3 << 8) /* RWIVF */ -#define PS3_AUDIO_AO_3WCTRL_ASODB_16BIT (0x0 << 8) /* RWI-V */ -#define PS3_AUDIO_AO_3WCTRL_ASODB_RESVD (0x1 << 8) /* RWI-V */ -#define PS3_AUDIO_AO_3WCTRL_ASODB_20BIT (0x2 << 8) /* RW--V */ -#define PS3_AUDIO_AO_3WCTRL_ASODB_24BIT (0x3 << 8) /* RW--V */ -/* -Data Format Mode -Specifies the data format where (LSB side or MSB) the data(in 20 bit -or 24 bit resolution mode) is put in a 32 bit field. -0 - Data put on LSB side -1 - Data put on MSB side -*/ -#define PS3_AUDIO_AO_3WCTRL_ASODF (1 << 11) /* RWIVF */ -#define PS3_AUDIO_AO_3WCTRL_ASODF_LSB (0 << 11) /* RWI-V */ -#define PS3_AUDIO_AO_3WCTRL_ASODF_MSB (1 << 11) /* RW--V */ -/* -Buffer Reset -Performs buffer reset. Writing 1 to this bit initializes the -corresponding 3-Wire Audio Output buffers(both L and R). -*/ -#define PS3_AUDIO_AO_3WCTRL_ASOBRST (1 << 16) /* CWIVF */ -#define PS3_AUDIO_AO_3WCTRL_ASOBRST_IDLE (0 << 16) /* -WI-V */ -#define PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET (1 << 16) /* -W--T */ - -/* -S/PDIF Audio Output Channel 0/1 Control Register -Configures settings for S/PDIF Audio Output Channel 0/1. - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |S|0 0 0|S|0 0|S| SPOSR |0 0|SPO|0 0 0 0|S|0|SPO|0 0 0 0 0 0 0|S| AO_SPDCTRL - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ -/* -Buffer reset. Writing 1 to this bit initializes the -corresponding S/PDIF output buffer pointer. -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPOBRST (1 << 0) /* CWIVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPOBRST_IDLE (0 << 0) /* -WI-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPOBRST_RESET (1 << 0) /* -W--T */ - -/* -Data Bit Mode -Specifies number of data bits -0 - 16 bits -1 - Reserved -2 - 20 bits -3 - 24 bits -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPODB_MASK (0x3 << 8) /* RWIVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPODB_16BIT (0x0 << 8) /* RWI-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPODB_RESVD (0x1 << 8) /* RW--V */ -#define PS3_AUDIO_AO_SPDCTRL_SPODB_20BIT (0x2 << 8) /* RW--V */ -#define PS3_AUDIO_AO_SPDCTRL_SPODB_24BIT (0x3 << 8) /* RW--V */ -/* -Data format Mode -Specifies the data format, where (LSB side or MSB) -the data(in 20 or 24 bit resolution) is put in the -32 bit field. -0 - LSB Side -1 - MSB Side -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPODF (1 << 11) /* RWIVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPODF_LSB (0 << 11) /* RWI-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPODF_MSB (1 << 11) /* RW--V */ -/* -Source Select -Specifies the source of the S/PDIF output. When 0, output -operation is controlled by 3wen[0] of AO_3WMCTRL register. -The SR must have the same setting as the a0_3wmctrl reg. -0 - 3-Wire Audio OUT Ch0 Buffer -1 - S/PDIF buffer -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPOSS_MASK (0x3 << 16) /* RWIVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPOSS_3WEN (0x0 << 16) /* RWI-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPOSS_SPDIF (0x1 << 16) /* RW--V */ -/* -Sampling Rate -Specifies the divide ratio of the bit clock (clock output -from bclko) used by the S/PDIF Output Clock, which -is applied to the master clock selected by mcksel. -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPOSR (0xf << 20) /* RWIVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV2 (0x1 << 20) /* RWI-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV4 (0x2 << 20) /* RW--V */ -#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV8 (0x4 << 20) /* RW--V */ -#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV12 (0x6 << 20) /* RW--V */ -/* -Master Clock Select -0 - Master Clock 0 -1 - Master Clock 1 -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL (1 << 24) /* RWIVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL_CLK0 (0 << 24) /* RWI-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL_CLK1 (1 << 24) /* RW--V */ - -/* -S/PDIF Output Channel Operational Status -This bit becomes 1 after S/PDIF Output Channel is in -action by setting 1 to spoen. This bit becomes 0 -after S/PDIF Output Channel is out of action by setting -0 to spoen. -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPORUN (1 << 27) /* R-IVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPORUN_STOPPED (0 << 27) /* R-I-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPORUN_RUNNING (1 << 27) /* R---V */ - -/* -S/PDIF Audio Output Channel Output Enable -Enables and disables output operation. This bit is used -only when sposs = 1 -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPOEN (1 << 31) /* RWIVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPOEN_DISABLED (0 << 31) /* RWI-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPOEN_ENABLED (1 << 31) /* RW--V */ - -/* -S/PDIF Audio Output Channel Channel Status -Setting Registers. -Configures channel status bit settings for each block -(192 bits). -Output is performed from the MSB(AO_SPDCS0 register bit 31). -The same value is added for subframes within the same frame. - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - | SPOCS | AO_SPDCS - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - -S/PDIF Audio Output Channel User Bit Setting -Configures user bit settings for each block (384 bits). -Output is performed from the MSB(ao_spdub0 register bit 31). - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - | SPOUB | AO_SPDUB - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ -/***************************************************************************** - * - * DMAC register - * - *****************************************************************************/ -/* -The PS3_AUDIO_KICK register is used to initiate a DMA transfer and monitor -its status - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0|STATU|0 0 0| EVENT |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|R| KICK - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ -/* -The REQUEST field is written to ACTIVE to initiate a DMA request when EVENT -occurs. -It will return to the DONE state when the request is completed. -The registers for a DMA channel should only be written if REQUEST is IDLE. -*/ - -#define PS3_AUDIO_KICK_REQUEST (1 << 0) /* RWIVF */ -#define PS3_AUDIO_KICK_REQUEST_IDLE (0 << 0) /* RWI-V */ -#define PS3_AUDIO_KICK_REQUEST_ACTIVE (1 << 0) /* -W--T */ - -/* - *The EVENT field is used to set the event in which - *the DMA request becomes active. - */ -#define PS3_AUDIO_KICK_EVENT_MASK (0x1f << 16) /* RWIVF */ -#define PS3_AUDIO_KICK_EVENT_ALWAYS (0x00 << 16) /* RWI-V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY (0x01 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT0_UNDERFLOW (0x02 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT1_EMPTY (0x03 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT1_UNDERFLOW (0x04 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT2_EMPTY (0x05 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT2_UNDERFLOW (0x06 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT3_EMPTY (0x07 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT3_UNDERFLOW (0x08 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SPDIF0_BLOCKTRANSFERCOMPLETE \ - (0x09 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SPDIF0_UNDERFLOW (0x0A << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SPDIF0_EMPTY (0x0B << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SPDIF1_BLOCKTRANSFERCOMPLETE \ - (0x0C << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SPDIF1_UNDERFLOW (0x0D << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SPDIF1_EMPTY (0x0E << 16) /* RW--V */ - -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA(n) \ - ((0x13 + (n)) << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA0 (0x13 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA1 (0x14 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA2 (0x15 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA3 (0x16 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA4 (0x17 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA5 (0x18 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA6 (0x19 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA7 (0x1A << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA8 (0x1B << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA9 (0x1C << 16) /* RW--V */ - -/* -The STATUS field can be used to monitor the progress of a DMA request. -DONE indicates the previous request has completed. -EVENT indicates that the DMA engine is waiting for the EVENT to occur. -PENDING indicates that the DMA engine has not started processing this -request, but the EVENT has occured. -DMA indicates that the data transfer is in progress. -NOTIFY indicates that the notifier signalling end of transfer is being written. -CLEAR indicated that the previous transfer was cleared. -ERROR indicates the previous transfer requested an unsupported -source/destination combination. -*/ - -#define PS3_AUDIO_KICK_STATUS_MASK (0x7 << 24) /* R-IVF */ -#define PS3_AUDIO_KICK_STATUS_DONE (0x0 << 24) /* R-I-V */ -#define PS3_AUDIO_KICK_STATUS_EVENT (0x1 << 24) /* R---V */ -#define PS3_AUDIO_KICK_STATUS_PENDING (0x2 << 24) /* R---V */ -#define PS3_AUDIO_KICK_STATUS_DMA (0x3 << 24) /* R---V */ -#define PS3_AUDIO_KICK_STATUS_NOTIFY (0x4 << 24) /* R---V */ -#define PS3_AUDIO_KICK_STATUS_CLEAR (0x5 << 24) /* R---V */ -#define PS3_AUDIO_KICK_STATUS_ERROR (0x6 << 24) /* R---V */ - -/* -The PS3_AUDIO_SOURCE register specifies the source address for transfers. - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - | START |0 0 0 0 0|TAR| SOURCE - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ - -/* -The Audio DMA engine uses 128-byte transfers, thus the address must be aligned -to a 128 byte boundary. The low seven bits are assumed to be 0. -*/ - -#define PS3_AUDIO_SOURCE_START_MASK (0x01FFFFFF << 7) /* RWIUF */ - -/* -The TARGET field specifies the memory space containing the source address. -*/ - -#define PS3_AUDIO_SOURCE_TARGET_MASK (3 << 0) /* RWIVF */ -#define PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY (2 << 0) /* RW--V */ - -/* -The PS3_AUDIO_DEST register specifies the destination address for transfers. - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - | START |0 0 0 0 0|TAR| DEST - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ - -/* -The Audio DMA engine uses 128-byte transfers, thus the address must be aligned -to a 128 byte boundary. The low seven bits are assumed to be 0. -*/ - -#define PS3_AUDIO_DEST_START_MASK (0x01FFFFFF << 7) /* RWIUF */ - -/* -The TARGET field specifies the memory space containing the destination address -AUDIOFIFO = Audio WriteData FIFO, -*/ - -#define PS3_AUDIO_DEST_TARGET_MASK (3 << 0) /* RWIVF */ -#define PS3_AUDIO_DEST_TARGET_AUDIOFIFO (1 << 0) /* RW--V */ - -/* -PS3_AUDIO_DMASIZE specifies the number of 128-byte blocks + 1 to transfer. -So a value of 0 means 128-bytes will get transfered. - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| BLOCKS | DMASIZE - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ - - -#define PS3_AUDIO_DMASIZE_BLOCKS_MASK (0x7f << 0) /* RWIUF */ - -/* - * source/destination address for internal fifos - */ -#define PS3_AUDIO_AO_3W_LDATA(n) (0x1000 + (0x100 * (n))) -#define PS3_AUDIO_AO_3W_RDATA(n) (0x1080 + (0x100 * (n))) - -#define PS3_AUDIO_AO_SPD_DATA(n) (0x2000 + (0x400 * (n))) - - -/* - * field attiribute - * - * Read - * ' ' = Other Information - * '-' = Field is part of a write-only register - * 'C' = Value read is always the same, constant value line follows (C) - * 'R' = Value is read - * - * Write - * ' ' = Other Information - * '-' = Must not be written (D), value ignored when written (R,A,F) - * 'W' = Can be written - * - * Internal State - * ' ' = Other Information - * '-' = No internal state - * 'X' = Internal state, initial value is unknown - * 'I' = Internal state, initial value is known and follows (I) - * - * Declaration/Size - * ' ' = Other Information - * '-' = Does Not Apply - * 'V' = Type is void - * 'U' = Type is unsigned integer - * 'S' = Type is signed integer - * 'F' = Type is IEEE floating point - * '1' = Byte size (008) - * '2' = Short size (016) - * '3' = Three byte size (024) - * '4' = Word size (032) - * '8' = Double size (064) - * - * Define Indicator - * ' ' = Other Information - * 'D' = Device - * 'M' = Memory - * 'R' = Register - * 'A' = Array of Registers - * 'F' = Field - * 'V' = Value - * 'T' = Task - */ - diff --git a/trunk/sound/sh/Kconfig b/trunk/sound/sh/Kconfig deleted file mode 100644 index b7e08ef22a94..000000000000 --- a/trunk/sound/sh/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -# ALSA SH drivers - -menu "SUPERH devices" - depends on SND!=n && SUPERH - -config SND_AICA - tristate "Dreamcast Yamaha AICA sound" - depends on SH_DREAMCAST && SND - select SND_PCM - help - ALSA Sound driver for the SEGA Dreamcast console. - -endmenu - diff --git a/trunk/sound/sh/Makefile b/trunk/sound/sh/Makefile deleted file mode 100644 index 8fdcb6e26f00..000000000000 --- a/trunk/sound/sh/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for ALSA -# - -snd-aica-objs := aica.o - -# Toplevel Module Dependency -obj-$(CONFIG_SND_AICA) += snd-aica.o diff --git a/trunk/sound/sh/aica.c b/trunk/sound/sh/aica.c deleted file mode 100644 index 739786529ca5..000000000000 --- a/trunk/sound/sh/aica.c +++ /dev/null @@ -1,665 +0,0 @@ -/* -* This code is licenced under -* the General Public Licence -* version 2 -* -* Copyright Adrian McMenamin 2005, 2006, 2007 -* -* Requires firmware (BSD licenced) available from: -* http://linuxdc.cvs.sourceforge.net/linuxdc/linux-sh-dc/sound/oss/aica/firmware/ -* or the maintainer -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of version 2 of the GNU General Public License as published by -* the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "aica.h" - -MODULE_AUTHOR("Adrian McMenamin "); -MODULE_DESCRIPTION("Dreamcast AICA sound (pcm) driver"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{Yamaha/SEGA, AICA}}"); - -/* module parameters */ -#define CARD_NAME "AICA" -static int index = -1; -static char *id; -static int enable = 1; -module_param(index, int, 0444); -MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); -module_param(id, charp, 0444); -MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); -module_param(enable, bool, 0644); -MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard."); - -/* Use workqueue */ -static struct workqueue_struct *aica_queue; - -/* Simple platform device */ -static struct platform_device *pd; -static struct resource aica_memory_space[2] = { - { - .name = "AICA ARM CONTROL", - .start = ARM_RESET_REGISTER, - .flags = IORESOURCE_MEM, - .end = ARM_RESET_REGISTER + 3, - }, - { - .name = "AICA Sound RAM", - .start = SPU_MEMORY_BASE, - .flags = IORESOURCE_MEM, - .end = SPU_MEMORY_BASE + 0x200000 - 1, - }, -}; - -/* SPU specific functions */ -/* spu_write_wait - wait for G2-SH FIFO to clear */ -static void spu_write_wait(void) -{ - int time_count; - time_count = 0; - while (1) { - if (!(readl(G2_FIFO) & 0x11)) - break; - /* To ensure hardware failure doesn't wedge kernel */ - time_count++; - if (time_count > 0x10000) { - snd_printk - ("WARNING: G2 FIFO appears to be blocked.\n"); - break; - } - } -} - -/* spu_memset - write to memory in SPU address space */ -static void spu_memset(u32 toi, u32 what, int length) -{ - int i; - snd_assert(length % 4 == 0, return); - for (i = 0; i < length; i++) { - if (!(i % 8)) - spu_write_wait(); - writel(what, toi + SPU_MEMORY_BASE); - toi++; - } -} - -/* spu_memload - write to SPU address space */ -static void spu_memload(u32 toi, void *from, int length) -{ - u32 *froml = from; - u32 __iomem *to = (u32 __iomem *) (SPU_MEMORY_BASE + toi); - int i; - u32 val; - length = DIV_ROUND_UP(length, 4); - spu_write_wait(); - for (i = 0; i < length; i++) { - if (!(i % 8)) - spu_write_wait(); - val = *froml; - writel(val, to); - froml++; - to++; - } -} - -/* spu_disable - set spu registers to stop sound output */ -static void spu_disable(void) -{ - int i; - u32 regval; - spu_write_wait(); - regval = readl(ARM_RESET_REGISTER); - regval |= 1; - spu_write_wait(); - writel(regval, ARM_RESET_REGISTER); - for (i = 0; i < 64; i++) { - spu_write_wait(); - regval = readl(SPU_REGISTER_BASE + (i * 0x80)); - regval = (regval & ~0x4000) | 0x8000; - spu_write_wait(); - writel(regval, SPU_REGISTER_BASE + (i * 0x80)); - } -} - -/* spu_enable - set spu registers to enable sound output */ -static void spu_enable(void) -{ - u32 regval = readl(ARM_RESET_REGISTER); - regval &= ~1; - spu_write_wait(); - writel(regval, ARM_RESET_REGISTER); -} - -/* - * Halt the sound processor, clear the memory, - * load some default ARM7 code, and then restart ARM7 -*/ -static void spu_reset(void) -{ - spu_disable(); - spu_memset(0, 0, 0x200000 / 4); - /* Put ARM7 in endless loop */ - ctrl_outl(0xea000002, SPU_MEMORY_BASE); - spu_enable(); -} - -/* aica_chn_start - write to spu to start playback */ -static void aica_chn_start(void) -{ - spu_write_wait(); - writel(AICA_CMD_KICK | AICA_CMD_START, (u32 *) AICA_CONTROL_POINT); -} - -/* aica_chn_halt - write to spu to halt playback */ -static void aica_chn_halt(void) -{ - spu_write_wait(); - writel(AICA_CMD_KICK | AICA_CMD_STOP, (u32 *) AICA_CONTROL_POINT); -} - -/* ALSA code below */ -static struct snd_pcm_hardware snd_pcm_aica_playback_hw = { - .info = (SNDRV_PCM_INFO_NONINTERLEAVED), - .formats = - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_IMA_ADPCM), - .rates = SNDRV_PCM_RATE_8000_48000, - .rate_min = 8000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = AICA_BUFFER_SIZE, - .period_bytes_min = AICA_PERIOD_SIZE, - .period_bytes_max = AICA_PERIOD_SIZE, - .periods_min = AICA_PERIOD_NUMBER, - .periods_max = AICA_PERIOD_NUMBER, -}; - -static int aica_dma_transfer(int channels, int buffer_size, - struct snd_pcm_substream *substream) -{ - int q, err, period_offset; - struct snd_card_aica *dreamcastcard; - struct snd_pcm_runtime *runtime; - err = 0; - dreamcastcard = substream->pcm->private_data; - period_offset = dreamcastcard->clicks; - period_offset %= (AICA_PERIOD_NUMBER / channels); - runtime = substream->runtime; - for (q = 0; q < channels; q++) { - err = dma_xfer(AICA_DMA_CHANNEL, - (unsigned long) (runtime->dma_area + - (AICA_BUFFER_SIZE * q) / - channels + - AICA_PERIOD_SIZE * - period_offset), - AICA_CHANNEL0_OFFSET + q * CHANNEL_OFFSET + - AICA_PERIOD_SIZE * period_offset, - buffer_size / channels, AICA_DMA_MODE); - if (unlikely(err < 0)) - break; - dma_wait_for_completion(AICA_DMA_CHANNEL); - } - return err; -} - -static void startup_aica(struct snd_card_aica *dreamcastcard) -{ - spu_memload(AICA_CHANNEL0_CONTROL_OFFSET, - dreamcastcard->channel, sizeof(struct aica_channel)); - aica_chn_start(); -} - -static void run_spu_dma(struct work_struct *work) -{ - int buffer_size; - struct snd_pcm_runtime *runtime; - struct snd_card_aica *dreamcastcard; - dreamcastcard = - container_of(work, struct snd_card_aica, spu_dma_work); - runtime = dreamcastcard->substream->runtime; - if (unlikely(dreamcastcard->dma_check == 0)) { - buffer_size = - frames_to_bytes(runtime, runtime->buffer_size); - if (runtime->channels > 1) - dreamcastcard->channel->flags |= 0x01; - aica_dma_transfer(runtime->channels, buffer_size, - dreamcastcard->substream); - startup_aica(dreamcastcard); - dreamcastcard->clicks = - buffer_size / (AICA_PERIOD_SIZE * runtime->channels); - return; - } else { - aica_dma_transfer(runtime->channels, - AICA_PERIOD_SIZE * runtime->channels, - dreamcastcard->substream); - snd_pcm_period_elapsed(dreamcastcard->substream); - dreamcastcard->clicks++; - if (unlikely(dreamcastcard->clicks >= AICA_PERIOD_NUMBER)) - dreamcastcard->clicks %= AICA_PERIOD_NUMBER; - mod_timer(&dreamcastcard->timer, jiffies + 1); - } -} - -static void aica_period_elapsed(unsigned long timer_var) -{ - /*timer function - so cannot sleep */ - int play_period; - struct snd_pcm_runtime *runtime; - struct snd_pcm_substream *substream; - struct snd_card_aica *dreamcastcard; - substream = (struct snd_pcm_substream *) timer_var; - runtime = substream->runtime; - dreamcastcard = substream->pcm->private_data; - /* Have we played out an additional period? */ - play_period = - frames_to_bytes(runtime, - readl - (AICA_CONTROL_CHANNEL_SAMPLE_NUMBER)) / - AICA_PERIOD_SIZE; - if (play_period == dreamcastcard->current_period) { - /* reschedule the timer */ - mod_timer(&(dreamcastcard->timer), jiffies + 1); - return; - } - if (runtime->channels > 1) - dreamcastcard->current_period = play_period; - if (unlikely(dreamcastcard->dma_check == 0)) - dreamcastcard->dma_check = 1; - queue_work(aica_queue, &(dreamcastcard->spu_dma_work)); -} - -static void spu_begin_dma(struct snd_pcm_substream *substream) -{ - struct snd_card_aica *dreamcastcard; - struct snd_pcm_runtime *runtime; - runtime = substream->runtime; - dreamcastcard = substream->pcm->private_data; - /*get the queue to do the work */ - queue_work(aica_queue, &(dreamcastcard->spu_dma_work)); - /* Timer may already be running */ - if (unlikely(dreamcastcard->timer.data)) { - mod_timer(&dreamcastcard->timer, jiffies + 4); - return; - } - init_timer(&(dreamcastcard->timer)); - dreamcastcard->timer.data = (unsigned long) substream; - dreamcastcard->timer.function = aica_period_elapsed; - dreamcastcard->timer.expires = jiffies + 4; - add_timer(&(dreamcastcard->timer)); -} - -static int snd_aicapcm_pcm_open(struct snd_pcm_substream - *substream) -{ - struct snd_pcm_runtime *runtime; - struct aica_channel *channel; - struct snd_card_aica *dreamcastcard; - if (!enable) - return -ENOENT; - dreamcastcard = substream->pcm->private_data; - channel = kmalloc(sizeof(struct aica_channel), GFP_KERNEL); - if (!channel) - return -ENOMEM; - /* set defaults for channel */ - channel->sfmt = SM_8BIT; - channel->cmd = AICA_CMD_START; - channel->vol = dreamcastcard->master_volume; - channel->pan = 0x80; - channel->pos = 0; - channel->flags = 0; /* default to mono */ - dreamcastcard->channel = channel; - runtime = substream->runtime; - runtime->hw = snd_pcm_aica_playback_hw; - spu_enable(); - dreamcastcard->clicks = 0; - dreamcastcard->current_period = 0; - dreamcastcard->dma_check = 0; - return 0; -} - -static int snd_aicapcm_pcm_close(struct snd_pcm_substream - *substream) -{ - struct snd_card_aica *dreamcastcard = substream->pcm->private_data; - flush_workqueue(aica_queue); - if (dreamcastcard->timer.data) - del_timer(&dreamcastcard->timer); - kfree(dreamcastcard->channel); - spu_disable(); - return 0; -} - -static int snd_aicapcm_pcm_hw_free(struct snd_pcm_substream - *substream) -{ - /* Free the DMA buffer */ - return snd_pcm_lib_free_pages(substream); -} - -static int snd_aicapcm_pcm_hw_params(struct snd_pcm_substream - *substream, struct snd_pcm_hw_params - *hw_params) -{ - /* Allocate a DMA buffer using ALSA built-ins */ - return - snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); -} - -static int snd_aicapcm_pcm_prepare(struct snd_pcm_substream - *substream) -{ - struct snd_card_aica *dreamcastcard = substream->pcm->private_data; - if ((substream->runtime)->format == SNDRV_PCM_FORMAT_S16_LE) - dreamcastcard->channel->sfmt = SM_16BIT; - dreamcastcard->channel->freq = substream->runtime->rate; - dreamcastcard->substream = substream; - return 0; -} - -static int snd_aicapcm_pcm_trigger(struct snd_pcm_substream - *substream, int cmd) -{ - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - spu_begin_dma(substream); - break; - case SNDRV_PCM_TRIGGER_STOP: - aica_chn_halt(); - break; - default: - return -EINVAL; - } - return 0; -} - -static unsigned long snd_aicapcm_pcm_pointer(struct snd_pcm_substream - *substream) -{ - return readl(AICA_CONTROL_CHANNEL_SAMPLE_NUMBER); -} - -static struct snd_pcm_ops snd_aicapcm_playback_ops = { - .open = snd_aicapcm_pcm_open, - .close = snd_aicapcm_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_aicapcm_pcm_hw_params, - .hw_free = snd_aicapcm_pcm_hw_free, - .prepare = snd_aicapcm_pcm_prepare, - .trigger = snd_aicapcm_pcm_trigger, - .pointer = snd_aicapcm_pcm_pointer, -}; - -/* TO DO: set up to handle more than one pcm instance */ -static int __init snd_aicapcmchip(struct snd_card_aica - *dreamcastcard, int pcm_index) -{ - struct snd_pcm *pcm; - int err; - /* AICA has no capture ability */ - err = - snd_pcm_new(dreamcastcard->card, "AICA PCM", pcm_index, 1, 0, - &pcm); - if (unlikely(err < 0)) - return err; - pcm->private_data = dreamcastcard; - strcpy(pcm->name, "AICA PCM"); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, - &snd_aicapcm_playback_ops); - /* Allocate the DMA buffers */ - err = - snd_pcm_lib_preallocate_pages_for_all(pcm, - SNDRV_DMA_TYPE_CONTINUOUS, - snd_dma_continuous_data - (GFP_KERNEL), - AICA_BUFFER_SIZE, - AICA_BUFFER_SIZE); - return err; -} - -/* Mixer controls */ -static int aica_pcmswitch_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int aica_pcmswitch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = 1; /* TO DO: Fix me */ - return 0; -} - -static int aica_pcmswitch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - if (ucontrol->value.integer.value[0] == 1) - return 0; /* TO DO: Fix me */ - else - aica_chn_halt(); - return 0; -} - -static int aica_pcmvolume_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 0xFF; - return 0; -} - -static int aica_pcmvolume_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_card_aica *dreamcastcard; - dreamcastcard = kcontrol->private_data; - if (unlikely(!dreamcastcard->channel)) - return -ETXTBSY; /* we've not yet been set up */ - ucontrol->value.integer.value[0] = dreamcastcard->channel->vol; - return 0; -} - -static int aica_pcmvolume_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_card_aica *dreamcastcard; - dreamcastcard = kcontrol->private_data; - if (unlikely(!dreamcastcard->channel)) - return -ETXTBSY; - if (unlikely(dreamcastcard->channel->vol == - ucontrol->value.integer.value[0])) - return 0; - dreamcastcard->channel->vol = ucontrol->value.integer.value[0]; - dreamcastcard->master_volume = ucontrol->value.integer.value[0]; - spu_memload(AICA_CHANNEL0_CONTROL_OFFSET, - dreamcastcard->channel, sizeof(struct aica_channel)); - return 1; -} - -static struct snd_kcontrol_new snd_aica_pcmswitch_control __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Switch", - .index = 0, - .info = aica_pcmswitch_info, - .get = aica_pcmswitch_get, - .put = aica_pcmswitch_put -}; - -static struct snd_kcontrol_new snd_aica_pcmvolume_control __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Volume", - .index = 0, - .info = aica_pcmvolume_info, - .get = aica_pcmvolume_get, - .put = aica_pcmvolume_put -}; - -static int load_aica_firmware(void) -{ - int err; - const struct firmware *fw_entry; - spu_reset(); - err = request_firmware(&fw_entry, "aica_firmware.bin", &pd->dev); - if (unlikely(err)) - return err; - /* write firware into memory */ - spu_disable(); - spu_memload(0, fw_entry->data, fw_entry->size); - spu_enable(); - release_firmware(fw_entry); - return err; -} - -static int __devinit add_aicamixer_controls(struct snd_card_aica - *dreamcastcard) -{ - int err; - err = snd_ctl_add - (dreamcastcard->card, - snd_ctl_new1(&snd_aica_pcmvolume_control, dreamcastcard)); - if (unlikely(err < 0)) - return err; - err = snd_ctl_add - (dreamcastcard->card, - snd_ctl_new1(&snd_aica_pcmswitch_control, dreamcastcard)); - if (unlikely(err < 0)) - return err; - return 0; -} - -static int snd_aica_remove(struct platform_device *devptr) -{ - struct snd_card_aica *dreamcastcard; - dreamcastcard = platform_get_drvdata(devptr); - if (unlikely(!dreamcastcard)) - return -ENODEV; - snd_card_free(dreamcastcard->card); - kfree(dreamcastcard); - platform_set_drvdata(devptr, NULL); - return 0; -} - -static int __init snd_aica_probe(struct platform_device *devptr) -{ - int err; - struct snd_card_aica *dreamcastcard; - dreamcastcard = kmalloc(sizeof(struct snd_card_aica), GFP_KERNEL); - if (unlikely(!dreamcastcard)) - return -ENOMEM; - dreamcastcard->card = - snd_card_new(index, SND_AICA_DRIVER, THIS_MODULE, 0); - if (unlikely(!dreamcastcard->card)) { - kfree(dreamcastcard); - return -ENODEV; - } - strcpy(dreamcastcard->card->driver, "snd_aica"); - strcpy(dreamcastcard->card->shortname, SND_AICA_DRIVER); - strcpy(dreamcastcard->card->longname, - "Yamaha AICA Super Intelligent Sound Processor for SEGA Dreamcast"); - /* Prepare to use the queue */ - INIT_WORK(&(dreamcastcard->spu_dma_work), run_spu_dma); - /* Load the PCM 'chip' */ - err = snd_aicapcmchip(dreamcastcard, 0); - if (unlikely(err < 0)) - goto freedreamcast; - snd_card_set_dev(dreamcastcard->card, &devptr->dev); - dreamcastcard->timer.data = 0; - dreamcastcard->channel = NULL; - /* Add basic controls */ - err = add_aicamixer_controls(dreamcastcard); - if (unlikely(err < 0)) - goto freedreamcast; - /* Register the card with ALSA subsystem */ - err = snd_card_register(dreamcastcard->card); - if (unlikely(err < 0)) - goto freedreamcast; - platform_set_drvdata(devptr, dreamcastcard); - aica_queue = create_workqueue(CARD_NAME); - if (unlikely(!aica_queue)) - goto freedreamcast; - snd_printk - ("ALSA Driver for Yamaha AICA Super Intelligent Sound Processor\n"); - return 0; - freedreamcast: - snd_card_free(dreamcastcard->card); - kfree(dreamcastcard); - return err; -} - -static struct platform_driver snd_aica_driver = { - .probe = snd_aica_probe, - .remove = snd_aica_remove, - .driver = { - .name = SND_AICA_DRIVER}, -}; - -static int __init aica_init(void) -{ - int err; - err = platform_driver_register(&snd_aica_driver); - if (unlikely(err < 0)) - return err; - pd = platform_device_register_simple(SND_AICA_DRIVER, -1, - aica_memory_space, 2); - if (unlikely(IS_ERR(pd))) { - platform_driver_unregister(&snd_aica_driver); - return PTR_ERR(pd); - } - /* Load the firmware */ - return load_aica_firmware(); -} - -static void __exit aica_exit(void) -{ - /* Destroy the aica kernel thread * - * being extra cautious to check if it exists*/ - if (likely(aica_queue)) - destroy_workqueue(aica_queue); - platform_device_unregister(pd); - platform_driver_unregister(&snd_aica_driver); - /* Kill any sound still playing and reset ARM7 to safe state */ - spu_reset(); -} - -module_init(aica_init); -module_exit(aica_exit); diff --git a/trunk/sound/sh/aica.h b/trunk/sound/sh/aica.h deleted file mode 100644 index 8c11e3d10a50..000000000000 --- a/trunk/sound/sh/aica.h +++ /dev/null @@ -1,81 +0,0 @@ -/* aica.h - * Header file for ALSA driver for - * Sega Dreamcast Yamaha AICA sound - * Copyright Adrian McMenamin - * - * 2006 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* SPU memory and register constants etc */ -#define G2_FIFO 0xa05f688c -#define SPU_MEMORY_BASE 0xA0800000 -#define ARM_RESET_REGISTER 0xA0702C00 -#define SPU_REGISTER_BASE 0xA0700000 - -/* AICA channels stuff */ -#define AICA_CONTROL_POINT 0xA0810000 -#define AICA_CONTROL_CHANNEL_SAMPLE_NUMBER 0xA0810008 -#define AICA_CHANNEL0_CONTROL_OFFSET 0x10004 - -/* Command values */ -#define AICA_CMD_KICK 0x80000000 -#define AICA_CMD_NONE 0 -#define AICA_CMD_START 1 -#define AICA_CMD_STOP 2 -#define AICA_CMD_VOL 3 - -/* Sound modes */ -#define SM_8BIT 1 -#define SM_16BIT 0 -#define SM_ADPCM 2 - -/* Buffer and period size */ -#define AICA_BUFFER_SIZE 0x8000 -#define AICA_PERIOD_SIZE 0x800 -#define AICA_PERIOD_NUMBER 16 - -#define AICA_CHANNEL0_OFFSET 0x11000 -#define AICA_CHANNEL1_OFFSET 0x21000 -#define CHANNEL_OFFSET 0x10000 - -#define AICA_DMA_CHANNEL 0 -#define AICA_DMA_MODE 5 - -#define SND_AICA_DRIVER "AICA" - -struct aica_channel { - uint32_t cmd; /* Command ID */ - uint32_t pos; /* Sample position */ - uint32_t length; /* Sample length */ - uint32_t freq; /* Frequency */ - uint32_t vol; /* Volume 0-255 */ - uint32_t pan; /* Pan 0-255 */ - uint32_t sfmt; /* Sound format */ - uint32_t flags; /* Bit flags */ -}; - -struct snd_card_aica { - struct work_struct spu_dma_work; - struct snd_card *card; - struct aica_channel *channel; - struct snd_pcm_substream *substream; - int clicks; - int current_period; - struct timer_list timer; - int master_volume; - int dma_check; -}; diff --git a/trunk/sound/soc/Kconfig b/trunk/sound/soc/Kconfig index 97b255233175..10cffc087181 100644 --- a/trunk/sound/soc/Kconfig +++ b/trunk/sound/soc/Kconfig @@ -27,7 +27,6 @@ config SND_SOC source "sound/soc/at91/Kconfig" source "sound/soc/pxa/Kconfig" source "sound/soc/s3c24xx/Kconfig" -source "sound/soc/sh/Kconfig" # Supported codecs source "sound/soc/codecs/Kconfig" diff --git a/trunk/sound/soc/Makefile b/trunk/sound/soc/Makefile index 304140377632..0ae2e49036f9 100644 --- a/trunk/sound/soc/Makefile +++ b/trunk/sound/soc/Makefile @@ -1,4 +1,4 @@ snd-soc-core-objs := soc-core.o soc-dapm.o obj-$(CONFIG_SND_SOC) += snd-soc-core.o -obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ s3c24xx/ sh/ +obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ s3c24xx/ diff --git a/trunk/sound/soc/s3c24xx/Kconfig b/trunk/sound/soc/s3c24xx/Kconfig index e97c68306a9a..044a3712077a 100644 --- a/trunk/sound/soc/s3c24xx/Kconfig +++ b/trunk/sound/soc/s3c24xx/Kconfig @@ -1,7 +1,6 @@ config SND_S3C24XX_SOC tristate "SoC Audio for the Samsung S3C24XX chips" depends on ARCH_S3C2410 && SND_SOC - select SND_PCM help Say Y or M if you want to add support for codecs attached to the S3C24XX AC97, I2S or SSP interface. You will also need @@ -9,29 +8,3 @@ config SND_S3C24XX_SOC config SND_S3C24XX_SOC_I2S tristate - -config SND_S3C2443_SOC_AC97 - tristate - select AC97_BUS - select SND_AC97_CODEC - select SND_SOC_AC97_BUS - -config SND_S3C24XX_SOC_NEO1973_WM8753 - tristate "SoC I2S Audio support for NEO1973 - WM8753" - depends on SND_S3C24XX_SOC && MACH_GTA01 - select SND_S3C24XX_SOC_I2S - select SND_SOC_WM8753 - help - Say Y if you want to add support for SoC audio on smdk2440 - with the WM8753. - -config SND_S3C24XX_SOC_SMDK2443_WM9710 - tristate "SoC AC97 Audio support for SMDK2443 - WM9710" - depends on SND_S3C24XX_SOC && MACH_SMDK2443 - select SND_S3C2443_SOC_AC97 - select SND_SOC_AC97_CODEC - help - Say Y if you want to add support for SoC audio on smdk2443 - with the WM9710. - - diff --git a/trunk/sound/soc/s3c24xx/Makefile b/trunk/sound/soc/s3c24xx/Makefile index 13c92f0fa1e4..6f0fffcb30f5 100644 --- a/trunk/sound/soc/s3c24xx/Makefile +++ b/trunk/sound/soc/s3c24xx/Makefile @@ -1,15 +1,6 @@ # S3c24XX Platform Support snd-soc-s3c24xx-objs := s3c24xx-pcm.o snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o -snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o -obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o - -# S3C24XX Machine Support -snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o -snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o - -obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o -obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o diff --git a/trunk/sound/soc/s3c24xx/lm4857.h b/trunk/sound/soc/s3c24xx/lm4857.h deleted file mode 100644 index 0cf5b7011d6f..000000000000 --- a/trunk/sound/soc/s3c24xx/lm4857.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * lm4857.h -- ALSA Soc Audio Layer - * - * Copyright 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Revision history - * 18th Jun 2007 Initial version. - */ - -#ifndef LM4857_H_ -#define LM4857_H_ - -/* The register offsets in the cache array */ -#define LM4857_MVOL 0 -#define LM4857_LVOL 1 -#define LM4857_RVOL 2 -#define LM4857_CTRL 3 - -/* the shifts required to set these bits */ -#define LM4857_3D 5 -#define LM4857_WAKEUP 5 -#define LM4857_EPGAIN 4 - -#endif /*LM4857_H_*/ - diff --git a/trunk/sound/soc/s3c24xx/neo1973_wm8753.c b/trunk/sound/soc/s3c24xx/neo1973_wm8753.c deleted file mode 100644 index d5a8fc2cf8d6..000000000000 --- a/trunk/sound/soc/s3c24xx/neo1973_wm8753.c +++ /dev/null @@ -1,670 +0,0 @@ -/* - * neo1973_wm8753.c -- SoC audio for Neo1973 - * - * Copyright 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Revision history - * 20th Jan 2007 Initial version. - * 05th Feb 2007 Rename all to Neo1973 - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../codecs/wm8753.h" -#include "lm4857.h" -#include "s3c24xx-pcm.h" -#include "s3c24xx-i2s.h" - -/* define the scenarios */ -#define NEO_AUDIO_OFF 0 -#define NEO_GSM_CALL_AUDIO_HANDSET 1 -#define NEO_GSM_CALL_AUDIO_HEADSET 2 -#define NEO_GSM_CALL_AUDIO_BLUETOOTH 3 -#define NEO_STEREO_TO_SPEAKERS 4 -#define NEO_STEREO_TO_HEADPHONES 5 -#define NEO_CAPTURE_HANDSET 6 -#define NEO_CAPTURE_HEADSET 7 -#define NEO_CAPTURE_BLUETOOTH 8 - -static struct snd_soc_machine neo1973; -static struct i2c_client *i2c; - -static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - unsigned int pll_out = 0, bclk = 0; - int ret = 0; - unsigned long iis_clkrate; - - iis_clkrate = s3c24xx_i2s_get_clockrate(); - - switch (params_rate(params)) { - case 8000: - case 16000: - pll_out = 12288000; - break; - case 48000: - bclk = WM8753_BCLK_DIV_4; - pll_out = 12288000; - break; - case 96000: - bclk = WM8753_BCLK_DIV_2; - pll_out = 12288000; - break; - case 11025: - bclk = WM8753_BCLK_DIV_16; - pll_out = 11289600; - break; - case 22050: - bclk = WM8753_BCLK_DIV_8; - pll_out = 11289600; - break; - case 44100: - bclk = WM8753_BCLK_DIV_4; - pll_out = 11289600; - break; - case 88200: - bclk = WM8753_BCLK_DIV_2; - pll_out = 11289600; - break; - } - - /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, - SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = cpu_dai->dai_ops.set_fmt(cpu_dai, - SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8753_MCLK, pll_out, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set MCLK division for sample rate */ - ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, - S3C2410_IISMOD_32FS ); - if (ret < 0) - return ret; - - /* set codec BCLK division for sample rate */ - ret = codec_dai->dai_ops.set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk); - if (ret < 0) - return ret; - - /* set prescaler division for sample rate */ - ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, - S3C24XX_PRESCALE(4,4)); - if (ret < 0) - return ret; - - /* codec PLL input is PCLK/4 */ - ret = codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1, - iis_clkrate / 4, pll_out); - if (ret < 0) - return ret; - - return 0; -} - -static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; - - /* disable the PLL */ - return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1, 0, 0); -} - -/* - * Neo1973 WM8753 HiFi DAI opserations. - */ -static struct snd_soc_ops neo1973_hifi_ops = { - .hw_params = neo1973_hifi_hw_params, - .hw_free = neo1973_hifi_hw_free, -}; - -static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; - unsigned int pcmdiv = 0; - int ret = 0; - unsigned long iis_clkrate; - - iis_clkrate = s3c24xx_i2s_get_clockrate(); - - if (params_rate(params) != 8000) - return -EINVAL; - if (params_channels(params) != 1) - return -EINVAL; - - pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */ - - /* todo: gg check mode (DSP_B) against CSR datasheet */ - /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8753_PCMCLK, 12288000, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set codec PCM division for sample rate */ - ret = codec_dai->dai_ops.set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv); - if (ret < 0) - return ret; - - /* configue and enable PLL for 12.288MHz output */ - ret = codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2, - iis_clkrate / 4, 12288000); - if (ret < 0) - return ret; - - return 0; -} - -static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; - - /* disable the PLL */ - return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2, 0, 0); -} - -static struct snd_soc_ops neo1973_voice_ops = { - .hw_params = neo1973_voice_hw_params, - .hw_free = neo1973_voice_hw_free, -}; - -static int neo1973_scenario = 0; - -static int neo1973_get_scenario(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = neo1973_scenario; - return 0; -} - -static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario) -{ - switch(neo1973_scenario) { - case NEO_AUDIO_OFF: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - break; - case NEO_GSM_CALL_AUDIO_HANDSET: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 1); - break; - case NEO_GSM_CALL_AUDIO_HEADSET: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 1); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - break; - case NEO_GSM_CALL_AUDIO_BLUETOOTH: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - break; - case NEO_STEREO_TO_SPEAKERS: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - break; - case NEO_STEREO_TO_HEADPHONES: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - break; - case NEO_CAPTURE_HANDSET: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 1); - break; - case NEO_CAPTURE_HEADSET: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 1); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - break; - case NEO_CAPTURE_BLUETOOTH: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - break; - default: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - } - - snd_soc_dapm_sync_endpoints(codec); - - return 0; -} - -static int neo1973_set_scenario(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if (neo1973_scenario == ucontrol->value.integer.value[0]) - return 0; - - neo1973_scenario = ucontrol->value.integer.value[0]; - set_scenario_endpoints(codec, neo1973_scenario); - return 1; -} - -static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0}; - -static void lm4857_write_regs(void) -{ - if (i2c_master_send(i2c, lm4857_regs, 4) != 4) - printk(KERN_ERR "lm4857: i2c write failed\n"); -} - -static int lm4857_get_reg(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int reg=kcontrol->private_value & 0xFF; - int shift = (kcontrol->private_value >> 8) & 0x0F; - int mask = (kcontrol->private_value >> 16) & 0xFF; - - ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask; - return 0; -} - -static int lm4857_set_reg(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int reg = kcontrol->private_value & 0xFF; - int shift = (kcontrol->private_value >> 8) & 0x0F; - int mask = (kcontrol->private_value >> 16) & 0xFF; - - if (((lm4857_regs[reg] >> shift ) & mask) == - ucontrol->value.integer.value[0]) - return 0; - - lm4857_regs[reg] &= ~ (mask << shift); - lm4857_regs[reg] |= ucontrol->value.integer.value[0] << shift; - lm4857_write_regs(); - return 1; -} - -static int lm4857_get_mode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 value = lm4857_regs[LM4857_CTRL] & 0x0F; - - if (value) - value -= 5; - - ucontrol->value.integer.value[0] = value; - return 0; -} - -static int lm4857_set_mode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 value = ucontrol->value.integer.value[0]; - - if (value) - value += 5; - - if ((lm4857_regs[LM4857_CTRL] & 0x0F) == value) - return 0; - - lm4857_regs[LM4857_CTRL] &= 0xF0; - lm4857_regs[LM4857_CTRL] |= value; - lm4857_write_regs(); - return 1; -} - -static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { - SND_SOC_DAPM_LINE("Audio Out", NULL), - SND_SOC_DAPM_LINE("GSM Line Out", NULL), - SND_SOC_DAPM_LINE("GSM Line In", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("Call Mic", NULL), -}; - - -/* example machine audio_mapnections */ -static const char* audio_map[][3] = { - - /* Connections to the lm4857 amp */ - {"Audio Out", NULL, "LOUT1"}, - {"Audio Out", NULL, "ROUT1"}, - - /* Connections to the GSM Module */ - {"GSM Line Out", NULL, "MONO1"}, - {"GSM Line Out", NULL, "MONO2"}, - {"RXP", NULL, "GSM Line In"}, - {"RXN", NULL, "GSM Line In"}, - - /* Connections to Headset */ - {"MIC1", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Headset Mic"}, - - /* Call Mic */ - {"MIC2", NULL, "Mic Bias"}, - {"MIC2N", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Call Mic"}, - - /* Connect the ALC pins */ - {"ACIN", NULL, "ACOP"}, - - {NULL, NULL, NULL}, -}; - -static const char *lm4857_mode[] = { - "Off", - "Call Speaker", - "Stereo Speakers", - "Stereo Speakers + Headphones", - "Headphones" -}; - -static const struct soc_enum lm4857_mode_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode), -}; - -static const char *neo_scenarios[] = { - "Off", - "GSM Handset", - "GSM Headset", - "GSM Bluetooth", - "Speakers", - "Headphones", - "Capture Handset", - "Capture Headset", - "Capture Bluetooth" -}; - -static const struct soc_enum neo_scenario_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(neo_scenarios),neo_scenarios), -}; - -static const struct snd_kcontrol_new wm8753_neo1973_controls[] = { - SOC_SINGLE_EXT("Amp Left Playback Volume", LM4857_LVOL, 0, 31, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_SINGLE_EXT("Amp Right Playback Volume", LM4857_RVOL, 0, 31, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_SINGLE_EXT("Amp Mono Playback Volume", LM4857_MVOL, 0, 31, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_ENUM_EXT("Amp Mode", lm4857_mode_enum[0], - lm4857_get_mode, lm4857_set_mode), - SOC_ENUM_EXT("Neo Mode", neo_scenario_enum[0], - neo1973_get_scenario, neo1973_set_scenario), - SOC_SINGLE_EXT("Amp Spk 3D Playback Switch", LM4857_LVOL, 5, 1, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_SINGLE_EXT("Amp HP 3d Playback Switch", LM4857_RVOL, 5, 1, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_SINGLE_EXT("Amp Fast Wakeup Playback Switch", LM4857_CTRL, 5, 1, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_SINGLE_EXT("Amp Earpiece 6dB Playback Switch", LM4857_CTRL, 4, 1, 0, - lm4857_get_reg, lm4857_set_reg), -}; - -/* - * This is an example machine initialisation for a wm8753 connected to a - * neo1973 II. It is missing logic to detect hp/mic insertions and logic - * to re-route the audio in such an event. - */ -static int neo1973_wm8753_init(struct snd_soc_codec *codec) -{ - int i, err; - - /* set up NC codec pins */ - snd_soc_dapm_set_endpoint(codec, "LOUT2", 0); - snd_soc_dapm_set_endpoint(codec, "ROUT2", 0); - snd_soc_dapm_set_endpoint(codec, "OUT3", 0); - snd_soc_dapm_set_endpoint(codec, "OUT4", 0); - snd_soc_dapm_set_endpoint(codec, "LINE1", 0); - snd_soc_dapm_set_endpoint(codec, "LINE2", 0); - - - /* set endpoints to default mode */ - set_scenario_endpoints(codec, NEO_AUDIO_OFF); - - /* Add neo1973 specific widgets */ - for (i = 0; i < ARRAY_SIZE(wm8753_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &wm8753_dapm_widgets[i]); - - /* add neo1973 specific controls */ - for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) { - err = snd_ctl_add(codec->card, - snd_soc_cnew(&wm8753_neo1973_controls[i], - codec, NULL)); - if (err < 0) - return err; - } - - /* set up neo1973 specific audio path audio_mapnects */ - for (i = 0; audio_map[i][0] != NULL; i++) { - snd_soc_dapm_connect_input(codec, audio_map[i][0], - audio_map[i][1], audio_map[i][2]); - } - - snd_soc_dapm_sync_endpoints(codec); - return 0; -} - -/* - * BT Codec DAI - */ -static struct snd_soc_cpu_dai bt_dai = -{ .name = "Bluetooth", - .id = 0, - .type = SND_SOC_DAI_PCM, - .playback = { - .channels_min = 1, - .channels_max = 1, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 1, - .channels_max = 1, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, -}; - -static struct snd_soc_dai_link neo1973_dai[] = { -{ /* Hifi Playback - for similatious use with voice below */ - .name = "WM8753", - .stream_name = "WM8753 HiFi", - .cpu_dai = &s3c24xx_i2s_dai, - .codec_dai = &wm8753_dai[WM8753_DAI_HIFI], - .init = neo1973_wm8753_init, - .ops = &neo1973_hifi_ops, -}, -{ /* Voice via BT */ - .name = "Bluetooth", - .stream_name = "Voice", - .cpu_dai = &bt_dai, - .codec_dai = &wm8753_dai[WM8753_DAI_VOICE], - .ops = &neo1973_voice_ops, -}, -}; - -static struct snd_soc_machine neo1973 = { - .name = "neo1973", - .dai_link = neo1973_dai, - .num_links = ARRAY_SIZE(neo1973_dai), -}; - -static struct wm8753_setup_data neo1973_wm8753_setup = { - .i2c_address = 0x1a, -}; - -static struct snd_soc_device neo1973_snd_devdata = { - .machine = &neo1973, - .platform = &s3c24xx_soc_platform, - .codec_dev = &soc_codec_dev_wm8753, - .codec_data = &neo1973_wm8753_setup, -}; - -static struct i2c_client client_template; - -static unsigned short normal_i2c[] = { 0x7C, I2C_CLIENT_END }; - -/* Magic definition of all other variables and things */ -I2C_CLIENT_INSMOD; - -static int lm4857_amp_probe(struct i2c_adapter *adap, int addr, int kind) -{ - int ret; - - client_template.adapter = adap; - client_template.addr = addr; - - i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) - return -ENOMEM; - - ret = i2c_attach_client(i2c); - if (ret < 0) { - printk(KERN_ERR "LM4857 failed to attach at addr %x\n", addr); - goto exit_err; - } - - lm4857_write_regs(); - return ret; - -exit_err: - kfree(i2c); - return ret; -} - -static int lm4857_i2c_detach(struct i2c_client *client) -{ - i2c_detach_client(client); - kfree(client); - return 0; -} - -static int lm4857_i2c_attach(struct i2c_adapter *adap) -{ - return i2c_probe(adap, &addr_data, lm4857_amp_probe); -} - -/* corgi i2c codec control layer */ -static struct i2c_driver lm4857_i2c_driver = { - .driver = { - .name = "LM4857 I2C Amp", - .owner = THIS_MODULE, - }, - .id = I2C_DRIVERID_LM4857, - .attach_adapter = lm4857_i2c_attach, - .detach_client = lm4857_i2c_detach, - .command = NULL, -}; - -static struct i2c_client client_template = { - .name = "LM4857", - .driver = &lm4857_i2c_driver, -}; - -static struct platform_device *neo1973_snd_device; - -static int __init neo1973_init(void) -{ - int ret; - - neo1973_snd_device = platform_device_alloc("soc-audio", -1); - if (!neo1973_snd_device) - return -ENOMEM; - - platform_set_drvdata(neo1973_snd_device, &neo1973_snd_devdata); - neo1973_snd_devdata.dev = &neo1973_snd_device->dev; - ret = platform_device_add(neo1973_snd_device); - - if (ret) - platform_device_put(neo1973_snd_device); - - ret = i2c_add_driver(&lm4857_i2c_driver); - if (ret != 0) - printk(KERN_ERR "can't add i2c driver"); - - return ret; -} - -static void __exit neo1973_exit(void) -{ - platform_device_unregister(neo1973_snd_device); -} - -module_init(neo1973_init); -module_exit(neo1973_exit); - -/* Module information */ -MODULE_AUTHOR("Graeme Gregory, graeme.gregory@wolfsonmicro.com, www.wolfsonmicro.com"); -MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/s3c24xx/s3c2443-ac97.c b/trunk/sound/soc/s3c24xx/s3c2443-ac97.c deleted file mode 100644 index 75acf7ef5528..000000000000 --- a/trunk/sound/soc/s3c24xx/s3c2443-ac97.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * s3c2443-ac97.c -- ALSA Soc Audio Layer - * - * (c) 2007 Wolfson Microelectronics PLC. - * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * Copyright (C) 2005, Sean Choi - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Revision history - * 21st Mar 2007 Initial Version - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "s3c24xx-pcm.h" -#include "s3c24xx-ac97.h" - -struct s3c24xx_ac97_info { - void __iomem *regs; - struct clk *ac97_clk; -}; -static struct s3c24xx_ac97_info s3c24xx_ac97; - -DECLARE_COMPLETION(ac97_completion); -static u32 codec_ready; -static DECLARE_MUTEX(ac97_mutex); - -static unsigned short s3c2443_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - u32 ac_glbctrl; - u32 ac_codec_cmd; - u32 stat, addr, data; - - down(&ac97_mutex); - - codec_ready = S3C_AC97_GLBSTAT_CODECREADY; - ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg); - writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - - udelay(50); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - wait_for_completion(&ac97_completion); - - stat = readl(s3c24xx_ac97.regs + S3C_AC97_STAT); - addr = (stat >> 16) & 0x7f; - data = (stat & 0xffff); - - if (addr != reg) - printk(KERN_ERR "s3c24xx-ac97: req addr = %02x," - " rep addr = %02x\n", reg, addr); - - up(&ac97_mutex); - - return (unsigned short)data; -} - -static void s3c2443_ac97_write(struct snd_ac97 *ac97, unsigned short reg, - unsigned short val) -{ - u32 ac_glbctrl; - u32 ac_codec_cmd; - - down(&ac97_mutex); - - codec_ready = S3C_AC97_GLBSTAT_CODECREADY; - ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val); - writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - - udelay(50); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - wait_for_completion(&ac97_completion); - - ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; - writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - - up(&ac97_mutex); - -} - -static void s3c2443_ac97_warm_reset(struct snd_ac97 *ac97) -{ - u32 ac_glbctrl; - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_WARMRESET; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = 0; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); -} - -static void s3c2443_ac97_cold_reset(struct snd_ac97 *ac97) -{ - u32 ac_glbctrl; - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = 0; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA | - S3C_AC97_GLBCTRL_PCMINTM_DMA | S3C_AC97_GLBCTRL_MICINTM_DMA; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); -} - -static irqreturn_t s3c2443_ac97_irq(int irq, void *dev_id) -{ - int status; - u32 ac_glbctrl; - - status = readl(s3c24xx_ac97.regs + S3C_AC97_GLBSTAT) & codec_ready; - - if (status) { - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - complete(&ac97_completion); - } - return IRQ_HANDLED; -} - -struct snd_ac97_bus_ops soc_ac97_ops = { - .read = s3c2443_ac97_read, - .write = s3c2443_ac97_write, - .warm_reset = s3c2443_ac97_warm_reset, - .reset = s3c2443_ac97_cold_reset, -}; - -static struct s3c2410_dma_client s3c2443_dma_client_out = { - .name = "AC97 PCM Stereo out" -}; - -static struct s3c2410_dma_client s3c2443_dma_client_in = { - .name = "AC97 PCM Stereo in" -}; - -static struct s3c2410_dma_client s3c2443_dma_client_micin = { - .name = "AC97 Mic Mono in" -}; - -static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_out = { - .client = &s3c2443_dma_client_out, - .channel = DMACH_PCM_OUT, - .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, - .dma_size = 4, -}; - -static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_in = { - .client = &s3c2443_dma_client_in, - .channel = DMACH_PCM_IN, - .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, - .dma_size = 4, -}; - -static struct s3c24xx_pcm_dma_params s3c2443_ac97_mic_mono_in = { - .client = &s3c2443_dma_client_micin, - .channel = DMACH_MIC_IN, - .dma_addr = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA, - .dma_size = 4, -}; - -static int s3c2443_ac97_probe(struct platform_device *pdev) -{ - int ret; - u32 ac_glbctrl; - - s3c24xx_ac97.regs = ioremap(S3C2440_PA_AC97, 0x100); - if (s3c24xx_ac97.regs == NULL) - return -ENXIO; - - s3c24xx_ac97.ac97_clk = clk_get(&pdev->dev, "ac97"); - if (s3c24xx_ac97.ac97_clk == NULL) { - printk(KERN_ERR "s3c2443-ac97 failed to get ac97_clock\n"); - iounmap(s3c24xx_ac97.regs); - return -ENODEV; - } - clk_enable(s3c24xx_ac97.ac97_clk); - - s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2443_GPE0_AC_nRESET); - s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2443_GPE1_AC_SYNC); - s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2443_GPE2_AC_BITCLK); - s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2443_GPE3_AC_SDI); - s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2443_GPE4_AC_SDO); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = 0; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - ret = request_irq(IRQ_S3C2443_AC97, s3c2443_ac97_irq, - IRQF_DISABLED, "AC97", NULL); - if (ret < 0) { - printk(KERN_ERR "s3c24xx-ac97: interrupt request failed.\n"); - clk_disable(s3c24xx_ac97.ac97_clk); - clk_put(s3c24xx_ac97.ac97_clk); - iounmap(s3c24xx_ac97.regs); - } - return ret; -} - -static void s3c2443_ac97_remove(struct platform_device *pdev) -{ - free_irq(IRQ_S3C2443_AC97, NULL); - clk_disable(s3c24xx_ac97.ac97_clk); - clk_put(s3c24xx_ac97.ac97_clk); - iounmap(s3c24xx_ac97.regs); -} - -static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_out; - else - cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_in; - - return 0; -} - -static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd) -{ - u32 ac_glbctrl; - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - switch(cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA; - else - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA; - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK; - else - ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK; - break; - } - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - return 0; -} - -static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - return -ENODEV; - else - cpu_dai->dma_data = &s3c2443_ac97_mic_mono_in; - - return 0; -} - -static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - u32 ac_glbctrl; - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - switch(cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA; - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK; - } - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - return 0; -} - -#define s3c2443_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ - SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) - -struct snd_soc_cpu_dai s3c2443_ac97_dai[] = { -{ - .name = "s3c2443-ac97", - .id = 0, - .type = SND_SOC_DAI_AC97, - .probe = s3c2443_ac97_probe, - .remove = s3c2443_ac97_remove, - .playback = { - .stream_name = "AC97 Playback", - .channels_min = 2, - .channels_max = 2, - .rates = s3c2443_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .stream_name = "AC97 Capture", - .channels_min = 2, - .channels_max = 2, - .rates = s3c2443_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = { - .hw_params = s3c2443_ac97_hw_params, - .trigger = s3c2443_ac97_trigger}, -}, -{ - .name = "pxa2xx-ac97-mic", - .id = 1, - .type = SND_SOC_DAI_AC97, - .capture = { - .stream_name = "AC97 Mic Capture", - .channels_min = 1, - .channels_max = 1, - .rates = s3c2443_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = { - .hw_params = s3c2443_ac97_hw_mic_params, - .trigger = s3c2443_ac97_mic_trigger,}, -}, -}; - -EXPORT_SYMBOL_GPL(s3c2443_ac97_dai); -EXPORT_SYMBOL_GPL(soc_ac97_ops); - -MODULE_AUTHOR("Graeme Gregory"); -MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/s3c24xx/s3c24xx-ac97.h b/trunk/sound/soc/s3c24xx/s3c24xx-ac97.h deleted file mode 100644 index 2b835e8260fa..000000000000 --- a/trunk/sound/soc/s3c24xx/s3c24xx-ac97.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * s3c24xx-ac97.c -- ALSA Soc Audio Layer - * - * (c) 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Revision history - * 10th Nov 2006 Initial version. - */ - -#ifndef S3C24XXAC97_H_ -#define S3C24XXAC97_H_ - -#define AC_CMD_ADDR(x) (x << 16) -#define AC_CMD_DATA(x) (x & 0xffff) - -extern struct snd_soc_cpu_dai s3c2443_ac97_dai[]; - -#endif /*S3C24XXAC97_H_*/ diff --git a/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c b/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c index 39f02462e07d..8ca314dc8891 100644 --- a/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -344,11 +344,11 @@ static int s3c24xx_i2s_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai, DBG("Entered %s\n", __FUNCTION__); switch (div_id) { - case S3C24XX_DIV_BCLK: + case S3C24XX_DIV_MCLK: reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~S3C2410_IISMOD_FS_MASK; writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); break; - case S3C24XX_DIV_MCLK: + case S3C24XX_DIV_BCLK: reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS); writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); break; diff --git a/trunk/sound/soc/s3c24xx/smdk2443_wm9710.c b/trunk/sound/soc/s3c24xx/smdk2443_wm9710.c deleted file mode 100644 index d46cd811ceb3..000000000000 --- a/trunk/sound/soc/s3c24xx/smdk2443_wm9710.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * smdk2443_wm9710.c -- SoC audio for smdk2443 - * - * Copyright 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Revision history - * 8th Mar 2007 Initial version. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "../codecs/ac97.h" -#include "s3c24xx-pcm.h" -#include "s3c24xx-ac97.h" - -static struct snd_soc_machine smdk2443; - -static struct snd_soc_dai_link smdk2443_dai[] = { -{ - .name = "AC97", - .stream_name = "AC97 HiFi", - .cpu_dai = &s3c2443_ac97_dai[0], - .codec_dai = &ac97_dai, -}, -}; - -static struct snd_soc_machine smdk2443 = { - .name = "SMDK2443", - .dai_link = smdk2443_dai, - .num_links = ARRAY_SIZE(smdk2443_dai), -}; - -static struct snd_soc_device smdk2443_snd_ac97_devdata = { - .machine = &smdk2443, - .platform = &s3c24xx_soc_platform, - .codec_dev = &soc_codec_dev_ac97, -}; - -static struct platform_device *smdk2443_snd_ac97_device; - -static int __init smdk2443_init(void) -{ - int ret; - - smdk2443_snd_ac97_device = platform_device_alloc("soc-audio", -1); - if (!smdk2443_snd_ac97_device) - return -ENOMEM; - - platform_set_drvdata(smdk2443_snd_ac97_device, - &smdk2443_snd_ac97_devdata); - smdk2443_snd_ac97_devdata.dev = &smdk2443_snd_ac97_device->dev; - ret = platform_device_add(smdk2443_snd_ac97_device); - - if (ret) - platform_device_put(smdk2443_snd_ac97_device); - - return ret; -} - -static void __exit smdk2443_exit(void) -{ - platform_device_unregister(smdk2443_snd_ac97_device); -} - -module_init(smdk2443_init); -module_exit(smdk2443_exit); - -/* Module information */ -MODULE_AUTHOR("Graeme Gregory, graeme.gregory@wolfsonmicro.com, www.wolfsonmicro.com"); -MODULE_DESCRIPTION("ALSA SoC WM9710 SMDK2443"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/sh/Kconfig b/trunk/sound/soc/sh/Kconfig deleted file mode 100644 index f03220d23e73..000000000000 --- a/trunk/sound/soc/sh/Kconfig +++ /dev/null @@ -1,38 +0,0 @@ -menu "SoC Audio support for SuperH" - -config SND_SOC_PCM_SH7760 - tristate "SoC Audio support for Renesas SH7760" - depends on CPU_SUBTYPE_SH7760 && SND_SOC && SH_DMABRG - help - Enable this option for SH7760 AC97/I2S audio support. - - -## -## Audio unit modules -## - -config SND_SOC_SH4_HAC - select AC97_BUS - select SND_SOC_AC97_BUS - select SND_AC97_CODEC - tristate - -config SND_SOC_SH4_SSI - tristate - - - -## -## Boards -## - -config SND_SH7760_AC97 - tristate "SH7760 AC97 sound support" - depends on CPU_SUBTYPE_SH7760 && SND_SOC_PCM_SH7760 - select SND_SOC_SH4_HAC - select SND_SOC_AC97_CODEC - help - This option enables generic sound support for the first - AC97 unit of the SH7760. - -endmenu diff --git a/trunk/sound/soc/sh/Makefile b/trunk/sound/soc/sh/Makefile deleted file mode 100644 index a8e8ab81cc6a..000000000000 --- a/trunk/sound/soc/sh/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -## DMA engines -snd-soc-dma-sh7760-objs := dma-sh7760.o -obj-$(CONFIG_SND_SOC_PCM_SH7760) += snd-soc-dma-sh7760.o - -## audio units found on some SH-4 -snd-soc-hac-objs := hac.o -snd-soc-ssi-objs := ssi.o -obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o -obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o - -## boards -snd-soc-sh7760-ac97-objs := sh7760-ac97.o - -obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o diff --git a/trunk/sound/soc/sh/dma-sh7760.c b/trunk/sound/soc/sh/dma-sh7760.c deleted file mode 100644 index cdee374b843e..000000000000 --- a/trunk/sound/soc/sh/dma-sh7760.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * SH7760 ("camelot") DMABRG audio DMA unit support - * - * Copyright (C) 2007 Manuel Lauss - * licensed under the terms outlined in the file COPYING at the root - * of the linux kernel sources. - * - * The SH7760 DMABRG provides 4 dma channels (2x rec, 2x play), which - * trigger an interrupt when one half of the programmed transfer size - * has been xmitted. - * - * FIXME: little-endian only for now - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* registers and bits */ -#define BRGATXSAR 0x00 -#define BRGARXDAR 0x04 -#define BRGATXTCR 0x08 -#define BRGARXTCR 0x0C -#define BRGACR 0x10 -#define BRGATXTCNT 0x14 -#define BRGARXTCNT 0x18 - -#define ACR_RAR (1 << 18) -#define ACR_RDS (1 << 17) -#define ACR_RDE (1 << 16) -#define ACR_TAR (1 << 2) -#define ACR_TDS (1 << 1) -#define ACR_TDE (1 << 0) - -/* receiver/transmitter data alignment */ -#define ACR_RAM_NONE (0 << 24) -#define ACR_RAM_4BYTE (1 << 24) -#define ACR_RAM_2WORD (2 << 24) -#define ACR_TAM_NONE (0 << 8) -#define ACR_TAM_4BYTE (1 << 8) -#define ACR_TAM_2WORD (2 << 8) - - -struct camelot_pcm { - unsigned long mmio; /* DMABRG audio channel control reg MMIO */ - unsigned int txid; /* ID of first DMABRG IRQ for this unit */ - - struct snd_pcm_substream *tx_ss; - unsigned long tx_period_size; - unsigned int tx_period; - - struct snd_pcm_substream *rx_ss; - unsigned long rx_period_size; - unsigned int rx_period; - -} cam_pcm_data[2] = { - { - .mmio = 0xFE3C0040, - .txid = DMABRGIRQ_A0TXF, - }, - { - .mmio = 0xFE3C0060, - .txid = DMABRGIRQ_A1TXF, - }, -}; - -#define BRGREG(x) (*(unsigned long *)(cam->mmio + (x))) - -/* - * set a minimum of 16kb per period, to avoid interrupt-"storm" and - * resulting skipping. In general, the bigger the minimum size, the - * better for overall system performance. (The SH7760 is a puny CPU - * with a slow SDRAM interface and poor internal bus bandwidth, - * *especially* when the LCDC is active). The minimum for the DMAC - * is 8 bytes; 16kbytes are enough to get skip-free playback of a - * 44kHz/16bit/stereo MP3 on a lightly loaded system, and maintain - * reasonable responsiveness in MPlayer. - */ -#define DMABRG_PERIOD_MIN 16 * 1024 -#define DMABRG_PERIOD_MAX 0x03fffffc -#define DMABRG_PREALLOC_BUFFER 32 * 1024 -#define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024 - -/* support everything the SSI supports */ -#define DMABRG_RATES \ - SNDRV_PCM_RATE_8000_192000 - -#define DMABRG_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \ - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \ - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) - -static struct snd_pcm_hardware camelot_pcm_hardware = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = DMABRG_FMTS, - .rates = DMABRG_RATES, - .rate_min = 8000, - .rate_max = 192000, - .channels_min = 2, - .channels_max = 8, /* max of the SSI */ - .buffer_bytes_max = DMABRG_PERIOD_MAX, - .period_bytes_min = DMABRG_PERIOD_MIN, - .period_bytes_max = DMABRG_PERIOD_MAX / 2, - .periods_min = 2, - .periods_max = 2, - .fifo_size = 128, -}; - -static void camelot_txdma(void *data) -{ - struct camelot_pcm *cam = data; - cam->tx_period ^= 1; - snd_pcm_period_elapsed(cam->tx_ss); -} - -static void camelot_rxdma(void *data) -{ - struct camelot_pcm *cam = data; - cam->rx_period ^= 1; - snd_pcm_period_elapsed(cam->rx_ss); -} - -static int camelot_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - int ret, dmairq; - - snd_soc_set_runtime_hwparams(substream, &camelot_pcm_hardware); - - /* DMABRG buffer half/full events */ - dmairq = (recv) ? cam->txid + 2 : cam->txid; - if (recv) { - cam->rx_ss = substream; - ret = dmabrg_request_irq(dmairq, camelot_rxdma, cam); - if (unlikely(ret)) { - pr_debug("audio unit %d irqs already taken!\n", - rtd->dai->cpu_dai->id); - return -EBUSY; - } - (void)dmabrg_request_irq(dmairq + 1,camelot_rxdma, cam); - } else { - cam->tx_ss = substream; - ret = dmabrg_request_irq(dmairq, camelot_txdma, cam); - if (unlikely(ret)) { - pr_debug("audio unit %d irqs already taken!\n", - rtd->dai->cpu_dai->id); - return -EBUSY; - } - (void)dmabrg_request_irq(dmairq + 1, camelot_txdma, cam); - } - return 0; -} - -static int camelot_pcm_close(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - int dmairq; - - dmairq = (recv) ? cam->txid + 2 : cam->txid; - - if (recv) - cam->rx_ss = NULL; - else - cam->tx_ss = NULL; - - dmabrg_free_irq(dmairq + 1); - dmabrg_free_irq(dmairq); - - return 0; -} - -static int camelot_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - int ret; - - ret = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); - if (ret < 0) - return ret; - - if (recv) { - cam->rx_period_size = params_period_bytes(hw_params); - cam->rx_period = 0; - } else { - cam->tx_period_size = params_period_bytes(hw_params); - cam->tx_period = 0; - } - return 0; -} - -static int camelot_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_pages(substream); -} - -static int camelot_prepare(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; - - pr_debug("PCM data: addr 0x%08ulx len %d\n", - (u32)runtime->dma_addr, runtime->dma_bytes); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - BRGREG(BRGATXSAR) = (unsigned long)runtime->dma_area; - BRGREG(BRGATXTCR) = runtime->dma_bytes; - } else { - BRGREG(BRGARXDAR) = (unsigned long)runtime->dma_area; - BRGREG(BRGARXTCR) = runtime->dma_bytes; - } - - return 0; -} - -static inline void dmabrg_play_dma_start(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* start DMABRG engine: XFER start, auto-addr-reload */ - BRGREG(BRGACR) = acr | ACR_TDE | ACR_TAR | ACR_TAM_2WORD; -} - -static inline void dmabrg_play_dma_stop(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* forcibly terminate data transmission */ - BRGREG(BRGACR) = acr | ACR_TDS; -} - -static inline void dmabrg_rec_dma_start(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* start DMABRG engine: recv start, auto-reload */ - BRGREG(BRGACR) = acr | ACR_RDE | ACR_RAR | ACR_RAM_2WORD; -} - -static inline void dmabrg_rec_dma_stop(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* forcibly terminate data receiver */ - BRGREG(BRGACR) = acr | ACR_RDS; -} - -static int camelot_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - if (recv) - dmabrg_rec_dma_start(cam); - else - dmabrg_play_dma_start(cam); - break; - case SNDRV_PCM_TRIGGER_STOP: - if (recv) - dmabrg_rec_dma_stop(cam); - else - dmabrg_play_dma_stop(cam); - break; - default: - return -EINVAL; - } - - return 0; -} - -static snd_pcm_uframes_t camelot_pos(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - unsigned long pos; - - /* cannot use the DMABRG pointer register: under load, by the - * time ALSA comes around to read the register, it is already - * far ahead (or worse, already done with the fragment) of the - * position at the time the IRQ was triggered, which results in - * fast-playback sound in my test application (ScummVM) - */ - if (recv) - pos = cam->rx_period ? cam->rx_period_size : 0; - else - pos = cam->tx_period ? cam->tx_period_size : 0; - - return bytes_to_frames(runtime, pos); -} - -static struct snd_pcm_ops camelot_pcm_ops = { - .open = camelot_pcm_open, - .close = camelot_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = camelot_hw_params, - .hw_free = camelot_hw_free, - .prepare = camelot_prepare, - .trigger = camelot_trigger, - .pointer = camelot_pos, -}; - -static void camelot_pcm_free(struct snd_pcm *pcm) -{ - snd_pcm_lib_preallocate_free_for_all(pcm); -} - -static int camelot_pcm_new(struct snd_card *card, - struct snd_soc_codec_dai *dai, - struct snd_pcm *pcm) -{ - /* dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel - * in MMAP mode (i.e. aplay -M) - */ - snd_pcm_lib_preallocate_pages_for_all(pcm, - SNDRV_DMA_TYPE_CONTINUOUS, - snd_dma_continuous_data(GFP_KERNEL), - DMABRG_PREALLOC_BUFFER, DMABRG_PREALLOC_BUFFER_MAX); - - return 0; -} - -struct snd_soc_platform sh7760_soc_platform = { - .name = "sh7760-pcm", - .pcm_ops = &camelot_pcm_ops, - .pcm_new = camelot_pcm_new, - .pcm_free = camelot_pcm_free, -}; -EXPORT_SYMBOL_GPL(sh7760_soc_platform); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver"); -MODULE_AUTHOR("Manuel Lauss "); diff --git a/trunk/sound/soc/sh/hac.c b/trunk/sound/soc/sh/hac.c deleted file mode 100644 index 8e3f03908cdb..000000000000 --- a/trunk/sound/soc/sh/hac.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Hitachi Audio Controller (AC97) support for SH7760/SH7780 - * - * Copyright (c) 2007 Manuel Lauss - * licensed under the terms outlined in the file COPYING at the root - * of the linux kernel sources. - * - * dont forget to set IPSEL/OMSEL register bits (in your board code) to - * enable HAC output pins! - */ - -/* BIG FAT FIXME: although the SH7760 has 2 independent AC97 units, only - * the FIRST can be used since ASoC does not pass any information to the - * ac97_read/write() functions regarding WHICH unit to use. You'll have - * to edit the code a bit to use the other AC97 unit. --mlau - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* regs and bits */ -#define HACCR 0x08 -#define HACCSAR 0x20 -#define HACCSDR 0x24 -#define HACPCML 0x28 -#define HACPCMR 0x2C -#define HACTIER 0x50 -#define HACTSR 0x54 -#define HACRIER 0x58 -#define HACRSR 0x5C -#define HACACR 0x60 - -#define CR_CR (1 << 15) /* "codec-ready" indicator */ -#define CR_CDRT (1 << 11) /* cold reset */ -#define CR_WMRT (1 << 10) /* warm reset */ -#define CR_B9 (1 << 9) /* the mysterious "bit 9" */ -#define CR_ST (1 << 5) /* AC97 link start bit */ - -#define CSAR_RD (1 << 19) /* AC97 data read bit */ -#define CSAR_WR (0) - -#define TSR_CMDAMT (1 << 31) -#define TSR_CMDDMT (1 << 30) - -#define RSR_STARY (1 << 22) -#define RSR_STDRY (1 << 21) - -#define ACR_DMARX16 (1 << 30) -#define ACR_DMATX16 (1 << 29) -#define ACR_TX12ATOM (1 << 26) -#define ACR_DMARX20 ((1 << 24) | (1 << 22)) -#define ACR_DMATX20 ((1 << 23) | (1 << 21)) - -#define CSDR_SHIFT 4 -#define CSDR_MASK (0xffff << CSDR_SHIFT) -#define CSAR_SHIFT 12 -#define CSAR_MASK (0x7f << CSAR_SHIFT) - -#define AC97_WRITE_RETRY 1 -#define AC97_READ_RETRY 5 - -/* manual-suggested AC97 codec access timeouts (us) */ -#define TMO_E1 500 /* 21 < E1 < 1000 */ -#define TMO_E2 13 /* 13 < E2 */ -#define TMO_E3 21 /* 21 < E3 */ -#define TMO_E4 500 /* 21 < E4 < 1000 */ - -struct hac_priv { - unsigned long mmio; /* HAC base address */ -} hac_cpu_data[] = { -#if defined(CONFIG_CPU_SUBTYPE_SH7760) - { - .mmio = 0xFE240000, - }, - { - .mmio = 0xFE250000, - }, -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) - { - .mmio = 0xFFE40000, - }, -#else -#error "Unsupported SuperH SoC" -#endif -}; - -#define HACREG(reg) (*(unsigned long *)(hac->mmio + (reg))) - -/* - * AC97 read/write flow as outlined in the SH7760 manual (pages 903-906) - */ -static int hac_get_codec_data(struct hac_priv *hac, unsigned short r, - unsigned short *v) -{ - unsigned int to1, to2, i; - unsigned short adr; - - for (i = 0; i < AC97_READ_RETRY; ++i) { - *v = 0; - /* wait for HAC to receive something from the codec */ - for (to1 = TMO_E4; - to1 && !(HACREG(HACRSR) & RSR_STARY); - --to1) - udelay(1); - for (to2 = TMO_E4; - to2 && !(HACREG(HACRSR) & RSR_STDRY); - --to2) - udelay(1); - - if (!to1 && !to2) - return 0; /* codec comm is down */ - - adr = ((HACREG(HACCSAR) & CSAR_MASK) >> CSAR_SHIFT); - *v = ((HACREG(HACCSDR) & CSDR_MASK) >> CSDR_SHIFT); - - HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY); - - if (r == adr) - break; - - /* manual says: wait at least 21 usec before retrying */ - udelay(21); - } - HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY); - return (i < AC97_READ_RETRY); -} - -static unsigned short hac_read_codec_aux(struct hac_priv *hac, - unsigned short reg) -{ - unsigned short val; - unsigned int i, to; - - for (i = 0; i < AC97_READ_RETRY; i++) { - /* send_read_request */ - local_irq_disable(); - HACREG(HACTSR) &= ~(TSR_CMDAMT); - HACREG(HACCSAR) = (reg << CSAR_SHIFT) | CSAR_RD; - local_irq_enable(); - - for (to = TMO_E3; - to && !(HACREG(HACTSR) & TSR_CMDAMT); - --to) - udelay(1); - - HACREG(HACTSR) &= ~TSR_CMDAMT; - val = 0; - if (hac_get_codec_data(hac, reg, &val) != 0) - break; - } - - if (i == AC97_READ_RETRY) - return ~0; - - return val; -} - -static void hac_ac97_write(struct snd_ac97 *ac97, unsigned short reg, - unsigned short val) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac = &hac_cpu_data[unit_id]; - unsigned int i, to; - /* write_codec_aux */ - for (i = 0; i < AC97_WRITE_RETRY; i++) { - /* send_write_request */ - local_irq_disable(); - HACREG(HACTSR) &= ~(TSR_CMDDMT | TSR_CMDAMT); - HACREG(HACCSDR) = (val << CSDR_SHIFT); - HACREG(HACCSAR) = (reg << CSAR_SHIFT) & (~CSAR_RD); - local_irq_enable(); - - /* poll-wait for CMDAMT and CMDDMT */ - for (to = TMO_E1; - to && !(HACREG(HACTSR) & (TSR_CMDAMT|TSR_CMDDMT)); - --to) - udelay(1); - - HACREG(HACTSR) &= ~(TSR_CMDAMT | TSR_CMDDMT); - if (to) - break; - /* timeout, try again */ - } -} - -static unsigned short hac_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac = &hac_cpu_data[unit_id]; - return hac_read_codec_aux(hac, reg); -} - -static void hac_ac97_warmrst(struct snd_ac97 *ac97) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac = &hac_cpu_data[unit_id]; - unsigned int tmo; - - HACREG(HACCR) = CR_WMRT | CR_ST | CR_B9; - msleep(10); - HACREG(HACCR) = CR_ST | CR_B9; - for (tmo = 1000; (tmo > 0) && !(HACREG(HACCR) & CR_CR); tmo--) - udelay(1); - - if (!tmo) - printk(KERN_INFO "hac: reset: AC97 link down!\n"); - /* settings this bit lets us have a conversation with codec */ - HACREG(HACACR) |= ACR_TX12ATOM; -} - -static void hac_ac97_coldrst(struct snd_ac97 *ac97) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac; - hac = &hac_cpu_data[unit_id]; - - HACREG(HACCR) = 0; - HACREG(HACCR) = CR_CDRT | CR_ST | CR_B9; - msleep(10); - hac_ac97_warmrst(ac97); -} - -struct snd_ac97_bus_ops soc_ac97_ops = { - .read = hac_ac97_read, - .write = hac_ac97_write, - .reset = hac_ac97_coldrst, - .warm_reset = hac_ac97_warmrst, -}; -EXPORT_SYMBOL_GPL(soc_ac97_ops); - -static int hac_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct hac_priv *hac = &hac_cpu_data[rtd->dai->cpu_dai->id]; - int d = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; - - switch (params->msbits) { - case 16: - HACREG(HACACR) |= d ? ACR_DMARX16 : ACR_DMATX16; - HACREG(HACACR) &= d ? ~ACR_DMARX20 : ~ACR_DMATX20; - break; - case 20: - HACREG(HACACR) &= d ? ~ACR_DMARX16 : ~ACR_DMATX16; - HACREG(HACACR) |= d ? ACR_DMARX20 : ACR_DMATX20; - break; - default: - pr_debug("hac: invalid depth %d bit\n", params->msbits); - return -EINVAL; - break; - } - - return 0; -} - -#define AC97_RATES \ - SNDRV_PCM_RATE_8000_192000 - -#define AC97_FMTS \ - SNDRV_PCM_FMTBIT_S16_LE - -struct snd_soc_cpu_dai sh4_hac_dai[] = { -{ - .name = "HAC0", - .id = 0, - .type = SND_SOC_DAI_AC97, - .playback = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .capture = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .ops = { - .hw_params = hac_hw_params, - }, -}, -#ifdef CONFIG_CPU_SUBTYPE_SH7760 -{ - .name = "HAC1", - .id = 1, - .type = SND_SOC_DAI_AC97, - .playback = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .capture = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .ops = { - .hw_params = hac_hw_params, - }, - -}, -#endif -}; -EXPORT_SYMBOL_GPL(sh4_hac_dai); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver"); -MODULE_AUTHOR("Manuel Lauss "); diff --git a/trunk/sound/soc/sh/sh7760-ac97.c b/trunk/sound/soc/sh/sh7760-ac97.c deleted file mode 100644 index 5563f14511fa..000000000000 --- a/trunk/sound/soc/sh/sh7760-ac97.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Generic AC97 sound support for SH7760 - * - * (c) 2007 Manuel Lauss - * - * Licensed under the GPLv2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../codecs/ac97.h" - -#define IPSEL 0xFE400034 - -/* platform specific structs can be declared here */ -extern struct snd_soc_cpu_dai sh4_hac_dai[2]; -extern struct snd_soc_platform sh7760_soc_platform; - -static int machine_init(struct snd_soc_codec *codec) -{ - snd_soc_dapm_sync_endpoints(codec); - return 0; -} - -static struct snd_soc_dai_link sh7760_ac97_dai = { - .name = "AC97", - .stream_name = "AC97 HiFi", - .cpu_dai = &sh4_hac_dai[0], /* HAC0 */ - .codec_dai = &ac97_dai, - .init = machine_init, - .ops = NULL, -}; - -static struct snd_soc_machine sh7760_ac97_soc_machine = { - .name = "SH7760 AC97", - .dai_link = &sh7760_ac97_dai, - .num_links = 1, -}; - -static struct snd_soc_device sh7760_ac97_snd_devdata = { - .machine = &sh7760_ac97_soc_machine, - .platform = &sh7760_soc_platform, - .codec_dev = &soc_codec_dev_ac97, -}; - -static struct platform_device *sh7760_ac97_snd_device; - -static int __init sh7760_ac97_init(void) -{ - int ret; - unsigned short ipsel; - - /* enable both AC97 controllers in pinmux reg */ - ipsel = ctrl_inw(IPSEL); - ctrl_outw(ipsel | (3 << 10), IPSEL); - - ret = -ENOMEM; - sh7760_ac97_snd_device = platform_device_alloc("soc-audio", -1); - if (!sh7760_ac97_snd_device) - goto out; - - platform_set_drvdata(sh7760_ac97_snd_device, - &sh7760_ac97_snd_devdata); - sh7760_ac97_snd_devdata.dev = &sh7760_ac97_snd_device->dev; - ret = platform_device_add(sh7760_ac97_snd_device); - - if (ret) - platform_device_put(sh7760_ac97_snd_device); - -out: - return ret; -} - -static void __exit sh7760_ac97_exit(void) -{ - platform_device_unregister(sh7760_ac97_snd_device); -} - -module_init(sh7760_ac97_init); -module_exit(sh7760_ac97_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Generic SH7760 AC97 sound machine"); -MODULE_AUTHOR("Manuel Lauss "); diff --git a/trunk/sound/soc/sh/ssi.c b/trunk/sound/soc/sh/ssi.c deleted file mode 100644 index b72bc316cb8e..000000000000 --- a/trunk/sound/soc/sh/ssi.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Serial Sound Interface (I2S) support for SH7760/SH7780 - * - * Copyright (c) 2007 Manuel Lauss - * - * licensed under the terms outlined in the file COPYING at the root - * of the linux kernel sources. - * - * dont forget to set IPSEL/OMSEL register bits (in your board code) to - * enable SSI output pins! - */ - -/* - * LIMITATIONS: - * The SSI unit has only one physical data line, so full duplex is - * impossible. This can be remedied on the SH7760 by using the - * other SSI unit for recording; however the SH7780 has only 1 SSI - * unit, and its pins are shared with the AC97 unit, among others. - * - * FEATURES: - * The SSI features "compressed mode": in this mode it continuously - * streams PCM data over the I2S lines and uses LRCK as a handshake - * signal. Can be used to send compressed data (AC3/DTS) to a DSP. - * The number of bits sent over the wire in a frame can be adjusted - * and can be independent from the actual sample bit depth. This is - * useful to support TDM mode codecs like the AD1939 which have a - * fixed TDM slot size, regardless of sample resolution. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SSICR 0x00 -#define SSISR 0x04 - -#define CR_DMAEN (1 << 28) -#define CR_CHNL_SHIFT 22 -#define CR_CHNL_MASK (3 << CR_CHNL_SHIFT) -#define CR_DWL_SHIFT 19 -#define CR_DWL_MASK (7 << CR_DWL_SHIFT) -#define CR_SWL_SHIFT 16 -#define CR_SWL_MASK (7 << CR_SWL_SHIFT) -#define CR_SCK_MASTER (1 << 15) /* bitclock master bit */ -#define CR_SWS_MASTER (1 << 14) /* wordselect master bit */ -#define CR_SCKP (1 << 13) /* I2Sclock polarity */ -#define CR_SWSP (1 << 12) /* LRCK polarity */ -#define CR_SPDP (1 << 11) -#define CR_SDTA (1 << 10) /* i2s alignment (msb/lsb) */ -#define CR_PDTA (1 << 9) /* fifo data alignment */ -#define CR_DEL (1 << 8) /* delay data by 1 i2sclk */ -#define CR_BREN (1 << 7) /* clock gating in burst mode */ -#define CR_CKDIV_SHIFT 4 -#define CR_CKDIV_MASK (7 << CR_CKDIV_SHIFT) /* bitclock divider */ -#define CR_MUTE (1 << 3) /* SSI mute */ -#define CR_CPEN (1 << 2) /* compressed mode */ -#define CR_TRMD (1 << 1) /* transmit/receive select */ -#define CR_EN (1 << 0) /* enable SSI */ - -#define SSIREG(reg) (*(unsigned long *)(ssi->mmio + (reg))) - -struct ssi_priv { - unsigned long mmio; - unsigned long sysclk; - int inuse; -} ssi_cpu_data[] = { -#if defined(CONFIG_CPU_SUBTYPE_SH7760) - { - .mmio = 0xFE680000, - }, - { - .mmio = 0xFE690000, - }, -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) - { - .mmio = 0xFFE70000, - }, -#else -#error "Unsupported SuperH SoC" -#endif -}; - -/* - * track usage of the SSI; it is simplex-only so prevent attempts of - * concurrent playback + capture. FIXME: any locking required? - */ -static int ssi_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; - if (ssi->inuse) { - pr_debug("ssi: already in use!\n"); - return -EBUSY; - } else - ssi->inuse = 1; - return 0; -} - -static void ssi_shutdown(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; - - ssi->inuse = 0; -} - -static int ssi_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - SSIREG(SSICR) |= CR_DMAEN | CR_EN; - break; - case SNDRV_PCM_TRIGGER_STOP: - SSIREG(SSICR) &= ~(CR_DMAEN | CR_EN); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int ssi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; - unsigned long ssicr = SSIREG(SSICR); - unsigned int bits, channels, swl, recv, i; - - channels = params_channels(params); - bits = params->msbits; - recv = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 0 : 1; - - pr_debug("ssi_hw_params() enter\nssicr was %08lx\n", ssicr); - pr_debug("bits: %d channels: %d\n", bits, channels); - - ssicr &= ~(CR_TRMD | CR_CHNL_MASK | CR_DWL_MASK | CR_PDTA | - CR_SWL_MASK); - - /* direction (send/receive) */ - if (!recv) - ssicr |= CR_TRMD; /* transmit */ - - /* channels */ - if ((channels < 2) || (channels > 8) || (channels & 1)) { - pr_debug("ssi: invalid number of channels\n"); - return -EINVAL; - } - ssicr |= ((channels >> 1) - 1) << CR_CHNL_SHIFT; - - /* DATA WORD LENGTH (DWL): databits in audio sample */ - i = 0; - switch (bits) { - case 32: ++i; - case 24: ++i; - case 22: ++i; - case 20: ++i; - case 18: ++i; - case 16: ++i; - ssicr |= i << CR_DWL_SHIFT; - case 8: break; - default: - pr_debug("ssi: invalid sample width\n"); - return -EINVAL; - } - - /* - * SYSTEM WORD LENGTH: size in bits of half a frame over the I2S - * wires. This is usually bits_per_sample x channels/2; i.e. in - * Stereo mode the SWL equals DWL. SWL can be bigger than the - * product of (channels_per_slot x samplebits), e.g. for codecs - * like the AD1939 which only accept 32bit wide TDM slots. For - * "standard" I2S operation we set SWL = chans / 2 * DWL here. - * Waiting for ASoC to get TDM support ;-) - */ - if ((bits > 16) && (bits <= 24)) { - bits = 24; /* these are padded by the SSI */ - /*ssicr |= CR_PDTA;*/ /* cpu/data endianness ? */ - } - i = 0; - swl = (bits * channels) / 2; - switch (swl) { - case 256: ++i; - case 128: ++i; - case 64: ++i; - case 48: ++i; - case 32: ++i; - case 16: ++i; - ssicr |= i << CR_SWL_SHIFT; - case 8: break; - default: - pr_debug("ssi: invalid system word length computed\n"); - return -EINVAL; - } - - SSIREG(SSICR) = ssicr; - - pr_debug("ssi_hw_params() leave\nssicr is now %08lx\n", ssicr); - return 0; -} - -static int ssi_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, int clk_id, - unsigned int freq, int dir) -{ - struct ssi_priv *ssi = &ssi_cpu_data[cpu_dai->id]; - - ssi->sysclk = freq; - - return 0; -} - -/* - * This divider is used to generate the SSI_SCK (I2S bitclock) from the - * clock at the HAC_BIT_CLK ("oversampling clock") pin. - */ -static int ssi_set_clkdiv(struct snd_soc_cpu_dai *dai, int did, int div) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - unsigned long ssicr; - int i; - - i = 0; - ssicr = SSIREG(SSICR) & ~CR_CKDIV_MASK; - switch (div) { - case 16: ++i; - case 8: ++i; - case 4: ++i; - case 2: ++i; - SSIREG(SSICR) = ssicr | (i << CR_CKDIV_SHIFT); - case 1: break; - default: - pr_debug("ssi: invalid sck divider %d\n", div); - return -EINVAL; - } - - return 0; -} - -static int ssi_set_fmt(struct snd_soc_cpu_dai *dai, unsigned int fmt) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - unsigned long ssicr = SSIREG(SSICR); - - pr_debug("ssi_set_fmt()\nssicr was 0x%08lx\n", ssicr); - - ssicr &= ~(CR_DEL | CR_PDTA | CR_BREN | CR_SWSP | CR_SCKP | - CR_SWS_MASTER | CR_SCK_MASTER); - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - break; - case SND_SOC_DAIFMT_RIGHT_J: - ssicr |= CR_DEL | CR_PDTA; - break; - case SND_SOC_DAIFMT_LEFT_J: - ssicr |= CR_DEL; - break; - default: - pr_debug("ssi: unsupported format\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { - case SND_SOC_DAIFMT_CONT: - break; - case SND_SOC_DAIFMT_GATED: - ssicr |= CR_BREN; - break; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - ssicr |= CR_SCKP; /* sample data at low clkedge */ - break; - case SND_SOC_DAIFMT_NB_IF: - ssicr |= CR_SCKP | CR_SWSP; - break; - case SND_SOC_DAIFMT_IB_NF: - break; - case SND_SOC_DAIFMT_IB_IF: - ssicr |= CR_SWSP; /* word select starts low */ - break; - default: - pr_debug("ssi: invalid inversion\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - break; - case SND_SOC_DAIFMT_CBS_CFM: - ssicr |= CR_SCK_MASTER; - break; - case SND_SOC_DAIFMT_CBM_CFS: - ssicr |= CR_SWS_MASTER; - break; - case SND_SOC_DAIFMT_CBS_CFS: - ssicr |= CR_SWS_MASTER | CR_SCK_MASTER; - break; - default: - pr_debug("ssi: invalid master/slave configuration\n"); - return -EINVAL; - } - - SSIREG(SSICR) = ssicr; - pr_debug("ssi_set_fmt() leave\nssicr is now 0x%08lx\n", ssicr); - - return 0; -} - -/* the SSI depends on an external clocksource (at HAC_BIT_CLK) even in - * Master mode, so really this is board specific; the SSI can do any - * rate with the right bitclk and divider settings. - */ -#define SSI_RATES \ - SNDRV_PCM_RATE_8000_192000 - -/* the SSI can do 8-32 bit samples, with 8 possible channels */ -#define SSI_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \ - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \ - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) - -struct snd_soc_cpu_dai sh4_ssi_dai[] = { -{ - .name = "SSI0", - .id = 0, - .type = SND_SOC_DAI_I2S, - .playback = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .capture = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .ops = { - .startup = ssi_startup, - .shutdown = ssi_shutdown, - .trigger = ssi_trigger, - .hw_params = ssi_hw_params, - }, - .dai_ops = { - .set_sysclk = ssi_set_sysclk, - .set_clkdiv = ssi_set_clkdiv, - .set_fmt = ssi_set_fmt, - }, -}, -#ifdef CONFIG_CPU_SUBTYPE_SH7760 -{ - .name = "SSI1", - .id = 1, - .type = SND_SOC_DAI_I2S, - .playback = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .capture = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .ops = { - .startup = ssi_startup, - .shutdown = ssi_shutdown, - .trigger = ssi_trigger, - .hw_params = ssi_hw_params, - }, - .dai_ops = { - .set_sysclk = ssi_set_sysclk, - .set_clkdiv = ssi_set_clkdiv, - .set_fmt = ssi_set_fmt, - }, -}, -#endif -}; -EXPORT_SYMBOL_GPL(sh4_ssi_dai); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver"); -MODULE_AUTHOR("Manuel Lauss "); diff --git a/trunk/sound/usb/usbaudio.c b/trunk/sound/usb/usbaudio.c index 7bd5852fcc0d..8ebc1adb5ed9 100644 --- a/trunk/sound/usb/usbaudio.c +++ b/trunk/sound/usb/usbaudio.c @@ -2350,9 +2350,7 @@ static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat * return 1; break; case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ - if (device_setup[chip->index] == 0x00 || - fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3) - return 1; + return 1; } return 0; } @@ -2532,18 +2530,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat * * but we give normal PCM format to get the existing * apps working... */ - switch (chip->usb_id) { - - case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ - if (device_setup[chip->index] == 0x00 && - fp->altsetting == 6) - pcm_format = SNDRV_PCM_FORMAT_S16_BE; - else - pcm_format = SNDRV_PCM_FORMAT_S16_LE; - break; - default: - pcm_format = SNDRV_PCM_FORMAT_S16_LE; - } + pcm_format = SNDRV_PCM_FORMAT_S16_LE; } else { pcm_format = parse_audio_format_i_type(chip, fp, format, fmt); if (pcm_format < 0) @@ -3264,11 +3251,6 @@ static int snd_usb_cm106_boot_quirk(struct usb_device *dev) static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, int iface, int altno) { - /* Reset ALL ifaces to 0 altsetting. - * Call it for every possible altsetting of every interface. - */ - usb_set_interface(chip->dev, iface, 0); - if (device_setup[chip->index] & AUDIOPHILE_SET) { if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS) && altno != 6) diff --git a/trunk/sound/usb/usbquirks.h b/trunk/sound/usb/usbquirks.h index 5a2f518c6629..374fbf657a2d 100644 --- a/trunk/sound/usb/usbquirks.h +++ b/trunk/sound/usb/usbquirks.h @@ -52,24 +52,6 @@ .bInterfaceClass = USB_CLASS_AUDIO, .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL }, -{ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, - .idVendor = 0x046d, - .idProduct = 0x08ae, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL -}, -{ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, - .idVendor = 0x046d, - .idProduct = 0x08c6, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL -}, { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_CLASS | @@ -1069,15 +1051,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), .type = QUIRK_MIDI_STANDARD_INTERFACE } }, -{ - USB_DEVICE(0x0582, 0x0060), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "Roland", - .product_name = "EXR Series", - .ifnum = 0, - .type = QUIRK_MIDI_STANDARD_INTERFACE - } -}, + /* TODO: add Roland EXR support */ { /* has ID 0x0067 when not in "Advanced Driver" mode */ USB_DEVICE(0x0582, 0x0065), @@ -1120,19 +1094,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, -{ - USB_DEVICE(0x582, 0x00a6), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "Roland", - .product_name = "Juno-G", - .ifnum = 0, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const struct snd_usb_midi_endpoint_info) { - .out_cables = 0x0001, - .in_cables = 0x0001 - } - } -}, { /* * This quirk is for the "Advanced" modes of the Edirol UA-25. * If the switch is not in an advanced setting, the UA-25 has @@ -1269,37 +1230,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, /* TODO: add Edirol MD-P1 support */ -{ - /* Roland SH-201 */ - USB_DEVICE(0x0582, 0x00ad), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "Roland", - .product_name = "SH-201", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const struct snd_usb_audio_quirk[]) { - { - .ifnum = 0, - .type = QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const struct snd_usb_midi_endpoint_info) { - .out_cables = 0x0001, - .in_cables = 0x0001 - } - }, - { - .ifnum = -1 - } - } - } -}, /* Guillemot devices */ { diff --git a/trunk/sound/usb/usx2y/usbusx2yaudio.c b/trunk/sound/usb/usx2y/usbusx2yaudio.c index 48e9aa3f18c9..0a352e46862f 100644 --- a/trunk/sound/usb/usx2y/usbusx2yaudio.c +++ b/trunk/sound/usb/usx2y/usbusx2yaudio.c @@ -935,9 +935,10 @@ static struct snd_pcm_ops snd_usX2Y_pcm_ops = */ static void usX2Y_audio_stream_free(struct snd_usX2Y_substream **usX2Y_substream) { - kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]); - usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK] = NULL; - + if (NULL != usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]) { + kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]); + usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK] = NULL; + } kfree(usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]); usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE] = NULL; }